diff --git a/.gitignore b/.gitignore index 7c2d6ec..60fb59a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,38 @@ node_modules /generated subgraph.yaml /build + +# Graph CLI generated artifacts +build/ +generated/ + +# Dependency directories +node_modules/ +jspm_packages/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# dotenv environment variables file +.env + +# Testing +coverage +coverage.json + +# Typechain +typechain +typechain-types + +# Hardhat files +cache diff --git a/Pipfile b/Pipfile index 7a9e19a..ee360a9 100644 --- a/Pipfile +++ b/Pipfile @@ -8,4 +8,4 @@ name = "pypi" [dev-packages] [requires] -python_version = "3.6" +python_version = "3.6" \ No newline at end of file diff --git a/README.md b/README.md index 473abce..65b9e8a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# subgraph-test +# base-index-test 1. Install node packages -2. Generate types and classes ```npm run init``` -3. Run ```npm run prepare:``` to create a subgraph manifest specifically for the deployment chain +2. Generate types and classes `npm run init` +3. Run `npm run prepare:` to create a subgraph manifest specifically for the deployment chain 4. Deploy subgraph to your studio or hosted service account diff --git a/abis/v3/ConfigBuilderV3.json b/abis/v3/ConfigBuilderV3.json new file mode 100644 index 0000000..68d0f80 --- /dev/null +++ b/abis/v3/ConfigBuilderV3.json @@ -0,0 +1,149 @@ +{ + "abi": [ + { + "type": "event", + "name": "ConfigUpdated", + "inputs": [ + { + "name": "encodedConfig", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "CurrenciesUpdate", + "inputs": [ + { + "name": "currenciesHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "CurrencyRegistered", + "inputs": [ + { + "name": "currency", + "type": "address", + "indexed": false, + "internalType": "Currency" + }, + { + "name": "name", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "symbol", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "decimals", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FinishRebalancing", + "inputs": [ + { + "name": "snapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "newCurrencyIdSet", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + }, + { + "name": "weights", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FinishVaultRebalancing", + "inputs": [ + { + "name": "snapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "currencyIdSet", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + }, + { + "name": "currencies", + "type": "address[]", + "indexed": false, + "internalType": "Currency[]" + }, + { + "name": "balances", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ReceiveVaultResult", + "inputs": [ + { + "name": "resultHash", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetForwarder", + "inputs": [ + { + "name": "forwarder", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StartRebalancing", + "inputs": [], + "anonymous": false + } + ] +} diff --git a/abis/v3/IndexFactoryV3.json b/abis/v3/IndexFactoryV3.json new file mode 100644 index 0000000..2ecc3c7 --- /dev/null +++ b/abis/v3/IndexFactoryV3.json @@ -0,0 +1,41 @@ +{ + "abi": [ + { + "type": "event", + "name": "Deployed", + "inputs": [ + { + "name": "index", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "name", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "symbol", + "type": "string", + "indexed": false, + "internalType": "string" + }, + { + "name": "reserve", + "type": "address", + "indexed": false, + "internalType": "Currency" + }, + { + "name": "governance", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + } + ] +} diff --git a/abis/v3/IndexTokenV3.json b/abis/v3/IndexTokenV3.json new file mode 100644 index 0000000..5874cdb --- /dev/null +++ b/abis/v3/IndexTokenV3.json @@ -0,0 +1,413 @@ +{ + "abi": [ + { + "type": "event", + "name": "AdminChanged", + "inputs": [ + { + "name": "previousAdmin", + "type": "address", + "indexed": false, + "internalType": "address" + }, + { + "name": "newAdmin", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "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": "BeaconUpgraded", + "inputs": [ + { + "name": "beacon", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ConfigUpdated", + "inputs": [ + { + "name": "encodedConfig", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Consume", + "inputs": [ + { + "name": "currency", + "type": "address", + "indexed": false, + "internalType": "Currency" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Deposit", + "inputs": [ + { + "name": "sender", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "owner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "reserve", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Donate", + "inputs": [ + { + "name": "currency", + "type": "address", + "indexed": false, + "internalType": "Currency" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeAccrued", + "inputs": [ + { + "name": "depositFee", + "type": "uint96", + "indexed": false, + "internalType": "uint96" + }, + { + "name": "redemptionFee", + "type": "uint96", + "indexed": false, + "internalType": "uint96" + }, + { + "name": "AUMFee", + "type": "uint96", + "indexed": false, + "internalType": "uint96" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FeeSettled", + "inputs": [ + { + "name": "fee", + "type": "uint96", + "indexed": false, + "internalType": "uint96" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "FinishRebalancing", + "inputs": [ + { + "name": "snapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "currencies", + "type": "address[]", + "indexed": false, + "internalType": "Currency[]" + }, + { + "name": "balances", + "type": "uint256[]", + "indexed": false, + "internalType": "uint256[]" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint8", + "indexed": false, + "internalType": "uint8" + } + ], + "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": "SetConfigBuilder", + "inputs": [ + { + "name": "configBuilder", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SetRebalancer", + "inputs": [ + { + "name": "rebalancer", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "SnapshotTransfer", + "inputs": [ + { + "name": "snapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "amount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "from", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "to", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "StartRebalancing", + "inputs": [ + { + "name": "snapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "kBalance", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "withdrawals", + "type": "tuple", + "indexed": false, + "internalType": "struct IVault.CurrencyWithdrawal", + "components": [ + { + "name": "currencyIndexSet", + "type": "uint256[]", + "internalType": "uint256[]" + }, + { + "name": "amounts", + "type": "uint256[]", + "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": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "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": "shares", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "k", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "reserve", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + } + ] +} diff --git a/config/base.json b/config/base.json index 71b7d6b..4108054 100644 --- a/config/base.json +++ b/config/base.json @@ -1,31 +1,22 @@ { - "network": "base", - "chainID": 8453, - "v1": false, - "v2": { - "indexFactory": [ - { - "name": "CookieTestFactory", - "address": "0x91318C0675df6be2AA16A420cCC22705C66b37De", - "startBlock": 25377665, - "nativeAsset": { - "name": "Ethereum", - "symbol": "ETH", - "decimals": 18 - } - }, - { - "name": "JMXFactory", - "address": "0xb1E88fd8cC0bcfCaB479f7DDDb8e972a52c62Dfd", - "startBlock": 25386107, - "nativeAsset": { - "name": "Ethereum", - "symbol": "ETH", - "decimals": 18 - } - } - ] - }, - "ephtr": false, - "savingsVaults": false -} \ No newline at end of file + "network": "base", + "chainID": 8453, + "v1": false, + "v2": false, + "v3": { + "indexFactory": [ + { + "name": "JMXFactoryProd", + "address": "0x9c5816bd3B4C360427EFC5FCbFB82A60C8c279F8", + "startBlock": 25771303, + "nativeAsset": { + "name": "Ethereum", + "symbol": "ETH", + "decimals": 18 + } + } + ] + }, + "ephtr": false, + "savingsVaults": false +} diff --git a/config/init.json b/config/init.json index 1d1d357..1ac5d04 100644 --- a/config/init.json +++ b/config/init.json @@ -1,28 +1,35 @@ { - "network": "mainnet", - "chainID": 1, - "v1": { - "indexFactory": { - "address": "0x0000000000000000000000000000000000000000", - "startBlock": 1 - } - }, - "v2": { - "indexFactory": { - "name": "IndexFactoryV2", - "address": "0x0000000000000000000000000000000000000000", - "startBlock": 1 - } - }, - "ephtr": true, - "savingsVaults": [ - { - "name": "USVVault", - "address": "0x0000000000000000000000000000000000000000", - "vaultAsset": "0x0000000000000000000000000000000000000000", - "viewAddress": "0x0000000000000000000000000000000000000000", - "chainlinkFeedRegistryAddress": "0x0000000000000000000000000000000000000000", - "startBlock": 1 - } - ] -} \ No newline at end of file + "network": "mainnet", + "chainID": 1, + "v1": { + "indexFactory": { + "address": "0x0000000000000000000000000000000000000000", + "startBlock": 1 + } + }, + "v2": { + "indexFactory": { + "name": "IndexFactoryV2", + "address": "0x0000000000000000000000000000000000000000", + "startBlock": 1 + } + }, + "v3": { + "indexFactory": { + "name": "IndexFactoryV3", + "address": "0x0000000000000000000000000000000000000000", + "startBlock": 1 + } + }, + "ephtr": true, + "savingsVaults": [ + { + "name": "USVVault", + "address": "0x0000000000000000000000000000000000000000", + "vaultAsset": "0x0000000000000000000000000000000000000000", + "viewAddress": "0x0000000000000000000000000000000000000000", + "chainlinkFeedRegistryAddress": "0x0000000000000000000000000000000000000000", + "startBlock": 1 + } + ] +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a008fc9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,50 @@ +version: "3" +services: + graph-node: + image: graphprotocol/graph-node + ports: + - "8000:8000" + - "8001:8001" + - "8020:8020" + - "8030:8030" + - "8040:8040" + depends_on: + - ipfs + - postgres + extra_hosts: + - host.docker.internal:host-gateway + environment: + postgres_host: postgres + postgres_user: graph-node + postgres_pass: let-me-in + postgres_db: graph-node + ipfs: "ipfs:5001" + ethereum: "mainnet:http://host.docker.internal:8545" + GRAPH_LOG: info + ipfs: + image: ipfs/kubo:v0.17.0 + ports: + - "5001:5001" + volumes: + - ./data/ipfs:/data/ipfs + postgres: + image: postgres:14 + ports: + - "5432:5432" + command: + [ + "postgres", + "-cshared_preload_libraries=pg_stat_statements", + "-cmax_connections=200", + ] + environment: + POSTGRES_USER: graph-node + POSTGRES_PASSWORD: let-me-in + POSTGRES_DB: graph-node + # FIXME: remove this env. var. which we shouldn't need. Introduced by + # , maybe as a + # workaround for https://github.com/docker/for-mac/issues/6270? + PGDATA: "/var/lib/postgresql/data" + POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" + volumes: + - ./data/postgres:/var/lib/postgresql/data diff --git a/dockerfile b/dockerfile index 7edfd76..658c823 100644 --- a/dockerfile +++ b/dockerfile @@ -6,7 +6,7 @@ ENV ARGS="" RUN apt update \ && apt install -y sudo curl postgresql postgresql-contrib - + RUN curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - \ && sudo apt-get install -y nodejs diff --git a/package-lock.json b/package-lock.json index 8e64825..f9d3118 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10 +1,10 @@ { - "name": "subgraph-test", + "name": "base-index-test", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "subgraph-test", + "name": "base-index-test", "license": "UNLICENSED", "dependencies": { "@graphprotocol/graph-ts": "^0.35.0", @@ -15,17 +15,18 @@ } }, "node_modules/@graphprotocol/graph-ts": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.35.0.tgz", - "integrity": "sha512-dM+I/e/WeBa8Q3m4ZLFfJjKBS9YwV+DLggWi8oEIGmnhPAZ298QB6H4hquvxqaOTSXJ2j9tPsw3xSmbRLwk39A==", + "version": "0.35.1", + "resolved": "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.35.1.tgz", + "integrity": "sha512-74CfuQmf7JI76/XCC34FTkMMKeaf+3Pn0FIV3m9KNeaOJ+OI3CvjMIVRhOZdKcJxsFCBGaCCl0eQjh47xTjxKA==", "dependencies": { "assemblyscript": "0.19.10" } }, - "node_modules/@graphprotocol/graph-ts/node_modules/assemblyscript": { + "node_modules/assemblyscript": { "version": "0.19.10", "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.10.tgz", "integrity": "sha512-HavcUBXB3mBTRGJcpvaQjmnmaqKHBGREjSPNsIvnAk2f9dj78y4BkMaSSdvBQYWcDDzsHQjyUC8stICFkD1Odg==", + "license": "Apache-2.0", "dependencies": { "binaryen": "101.0.0-nightly.20210723", "long": "^4.0.0" @@ -39,43 +40,11 @@ "url": "https://opencollective.com/assemblyscript" } }, - "node_modules/@graphprotocol/graph-ts/node_modules/binaryen": { + "node_modules/binaryen": { "version": "101.0.0-nightly.20210723", "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210723.tgz", "integrity": "sha512-eioJNqhHlkguVSbblHOtLqlhtC882SOEPKmNFZaDuz1hzQjolxZ+eu3/kaS10n3sGPONsIZsO7R9fR00UyhEUA==", - "bin": { - "wasm-opt": "bin/wasm-opt" - } - }, - "node_modules/@graphprotocol/graph-ts/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/assemblyscript": { - "version": "0.19.23", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.23.tgz", - "integrity": "sha512-fwOQNZVTMga5KRsfY80g7cpOl4PsFQczMwHzdtgoqLXaYhkhavufKb0sB0l3T1DUxpAufA0KNhlbpuuhZUwxMA==", - "dev": true, - "dependencies": { - "binaryen": "102.0.0-nightly.20211028", - "long": "^5.2.0", - "source-map-support": "^0.5.20" - }, - "bin": { - "asc": "bin/asc", - "asinit": "bin/asinit" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/assemblyscript" - } - }, - "node_modules/binaryen": { - "version": "102.0.0-nightly.20211028", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-102.0.0-nightly.20211028.tgz", - "integrity": "sha512-GCJBVB5exbxzzvyt8MGDv/MeUjs6gkXDvf4xOIItRBptYl0Tz5sm1o/uG95YK0L0VeG5ajDu3hRtkBP2kzqC5w==", - "dev": true, + "license": "Apache-2.0", "bin": { "wasm-opt": "bin/wasm-opt" } @@ -84,19 +53,21 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" }, "node_modules/matchstick-as": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/matchstick-as/-/matchstick-as-0.5.0.tgz", "integrity": "sha512-4K619YDH+so129qt4RB4JCNxaFwJJYLXPc7drpG+/mIj86Cfzg6FKs/bA91cnajmS1CLHdhHl9vt6Kd6Oqvfkg==", "dev": true, + "license": "MIT", "dependencies": { "@graphprotocol/graph-ts": "^0.27.0", "assemblyscript": "^0.19.20", @@ -117,6 +88,7 @@ "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.10.tgz", "integrity": "sha512-HavcUBXB3mBTRGJcpvaQjmnmaqKHBGREjSPNsIvnAk2f9dj78y4BkMaSSdvBQYWcDDzsHQjyUC8stICFkD1Odg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "binaryen": "101.0.0-nightly.20210723", "long": "^4.0.0" @@ -130,25 +102,48 @@ "url": "https://opencollective.com/assemblyscript" } }, - "node_modules/matchstick-as/node_modules/binaryen": { - "version": "101.0.0-nightly.20210723", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-101.0.0-nightly.20210723.tgz", - "integrity": "sha512-eioJNqhHlkguVSbblHOtLqlhtC882SOEPKmNFZaDuz1hzQjolxZ+eu3/kaS10n3sGPONsIZsO7R9fR00UyhEUA==", + "node_modules/matchstick-as/node_modules/assemblyscript": { + "version": "0.19.23", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.19.23.tgz", + "integrity": "sha512-fwOQNZVTMga5KRsfY80g7cpOl4PsFQczMwHzdtgoqLXaYhkhavufKb0sB0l3T1DUxpAufA0KNhlbpuuhZUwxMA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "binaryen": "102.0.0-nightly.20211028", + "long": "^5.2.0", + "source-map-support": "^0.5.20" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" + } + }, + "node_modules/matchstick-as/node_modules/assemblyscript/node_modules/binaryen": { + "version": "102.0.0-nightly.20211028", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-102.0.0-nightly.20211028.tgz", + "integrity": "sha512-GCJBVB5exbxzzvyt8MGDv/MeUjs6gkXDvf4xOIItRBptYl0Tz5sm1o/uG95YK0L0VeG5ajDu3hRtkBP2kzqC5w==", "dev": true, + "license": "Apache-2.0", "bin": { "wasm-opt": "bin/wasm-opt" } }, - "node_modules/matchstick-as/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true + "node_modules/matchstick-as/node_modules/assemblyscript/node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/mustache": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", "bin": { "mustache": "bin/mustache" } @@ -158,6 +153,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -167,6 +163,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -177,6 +174,7 @@ "resolved": "https://registry.npmjs.org/wabt/-/wabt-1.0.24.tgz", "integrity": "sha512-8l7sIOd3i5GWfTWciPL0+ff/FK/deVK2Q6FN+MPz4vfUcD78i2M/49XJTwF6aml91uIiuXJEsLKWMB2cw/mtKg==", "dev": true, + "license": "Apache-2.0", "bin": { "wasm-decompile": "bin/wasm-decompile", "wasm-interp": "bin/wasm-interp", diff --git a/package.json b/package.json index 16a2d92..f8d20e4 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { - "name": "subgraph-test", + "name": "base-index-test", "license": "UNLICENSED", "scripts": { "codegen": "graph codegen", "build": "graph build", - "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ subgraph-test", - "create-local": "graph create --node http://localhost:8020/ subgraph-test", - "remove-local": "graph remove --node http://localhost:8020/ subgraph-test", - "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 subgraph-test", + "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ base-index-test", + "create-local": "graph create --node http://localhost:8020/ base-index-test", + "remove-local": "graph remove --node http://localhost:8020/ base-index-test", + "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 base-index-test", "test": "graph test", "prepare:mainnet": "npm run clean && npx mustache config/mainnet.json subgraph.template.yaml > subgraph.yaml", "prepare:avalanche": "npm run clean && npx mustache config/avalanche.json subgraph.template.yaml > subgraph.yaml", diff --git a/schema.graphql b/schema.graphql index a6cd8b7..f609fb3 100644 --- a/schema.graphql +++ b/schema.graphql @@ -12,21 +12,21 @@ type Index @entity { aumFee: BigDecimal! k: BigInt isRebalancing: Boolean - anatomy: Anatomy @derivedFrom(field:"index") - lzConfig: LZConfig @derivedFrom(field:"index") - config : Config @derivedFrom(field:"index") + anatomy: Anatomy @derivedFrom(field: "index") + lzConfig: LZConfig @derivedFrom(field: "index") + config: Config @derivedFrom(field: "index") totalFees: BigDecimal totalSupply: BigDecimal! holders: BigInt! assets: [ChainIDToAssetMapping!]! - history: [HistoricalIndexBalance!]! @derivedFrom(field:"index") + history: [HistoricalIndexBalance!]! @derivedFrom(field: "index") } "Entry point for all information related to accounts" type Account @entity { id: Bytes! - indices: [IndexAccount!]! @derivedFrom(field:"account") - history: [HistoricalAccountBalance!]! @derivedFrom(field:"account") + indices: [IndexAccount!]! @derivedFrom(field: "account") + history: [HistoricalAccountBalance!]! @derivedFrom(field: "account") } type IndexAsset @entity { @@ -60,7 +60,7 @@ type HistoricalIndexBalance @entity { type HistoricalAccountBalance @entity { id: String! timestamp: BigInt! - index: Bytes! + index: Bytes! account: Account! balance: BigDecimal! } @@ -73,7 +73,7 @@ type HistoricalIndexAsset @entity { chainID: BigInt! timestamp: BigInt! balance: BigDecimal! - weight:BigInt + weight: BigInt } type HistoricalPrice @entity { @@ -88,6 +88,7 @@ enum ProtocolVersion { Undefined v1 v2 + v3 } type ChainIDToAssetMapping @entity { @@ -115,7 +116,7 @@ type Config @entity { type LZConfig @entity { id: Bytes! index: Index! - eIds:BigInt! + eIds: BigInt! minGas: [BigInt!]! } @@ -131,4 +132,4 @@ type CurrencySet @entity { index: Bytes! chainIndex: BigInt! sets: [BigInt!]! -} \ No newline at end of file +} diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..d0e7f11 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,9 @@ +import { BigInt } from "@graphprotocol/graph-ts"; + +export const ZERO = BigInt.zero(); +export const ONE = BigInt.fromI32(1); +export const TEN = BigInt.fromI32(10); +export const BP = BigInt.fromI32(10000); +export const WAD = TEN.pow(18); +export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' +export const ADDRESS_LENGTH = ZERO_ADDRESS.length diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..5aeca61 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,36 @@ +import { BigInt, TypedMap } from "@graphprotocol/graph-ts"; + +let chainIDMap = new TypedMap>() +chainIDMap.set(BigInt.fromI32(43114), ["Avalanche", "AVAX", "18"]) +chainIDMap.set(BigInt.fromI32(43113), ["Avalanche", "AVAX", "18"]) +chainIDMap.set(BigInt.fromI32(80001), ["Matic", "MATIC", "18"]) +chainIDMap.set(BigInt.fromI32(137), ["Matic", "MATIC", "18"]) +chainIDMap.set(BigInt.fromI32(97), ["Binance Coin", "BNB", "18"]) +chainIDMap.set(BigInt.fromI32(56), ["Binance Coin", "BNB", "18"]) +chainIDMap.set(BigInt.fromI32(1), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(42161), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(10), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(8453), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(100), ["XDAI", "XDAI", "18"]) +chainIDMap.set(BigInt.fromI32(10200), ["XDAI", "XDAI", "18"]) +chainIDMap.set(BigInt.fromI32(5000), ["Mantle", "MNT", "18"]) +chainIDMap.set(BigInt.fromI32(250), ["Fantom", "FTM", "18"]) +chainIDMap.set(BigInt.fromI32(4002), ["Fantom", "FTM", "18"]) +chainIDMap.set(BigInt.fromI32(1088), ["Metis", "METIS", "18"]) +chainIDMap.set(BigInt.fromI32(59144), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(40), ["Telos", "TLOS", "18"]) +chainIDMap.set(BigInt.fromI32(1313161554), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(204), ["Binance Coin", "BNB", "18"]) +chainIDMap.set(BigInt.fromI32(41), ["Telos", "TLOS", "18"]) +chainIDMap.set(BigInt.fromI32(5003), ["Mantle", "MNT", "18"]) +chainIDMap.set(BigInt.fromI32(84532), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(421614), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(11155111), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(11155420), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(7700), ["Canto", "CANTO", "18"]) +chainIDMap.set(BigInt.fromI32(59140), ["Ethereum", "ETH", "18"]) +chainIDMap.set(BigInt.fromI32(5611), ["Binance Coin", "tBNB", "18"]) + +export function selectNativeAsset(chainID: BigInt): Array | null { + return chainIDMap.get(chainID) +} \ No newline at end of file diff --git a/src/v2/ConfigBuilder.ts b/src/v2/ConfigBuilder.ts index 50fce6e..a893ec3 100644 --- a/src/v2/ConfigBuilder.ts +++ b/src/v2/ConfigBuilder.ts @@ -1,9 +1,8 @@ -import { Bytes, BigInt, Address, ethereum, dataSource, BigDecimal, log, ByteArray, TypedMap, DataSourceContext } from "@graphprotocol/graph-ts"; +import { Address, BigDecimal, BigInt, Bytes, dataSource, DataSourceContext, ethereum, log, TypedMap } from "@graphprotocol/graph-ts"; +import { Messenger } from "../../generated/templates"; +import { ConfigUpdated as ConfigUpdatedEvent, CurrencyRegistered as CurrencyRegisteredEvent, FinishChainRebalancing as FinishChainRebalancingEvent, FinishRebalancing as FinishRebalancingEvent, RegisterChain as RegisterChainEvent, SetMessenger as SetMessengerEvent, StartRebalancing as StartRebalancingEvent } from "../../generated/templates/ConfigBuilder/ConfigBuilder"; import { createOrLoadAnatomyEntity, createOrLoadChainIDToAssetMappingEntity, createOrLoadConfigEntity, createOrLoadCurrencySetEntity, createOrLoadHistoricalIndexAssetEntity, createOrLoadHistoricalIndexBalanceEntity, createOrLoadIndexAssetEntity, createOrLoadIndexEntity, loadChainIDToAssetMappingEntity, loadIndexAssetEntity } from "../EntityCreation"; -import { ConfigUpdated as ConfigUpdatedEvent, CurrencyRegistered as CurrencyRegisteredEvent, FinishChainRebalancing as FinishChainRebalancingEvent, RegisterChain as RegisterChainEvent, FinishRebalancing as FinishRebalancingEvent, SetMessenger as SetMessengerEvent, StartRebalancing as StartRebalancingEvent } from "../../generated/templates/ConfigBuilder/ConfigBuilder" import { convertAUMFeeRate } from "../v1/FeePool"; -import { CurrencySet, HistoricalIndexAsset } from "../../generated/schema"; -import { Messenger } from "../../generated/templates"; export function handleConfigUpdate(event: ConfigUpdatedEvent): void { let indexAddress = dataSource.context().getBytes('indexAddress') diff --git a/src/v3/ConfigBuilder.ts b/src/v3/ConfigBuilder.ts new file mode 100644 index 0000000..a4b85ba --- /dev/null +++ b/src/v3/ConfigBuilder.ts @@ -0,0 +1,278 @@ +import { + BigDecimal, + BigInt, + Bytes, + dataSource, + ethereum, + log +} from "@graphprotocol/graph-ts"; + +import { + ConfigUpdated as ConfigUpdatedEvent, + CurrencyRegistered as CurrencyRegisteredEvent, + FinishRebalancing as FinishRebalancingEvent, + FinishVaultRebalancing as FinishVaultRebalancingEvent, + StartRebalancing as StartRebalancingEvent, +} from "../../generated/templates/ConfigBuilderV3/ConfigBuilderV3"; +import { + createOrLoadAnatomyEntity, + createOrLoadChainIDToAssetMappingEntity, + createOrLoadConfigEntity, + createOrLoadCurrencySetEntity, + createOrLoadHistoricalIndexAssetEntity, + createOrLoadHistoricalIndexBalanceEntity, + createOrLoadIndexAssetEntity, + createOrLoadIndexEntity, + loadChainIDToAssetMappingEntity, + loadIndexAssetEntity, +} from "../EntityCreation"; + +import { BP, ONE, TEN, WAD, ZERO } from "../constants"; +import { convertAUMFeeRate } from "../v1/FeePool"; + +export function handleConfigUpdate(event: ConfigUpdatedEvent): void { + const indexAddress = dataSource.context().getBytes("indexAddress"); + const indexEntity = createOrLoadIndexEntity(indexAddress); + const configEntity = createOrLoadConfigEntity(indexAddress); + const decoded = ethereum + .decode( + "((uint256,bool,address),(uint16,bool),(uint16,bool))", + event.params.encodedConfig, + )! + .toTuple(); + configEntity.AUMDilutionPerSecond = decoded[0].toTuple()[0].toBigInt(); + configEntity.useCustomAUMFee = decoded[0].toTuple()[1].toBoolean(); + configEntity.metadata = decoded[0].toTuple()[2].toAddress(); + configEntity.depositFeeInBP = decoded[1].toTuple()[0].toBigInt(); + configEntity.depositCustomCallback = decoded[1].toTuple()[1].toBoolean(); + configEntity.redemptionFeeInBP = decoded[2].toTuple()[0].toBigInt(); + configEntity.redemptionCustomCallback = decoded[2].toTuple()[1].toBoolean(); + const aumFee = decoded[0].toTuple()[0].toBigInt(); + const scalar = new BigDecimal(BP); + const mintingFee = new BigDecimal(decoded[1].toTuple()[0].toBigInt()).div( + scalar, + ); + const redemptionFee = new BigDecimal(decoded[2].toTuple()[0].toBigInt()).div( + scalar, + ); + indexEntity.mintingFee = mintingFee; + indexEntity.redemptionFee = redemptionFee; + indexEntity.save(); + configEntity.save(); + convertAUMFeeRate(indexAddress, aumFee); +} + +export function handleStartRebalancing(event: StartRebalancingEvent): void { + const indexAddress = dataSource.context().getBytes("indexAddress"); + const indexEntity = createOrLoadIndexEntity(indexAddress); + indexEntity.isRebalancing = true; + indexEntity.save(); +} + +export function handleCurrencyRegistered(event: CurrencyRegisteredEvent): void { + const builderContext = dataSource.context() + const indexAddress = builderContext.getBytes("indexAddress"); + const chainID = builderContext.getBigInt("chainID"); + log.debug("Currency registered event: {} {} {} {} {}", [event.params.name, event.params.symbol, event.params.decimals.toString(), event.params.currency.toHexString(), chainID.toString()]) + + const indexAssetEntity = createOrLoadIndexAssetEntity( + indexAddress, + event.params.currency, + chainID, + ); + const chainIDToAssetMappingEntity = createOrLoadChainIDToAssetMappingEntity( + indexAddress, + chainID, + ); + indexAssetEntity.name = event.params.name; + indexAssetEntity.symbol = event.params.symbol; + indexAssetEntity.decimals = event.params.decimals; + indexAssetEntity.currencyID = chainIDToAssetMappingEntity.registeredAssets; + + chainIDToAssetMappingEntity.registeredAssets = + chainIDToAssetMappingEntity.registeredAssets!.plus(ONE); + + chainIDToAssetMappingEntity.save(); + indexAssetEntity.save(); +} + +export function handleFinishChainRebalancing( + event: FinishVaultRebalancingEvent, +): void { + const indexAddress = dataSource.context().getBytes("indexAddress"); + const reserveAsset = dataSource.context().getBytes("reserveAsset"); + const indexEntity = createOrLoadIndexEntity(indexAddress); + const chainID = dataSource.context().getBigInt("chainID"); + const chainIDToAssetMappingEntity = createOrLoadChainIDToAssetMappingEntity( + indexAddress, + chainID, + ); + chainIDToAssetMappingEntity.latestSnapshot = event.params.snapshot; + if (event.params.currencies.length == 0) { + for (let i = 0; i < chainIDToAssetMappingEntity.assets.length; i++) { + const indexAssetEntity = loadIndexAssetEntity( + chainIDToAssetMappingEntity.assets[i], + ); + indexAssetEntity.balance = BigDecimal.zero(); + indexAssetEntity.weight = ZERO; + indexAssetEntity.save(); + } + const emptyAssetArray: string[] = []; + if (chainID == indexEntity.chainID) { + emptyAssetArray.push( + createOrLoadIndexAssetEntity( + indexAddress, + reserveAsset, + indexEntity.chainID, + ).id, + ); + } + chainIDToAssetMappingEntity.assets = emptyAssetArray; + chainIDToAssetMappingEntity.save(); + + const indexAssets = indexEntity.assets; + const idx = indexAssets.indexOf(chainIDToAssetMappingEntity.id); + indexAssets.splice(idx, 1); + indexEntity.assets = indexAssets; + indexEntity.save(); + } else { + const chainIDAssetArray: string[] = []; + const reserveAssetEntity = createOrLoadIndexAssetEntity( + indexAddress, + reserveAsset, + indexEntity.chainID, + ); + if (chainID == indexEntity.chainID) { + reserveAssetEntity.balance = BigDecimal.zero(); + reserveAssetEntity.save(); + chainIDAssetArray.push(reserveAssetEntity.id); + } + for (let i = 0; i < event.params.currencies.length; i++) { + const balance = new BigDecimal(event.params.balances[i]); + const asset = event.params.currencies[i]; + log.warning('FinishVaultRebalancingEvent currencies[i] = {}', [asset.toHexString()]) + const indexAssetEntity = createOrLoadIndexAssetEntity( + indexAddress, + asset, + chainID, + ); + const scalar = new BigDecimal(TEN.pow(u8(indexAssetEntity.decimals))); + indexAssetEntity.balance = balance.div(scalar); + indexAssetEntity.save(); + if (indexAssetEntity.id != reserveAssetEntity.id) { + chainIDAssetArray.push(indexAssetEntity.id); + } + } + for (let i = 0; i < chainIDToAssetMappingEntity.assets.length; i++) { + const id = chainIDToAssetMappingEntity.assets[i]; + if (!chainIDAssetArray.includes(id)) { + const indexAssetEntity = loadIndexAssetEntity(id); + indexAssetEntity.balance = BigDecimal.zero(); + indexAssetEntity.weight = ZERO; + indexAssetEntity.save(); + } + } + chainIDToAssetMappingEntity.assets = chainIDAssetArray; + chainIDToAssetMappingEntity.save(); + + if (!indexEntity.assets.includes(chainIDToAssetMappingEntity.id)) { + const indexAssetArray = indexEntity.assets; + indexAssetArray.push(chainIDToAssetMappingEntity.id); + log.debug('indexAssetArray: {}', [indexAssetArray.join('-')]) + indexEntity.assets = indexAssetArray; + indexEntity.save(); + } + } + chainIDToAssetMappingEntity.save(); + indexEntity.k = WAD; + indexEntity.save(); + saveHistoricalData(indexAddress, event.block.timestamp); +} + +export function saveHistoricalData(index: Bytes, timestamp: BigInt): void { + const indexEntity = createOrLoadIndexEntity(index); + const historicalIndexBalanceEntity = createOrLoadHistoricalIndexBalanceEntity( + index, + timestamp, + ); + historicalIndexBalanceEntity.totalSupply = indexEntity.totalSupply; + const historicalIndexAssetArray: string[] = []; + for (let i = 0; i < indexEntity.assets.length; i++) { + const chainIDToAssetMappingEntity = loadChainIDToAssetMappingEntity( + indexEntity.assets[i], + ); + const chainID = chainIDToAssetMappingEntity.chainID; + for (let y = 0; y < chainIDToAssetMappingEntity.assets.length; y++) { + const indexAssetEntity = loadIndexAssetEntity( + chainIDToAssetMappingEntity.assets[y], + ); + const historicalIndexAssetEntity = createOrLoadHistoricalIndexAssetEntity( + index, + indexAssetEntity.asset, + chainID, + timestamp, + ); + historicalIndexAssetEntity.balance = indexAssetEntity.balance; + if (indexAssetEntity.weight) { + historicalIndexAssetEntity.weight = indexAssetEntity.weight; + } + historicalIndexAssetEntity.save(); + historicalIndexAssetArray.push(historicalIndexAssetEntity.id); + } + } + historicalIndexBalanceEntity.assets = historicalIndexAssetArray; + historicalIndexBalanceEntity.save(); +} + +export function handleFinishRebalancing(event: FinishRebalancingEvent): void { + log.debug("weights {}", [event.params.weights.toString()]) + let indexAddress = dataSource.context().getBytes('indexAddress') + const chainID = dataSource.context().getBigInt('chainID') + let indexEntity = createOrLoadIndexEntity(indexAddress) + let anatomyEntity = createOrLoadAnatomyEntity(indexAddress) + let anatomyArray: string[] = [] + let chainIndexArray = [chainID] + for (let i = 0; i < chainIndexArray.length; i++) { + let currencySetEntity = createOrLoadCurrencySetEntity(indexAddress, chainIndexArray[i]) + currencySetEntity.sets = [event.params.newCurrencyIdSet[i]] + currencySetEntity.save() + anatomyArray.push(currencySetEntity.id) + let chainIDToAssetMappingEntity = createOrLoadChainIDToAssetMappingEntity(indexAddress, chainID) + + for (let x = 0; x < chainIDToAssetMappingEntity.assets.length; x++) { + const indexAssetEntity = loadIndexAssetEntity(chainIDToAssetMappingEntity.assets[x]) + indexAssetEntity.weight = event.params.weights[x] + indexAssetEntity.save() + } + + } + indexEntity.isRebalancing = false + anatomyEntity.chainIdSet = event.params.newCurrencyIdSet + anatomyEntity.currencyIdSets = anatomyArray + anatomyEntity.save() + indexEntity.save() +} + +export function convertBitSetToIDs(array: BigInt[]): BigInt[] { + const IDArray: BigInt[] = []; + for (let i = 0; i < array.length; i++) { + if (array[i] == ONE) { + IDArray.push(BigInt.fromI32(i)); + } + } + return IDArray; +} + +export function convertBigIntsToBitArray(array: BigInt[]): BigInt[] { + let expandedBitArray: BigInt[] = []; + for (let i = 0; i < array.length; i++) { + const bitArray: BigInt[] = []; + let chainBitSet = array[i]; + while (chainBitSet > ZERO) { + bitArray.push(chainBitSet.bitAnd(ONE)); + chainBitSet = chainBitSet.rightShift(1); + } + expandedBitArray = expandedBitArray.concat(bitArray); + } + return expandedBitArray; +} diff --git a/src/v3/IndexFactory.ts b/src/v3/IndexFactory.ts new file mode 100644 index 0000000..e46dd92 --- /dev/null +++ b/src/v3/IndexFactory.ts @@ -0,0 +1,79 @@ +import { + Address, + BigDecimal, + DataSourceContext, + dataSource, + log, +} from "@graphprotocol/graph-ts"; + +import { Deployed as DeployedEvent } from "../../generated/IndexFactoryV3/IndexFactoryV3"; +import { IndexTokenV3 as indexTemplate } from "../../generated/templates"; +import { + createOrLoadChainIDToAssetMappingEntity, + createOrLoadIndexAssetEntity, + createOrLoadIndexEntity, +} from "../EntityCreation"; + +import { ONE, WAD, ZERO } from "../constants"; +import { getTokenInfo } from "../v1/IndexFactory"; + +export function handleIndexDeployed(event: DeployedEvent): void { + const indexFactoryContext = dataSource.context(); + const chainID = indexFactoryContext.getBigInt("chainID"); + + const indexContext = new DataSourceContext(); + indexContext.setBytes("reserveAsset", event.params.reserve); + indexContext.setBytes("indexAddress", event.params.index); + indexContext.setBigInt("chainID", chainID); + indexTemplate.createWithContext(event.params.index, indexContext); + + const index = createOrLoadIndexEntity(event.params.index); + index.name = event.params.name; + index.symbol = event.params.symbol; + index.decimals = 18; + index.chainID = chainID; + index.version = "v3"; + index.creationDate = event.block.timestamp; + index.k = WAD; + index.totalFees = BigDecimal.zero(); + + const indexAssetEntity = createOrLoadIndexAssetEntity( + event.params.index, + event.params.reserve, + chainID, + ); + if ( + event.params.reserve == + Address.fromString("0x0000000000000000000000000000000000000000") + ) { + const nativeAssetInfo = dataSource.context().get("nativeAsset")!; + indexAssetEntity.name = nativeAssetInfo.toArray()[0].toString(); + indexAssetEntity.symbol = nativeAssetInfo.toArray()[1].toString(); + indexAssetEntity.decimals = nativeAssetInfo.toArray()[2].toI32(); + } else { + getTokenInfo(indexAssetEntity, event.params.reserve); + } + + const chainIDAssetArray: string[] = []; + const chainIDToAssetMappingEntity = createOrLoadChainIDToAssetMappingEntity( + event.params.index, + chainID, + ); + chainIDAssetArray.push(indexAssetEntity.id); + chainIDToAssetMappingEntity.assets = chainIDAssetArray; + chainIDToAssetMappingEntity.chainIndex = ZERO; + chainIDToAssetMappingEntity.latestSnapshot = ZERO; + chainIDToAssetMappingEntity.registeredAssets = ZERO; + + indexAssetEntity.currencyID = chainIDToAssetMappingEntity.registeredAssets; + chainIDToAssetMappingEntity.registeredAssets = + chainIDToAssetMappingEntity.registeredAssets!.plus(ONE); + + const indexAssetArray: string[] = []; + indexAssetArray.push(chainIDToAssetMappingEntity.id); + log.debug('DeployedEvent indexAssetArray = {}',[indexAssetArray.join('-')]) + index.assets = indexAssetArray; + chainIDToAssetMappingEntity.save(); + indexAssetEntity.save(); + index.save(); +} diff --git a/src/v3/IndexToken.ts b/src/v3/IndexToken.ts new file mode 100644 index 0000000..acc7870 --- /dev/null +++ b/src/v3/IndexToken.ts @@ -0,0 +1,118 @@ +import { + BigDecimal, + DataSourceContext, + dataSource, +} from "@graphprotocol/graph-ts"; +import { ConfigBuilderV3 as ConfigBuilderTemplate } from "../../generated/templates"; +import { + Deposit as DepositEvent, + FeeAccrued, + SetConfigBuilder as SetConfigbuilderEvent, + Withdraw as WithdrawEvent, +} from "../../generated/templates/IndexTokenV3/IndexTokenV3"; + +import { + createOrLoadIndexAssetEntity, + createOrLoadIndexEntity, + loadChainIDToAssetMappingEntity, + loadIndexAssetEntity, +} from "../EntityCreation"; +import { TEN, ZERO } from "../constants"; +import { saveHistoricalData } from "./ConfigBuilder"; + +export { handleTransfer } from "../v1/IndexToken"; + +export function handleDeposit(event: DepositEvent): void { + const indexContext = dataSource.context(); + const reserveAsset = indexContext.getBytes("reserveAsset"); + const chainID = indexContext.getBigInt("chainID"); + + const reserveAssetEntity = createOrLoadIndexAssetEntity( + event.address, + reserveAsset, + chainID, + ); + + const scalar = new BigDecimal(TEN.pow(u8(reserveAssetEntity.decimals))); + const amount = new BigDecimal(event.params.reserve).div(scalar); + + reserveAssetEntity.balance = reserveAssetEntity.balance.plus(amount); + + reserveAssetEntity.save(); + + saveHistoricalData(event.address, event.block.timestamp); +} + +export function handleWithdraw(event: WithdrawEvent): void { + const indexContext = dataSource.context(); + const reserveAsset = indexContext.getBytes("reserveAsset"); + const chainID = indexContext.getBigInt("chainID"); + + const reserveAssetEntity = createOrLoadIndexAssetEntity( + event.address, + reserveAsset, + chainID, + ); + const scalar = new BigDecimal(TEN.pow(u8(reserveAssetEntity.decimals))); + const amount = new BigDecimal(event.params.reserve).div(scalar); + reserveAssetEntity.balance = reserveAssetEntity.balance.minus(amount); + reserveAssetEntity.save(); + + if (event.params.k > ZERO) { + const indexEntity = createOrLoadIndexEntity(event.address); + + const assetScalar = BigDecimal.fromString("1").minus( + new BigDecimal(event.params.k).div(new BigDecimal(indexEntity.k!)), + ); + const indexAssets = indexEntity.assets; + for (let i = 0; i < indexAssets.length; i++) { + const chainIDToAssetMappingEntity = loadChainIDToAssetMappingEntity( + indexAssets[i], + ); + const chainIDAssetArray = chainIDToAssetMappingEntity.assets; + for (let y = 0; y < chainIDAssetArray.length; y++) { + const indexAssetEntity = loadIndexAssetEntity(chainIDAssetArray[y]); + indexAssetEntity.balance = indexAssetEntity.balance.times(assetScalar); + indexAssetEntity.save(); + } + } + + indexEntity.k = indexEntity.k!.minus(event.params.k); + + indexEntity.save(); + } + + saveHistoricalData(event.address, event.block.timestamp); +} + +export function handleFeeAccrued(event: FeeAccrued): void { + const indexEntity = createOrLoadIndexEntity(event.address); + + const scalar = new BigDecimal(TEN.pow(u8(indexEntity.decimals))); + const fees = new BigDecimal( + event.params.AUMFee.plus(event.params.depositFee).plus( + event.params.redemptionFee, + ), + ).div(scalar); + + indexEntity.totalFees = indexEntity.totalFees!.plus(fees); + + indexEntity.save(); +} + +export function handleSetConfigBuilder(event: SetConfigbuilderEvent): void { + const indexContext = dataSource.context(); + const indexAddress = indexContext.getBytes("indexAddress"); + const reserveAsset = indexContext.getBytes("reserveAsset"); + const chainID = indexContext.getBigInt("chainID"); + + const configBuilderContext = new DataSourceContext(); + configBuilderContext.setBytes("indexAddress", indexAddress); + configBuilderContext.setBytes("reserveAsset", reserveAsset); + configBuilderContext.setBigInt("chainID", chainID); + + ConfigBuilderTemplate.createWithContext( + event.params.configBuilder, + configBuilderContext, + ); +} diff --git a/subgraph.template.yaml b/subgraph.template.yaml index fd1483a..1f1301e 100644 --- a/subgraph.template.yaml +++ b/subgraph.template.yaml @@ -89,6 +89,49 @@ dataSources: file: ./src/v2/IndexFactory.ts {{/indexFactory}} {{/v2}} +{{#v3}} +{{#indexFactory}} + - kind: ethereum + name: {{name}} + network: {{network}} + context: + chainID: + type: BigInt + data: "{{chainID}}" + nativeAsset: + type: List + data: + - type: String + data: "{{nativeAsset.name}}" + - type: String + data: "{{nativeAsset.symbol}}" + - type: Int + data: {{nativeAsset.decimals}} + source: + address: "{{address}}" + abi: IndexFactoryV3 + startBlock: {{startBlock}} + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Index + abis: + - name: IndexFactoryV3 + file: ./abis/v3/IndexFactoryV3.json + - name: IndexTokenV3 + file: ./abis/v3/IndexTokenV3.json + - name: ERC20 + file: ./abis/ERC20.json + - name: MakerERC20 + file: ./abis/v1/MakerERC20.json + eventHandlers: + - event: Deployed(address,string,string,address,address) + handler: handleIndexDeployed + file: ./src/v3/IndexFactory.ts +{{/indexFactory}} +{{/v3}} {{#ephtr}} - kind: ethereum name: ephtr @@ -412,4 +455,66 @@ templates: handler: handleSetLZConfig file: ./src/v2/Messenger.ts -{{/v2}} \ No newline at end of file +{{/v2}} +{{#v3}} + - kind: ethereum + name: IndexTokenV3 + network: {{network}} + source: + abi: IndexTokenV3 + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - IndexAsset + - Index + - HistoricalIndexBalances + abis: + - name: IndexTokenV3 + file: ./abis/v3/IndexTokenV3.json + - name: ERC20 + file: ./abis/ERC20.json + - name: MakerERC20 + file: ./abis/v1/MakerERC20.json + eventHandlers: + - event: Deposit(indexed address,indexed address,uint256,uint256) + handler: handleDeposit + - event: Withdraw(indexed address,indexed address,indexed address,uint256,uint256,uint256) + handler: handleWithdraw + - event: FeeAccrued(uint96,uint96,uint96) + handler: handleFeeAccrued + - event: Transfer(indexed address,indexed address,uint256) + handler: handleTransfer + - event: SetConfigBuilder(address) + handler: handleSetConfigBuilder + file: ./src/v3/IndexToken.ts + - kind: ethereum + name: ConfigBuilderV3 + network: {{network}} + source: + abi: ConfigBuilderV3 + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Index + - IndexAsset + abis: + - name: ConfigBuilderV3 + file: ./abis/v3/ConfigBuilderV3.json + eventHandlers: + - event: ConfigUpdated(bytes) + handler: handleConfigUpdate + - event: CurrencyRegistered(address,string,string,uint8) + handler: handleCurrencyRegistered + - event: FinishVaultRebalancing(uint256,uint256[],address[],uint256[]) + handler: handleFinishChainRebalancing + - event: FinishRebalancing(uint256,uint256[],uint256[]) + handler: handleFinishRebalancing + - event: StartRebalancing() + handler: handleStartRebalancing + file: ./src/v3/ConfigBuilder.ts + +{{/v3}} \ No newline at end of file