├── .eslintignore ├── .eslintrc ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .prettierrc ├── LICENSE ├── README.md ├── abis ├── BaseRewardPool.json ├── Booster.json ├── CLAggregator.json ├── CToken.json ├── CurvePool.json ├── CurvePoolCoin128.json ├── CurvePoolCoin256.json ├── CurvePoolV1AdminFees.json ├── CurvePoolV2.json ├── CurveRegistry.json ├── CurveToken.json ├── CurveTriCryptoFactoryPool.json ├── ERC20.json ├── ExtraRewardStashV1.json ├── ExtraRewardStashV2.json ├── ExtraRewardStashV30.json ├── ExtraRewardStashV32.json ├── ExtraRewardStashV33.json ├── LendingVault.json ├── Llamma.json ├── Multicall.json ├── OneWayLendingFactory.json ├── RedeemableKeep3r.json ├── UniswapV2Factory.json ├── UniswapV2Pair.json ├── UniswapV3Factory.json ├── UniswapV3Quoter.json ├── VirtualBalanceRewardPool.json ├── VotiumV2.json └── YToken.json ├── package.json ├── packages ├── const │ ├── index.ts │ └── package.json └── utils │ ├── convex.ts │ ├── index.ts │ ├── maths.ts │ ├── package.json │ ├── pricing.ts │ └── time.ts ├── subgraphs ├── convex │ ├── abis │ │ ├── BaseRewardPool.json │ │ ├── Booster.json │ │ ├── CLAggregator.json │ │ ├── CToken.json │ │ ├── CurvePool.json │ │ ├── CurvePoolV2.json │ │ ├── CurveRegistry.json │ │ ├── CurveToken.json │ │ ├── CurveTriCryptoFactory.json │ │ ├── CurveTriCryptoFactoryPool.json │ │ ├── ERC20.json │ │ ├── ExtraRewardStashV1.json │ │ ├── ExtraRewardStashV2.json │ │ ├── ExtraRewardStashV30.json │ │ ├── ExtraRewardStashV32.json │ │ ├── ExtraRewardStashV33.json │ │ ├── FeeDeposit.json │ │ ├── FeeRegistry.json │ │ ├── LendingVault.json │ │ ├── Llamma.json │ │ ├── OneWayLendingFactory.json │ │ ├── RedeemableKeep3r.json │ │ ├── TreasuryManager.json │ │ ├── TreasurySwap.json │ │ ├── UniswapV2Factory.json │ │ ├── UniswapV2Pair.json │ │ ├── UniswapV3Factory.json │ │ ├── UniswapV3Quoter.json │ │ ├── VirtualBalanceRewardPool.json │ │ ├── VoteMarket.json │ │ ├── Votium.json │ │ ├── VotiumV2.json │ │ └── YToken.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ ├── mapping-3crv.ts │ │ ├── mapping-bribes-v2.ts │ │ ├── mapping-bribes.ts │ │ ├── mapping-fxs-deposits.ts │ │ ├── mapping-rewards.ts │ │ ├── mapping-treasury.ts │ │ ├── mapping.ts │ │ └── services │ │ │ ├── apr.ts │ │ │ ├── platform.ts │ │ │ ├── pools.ts │ │ │ ├── revenue.ts │ │ │ ├── snapshots.ts │ │ │ ├── user.ts │ │ │ └── utils.ts │ └── subgraph.yaml ├── cvxprisma │ ├── abis │ │ ├── CurvePoolV2.json │ │ ├── ERC20.json │ │ ├── TriCryptoNg.json │ │ ├── UniswapV2Factory.json │ │ ├── UniswapV2Pair.json │ │ ├── UniswapV3Factory.json │ │ ├── UniswapV3Quoter.json │ │ ├── cvxPrismaStaking.json │ │ └── yPrismaStaking.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ ├── cvx-prisma-staking.ts │ │ ├── services │ │ │ ├── entities.ts │ │ │ ├── snapshots.ts │ │ │ └── tokens.ts │ │ └── y-prisma-staking.ts │ └── subgraph.yaml ├── locker │ ├── abis │ │ ├── CvxLocker.json │ │ ├── ERC20.json │ │ ├── UniswapV2Factory.json │ │ ├── UniswapV2Pair.json │ │ ├── UniswapV3Factory.json │ │ ├── UniswapV3Quoter.json │ │ └── vlCvxExtraRewardDistribution.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ ├── extraMapping.ts │ │ ├── mapping.ts │ │ └── services │ │ │ ├── events.ts │ │ │ ├── tokens.ts │ │ │ └── users.ts │ └── subgraph.yaml ├── staking │ ├── abis │ │ ├── BaseRewardPool.json │ │ ├── CurvePool.json │ │ ├── CvxRewardPool.json │ │ ├── ERC20.json │ │ ├── UniswapV2Factory.json │ │ ├── UniswapV2Pair.json │ │ ├── UniswapV3Factory.json │ │ ├── UniswapV3Quoter.json │ │ └── VirtualBalanceRewardPool.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ ├── mapping.ts │ │ └── services │ │ │ ├── apr.ts │ │ │ ├── contracts.ts │ │ │ └── snapshot.ts │ └── subgraph.yaml ├── votium-fxn │ ├── abis │ │ └── VotiumVlCVXFXN.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ └── mapping.ts │ └── subgraph.yaml ├── votium-prisma │ ├── abis │ │ └── VotiumVlCVXPrisma.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ └── mapping.ts │ └── subgraph.yaml ├── votium │ ├── abis │ │ └── VotiumBribe.json │ ├── package.json │ ├── schema.graphql │ ├── src │ │ └── mapping.ts │ └── subgraph.yaml └── votiumv2 │ ├── abis │ └── VotiumV2.json │ ├── package.json │ ├── schema.graphql │ ├── src │ └── mapping.ts │ └── subgraph.yaml ├── tsconfig.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ 2 | generated/ 3 | node_modules/ -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "plugins": ["@typescript-eslint"], 4 | "extends": ["plugin:@typescript-eslint/recommended", "prettier", "prettier/@typescript-eslint"] 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | build/ 107 | generated/ 108 | .idea/ 109 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true, 4 | "printWidth": 120 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Convex resources 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Convex Subgraph 2 | 3 | --- 4 | 5 | ### Overview 6 | 7 | Historical data for the Convex platform (https://convexfinance.com/) 8 | The subgraphs included in this repository index various on-chain events and entities that can be useful to produce analytics for the platform. 9 | 10 | There are several subgraphs, each indexing a different aspect of the platform. 11 | 12 | Currently available subgraphs: 13 | 14 | - **convex**: Indexes events around the Booster contract where users deposit their Curve LP tokens. Allows, for instance, to query a pool's historical TVL and APR, platform revenue breakdown & users' withdrawals and deposits. (Live version) 15 | - **crv-emissions**: Indexes emissions of CRV to pools with gauges as well as estimates of the fees generated by these pools. (Live version) 16 | - **locker**: Indexes the vlCVX locker contract, allows to track the amount of CVX locked, the amount of rewards paid out over time. (Live version) 17 | - **staking**: Indexes historical APR for Convex Staking contracts (currently cvxCRV & CVX only). (Live version) 18 | - **tricrypto**: Indexes events of the tricrypto v2 pool on Curve. Soon to be expanded to all v2 pools. (Live version) 19 | - **votium**: Indexes bribes deposited on the Votium platform. (Live version) 20 | 21 | More to come! 22 | 23 | --- 24 | 25 | ### Set up and deployment: 26 | 27 | You will need to install yarn, then run: 28 | 29 | `yarn install` 30 | 31 | To create the necessary files from the GraphQL schema and ABIs: 32 | 33 | `yarn run codegen` 34 | 35 | You may opt to only run the command for a specific subgraph by specifying its name, e.g. `yarn run codegen:locker` 36 | 37 | To compile before deployment: 38 | 39 | `yarn run build` 40 | 41 | or specify a specific subgraph: `yarn run build:locker` 42 | 43 | Authenticate to the graph with the `graph auth` command, making sure that the auth token matches the platform where you'll deploy (studio vs. hosted for instance) 44 | 45 | Use `yarn run deploy`, `yarn run deploy local` or `yarn run deploy-hosted` or `yarn run deploy-studio` to deploy. 46 | The `package.json` files will have to be updated to point to your own account on the Graph. 47 | 48 | --- 49 | 50 | ### Sample queries 51 | 52 | Notebooks with sample queries are available at: here 53 | -------------------------------------------------------------------------------- /abis/CurvePoolCoin128.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "coins", 4 | "outputs": [{ "type": "address", "name": "" }], 5 | "inputs": [{ "type": "int128", "name": "arg0" }], 6 | "constant": true, 7 | "payable": false, 8 | "type": "function", 9 | "gas": 2310 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /abis/CurvePoolCoin256.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "coins", 4 | "outputs": [{ "type": "address", "name": "" }], 5 | "inputs": [{ "type": "uint256", "name": "arg0" }], 6 | "stateMutability": "view", 7 | "type": "function", 8 | "gas": 2280 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /abis/CurvePoolV1AdminFees.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "withdraw_admin_fees", 4 | "outputs": [], 5 | "inputs": [], 6 | "stateMutability": "nonpayable", 7 | "type": "function", 8 | "gas": 11347 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /abis/ERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] -------------------------------------------------------------------------------- /abis/ExtraRewardStashV1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { "internalType": "uint256", "name": "_pid", "type": "uint256" }, 5 | { "internalType": "address", "name": "_operator", "type": "address" }, 6 | { "internalType": "address", "name": "_staker", "type": "address" }, 7 | { "internalType": "address", "name": "_gauge", "type": "address" }, 8 | { "internalType": "address", "name": "_rFactory", "type": "address" } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [], 15 | "name": "claimRewards", 16 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 17 | "stateMutability": "nonpayable", 18 | "type": "function" 19 | }, 20 | { 21 | "inputs": [], 22 | "name": "gauge", 23 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 24 | "stateMutability": "view", 25 | "type": "function" 26 | }, 27 | { 28 | "inputs": [], 29 | "name": "getName", 30 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 31 | "stateMutability": "pure", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [], 36 | "name": "historicalRewards", 37 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "operator", 44 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 45 | "stateMutability": "view", 46 | "type": "function" 47 | }, 48 | { 49 | "inputs": [], 50 | "name": "pid", 51 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 52 | "stateMutability": "view", 53 | "type": "function" 54 | }, 55 | { 56 | "inputs": [], 57 | "name": "processStash", 58 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 59 | "stateMutability": "nonpayable", 60 | "type": "function" 61 | }, 62 | { 63 | "inputs": [], 64 | "name": "rewardFactory", 65 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 66 | "stateMutability": "view", 67 | "type": "function" 68 | }, 69 | { 70 | "inputs": [], 71 | "name": "staker", 72 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 73 | "stateMutability": "view", 74 | "type": "function" 75 | }, 76 | { 77 | "inputs": [], 78 | "name": "stashRewards", 79 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 80 | "stateMutability": "pure", 81 | "type": "function" 82 | }, 83 | { 84 | "inputs": [], 85 | "name": "tokenInfo", 86 | "outputs": [ 87 | { "internalType": "address", "name": "token", "type": "address" }, 88 | { "internalType": "address", "name": "rewardAddress", "type": "address" }, 89 | { "internalType": "uint256", "name": "lastActiveTime", "type": "uint256" } 90 | ], 91 | "stateMutability": "view", 92 | "type": "function" 93 | } 94 | ] 95 | -------------------------------------------------------------------------------- /abis/ExtraRewardStashV2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint256", 6 | "name": "_pid", 7 | "type": "uint256" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_operator", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "address", 16 | "name": "_staker", 17 | "type": "address" 18 | }, 19 | { 20 | "internalType": "address", 21 | "name": "_gauge", 22 | "type": "address" 23 | }, 24 | { 25 | "internalType": "address", 26 | "name": "_rFactory", 27 | "type": "address" 28 | } 29 | ], 30 | "stateMutability": "nonpayable", 31 | "type": "constructor" 32 | }, 33 | { 34 | "inputs": [], 35 | "name": "claimRewards", 36 | "outputs": [ 37 | { 38 | "internalType": "bool", 39 | "name": "", 40 | "type": "bool" 41 | } 42 | ], 43 | "stateMutability": "nonpayable", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "crv", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [], 61 | "name": "gauge", 62 | "outputs": [ 63 | { 64 | "internalType": "address", 65 | "name": "", 66 | "type": "address" 67 | } 68 | ], 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "getName", 75 | "outputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "", 79 | "type": "string" 80 | } 81 | ], 82 | "stateMutability": "pure", 83 | "type": "function" 84 | }, 85 | { 86 | "inputs": [ 87 | { 88 | "internalType": "address", 89 | "name": "", 90 | "type": "address" 91 | } 92 | ], 93 | "name": "historicalRewards", 94 | "outputs": [ 95 | { 96 | "internalType": "uint256", 97 | "name": "", 98 | "type": "uint256" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [], 106 | "name": "operator", 107 | "outputs": [ 108 | { 109 | "internalType": "address", 110 | "name": "", 111 | "type": "address" 112 | } 113 | ], 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "inputs": [], 119 | "name": "pid", 120 | "outputs": [ 121 | { 122 | "internalType": "uint256", 123 | "name": "", 124 | "type": "uint256" 125 | } 126 | ], 127 | "stateMutability": "view", 128 | "type": "function" 129 | }, 130 | { 131 | "inputs": [], 132 | "name": "processStash", 133 | "outputs": [ 134 | { 135 | "internalType": "bool", 136 | "name": "", 137 | "type": "bool" 138 | } 139 | ], 140 | "stateMutability": "nonpayable", 141 | "type": "function" 142 | }, 143 | { 144 | "inputs": [], 145 | "name": "rewardFactory", 146 | "outputs": [ 147 | { 148 | "internalType": "address", 149 | "name": "", 150 | "type": "address" 151 | } 152 | ], 153 | "stateMutability": "view", 154 | "type": "function" 155 | }, 156 | { 157 | "inputs": [], 158 | "name": "staker", 159 | "outputs": [ 160 | { 161 | "internalType": "address", 162 | "name": "", 163 | "type": "address" 164 | } 165 | ], 166 | "stateMutability": "view", 167 | "type": "function" 168 | }, 169 | { 170 | "inputs": [], 171 | "name": "stashRewards", 172 | "outputs": [ 173 | { 174 | "internalType": "bool", 175 | "name": "", 176 | "type": "bool" 177 | } 178 | ], 179 | "stateMutability": "nonpayable", 180 | "type": "function" 181 | }, 182 | { 183 | "inputs": [], 184 | "name": "tokenCount", 185 | "outputs": [ 186 | { 187 | "internalType": "uint256", 188 | "name": "", 189 | "type": "uint256" 190 | } 191 | ], 192 | "stateMutability": "view", 193 | "type": "function" 194 | }, 195 | { 196 | "inputs": [ 197 | { 198 | "internalType": "uint256", 199 | "name": "", 200 | "type": "uint256" 201 | } 202 | ], 203 | "name": "tokenInfo", 204 | "outputs": [ 205 | { 206 | "internalType": "address", 207 | "name": "token", 208 | "type": "address" 209 | }, 210 | { 211 | "internalType": "address", 212 | "name": "rewardAddress", 213 | "type": "address" 214 | }, 215 | { 216 | "internalType": "uint256", 217 | "name": "lastActiveTime", 218 | "type": "uint256" 219 | } 220 | ], 221 | "stateMutability": "view", 222 | "type": "function" 223 | } 224 | ] -------------------------------------------------------------------------------- /abis/ExtraRewardStashV30.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { "internalType": "uint256", "name": "_pid", "type": "uint256" }, 5 | { "internalType": "address", "name": "_operator", "type": "address" }, 6 | { "internalType": "address", "name": "_staker", "type": "address" }, 7 | { "internalType": "address", "name": "_gauge", "type": "address" }, 8 | { "internalType": "address", "name": "_rFactory", "type": "address" } 9 | ], 10 | "stateMutability": "nonpayable", 11 | "type": "constructor" 12 | }, 13 | { 14 | "inputs": [], 15 | "name": "claimRewards", 16 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 17 | "stateMutability": "nonpayable", 18 | "type": "function" 19 | }, 20 | { 21 | "inputs": [], 22 | "name": "crv", 23 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 24 | "stateMutability": "view", 25 | "type": "function" 26 | }, 27 | { 28 | "inputs": [], 29 | "name": "gauge", 30 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 31 | "stateMutability": "view", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [], 36 | "name": "getName", 37 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 38 | "stateMutability": "pure", 39 | "type": "function" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "hasRedirected", 44 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 45 | "stateMutability": "view", 46 | "type": "function" 47 | }, 48 | { 49 | "inputs": [{ "internalType": "address", "name": "", "type": "address" }], 50 | "name": "historicalRewards", 51 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 52 | "stateMutability": "view", 53 | "type": "function" 54 | }, 55 | { 56 | "inputs": [], 57 | "name": "operator", 58 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 59 | "stateMutability": "view", 60 | "type": "function" 61 | }, 62 | { 63 | "inputs": [], 64 | "name": "pid", 65 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 66 | "stateMutability": "view", 67 | "type": "function" 68 | }, 69 | { 70 | "inputs": [], 71 | "name": "processStash", 72 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 73 | "stateMutability": "nonpayable", 74 | "type": "function" 75 | }, 76 | { 77 | "inputs": [], 78 | "name": "rewardFactory", 79 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 80 | "stateMutability": "view", 81 | "type": "function" 82 | }, 83 | { 84 | "inputs": [], 85 | "name": "staker", 86 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 87 | "stateMutability": "view", 88 | "type": "function" 89 | }, 90 | { 91 | "inputs": [], 92 | "name": "stashRewards", 93 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 94 | "stateMutability": "pure", 95 | "type": "function" 96 | }, 97 | { 98 | "inputs": [], 99 | "name": "tokenCount", 100 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 106 | "name": "tokenInfo", 107 | "outputs": [ 108 | { "internalType": "address", "name": "token", "type": "address" }, 109 | { "internalType": "address", "name": "rewardAddress", "type": "address" } 110 | ], 111 | "stateMutability": "view", 112 | "type": "function" 113 | } 114 | ] 115 | -------------------------------------------------------------------------------- /abis/ExtraRewardStashV32.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, 3 | { 4 | "inputs": [], 5 | "name": "claimRewards", 6 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 7 | "stateMutability": "nonpayable", 8 | "type": "function" 9 | }, 10 | { 11 | "inputs": [], 12 | "name": "crv", 13 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 14 | "stateMutability": "view", 15 | "type": "function" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "gauge", 20 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 21 | "stateMutability": "view", 22 | "type": "function" 23 | }, 24 | { 25 | "inputs": [], 26 | "name": "getName", 27 | "outputs": [{ "internalType": "string", "name": "", "type": "string" }], 28 | "stateMutability": "pure", 29 | "type": "function" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "hasCurveRewards", 34 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 35 | "stateMutability": "view", 36 | "type": "function" 37 | }, 38 | { 39 | "inputs": [], 40 | "name": "hasRedirected", 41 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 42 | "stateMutability": "view", 43 | "type": "function" 44 | }, 45 | { 46 | "inputs": [{ "internalType": "address", "name": "", "type": "address" }], 47 | "name": "historicalRewards", 48 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 49 | "stateMutability": "view", 50 | "type": "function" 51 | }, 52 | { 53 | "inputs": [ 54 | { "internalType": "uint256", "name": "_pid", "type": "uint256" }, 55 | { "internalType": "address", "name": "_operator", "type": "address" }, 56 | { "internalType": "address", "name": "_staker", "type": "address" }, 57 | { "internalType": "address", "name": "_gauge", "type": "address" }, 58 | { "internalType": "address", "name": "_rFactory", "type": "address" } 59 | ], 60 | "name": "initialize", 61 | "outputs": [], 62 | "stateMutability": "nonpayable", 63 | "type": "function" 64 | }, 65 | { 66 | "inputs": [], 67 | "name": "operator", 68 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "pid", 75 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 76 | "stateMutability": "view", 77 | "type": "function" 78 | }, 79 | { 80 | "inputs": [], 81 | "name": "processStash", 82 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 83 | "stateMutability": "nonpayable", 84 | "type": "function" 85 | }, 86 | { 87 | "inputs": [], 88 | "name": "rewardFactory", 89 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 90 | "stateMutability": "view", 91 | "type": "function" 92 | }, 93 | { 94 | "inputs": [], 95 | "name": "rewardHook", 96 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 97 | "stateMutability": "view", 98 | "type": "function" 99 | }, 100 | { 101 | "inputs": [{ "internalType": "address", "name": "_token", "type": "address" }], 102 | "name": "setExtraReward", 103 | "outputs": [], 104 | "stateMutability": "nonpayable", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [{ "internalType": "address", "name": "_hook", "type": "address" }], 109 | "name": "setRewardHook", 110 | "outputs": [], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [], 116 | "name": "staker", 117 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 118 | "stateMutability": "view", 119 | "type": "function" 120 | }, 121 | { 122 | "inputs": [], 123 | "name": "stashRewards", 124 | "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], 125 | "stateMutability": "pure", 126 | "type": "function" 127 | }, 128 | { 129 | "inputs": [], 130 | "name": "tokenCount", 131 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 132 | "stateMutability": "view", 133 | "type": "function" 134 | }, 135 | { 136 | "inputs": [{ "internalType": "address", "name": "", "type": "address" }], 137 | "name": "tokenInfo", 138 | "outputs": [ 139 | { "internalType": "address", "name": "token", "type": "address" }, 140 | { "internalType": "address", "name": "rewardAddress", "type": "address" } 141 | ], 142 | "stateMutability": "view", 143 | "type": "function" 144 | }, 145 | { 146 | "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 147 | "name": "tokenList", 148 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 149 | "stateMutability": "view", 150 | "type": "function" 151 | } 152 | ] 153 | -------------------------------------------------------------------------------- /abis/Multicall.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "getCurrentBlockTimestamp", 6 | "outputs": [{ "name": "timestamp", "type": "uint256" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": false, 13 | "inputs": [ 14 | { 15 | "components": [ 16 | { "name": "target", "type": "address" }, 17 | { "name": "callData", "type": "bytes" } 18 | ], 19 | "name": "calls", 20 | "type": "tuple[]" 21 | } 22 | ], 23 | "name": "aggregate", 24 | "outputs": [ 25 | { "name": "blockNumber", "type": "uint256" }, 26 | { "name": "returnData", "type": "bytes[]" } 27 | ], 28 | "payable": false, 29 | "stateMutability": "nonpayable", 30 | "type": "function" 31 | }, 32 | { 33 | "constant": true, 34 | "inputs": [], 35 | "name": "getLastBlockHash", 36 | "outputs": [{ "name": "blockHash", "type": "bytes32" }], 37 | "payable": false, 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "constant": true, 43 | "inputs": [{ "name": "addr", "type": "address" }], 44 | "name": "getEthBalance", 45 | "outputs": [{ "name": "balance", "type": "uint256" }], 46 | "payable": false, 47 | "stateMutability": "view", 48 | "type": "function" 49 | }, 50 | { 51 | "constant": true, 52 | "inputs": [], 53 | "name": "getCurrentBlockDifficulty", 54 | "outputs": [{ "name": "difficulty", "type": "uint256" }], 55 | "payable": false, 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "constant": true, 61 | "inputs": [], 62 | "name": "getCurrentBlockGasLimit", 63 | "outputs": [{ "name": "gaslimit", "type": "uint256" }], 64 | "payable": false, 65 | "stateMutability": "view", 66 | "type": "function" 67 | }, 68 | { 69 | "constant": true, 70 | "inputs": [], 71 | "name": "getCurrentBlockCoinbase", 72 | "outputs": [{ "name": "coinbase", "type": "address" }], 73 | "payable": false, 74 | "stateMutability": "view", 75 | "type": "function" 76 | }, 77 | { 78 | "constant": true, 79 | "inputs": [{ "name": "blockNumber", "type": "uint256" }], 80 | "name": "getBlockHash", 81 | "outputs": [{ "name": "blockHash", "type": "bytes32" }], 82 | "payable": false, 83 | "stateMutability": "view", 84 | "type": "function" 85 | } 86 | ] 87 | -------------------------------------------------------------------------------- /abis/UniswapV3Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, 3 | { 4 | "anonymous": false, 5 | "inputs": [ 6 | { "indexed": true, "internalType": "uint24", "name": "fee", "type": "uint24" }, 7 | { "indexed": true, "internalType": "int24", "name": "tickSpacing", "type": "int24" } 8 | ], 9 | "name": "FeeAmountEnabled", 10 | "type": "event" 11 | }, 12 | { 13 | "anonymous": false, 14 | "inputs": [ 15 | { "indexed": true, "internalType": "address", "name": "oldOwner", "type": "address" }, 16 | { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } 17 | ], 18 | "name": "OwnerChanged", 19 | "type": "event" 20 | }, 21 | { 22 | "anonymous": false, 23 | "inputs": [ 24 | { "indexed": true, "internalType": "address", "name": "token0", "type": "address" }, 25 | { "indexed": true, "internalType": "address", "name": "token1", "type": "address" }, 26 | { "indexed": true, "internalType": "uint24", "name": "fee", "type": "uint24" }, 27 | { "indexed": false, "internalType": "int24", "name": "tickSpacing", "type": "int24" }, 28 | { "indexed": false, "internalType": "address", "name": "pool", "type": "address" } 29 | ], 30 | "name": "PoolCreated", 31 | "type": "event" 32 | }, 33 | { 34 | "inputs": [ 35 | { "internalType": "address", "name": "tokenA", "type": "address" }, 36 | { "internalType": "address", "name": "tokenB", "type": "address" }, 37 | { "internalType": "uint24", "name": "fee", "type": "uint24" } 38 | ], 39 | "name": "createPool", 40 | "outputs": [{ "internalType": "address", "name": "pool", "type": "address" }], 41 | "stateMutability": "nonpayable", 42 | "type": "function" 43 | }, 44 | { 45 | "inputs": [ 46 | { "internalType": "uint24", "name": "fee", "type": "uint24" }, 47 | { "internalType": "int24", "name": "tickSpacing", "type": "int24" } 48 | ], 49 | "name": "enableFeeAmount", 50 | "outputs": [], 51 | "stateMutability": "nonpayable", 52 | "type": "function" 53 | }, 54 | { 55 | "inputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], 56 | "name": "feeAmountTickSpacing", 57 | "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], 58 | "stateMutability": "view", 59 | "type": "function" 60 | }, 61 | { 62 | "inputs": [ 63 | { "internalType": "address", "name": "", "type": "address" }, 64 | { "internalType": "address", "name": "", "type": "address" }, 65 | { "internalType": "uint24", "name": "", "type": "uint24" } 66 | ], 67 | "name": "getPool", 68 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "owner", 75 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 76 | "stateMutability": "view", 77 | "type": "function" 78 | }, 79 | { 80 | "inputs": [], 81 | "name": "parameters", 82 | "outputs": [ 83 | { "internalType": "address", "name": "factory", "type": "address" }, 84 | { "internalType": "address", "name": "token0", "type": "address" }, 85 | { "internalType": "address", "name": "token1", "type": "address" }, 86 | { "internalType": "uint24", "name": "fee", "type": "uint24" }, 87 | { "internalType": "int24", "name": "tickSpacing", "type": "int24" } 88 | ], 89 | "stateMutability": "view", 90 | "type": "function" 91 | }, 92 | { 93 | "inputs": [{ "internalType": "address", "name": "_owner", "type": "address" }], 94 | "name": "setOwner", 95 | "outputs": [], 96 | "stateMutability": "nonpayable", 97 | "type": "function" 98 | } 99 | ] 100 | -------------------------------------------------------------------------------- /abis/UniswapV3Quoter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { "internalType": "address", "name": "_factory", "type": "address" }, 5 | { "internalType": "address", "name": "_WETH9", "type": "address" } 6 | ], 7 | "stateMutability": "nonpayable", 8 | "type": "constructor" 9 | }, 10 | { 11 | "inputs": [], 12 | "name": "WETH9", 13 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 14 | "stateMutability": "view", 15 | "type": "function" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "factory", 20 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 21 | "stateMutability": "view", 22 | "type": "function" 23 | }, 24 | { 25 | "inputs": [ 26 | { "internalType": "bytes", "name": "path", "type": "bytes" }, 27 | { "internalType": "uint256", "name": "amountIn", "type": "uint256" } 28 | ], 29 | "name": "quoteExactInput", 30 | "outputs": [{ "internalType": "uint256", "name": "amountOut", "type": "uint256" }], 31 | "stateMutability": "nonpayable", 32 | "type": "function" 33 | }, 34 | { 35 | "inputs": [ 36 | { "internalType": "address", "name": "tokenIn", "type": "address" }, 37 | { "internalType": "address", "name": "tokenOut", "type": "address" }, 38 | { "internalType": "uint24", "name": "fee", "type": "uint24" }, 39 | { "internalType": "uint256", "name": "amountIn", "type": "uint256" }, 40 | { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" } 41 | ], 42 | "name": "quoteExactInputSingle", 43 | "outputs": [{ "internalType": "uint256", "name": "amountOut", "type": "uint256" }], 44 | "stateMutability": "view", 45 | "type": "function" 46 | }, 47 | { 48 | "inputs": [ 49 | { "internalType": "bytes", "name": "path", "type": "bytes" }, 50 | { "internalType": "uint256", "name": "amountOut", "type": "uint256" } 51 | ], 52 | "name": "quoteExactOutput", 53 | "outputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }], 54 | "stateMutability": "nonpayable", 55 | "type": "function" 56 | }, 57 | { 58 | "inputs": [ 59 | { "internalType": "address", "name": "tokenIn", "type": "address" }, 60 | { "internalType": "address", "name": "tokenOut", "type": "address" }, 61 | { "internalType": "uint24", "name": "fee", "type": "uint24" }, 62 | { "internalType": "uint256", "name": "amountOut", "type": "uint256" }, 63 | { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" } 64 | ], 65 | "name": "quoteExactOutputSingle", 66 | "outputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }], 67 | "stateMutability": "nonpayable", 68 | "type": "function" 69 | }, 70 | { 71 | "inputs": [ 72 | { "internalType": "int256", "name": "amount0Delta", "type": "int256" }, 73 | { "internalType": "int256", "name": "amount1Delta", "type": "int256" }, 74 | { "internalType": "bytes", "name": "path", "type": "bytes" } 75 | ], 76 | "name": "uniswapV3SwapCallback", 77 | "outputs": [], 78 | "stateMutability": "view", 79 | "type": "function" 80 | } 81 | ] 82 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "convex-subgraph", 3 | "private": true, 4 | "workspaces": [ 5 | "subgraphs/*", 6 | "packages/*" 7 | ], 8 | "scripts": { 9 | "build": "yarn workspaces run build", 10 | "codegen": "yarn workspaces run codegen", 11 | "deploy": "yarn workspaces run deploy", 12 | "deploy-hosted": "yarn workspaces run deploy-hosted", 13 | "deploy-studio": "yarn workspaces run deploy-studio", 14 | "deploy-local": "yarn workspaces run deploy-local", 15 | "prepare": "husky install" 16 | }, 17 | "devDependencies": { 18 | "@graphprotocol/graph-cli": "0.50.1", 19 | "@graphprotocol/graph-ts": "0.30.0", 20 | "@protofire/subgraph-toolkit": "^0.1.2", 21 | "@typescript-eslint/eslint-plugin": "^4.0.0", 22 | "@typescript-eslint/parser": "^4.0.0", 23 | "eslint": "^7.0.0", 24 | "eslint-config-prettier": "^6.0.0", 25 | "husky": ">=6", 26 | "lint-staged": ">=10", 27 | "prettier": "^2.0.0", 28 | "typescript": "^4.0.0" 29 | }, 30 | "lint-staged": { 31 | "*.{ts,js}": "eslint --cache --fix", 32 | "*.{js,ts,css,md}": "prettier --write" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/const/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "const", 3 | "version": "1.0.0", 4 | "description": "Constants", 5 | "license": "MIT", 6 | "main": "index.ts", 7 | "private": true, 8 | "scripts": { 9 | "codegen": "true", 10 | "build": "true" 11 | } 12 | } -------------------------------------------------------------------------------- /packages/utils/convex.ts: -------------------------------------------------------------------------------- 1 | import { BigDecimal } from '@graphprotocol/graph-ts/index' 2 | import { ERC20 } from 'convex/generated/Booster/ERC20' 3 | import { Address } from '@graphprotocol/graph-ts' 4 | 5 | export const CVX_CLIFF_SIZE = BigDecimal.fromString('100000') // * 1e18; //new cliff every 100,000 tokens 6 | export const CVX_CLIFF_COUNT = BigDecimal.fromString('1000') // 1,000 cliffs 7 | export const CVX_MAX_SUPPLY = BigDecimal.fromString('100000000') // * 1e18; //100 mil max supply 8 | const CVX_ADDRESS = Address.fromString('0x4e3FBD56CD56c3e72c1403e103b45Db9da5B9D2B') 9 | 10 | export function getCvxMintAmount(crvEarned: BigDecimal): BigDecimal { 11 | const cvxSupplyResult = ERC20.bind(CVX_ADDRESS).try_totalSupply() 12 | if (!cvxSupplyResult.reverted) { 13 | const cvxSupply = cvxSupplyResult.value.toBigDecimal().div(BigDecimal.fromString('1e18')) 14 | const currentCliff = cvxSupply.div(CVX_CLIFF_SIZE) 15 | if (currentCliff.lt(CVX_CLIFF_COUNT)) { 16 | const remaining = CVX_CLIFF_COUNT.minus(currentCliff) 17 | let cvxEarned = crvEarned.times(remaining).div(CVX_CLIFF_COUNT) 18 | const amountTillMax = CVX_MAX_SUPPLY.minus(cvxSupply) 19 | if (cvxEarned.gt(amountTillMax)) { 20 | cvxEarned = amountTillMax 21 | } 22 | return cvxEarned 23 | } 24 | } 25 | return BigDecimal.zero() 26 | } 27 | -------------------------------------------------------------------------------- /packages/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { Address, Bytes } from '@graphprotocol/graph-ts' 2 | import { ADDRESS_ZERO } from 'const' 3 | 4 | export function bytesToAddress(input: Bytes): Address { 5 | let inputAsStr = input.toHexString() 6 | if (inputAsStr.length != 42) { 7 | return ADDRESS_ZERO 8 | } else return Address.fromString(inputAsStr) 9 | } 10 | -------------------------------------------------------------------------------- /packages/utils/maths.ts: -------------------------------------------------------------------------------- 1 | import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' 2 | import { BIG_DECIMAL_ONE, BIG_DECIMAL_TWO, BIG_INT_ONE, BIG_INT_ZERO } from 'const' 3 | 4 | export function exponentToBigDecimal(decimals: BigInt): BigDecimal { 5 | let bd = BigDecimal.fromString('1') 6 | for (let i = BIG_INT_ZERO; i.lt(decimals as BigInt); i = i.plus(BIG_INT_ONE)) { 7 | bd = bd.times(BigDecimal.fromString('10')) 8 | } 9 | return bd 10 | } 11 | 12 | export function toDecimal(value: BigInt, decimals: i32): BigDecimal { 13 | let res = value.toBigDecimal() 14 | for (let i = 0; i < decimals; i++) { 15 | res = res.div(BigDecimal.fromString('10')) 16 | } 17 | return res 18 | } 19 | 20 | export function exponentToBigInt(decimals: BigInt): BigInt { 21 | let bd = BigInt.fromString('1') 22 | for (let i = BIG_INT_ZERO; i.lt(decimals as BigInt); i = i.plus(BIG_INT_ONE)) { 23 | bd = bd.times(BigInt.fromString('10')) 24 | } 25 | return bd 26 | } 27 | 28 | export function pow(base: BigDecimal, exp: i32): BigDecimal { 29 | let res = BigDecimal.fromString('1') 30 | for (let i = 0; i < exp; i++) { 31 | res = res.times(base) 32 | } 33 | return res 34 | } 35 | // a fast approximation of (1 + rate)^exponent 36 | // https://github.com/messari/subgraphs/blob/fa253e06de13f9b78849efe8da3481d53d92620a/subgraphs/_reference_/src/common/utils/numbers.ts 37 | export function bigDecimalExponential(rate: BigDecimal, exponent: BigDecimal): BigDecimal { 38 | // binomial expansion to obtain (1 + x)^n : (1 + rate)^exponent 39 | // 1 + n *x + (n/2*(n-1))*x**2+(n/6*(n-1)*(n-2))*x**3+(n/12*(n-1)*(n-2)*(n-3))*x**4 40 | // this is less precise, but more efficient than `powerBigDecimal` when power is big 41 | const firstTerm = exponent.times(rate) 42 | const secondTerm = exponent.div(BIG_DECIMAL_TWO).times(exponent.minus(BIG_DECIMAL_ONE)).times(rate.times(rate)) 43 | const thirdTerm = exponent 44 | .div(BigDecimal.fromString('6')) 45 | .times(exponent.minus(BIG_DECIMAL_TWO)) 46 | .times(rate.times(rate).times(rate)) 47 | const fourthTerm = exponent 48 | .div(BigDecimal.fromString('12')) 49 | .times(exponent.minus(BigDecimal.fromString('3'))) 50 | .times(rate.times(rate).times(rate).times(rate)) 51 | return firstTerm.plus(secondTerm).plus(thirdTerm).plus(fourthTerm) 52 | } 53 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "utils", 3 | "version": "1.0.0", 4 | "description": "Utility functions", 5 | "license": "MIT", 6 | "main": "index.ts", 7 | "private": true, 8 | "scripts": { 9 | "codegen": "true", 10 | "build": "true" 11 | } 12 | } -------------------------------------------------------------------------------- /packages/utils/time.ts: -------------------------------------------------------------------------------- 1 | import { BigInt } from '@graphprotocol/graph-ts' 2 | 3 | export const DAY = BigInt.fromI32(60 * 60 * 24) 4 | export const WEEK = BigInt.fromI32(60 * 60 * 24 * 7) 5 | export const HOUR = BigInt.fromI32(60 * 60) 6 | 7 | export function getIntervalFromTimestamp(timestamp: BigInt, interval: BigInt): BigInt { 8 | return timestamp.div(interval).times(interval) 9 | } 10 | -------------------------------------------------------------------------------- /subgraphs/convex/abis/ERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/ExtraRewardStashV1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint256", 6 | "name": "_pid", 7 | "type": "uint256" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_operator", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "address", 16 | "name": "_staker", 17 | "type": "address" 18 | }, 19 | { 20 | "internalType": "address", 21 | "name": "_gauge", 22 | "type": "address" 23 | }, 24 | { 25 | "internalType": "address", 26 | "name": "_rFactory", 27 | "type": "address" 28 | } 29 | ], 30 | "stateMutability": "nonpayable", 31 | "type": "constructor" 32 | }, 33 | { 34 | "inputs": [], 35 | "name": "claimRewards", 36 | "outputs": [ 37 | { 38 | "internalType": "bool", 39 | "name": "", 40 | "type": "bool" 41 | } 42 | ], 43 | "stateMutability": "nonpayable", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "gauge", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [], 61 | "name": "getName", 62 | "outputs": [ 63 | { 64 | "internalType": "string", 65 | "name": "", 66 | "type": "string" 67 | } 68 | ], 69 | "stateMutability": "pure", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "historicalRewards", 75 | "outputs": [ 76 | { 77 | "internalType": "uint256", 78 | "name": "", 79 | "type": "uint256" 80 | } 81 | ], 82 | "stateMutability": "view", 83 | "type": "function" 84 | }, 85 | { 86 | "inputs": [], 87 | "name": "operator", 88 | "outputs": [ 89 | { 90 | "internalType": "address", 91 | "name": "", 92 | "type": "address" 93 | } 94 | ], 95 | "stateMutability": "view", 96 | "type": "function" 97 | }, 98 | { 99 | "inputs": [], 100 | "name": "pid", 101 | "outputs": [ 102 | { 103 | "internalType": "uint256", 104 | "name": "", 105 | "type": "uint256" 106 | } 107 | ], 108 | "stateMutability": "view", 109 | "type": "function" 110 | }, 111 | { 112 | "inputs": [], 113 | "name": "processStash", 114 | "outputs": [ 115 | { 116 | "internalType": "bool", 117 | "name": "", 118 | "type": "bool" 119 | } 120 | ], 121 | "stateMutability": "nonpayable", 122 | "type": "function" 123 | }, 124 | { 125 | "inputs": [], 126 | "name": "rewardFactory", 127 | "outputs": [ 128 | { 129 | "internalType": "address", 130 | "name": "", 131 | "type": "address" 132 | } 133 | ], 134 | "stateMutability": "view", 135 | "type": "function" 136 | }, 137 | { 138 | "inputs": [], 139 | "name": "staker", 140 | "outputs": [ 141 | { 142 | "internalType": "address", 143 | "name": "", 144 | "type": "address" 145 | } 146 | ], 147 | "stateMutability": "view", 148 | "type": "function" 149 | }, 150 | { 151 | "inputs": [], 152 | "name": "stashRewards", 153 | "outputs": [ 154 | { 155 | "internalType": "bool", 156 | "name": "", 157 | "type": "bool" 158 | } 159 | ], 160 | "stateMutability": "pure", 161 | "type": "function" 162 | }, 163 | { 164 | "inputs": [], 165 | "name": "tokenInfo", 166 | "outputs": [ 167 | { 168 | "internalType": "address", 169 | "name": "token", 170 | "type": "address" 171 | }, 172 | { 173 | "internalType": "address", 174 | "name": "rewardAddress", 175 | "type": "address" 176 | }, 177 | { 178 | "internalType": "uint256", 179 | "name": "lastActiveTime", 180 | "type": "uint256" 181 | } 182 | ], 183 | "stateMutability": "view", 184 | "type": "function" 185 | } 186 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/ExtraRewardStashV2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint256", 6 | "name": "_pid", 7 | "type": "uint256" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_operator", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "address", 16 | "name": "_staker", 17 | "type": "address" 18 | }, 19 | { 20 | "internalType": "address", 21 | "name": "_gauge", 22 | "type": "address" 23 | }, 24 | { 25 | "internalType": "address", 26 | "name": "_rFactory", 27 | "type": "address" 28 | } 29 | ], 30 | "stateMutability": "nonpayable", 31 | "type": "constructor" 32 | }, 33 | { 34 | "inputs": [], 35 | "name": "claimRewards", 36 | "outputs": [ 37 | { 38 | "internalType": "bool", 39 | "name": "", 40 | "type": "bool" 41 | } 42 | ], 43 | "stateMutability": "nonpayable", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "crv", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [], 61 | "name": "gauge", 62 | "outputs": [ 63 | { 64 | "internalType": "address", 65 | "name": "", 66 | "type": "address" 67 | } 68 | ], 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "getName", 75 | "outputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "", 79 | "type": "string" 80 | } 81 | ], 82 | "stateMutability": "pure", 83 | "type": "function" 84 | }, 85 | { 86 | "inputs": [ 87 | { 88 | "internalType": "address", 89 | "name": "", 90 | "type": "address" 91 | } 92 | ], 93 | "name": "historicalRewards", 94 | "outputs": [ 95 | { 96 | "internalType": "uint256", 97 | "name": "", 98 | "type": "uint256" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [], 106 | "name": "operator", 107 | "outputs": [ 108 | { 109 | "internalType": "address", 110 | "name": "", 111 | "type": "address" 112 | } 113 | ], 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "inputs": [], 119 | "name": "pid", 120 | "outputs": [ 121 | { 122 | "internalType": "uint256", 123 | "name": "", 124 | "type": "uint256" 125 | } 126 | ], 127 | "stateMutability": "view", 128 | "type": "function" 129 | }, 130 | { 131 | "inputs": [], 132 | "name": "processStash", 133 | "outputs": [ 134 | { 135 | "internalType": "bool", 136 | "name": "", 137 | "type": "bool" 138 | } 139 | ], 140 | "stateMutability": "nonpayable", 141 | "type": "function" 142 | }, 143 | { 144 | "inputs": [], 145 | "name": "rewardFactory", 146 | "outputs": [ 147 | { 148 | "internalType": "address", 149 | "name": "", 150 | "type": "address" 151 | } 152 | ], 153 | "stateMutability": "view", 154 | "type": "function" 155 | }, 156 | { 157 | "inputs": [], 158 | "name": "staker", 159 | "outputs": [ 160 | { 161 | "internalType": "address", 162 | "name": "", 163 | "type": "address" 164 | } 165 | ], 166 | "stateMutability": "view", 167 | "type": "function" 168 | }, 169 | { 170 | "inputs": [], 171 | "name": "stashRewards", 172 | "outputs": [ 173 | { 174 | "internalType": "bool", 175 | "name": "", 176 | "type": "bool" 177 | } 178 | ], 179 | "stateMutability": "nonpayable", 180 | "type": "function" 181 | }, 182 | { 183 | "inputs": [], 184 | "name": "tokenCount", 185 | "outputs": [ 186 | { 187 | "internalType": "uint256", 188 | "name": "", 189 | "type": "uint256" 190 | } 191 | ], 192 | "stateMutability": "view", 193 | "type": "function" 194 | }, 195 | { 196 | "inputs": [ 197 | { 198 | "internalType": "uint256", 199 | "name": "", 200 | "type": "uint256" 201 | } 202 | ], 203 | "name": "tokenInfo", 204 | "outputs": [ 205 | { 206 | "internalType": "address", 207 | "name": "token", 208 | "type": "address" 209 | }, 210 | { 211 | "internalType": "address", 212 | "name": "rewardAddress", 213 | "type": "address" 214 | }, 215 | { 216 | "internalType": "uint256", 217 | "name": "lastActiveTime", 218 | "type": "uint256" 219 | } 220 | ], 221 | "stateMutability": "view", 222 | "type": "function" 223 | } 224 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/ExtraRewardStashV30.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "uint256", 6 | "name": "_pid", 7 | "type": "uint256" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_operator", 12 | "type": "address" 13 | }, 14 | { 15 | "internalType": "address", 16 | "name": "_staker", 17 | "type": "address" 18 | }, 19 | { 20 | "internalType": "address", 21 | "name": "_gauge", 22 | "type": "address" 23 | }, 24 | { 25 | "internalType": "address", 26 | "name": "_rFactory", 27 | "type": "address" 28 | } 29 | ], 30 | "stateMutability": "nonpayable", 31 | "type": "constructor" 32 | }, 33 | { 34 | "inputs": [], 35 | "name": "claimRewards", 36 | "outputs": [ 37 | { 38 | "internalType": "bool", 39 | "name": "", 40 | "type": "bool" 41 | } 42 | ], 43 | "stateMutability": "nonpayable", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "crv", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [], 61 | "name": "gauge", 62 | "outputs": [ 63 | { 64 | "internalType": "address", 65 | "name": "", 66 | "type": "address" 67 | } 68 | ], 69 | "stateMutability": "view", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "getName", 75 | "outputs": [ 76 | { 77 | "internalType": "string", 78 | "name": "", 79 | "type": "string" 80 | } 81 | ], 82 | "stateMutability": "pure", 83 | "type": "function" 84 | }, 85 | { 86 | "inputs": [], 87 | "name": "hasRedirected", 88 | "outputs": [ 89 | { 90 | "internalType": "bool", 91 | "name": "", 92 | "type": "bool" 93 | } 94 | ], 95 | "stateMutability": "view", 96 | "type": "function" 97 | }, 98 | { 99 | "inputs": [ 100 | { 101 | "internalType": "address", 102 | "name": "", 103 | "type": "address" 104 | } 105 | ], 106 | "name": "historicalRewards", 107 | "outputs": [ 108 | { 109 | "internalType": "uint256", 110 | "name": "", 111 | "type": "uint256" 112 | } 113 | ], 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "inputs": [], 119 | "name": "operator", 120 | "outputs": [ 121 | { 122 | "internalType": "address", 123 | "name": "", 124 | "type": "address" 125 | } 126 | ], 127 | "stateMutability": "view", 128 | "type": "function" 129 | }, 130 | { 131 | "inputs": [], 132 | "name": "pid", 133 | "outputs": [ 134 | { 135 | "internalType": "uint256", 136 | "name": "", 137 | "type": "uint256" 138 | } 139 | ], 140 | "stateMutability": "view", 141 | "type": "function" 142 | }, 143 | { 144 | "inputs": [], 145 | "name": "processStash", 146 | "outputs": [ 147 | { 148 | "internalType": "bool", 149 | "name": "", 150 | "type": "bool" 151 | } 152 | ], 153 | "stateMutability": "nonpayable", 154 | "type": "function" 155 | }, 156 | { 157 | "inputs": [], 158 | "name": "rewardFactory", 159 | "outputs": [ 160 | { 161 | "internalType": "address", 162 | "name": "", 163 | "type": "address" 164 | } 165 | ], 166 | "stateMutability": "view", 167 | "type": "function" 168 | }, 169 | { 170 | "inputs": [], 171 | "name": "staker", 172 | "outputs": [ 173 | { 174 | "internalType": "address", 175 | "name": "", 176 | "type": "address" 177 | } 178 | ], 179 | "stateMutability": "view", 180 | "type": "function" 181 | }, 182 | { 183 | "inputs": [], 184 | "name": "stashRewards", 185 | "outputs": [ 186 | { 187 | "internalType": "bool", 188 | "name": "", 189 | "type": "bool" 190 | } 191 | ], 192 | "stateMutability": "pure", 193 | "type": "function" 194 | }, 195 | { 196 | "inputs": [], 197 | "name": "tokenCount", 198 | "outputs": [ 199 | { 200 | "internalType": "uint256", 201 | "name": "", 202 | "type": "uint256" 203 | } 204 | ], 205 | "stateMutability": "view", 206 | "type": "function" 207 | }, 208 | { 209 | "inputs": [ 210 | { 211 | "internalType": "uint256", 212 | "name": "", 213 | "type": "uint256" 214 | } 215 | ], 216 | "name": "tokenInfo", 217 | "outputs": [ 218 | { 219 | "internalType": "address", 220 | "name": "token", 221 | "type": "address" 222 | }, 223 | { 224 | "internalType": "address", 225 | "name": "rewardAddress", 226 | "type": "address" 227 | } 228 | ], 229 | "stateMutability": "view", 230 | "type": "function" 231 | } 232 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/FeeRegistry.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "inputs": [], 9 | "name": "FEE_DENOMINATOR", 10 | "outputs": [ 11 | { 12 | "internalType": "uint256", 13 | "name": "", 14 | "type": "uint256" 15 | } 16 | ], 17 | "stateMutability": "view", 18 | "type": "function" 19 | }, 20 | { 21 | "inputs": [], 22 | "name": "cvxIncentive", 23 | "outputs": [ 24 | { 25 | "internalType": "uint256", 26 | "name": "", 27 | "type": "uint256" 28 | } 29 | ], 30 | "stateMutability": "view", 31 | "type": "function" 32 | }, 33 | { 34 | "inputs": [], 35 | "name": "cvxfxsIncentive", 36 | "outputs": [ 37 | { 38 | "internalType": "uint256", 39 | "name": "", 40 | "type": "uint256" 41 | } 42 | ], 43 | "stateMutability": "view", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "feeDeposit", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [ 61 | { 62 | "internalType": "address", 63 | "name": "_from", 64 | "type": "address" 65 | } 66 | ], 67 | "name": "getFeeDepositor", 68 | "outputs": [ 69 | { 70 | "internalType": "address", 71 | "name": "", 72 | "type": "address" 73 | } 74 | ], 75 | "stateMutability": "view", 76 | "type": "function" 77 | }, 78 | { 79 | "inputs": [], 80 | "name": "maxFees", 81 | "outputs": [ 82 | { 83 | "internalType": "uint256", 84 | "name": "", 85 | "type": "uint256" 86 | } 87 | ], 88 | "stateMutability": "view", 89 | "type": "function" 90 | }, 91 | { 92 | "inputs": [], 93 | "name": "owner", 94 | "outputs": [ 95 | { 96 | "internalType": "address", 97 | "name": "", 98 | "type": "address" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [], 106 | "name": "platformIncentive", 107 | "outputs": [ 108 | { 109 | "internalType": "uint256", 110 | "name": "", 111 | "type": "uint256" 112 | } 113 | ], 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "inputs": [ 119 | { 120 | "internalType": "address", 121 | "name": "", 122 | "type": "address" 123 | } 124 | ], 125 | "name": "redirectDepositMap", 126 | "outputs": [ 127 | { 128 | "internalType": "address", 129 | "name": "", 130 | "type": "address" 131 | } 132 | ], 133 | "stateMutability": "view", 134 | "type": "function" 135 | }, 136 | { 137 | "inputs": [ 138 | { 139 | "internalType": "address", 140 | "name": "_deposit", 141 | "type": "address" 142 | } 143 | ], 144 | "name": "setDepositAddress", 145 | "outputs": [], 146 | "stateMutability": "nonpayable", 147 | "type": "function" 148 | }, 149 | { 150 | "inputs": [ 151 | { 152 | "internalType": "uint256", 153 | "name": "_cvxfxs", 154 | "type": "uint256" 155 | }, 156 | { 157 | "internalType": "uint256", 158 | "name": "_cvx", 159 | "type": "uint256" 160 | }, 161 | { 162 | "internalType": "uint256", 163 | "name": "_platform", 164 | "type": "uint256" 165 | } 166 | ], 167 | "name": "setFees", 168 | "outputs": [], 169 | "stateMutability": "nonpayable", 170 | "type": "function" 171 | }, 172 | { 173 | "inputs": [ 174 | { 175 | "internalType": "address", 176 | "name": "_from", 177 | "type": "address" 178 | }, 179 | { 180 | "internalType": "address", 181 | "name": "_deposit", 182 | "type": "address" 183 | } 184 | ], 185 | "name": "setRedirectDepositAddress", 186 | "outputs": [], 187 | "stateMutability": "nonpayable", 188 | "type": "function" 189 | }, 190 | { 191 | "inputs": [], 192 | "name": "totalFees", 193 | "outputs": [ 194 | { 195 | "internalType": "uint256", 196 | "name": "", 197 | "type": "uint256" 198 | } 199 | ], 200 | "stateMutability": "view", 201 | "type": "function" 202 | } 203 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/UniswapV2Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_feeToSetter", 7 | "type": "address" 8 | } 9 | ], 10 | "payable": false, 11 | "stateMutability": "nonpayable", 12 | "type": "constructor" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "token0", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "token1", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "address", 32 | "name": "pair", 33 | "type": "address" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "name": "PairCreated", 43 | "type": "event" 44 | }, 45 | { 46 | "constant": true, 47 | "inputs": [ 48 | { 49 | "internalType": "uint256", 50 | "name": "", 51 | "type": "uint256" 52 | } 53 | ], 54 | "name": "allPairs", 55 | "outputs": [ 56 | { 57 | "internalType": "address", 58 | "name": "", 59 | "type": "address" 60 | } 61 | ], 62 | "payable": false, 63 | "stateMutability": "view", 64 | "type": "function" 65 | }, 66 | { 67 | "constant": true, 68 | "inputs": [], 69 | "name": "allPairsLength", 70 | "outputs": [ 71 | { 72 | "internalType": "uint256", 73 | "name": "", 74 | "type": "uint256" 75 | } 76 | ], 77 | "payable": false, 78 | "stateMutability": "view", 79 | "type": "function" 80 | }, 81 | { 82 | "constant": false, 83 | "inputs": [ 84 | { 85 | "internalType": "address", 86 | "name": "tokenA", 87 | "type": "address" 88 | }, 89 | { 90 | "internalType": "address", 91 | "name": "tokenB", 92 | "type": "address" 93 | } 94 | ], 95 | "name": "createPair", 96 | "outputs": [ 97 | { 98 | "internalType": "address", 99 | "name": "pair", 100 | "type": "address" 101 | } 102 | ], 103 | "payable": false, 104 | "stateMutability": "nonpayable", 105 | "type": "function" 106 | }, 107 | { 108 | "constant": true, 109 | "inputs": [], 110 | "name": "feeTo", 111 | "outputs": [ 112 | { 113 | "internalType": "address", 114 | "name": "", 115 | "type": "address" 116 | } 117 | ], 118 | "payable": false, 119 | "stateMutability": "view", 120 | "type": "function" 121 | }, 122 | { 123 | "constant": true, 124 | "inputs": [], 125 | "name": "feeToSetter", 126 | "outputs": [ 127 | { 128 | "internalType": "address", 129 | "name": "", 130 | "type": "address" 131 | } 132 | ], 133 | "payable": false, 134 | "stateMutability": "view", 135 | "type": "function" 136 | }, 137 | { 138 | "constant": true, 139 | "inputs": [ 140 | { 141 | "internalType": "address", 142 | "name": "", 143 | "type": "address" 144 | }, 145 | { 146 | "internalType": "address", 147 | "name": "", 148 | "type": "address" 149 | } 150 | ], 151 | "name": "getPair", 152 | "outputs": [ 153 | { 154 | "internalType": "address", 155 | "name": "", 156 | "type": "address" 157 | } 158 | ], 159 | "payable": false, 160 | "stateMutability": "view", 161 | "type": "function" 162 | }, 163 | { 164 | "constant": false, 165 | "inputs": [ 166 | { 167 | "internalType": "address", 168 | "name": "_feeTo", 169 | "type": "address" 170 | } 171 | ], 172 | "name": "setFeeTo", 173 | "outputs": [], 174 | "payable": false, 175 | "stateMutability": "nonpayable", 176 | "type": "function" 177 | }, 178 | { 179 | "constant": false, 180 | "inputs": [ 181 | { 182 | "internalType": "address", 183 | "name": "_feeToSetter", 184 | "type": "address" 185 | } 186 | ], 187 | "name": "setFeeToSetter", 188 | "outputs": [], 189 | "payable": false, 190 | "stateMutability": "nonpayable", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/UniswapV3Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "anonymous": false, 9 | "inputs": [ 10 | { 11 | "indexed": true, 12 | "internalType": "uint24", 13 | "name": "fee", 14 | "type": "uint24" 15 | }, 16 | { 17 | "indexed": true, 18 | "internalType": "int24", 19 | "name": "tickSpacing", 20 | "type": "int24" 21 | } 22 | ], 23 | "name": "FeeAmountEnabled", 24 | "type": "event" 25 | }, 26 | { 27 | "anonymous": false, 28 | "inputs": [ 29 | { 30 | "indexed": true, 31 | "internalType": "address", 32 | "name": "oldOwner", 33 | "type": "address" 34 | }, 35 | { 36 | "indexed": true, 37 | "internalType": "address", 38 | "name": "newOwner", 39 | "type": "address" 40 | } 41 | ], 42 | "name": "OwnerChanged", 43 | "type": "event" 44 | }, 45 | { 46 | "anonymous": false, 47 | "inputs": [ 48 | { 49 | "indexed": true, 50 | "internalType": "address", 51 | "name": "token0", 52 | "type": "address" 53 | }, 54 | { 55 | "indexed": true, 56 | "internalType": "address", 57 | "name": "token1", 58 | "type": "address" 59 | }, 60 | { 61 | "indexed": true, 62 | "internalType": "uint24", 63 | "name": "fee", 64 | "type": "uint24" 65 | }, 66 | { 67 | "indexed": false, 68 | "internalType": "int24", 69 | "name": "tickSpacing", 70 | "type": "int24" 71 | }, 72 | { 73 | "indexed": false, 74 | "internalType": "address", 75 | "name": "pool", 76 | "type": "address" 77 | } 78 | ], 79 | "name": "PoolCreated", 80 | "type": "event" 81 | }, 82 | { 83 | "inputs": [ 84 | { 85 | "internalType": "address", 86 | "name": "tokenA", 87 | "type": "address" 88 | }, 89 | { 90 | "internalType": "address", 91 | "name": "tokenB", 92 | "type": "address" 93 | }, 94 | { 95 | "internalType": "uint24", 96 | "name": "fee", 97 | "type": "uint24" 98 | } 99 | ], 100 | "name": "createPool", 101 | "outputs": [ 102 | { 103 | "internalType": "address", 104 | "name": "pool", 105 | "type": "address" 106 | } 107 | ], 108 | "stateMutability": "nonpayable", 109 | "type": "function" 110 | }, 111 | { 112 | "inputs": [ 113 | { 114 | "internalType": "uint24", 115 | "name": "fee", 116 | "type": "uint24" 117 | }, 118 | { 119 | "internalType": "int24", 120 | "name": "tickSpacing", 121 | "type": "int24" 122 | } 123 | ], 124 | "name": "enableFeeAmount", 125 | "outputs": [], 126 | "stateMutability": "nonpayable", 127 | "type": "function" 128 | }, 129 | { 130 | "inputs": [ 131 | { 132 | "internalType": "uint24", 133 | "name": "", 134 | "type": "uint24" 135 | } 136 | ], 137 | "name": "feeAmountTickSpacing", 138 | "outputs": [ 139 | { 140 | "internalType": "int24", 141 | "name": "", 142 | "type": "int24" 143 | } 144 | ], 145 | "stateMutability": "view", 146 | "type": "function" 147 | }, 148 | { 149 | "inputs": [ 150 | { 151 | "internalType": "address", 152 | "name": "", 153 | "type": "address" 154 | }, 155 | { 156 | "internalType": "address", 157 | "name": "", 158 | "type": "address" 159 | }, 160 | { 161 | "internalType": "uint24", 162 | "name": "", 163 | "type": "uint24" 164 | } 165 | ], 166 | "name": "getPool", 167 | "outputs": [ 168 | { 169 | "internalType": "address", 170 | "name": "", 171 | "type": "address" 172 | } 173 | ], 174 | "stateMutability": "view", 175 | "type": "function" 176 | }, 177 | { 178 | "inputs": [], 179 | "name": "owner", 180 | "outputs": [ 181 | { 182 | "internalType": "address", 183 | "name": "", 184 | "type": "address" 185 | } 186 | ], 187 | "stateMutability": "view", 188 | "type": "function" 189 | }, 190 | { 191 | "inputs": [], 192 | "name": "parameters", 193 | "outputs": [ 194 | { 195 | "internalType": "address", 196 | "name": "factory", 197 | "type": "address" 198 | }, 199 | { 200 | "internalType": "address", 201 | "name": "token0", 202 | "type": "address" 203 | }, 204 | { 205 | "internalType": "address", 206 | "name": "token1", 207 | "type": "address" 208 | }, 209 | { 210 | "internalType": "uint24", 211 | "name": "fee", 212 | "type": "uint24" 213 | }, 214 | { 215 | "internalType": "int24", 216 | "name": "tickSpacing", 217 | "type": "int24" 218 | } 219 | ], 220 | "stateMutability": "view", 221 | "type": "function" 222 | }, 223 | { 224 | "inputs": [ 225 | { 226 | "internalType": "address", 227 | "name": "_owner", 228 | "type": "address" 229 | } 230 | ], 231 | "name": "setOwner", 232 | "outputs": [], 233 | "stateMutability": "nonpayable", 234 | "type": "function" 235 | } 236 | ] -------------------------------------------------------------------------------- /subgraphs/convex/abis/UniswapV3Quoter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_factory", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_WETH9", 12 | "type": "address" 13 | } 14 | ], 15 | "stateMutability": "nonpayable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "inputs": [], 20 | "name": "WETH9", 21 | "outputs": [ 22 | { 23 | "internalType": "address", 24 | "name": "", 25 | "type": "address" 26 | } 27 | ], 28 | "stateMutability": "view", 29 | "type": "function" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "factory", 34 | "outputs": [ 35 | { 36 | "internalType": "address", 37 | "name": "", 38 | "type": "address" 39 | } 40 | ], 41 | "stateMutability": "view", 42 | "type": "function" 43 | }, 44 | { 45 | "inputs": [ 46 | { 47 | "internalType": "bytes", 48 | "name": "path", 49 | "type": "bytes" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "amountIn", 54 | "type": "uint256" 55 | } 56 | ], 57 | "name": "quoteExactInput", 58 | "outputs": [ 59 | { 60 | "internalType": "uint256", 61 | "name": "amountOut", 62 | "type": "uint256" 63 | } 64 | ], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "tokenIn", 73 | "type": "address" 74 | }, 75 | { 76 | "internalType": "address", 77 | "name": "tokenOut", 78 | "type": "address" 79 | }, 80 | { 81 | "internalType": "uint24", 82 | "name": "fee", 83 | "type": "uint24" 84 | }, 85 | { 86 | "internalType": "uint256", 87 | "name": "amountIn", 88 | "type": "uint256" 89 | }, 90 | { 91 | "internalType": "uint160", 92 | "name": "sqrtPriceLimitX96", 93 | "type": "uint160" 94 | } 95 | ], 96 | "name": "quoteExactInputSingle", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "amountOut", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "bytes", 111 | "name": "path", 112 | "type": "bytes" 113 | }, 114 | { 115 | "internalType": "uint256", 116 | "name": "amountOut", 117 | "type": "uint256" 118 | } 119 | ], 120 | "name": "quoteExactOutput", 121 | "outputs": [ 122 | { 123 | "internalType": "uint256", 124 | "name": "amountIn", 125 | "type": "uint256" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [ 133 | { 134 | "internalType": "address", 135 | "name": "tokenIn", 136 | "type": "address" 137 | }, 138 | { 139 | "internalType": "address", 140 | "name": "tokenOut", 141 | "type": "address" 142 | }, 143 | { 144 | "internalType": "uint24", 145 | "name": "fee", 146 | "type": "uint24" 147 | }, 148 | { 149 | "internalType": "uint256", 150 | "name": "amountOut", 151 | "type": "uint256" 152 | }, 153 | { 154 | "internalType": "uint160", 155 | "name": "sqrtPriceLimitX96", 156 | "type": "uint160" 157 | } 158 | ], 159 | "name": "quoteExactOutputSingle", 160 | "outputs": [ 161 | { 162 | "internalType": "uint256", 163 | "name": "amountIn", 164 | "type": "uint256" 165 | } 166 | ], 167 | "stateMutability": "nonpayable", 168 | "type": "function" 169 | }, 170 | { 171 | "inputs": [ 172 | { 173 | "internalType": "int256", 174 | "name": "amount0Delta", 175 | "type": "int256" 176 | }, 177 | { 178 | "internalType": "int256", 179 | "name": "amount1Delta", 180 | "type": "int256" 181 | }, 182 | { 183 | "internalType": "bytes", 184 | "name": "path", 185 | "type": "bytes" 186 | } 187 | ], 188 | "name": "uniswapV3SwapCallback", 189 | "outputs": [], 190 | "stateMutability": "view", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/convex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "convex", 3 | "license": "MIT", 4 | "version": "1.0.0", 5 | "files": [ 6 | "generated" 7 | ], 8 | "scripts": { 9 | "codegen": "graph codegen", 10 | "build": "graph build", 11 | "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ convex-community/convex", 12 | "deploy-hosted": "graph deploy --product hosted-service convex-community/convex", 13 | "deploy-studio": "graph deploy --studio convex", 14 | "create-local": "graph create --node http://localhost:8020/ convex/convex", 15 | "remove-local": "graph remove --node http://localhost:8020/ convex/convex", 16 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex/convex" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/convex/src/mapping-3crv.ts: -------------------------------------------------------------------------------- 1 | import { Address } from '@graphprotocol/graph-ts' 2 | import { getDailyRevenueSnapshot } from './services/revenue' 3 | import { RewardAdded } from '../generated/Booster/VirtualBalanceRewardPool' 4 | import { getUsdRate } from 'utils/pricing' 5 | import { BIG_DECIMAL_1E18, THREE_CRV_ADDRESS, THREE_CRV_TOKEN } from 'const' 6 | import { getPlatform } from './services/platform' 7 | import { getIntervalFromTimestamp, DAY } from 'utils/time' 8 | 9 | export function handleRewardAdded(event: RewardAdded): void { 10 | const amount = event.params.reward 11 | const threeCrvPrice = getUsdRate(THREE_CRV_ADDRESS) 12 | const value = amount.toBigDecimal().div(BIG_DECIMAL_1E18).times(threeCrvPrice) 13 | 14 | const platform = getPlatform() 15 | const day = getIntervalFromTimestamp(event.block.timestamp, DAY) 16 | const revenueSnapshot = getDailyRevenueSnapshot(day) 17 | 18 | revenueSnapshot.threeCrvRevenueToCvxCrvStakersAmount = 19 | revenueSnapshot.threeCrvRevenueToCvxCrvStakersAmount.plus(value) 20 | platform.totalThreeCrvRevenueToCvxCrvStakers = platform.totalThreeCrvRevenueToCvxCrvStakers.plus(value) 21 | 22 | revenueSnapshot.save() 23 | platform.save() 24 | } 25 | -------------------------------------------------------------------------------- /subgraphs/convex/src/mapping-bribes-v2.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IncreasedIncentive as IncreasedIncentiveEvent, 3 | NewIncentive as NewIncentiveEvent, 4 | UpdatedFee as UpdatedFeeEvent, 5 | } from '../generated/VotiumBribeV2/VotiumV2' 6 | 7 | import { BigInt } from '@graphprotocol/graph-ts' 8 | import { getPlatform } from './services/platform' 9 | import { getDecimals, getUsdRate } from 'utils/pricing' 10 | import { exponentToBigDecimal } from 'utils/maths' 11 | import { getDailyRevenueSnapshot } from './services/revenue' 12 | import { getIntervalFromTimestamp, DAY, WEEK } from 'utils/time' 13 | 14 | export function getCurrentRound(timestamp: BigInt): BigInt { 15 | const BASE = 1348 * 86400 * 14 16 | const week = getIntervalFromTimestamp(timestamp, WEEK) 17 | const round = week.minus(BigInt.fromI32(BASE)).div(WEEK.times(BigInt.fromI32(2))) 18 | return round 19 | } 20 | 21 | export function handleIncreasedIncentive(event: IncreasedIncentiveEvent): void { 22 | const bribeTokenPrice = getUsdRate(event.params._token) 23 | const decimals = getDecimals(event.params._token) 24 | const bribeValue = event.params._increase.toBigDecimal().div(exponentToBigDecimal(decimals)).times(bribeTokenPrice) 25 | const platform = getPlatform() 26 | const day = getIntervalFromTimestamp(event.block.timestamp, DAY) 27 | const futureWeeks = event.params._round.minus(getCurrentRound(event.block.timestamp)) 28 | const revenueSnapshot = getDailyRevenueSnapshot(day.plus(WEEK.times(futureWeeks))) 29 | 30 | revenueSnapshot.bribeRevenue = revenueSnapshot.bribeRevenue.plus(bribeValue) 31 | platform.totalBribeRevenue = platform.totalBribeRevenue.plus(bribeValue) 32 | platform.save() 33 | revenueSnapshot.save() 34 | } 35 | 36 | export function handleNewIncentive(event: NewIncentiveEvent): void { 37 | const bribeTokenPrice = getUsdRate(event.params._token) 38 | const decimals = getDecimals(event.params._token) 39 | const bribeValue = event.params._amount.toBigDecimal().div(exponentToBigDecimal(decimals)).times(bribeTokenPrice) 40 | const platform = getPlatform() 41 | const day = getIntervalFromTimestamp(event.block.timestamp, DAY) 42 | const futureWeeks = event.params._round.minus(getCurrentRound(event.block.timestamp)) 43 | const revenueSnapshot = getDailyRevenueSnapshot(day.plus(WEEK.times(futureWeeks))) 44 | 45 | revenueSnapshot.bribeRevenue = revenueSnapshot.bribeRevenue.plus(bribeValue) 46 | platform.totalBribeRevenue = platform.totalBribeRevenue.plus(bribeValue) 47 | platform.save() 48 | revenueSnapshot.save() 49 | } 50 | 51 | export function handleUpdatedFeeV2(event: UpdatedFeeEvent): void { 52 | const platform = getPlatform() 53 | 54 | platform.bribeFee = event.params._feeAmount 55 | platform.save() 56 | } 57 | -------------------------------------------------------------------------------- /subgraphs/convex/src/mapping-bribes.ts: -------------------------------------------------------------------------------- 1 | import { getPlatform } from './services/platform' 2 | import { Bribed, UpdatedFee } from '../generated/VotiumBribe/Votium' 3 | import { getDecimals, getUsdRate } from 'utils/pricing' 4 | import { exponentToBigDecimal } from 'utils/maths' 5 | import { getIntervalFromTimestamp, DAY } from 'utils/time' 6 | import { getDailyRevenueSnapshot } from './services/revenue' 7 | 8 | export function handleUpdatedFee(event: UpdatedFee): void { 9 | const platform = getPlatform() 10 | platform.bribeFee = event.params._feeAmount 11 | platform.save() 12 | } 13 | 14 | export function handleBribed(event: Bribed): void { 15 | const bribeTokenPrice = getUsdRate(event.params._token) 16 | const decimals = getDecimals(event.params._token) 17 | const bribeValue = event.params._amount.toBigDecimal().div(exponentToBigDecimal(decimals)).times(bribeTokenPrice) 18 | const platform = getPlatform() 19 | const day = getIntervalFromTimestamp(event.block.timestamp, DAY) 20 | const revenueSnapshot = getDailyRevenueSnapshot(day) 21 | 22 | revenueSnapshot.bribeRevenue = revenueSnapshot.bribeRevenue.plus(bribeValue) 23 | platform.totalBribeRevenue = platform.totalBribeRevenue.plus(bribeValue) 24 | platform.save() 25 | revenueSnapshot.save() 26 | } 27 | -------------------------------------------------------------------------------- /subgraphs/convex/src/mapping-fxs-deposits.ts: -------------------------------------------------------------------------------- 1 | import { getPlatform } from './services/platform' 2 | import { getUsdRate } from 'utils/pricing' 3 | import { getIntervalFromTimestamp, DAY } from 'utils/time' 4 | import { getDailyRevenueSnapshot } from './services/revenue' 5 | import { FeeDeposit, RewardsDistributed } from '../generated/FeeRegistry/FeeDeposit' 6 | import { FeeRegistry } from '../generated/FeeRegistry/FeeRegistry' 7 | import { BIG_DECIMAL_1E18, BIG_DECIMAL_ONE, DENOMINATOR, FEE_REGISTRY_ADDRESS } from 'const' 8 | import { SetDepositAddressCall } from '../generated/FeeRegistry/FeeRegistry' 9 | import { FeeDepositTemplate } from '../generated/templates' 10 | 11 | export function handleSetDepositAddress(call: SetDepositAddressCall): void { 12 | FeeDepositTemplate.create(call.inputs._deposit) 13 | } 14 | 15 | export function handleRewardsDistributed(event: RewardsDistributed): void { 16 | const registry = FeeRegistry.bind(FEE_REGISTRY_ADDRESS) 17 | const deposit = FeeDeposit.bind(event.address) 18 | const decimalDenominator = DENOMINATOR.toBigDecimal() 19 | const amount = event.params.amount.toBigDecimal().div(BIG_DECIMAL_1E18) 20 | 21 | const platform = getPlatform() 22 | const day = getIntervalFromTimestamp(event.block.timestamp, DAY) 23 | const revenueSnapshot = getDailyRevenueSnapshot(day) 24 | 25 | const callIncentive = deposit.callIncentive().toBigDecimal().div(decimalDenominator) 26 | const stakerIncentive = registry.cvxIncentive().toBigDecimal().div(decimalDenominator) 27 | const totalFees = registry.totalFees().toBigDecimal().div(decimalDenominator) 28 | const platformFee = registry.platformIncentive().toBigDecimal().div(decimalDenominator) 29 | const lpShare = BIG_DECIMAL_ONE.minus(totalFees) 30 | // technically rewards can be given in other tokens 31 | const tokenPrice = getUsdRate(event.params.token) 32 | 33 | // the amount logged doesn't include the caller fee so let's put it back 34 | const wholeFeeAmount = amount.div(BIG_DECIMAL_ONE.minus(callIncentive)) 35 | const fxsRevenueToCallers = wholeFeeAmount.minus(amount) 36 | 37 | // infer total revenue from it 38 | const totalFxsRevenue = amount.div(lpShare).times(tokenPrice) 39 | const fxsRevenueToLpProviders = totalFxsRevenue.minus(amount) 40 | 41 | // calc other amounts 42 | const fxsRevenueToCvxStakers = amount.times(stakerIncentive).div(totalFees) 43 | const fxsRevenueToPlatform = amount.times(platformFee).div(totalFees) 44 | const fxsRevenueToCvxFxsStakers = amount.minus(fxsRevenueToCvxStakers.plus(fxsRevenueToPlatform)) 45 | 46 | revenueSnapshot.fxsRevenueToCallersAmount = fxsRevenueToCallers 47 | revenueSnapshot.fxsRevenueToCvxStakersAmount = fxsRevenueToCvxStakers 48 | revenueSnapshot.fxsRevenueToPlatformAmount = fxsRevenueToPlatform 49 | revenueSnapshot.fxsRevenueToLpProvidersAmount = fxsRevenueToLpProviders 50 | revenueSnapshot.fxsRevenueToCvxFxsStakersAmount = fxsRevenueToCvxFxsStakers 51 | revenueSnapshot.totalFxsRevenue = totalFxsRevenue 52 | revenueSnapshot.fxsPrice = tokenPrice 53 | 54 | platform.totalFxsRevenueToPlatform = platform.totalFxsRevenueToPlatform.plus(fxsRevenueToPlatform) 55 | platform.totalFxsRevenue = platform.totalFxsRevenue.plus(totalFxsRevenue) 56 | platform.totalFxsRevenueToCallers = platform.totalFxsRevenueToCallers.plus(fxsRevenueToCallers) 57 | platform.totalFxsRevenueToCvxStakers = platform.totalFxsRevenueToCvxStakers.plus(fxsRevenueToCvxStakers) 58 | platform.totalFxsRevenueToCvxFxsStakers = platform.totalFxsRevenueToCvxFxsStakers.plus(fxsRevenueToCvxFxsStakers) 59 | platform.totalFxsRevenueToLpProviders = platform.totalFxsRevenueToLpProviders.plus(fxsRevenueToLpProviders) 60 | 61 | platform.save() 62 | revenueSnapshot.save() 63 | } 64 | -------------------------------------------------------------------------------- /subgraphs/convex/src/mapping-rewards.ts: -------------------------------------------------------------------------------- 1 | import { QueueNewRewardsCall } from '../generated/templates/PoolCrvRewards/BaseRewardPool' 2 | import { dataSource } from '@graphprotocol/graph-ts' 3 | import { PoolReward } from '../generated/schema' 4 | import { updateDailyRevenueSnapshotForCrv } from './services/revenue' 5 | 6 | export function handleNewRewardsQueued(call: QueueNewRewardsCall): void { 7 | const context = dataSource.context() 8 | const reward = new PoolReward(call.transaction.hash.toHexString() + '-' + call.to.toHexString()) 9 | reward.poolid = context.getString('pid') 10 | reward.crvRewards = call.inputs._rewards 11 | reward.timestamp = call.block.timestamp 12 | reward.contract = call.to 13 | reward.save() 14 | 15 | updateDailyRevenueSnapshotForCrv(call.inputs._rewards, call.block.timestamp) 16 | } 17 | -------------------------------------------------------------------------------- /subgraphs/convex/src/mapping-treasury.ts: -------------------------------------------------------------------------------- 1 | import { getDailyRevenueSnapshot } from './services/revenue' 2 | import { getUsdRate } from 'utils/pricing' 3 | import { BIG_DECIMAL_1E18, THREE_CRV_ADDRESS, THREE_CRV_TOKEN } from 'const' 4 | import { getPlatform } from './services/platform' 5 | import { getIntervalFromTimestamp, DAY } from 'utils/time' 6 | import { ClaimedReward } from '../generated/CvxCrvPol/TreasurySwap' 7 | import { Claimed } from '../generated/VoteMarketRewards/VoteMarket' 8 | import { Address, BigDecimal, BigInt } from '@graphprotocol/graph-ts' 9 | 10 | function addToRevenueSnapshot(timestamp: BigInt, value: BigDecimal): void { 11 | const platform = getPlatform() 12 | const day = getIntervalFromTimestamp(timestamp, DAY) 13 | const revenueSnapshot = getDailyRevenueSnapshot(day) 14 | 15 | revenueSnapshot.otherRevenue = revenueSnapshot.otherRevenue.plus(value) 16 | platform.totalOtherRevenue = platform.totalOtherRevenue.plus(value) 17 | 18 | revenueSnapshot.save() 19 | platform.save() 20 | } 21 | 22 | export function handleVoteMarketRewardClaimed(event: Claimed): void { 23 | if (event.params.user != Address.fromString('0x989AEb4d175e16225E39E87d0D97A3360524AD80')) { 24 | return 25 | } 26 | const amount = event.params.amount 27 | const tokenPrice = getUsdRate(event.params.rewardToken) 28 | const value = amount.toBigDecimal().div(BIG_DECIMAL_1E18).times(tokenPrice) 29 | addToRevenueSnapshot(event.block.timestamp, value) 30 | } 31 | 32 | export function handleRewardClaimed(event: ClaimedReward): void { 33 | const amount = event.params._amount 34 | const tokenPrice = getUsdRate(event.params._token) 35 | const value = amount.toBigDecimal().div(BIG_DECIMAL_1E18).times(tokenPrice) 36 | addToRevenueSnapshot(event.block.timestamp, value) 37 | } 38 | -------------------------------------------------------------------------------- /subgraphs/convex/src/services/platform.ts: -------------------------------------------------------------------------------- 1 | import { Platform } from '../../generated/schema' 2 | import { CONVEX_PLATFORM_ID } from 'const' 3 | import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' 4 | 5 | export function getPlatform(): Platform { 6 | let platform = Platform.load(CONVEX_PLATFORM_ID) 7 | if (!platform) { 8 | platform = new Platform(CONVEX_PLATFORM_ID) 9 | platform.bribeFee = BigInt.fromI32(400) 10 | platform.poolCount = BigInt.zero() 11 | platform.totalCrvRevenueToLpProviders = BigDecimal.zero() 12 | platform.totalCvxRevenueToLpProviders = BigDecimal.zero() 13 | platform.totalFxsRevenueToLpProviders = BigDecimal.zero() 14 | platform.totalCrvRevenueToCvxCrvStakers = BigDecimal.zero() 15 | platform.totalCvxRevenueToCvxCrvStakers = BigDecimal.zero() 16 | platform.totalThreeCrvRevenueToCvxCrvStakers = BigDecimal.zero() 17 | platform.totalFxsRevenueToCvxFxsStakers = BigDecimal.zero() 18 | platform.totalCrvRevenueToCvxStakers = BigDecimal.zero() 19 | platform.totalFxsRevenueToCvxStakers = BigDecimal.zero() 20 | platform.totalCrvRevenueToCallers = BigDecimal.zero() 21 | platform.totalFxsRevenueToCallers = BigDecimal.zero() 22 | platform.totalCrvRevenueToPlatform = BigDecimal.zero() 23 | platform.totalFxsRevenueToPlatform = BigDecimal.zero() 24 | platform.totalCrvRevenue = BigDecimal.zero() 25 | platform.totalFxsRevenue = BigDecimal.zero() 26 | platform.totalBribeRevenue = BigDecimal.zero() 27 | platform.totalOtherRevenue = BigDecimal.zero() 28 | } 29 | return platform 30 | } 31 | -------------------------------------------------------------------------------- /subgraphs/convex/src/services/snapshots.ts: -------------------------------------------------------------------------------- 1 | import { DailyPoolSnapshot, Pool } from '../../generated/schema' 2 | import { BigDecimal, BigInt, log } from '@graphprotocol/graph-ts' 3 | import { getIntervalFromTimestamp, DAY } from 'utils/time' 4 | import { bigDecimalExponential } from 'utils/maths' 5 | import { getPoolApr, getXcpProfitResult } from './pools' 6 | import {getLendingApr, getLpTokenPriceUSD, getLpTokenVirtualPrice, getPoolBaseApr, getV2PoolBaseApr} from './apr' 7 | import { getPlatform } from './platform' 8 | 9 | export function createNewSnapsot(snapId: string): DailyPoolSnapshot { 10 | const snapshot = new DailyPoolSnapshot(snapId) 11 | snapshot.id = snapId 12 | snapshot.poolid = '' 13 | snapshot.poolName = '' 14 | snapshot.withdrawalCount = BigInt.zero() 15 | snapshot.depositCount = BigInt.zero() 16 | snapshot.withdrawalVolume = BigInt.zero() 17 | snapshot.depositVolume = BigInt.zero() 18 | snapshot.withdrawalValue = BigDecimal.zero() 19 | snapshot.depositValue = BigDecimal.zero() 20 | snapshot.lpTokenBalance = BigInt.zero() 21 | snapshot.lpTokenVirtualPrice = BigDecimal.zero() 22 | snapshot.lpTokenUSDPrice = BigDecimal.zero() 23 | snapshot.xcpProfit = BigDecimal.zero() 24 | snapshot.xcpProfitA = BigDecimal.zero() 25 | snapshot.tvl = BigDecimal.zero() 26 | snapshot.curveTvlRatio = BigDecimal.zero() 27 | snapshot.crvApr = BigDecimal.zero() 28 | snapshot.cvxApr = BigDecimal.zero() 29 | snapshot.extraRewardsApr = BigDecimal.zero() 30 | snapshot.baseApr = BigDecimal.zero() 31 | snapshot.rawBaseApr = BigDecimal.zero() 32 | snapshot.timestamp = BigInt.zero() 33 | snapshot.block = BigInt.zero() 34 | snapshot.save() 35 | return snapshot 36 | } 37 | 38 | export function getDailyPoolSnapshot(pool: Pool, timestamp: BigInt, block: BigInt): DailyPoolSnapshot { 39 | const time = getIntervalFromTimestamp(timestamp, DAY) 40 | const snapId = pool.name + '-' + pool.poolid.toString() + '-' + time.toString() 41 | let snapshot = DailyPoolSnapshot.load(snapId) 42 | if (!snapshot) { 43 | log.info('Taking pool snapshot for pool {} ({}), block: {}', [pool.name, pool.swap.toHexString(), block.toString()]) 44 | snapshot = createNewSnapsot(snapId) 45 | snapshot.poolid = pool.poolid.toString() 46 | snapshot.poolName = pool.name 47 | snapshot.timestamp = timestamp 48 | snapshot.lpTokenVirtualPrice = getLpTokenVirtualPrice(pool) 49 | 50 | const lpPrice = getLpTokenPriceUSD(pool) 51 | log.debug('LP Token price USD for pool {}: {}', [pool.name, lpPrice.toString()]) 52 | pool.lpTokenUSDPrice = lpPrice 53 | snapshot.lpTokenUSDPrice = pool.lpTokenUSDPrice 54 | 55 | const aprs = getPoolApr(pool, timestamp, lpPrice) 56 | snapshot.crvApr = aprs[0] 57 | snapshot.cvxApr = aprs[1] 58 | snapshot.extraRewardsApr = aprs[2] 59 | pool.crvApr = aprs[0] 60 | pool.cvxApr = aprs[1] 61 | pool.extraRewardsApr = aprs[2] 62 | pool.save() 63 | 64 | snapshot.lpTokenBalance = pool.lpTokenBalance 65 | snapshot.tvl = pool.tvl 66 | snapshot.curveTvlRatio = pool.curveTvlRatio 67 | let baseApr = BigDecimal.zero() 68 | if (pool.isV2) { 69 | const xcpProfits = getXcpProfitResult(pool) 70 | snapshot.xcpProfit = xcpProfits[0] 71 | snapshot.xcpProfitA = xcpProfits[1] 72 | baseApr = getV2PoolBaseApr(pool, snapshot.xcpProfit, snapshot.xcpProfitA, timestamp) 73 | } else if (pool.isLending) { 74 | baseApr = getLendingApr(pool) 75 | } 76 | else { 77 | baseApr = getPoolBaseApr(pool, snapshot.lpTokenVirtualPrice, timestamp) 78 | } 79 | // annualize Apr 80 | const annualizedApr = bigDecimalExponential(baseApr, BigDecimal.fromString('365')) 81 | snapshot.baseApr = annualizedApr 82 | snapshot.rawBaseApr = baseApr 83 | snapshot.block = block 84 | snapshot.save() 85 | } 86 | return snapshot 87 | } 88 | 89 | export function takePoolSnapshots(timestamp: BigInt, block: BigInt): void { 90 | const platform = getPlatform() 91 | for (let i = 0; i < platform.poolCount.toI32(); ++i) { 92 | const pool = Pool.load(i.toString()) 93 | if (pool && pool.active) { 94 | getDailyPoolSnapshot(pool, timestamp, block) 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /subgraphs/convex/src/services/user.ts: -------------------------------------------------------------------------------- 1 | import { Address } from '@graphprotocol/graph-ts' 2 | import { User } from '../../generated/schema' 3 | 4 | export function getUser(address: Address): User { 5 | let user = User.load(address.toHexString()) 6 | if (!user) { 7 | user = new User(address.toHexString()) 8 | user.address = address 9 | user.save() 10 | } 11 | return user 12 | } 13 | -------------------------------------------------------------------------------- /subgraphs/convex/src/services/utils.ts: -------------------------------------------------------------------------------- 1 | import { ASSET_TYPES } from 'const' 2 | 3 | export function inferAssetType(curvePool: string, poolName: string): i32 { 4 | if (ASSET_TYPES.has(curvePool)) { 5 | return ASSET_TYPES.get(curvePool) 6 | } 7 | const description = poolName.toUpperCase() 8 | const stables = ['USD', 'DAI', 'MIM', 'TETHER', 'FRAX'] 9 | for (let i = 0; i < stables.length; i++) { 10 | if (description.indexOf(stables[i]) >= 0) { 11 | return 0 12 | } 13 | } 14 | 15 | if (description.indexOf('BTC') >= 0) { 16 | return 2 17 | } else if (description.indexOf('ETH') >= 0) { 18 | return 1 19 | } else { 20 | return 3 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /subgraphs/cvxprisma/abis/ERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] -------------------------------------------------------------------------------- /subgraphs/cvxprisma/abis/UniswapV2Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_feeToSetter", 7 | "type": "address" 8 | } 9 | ], 10 | "payable": false, 11 | "stateMutability": "nonpayable", 12 | "type": "constructor" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "token0", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "token1", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "address", 32 | "name": "pair", 33 | "type": "address" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "name": "PairCreated", 43 | "type": "event" 44 | }, 45 | { 46 | "constant": true, 47 | "inputs": [ 48 | { 49 | "internalType": "uint256", 50 | "name": "", 51 | "type": "uint256" 52 | } 53 | ], 54 | "name": "allPairs", 55 | "outputs": [ 56 | { 57 | "internalType": "address", 58 | "name": "", 59 | "type": "address" 60 | } 61 | ], 62 | "payable": false, 63 | "stateMutability": "view", 64 | "type": "function" 65 | }, 66 | { 67 | "constant": true, 68 | "inputs": [], 69 | "name": "allPairsLength", 70 | "outputs": [ 71 | { 72 | "internalType": "uint256", 73 | "name": "", 74 | "type": "uint256" 75 | } 76 | ], 77 | "payable": false, 78 | "stateMutability": "view", 79 | "type": "function" 80 | }, 81 | { 82 | "constant": false, 83 | "inputs": [ 84 | { 85 | "internalType": "address", 86 | "name": "tokenA", 87 | "type": "address" 88 | }, 89 | { 90 | "internalType": "address", 91 | "name": "tokenB", 92 | "type": "address" 93 | } 94 | ], 95 | "name": "createPair", 96 | "outputs": [ 97 | { 98 | "internalType": "address", 99 | "name": "pair", 100 | "type": "address" 101 | } 102 | ], 103 | "payable": false, 104 | "stateMutability": "nonpayable", 105 | "type": "function" 106 | }, 107 | { 108 | "constant": true, 109 | "inputs": [], 110 | "name": "feeTo", 111 | "outputs": [ 112 | { 113 | "internalType": "address", 114 | "name": "", 115 | "type": "address" 116 | } 117 | ], 118 | "payable": false, 119 | "stateMutability": "view", 120 | "type": "function" 121 | }, 122 | { 123 | "constant": true, 124 | "inputs": [], 125 | "name": "feeToSetter", 126 | "outputs": [ 127 | { 128 | "internalType": "address", 129 | "name": "", 130 | "type": "address" 131 | } 132 | ], 133 | "payable": false, 134 | "stateMutability": "view", 135 | "type": "function" 136 | }, 137 | { 138 | "constant": true, 139 | "inputs": [ 140 | { 141 | "internalType": "address", 142 | "name": "", 143 | "type": "address" 144 | }, 145 | { 146 | "internalType": "address", 147 | "name": "", 148 | "type": "address" 149 | } 150 | ], 151 | "name": "getPair", 152 | "outputs": [ 153 | { 154 | "internalType": "address", 155 | "name": "", 156 | "type": "address" 157 | } 158 | ], 159 | "payable": false, 160 | "stateMutability": "view", 161 | "type": "function" 162 | }, 163 | { 164 | "constant": false, 165 | "inputs": [ 166 | { 167 | "internalType": "address", 168 | "name": "_feeTo", 169 | "type": "address" 170 | } 171 | ], 172 | "name": "setFeeTo", 173 | "outputs": [], 174 | "payable": false, 175 | "stateMutability": "nonpayable", 176 | "type": "function" 177 | }, 178 | { 179 | "constant": false, 180 | "inputs": [ 181 | { 182 | "internalType": "address", 183 | "name": "_feeToSetter", 184 | "type": "address" 185 | } 186 | ], 187 | "name": "setFeeToSetter", 188 | "outputs": [], 189 | "payable": false, 190 | "stateMutability": "nonpayable", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/cvxprisma/abis/UniswapV3Quoter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_factory", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_WETH9", 12 | "type": "address" 13 | } 14 | ], 15 | "stateMutability": "nonpayable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "inputs": [], 20 | "name": "WETH9", 21 | "outputs": [ 22 | { 23 | "internalType": "address", 24 | "name": "", 25 | "type": "address" 26 | } 27 | ], 28 | "stateMutability": "view", 29 | "type": "function" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "factory", 34 | "outputs": [ 35 | { 36 | "internalType": "address", 37 | "name": "", 38 | "type": "address" 39 | } 40 | ], 41 | "stateMutability": "view", 42 | "type": "function" 43 | }, 44 | { 45 | "inputs": [ 46 | { 47 | "internalType": "bytes", 48 | "name": "path", 49 | "type": "bytes" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "amountIn", 54 | "type": "uint256" 55 | } 56 | ], 57 | "name": "quoteExactInput", 58 | "outputs": [ 59 | { 60 | "internalType": "uint256", 61 | "name": "amountOut", 62 | "type": "uint256" 63 | } 64 | ], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "tokenIn", 73 | "type": "address" 74 | }, 75 | { 76 | "internalType": "address", 77 | "name": "tokenOut", 78 | "type": "address" 79 | }, 80 | { 81 | "internalType": "uint24", 82 | "name": "fee", 83 | "type": "uint24" 84 | }, 85 | { 86 | "internalType": "uint256", 87 | "name": "amountIn", 88 | "type": "uint256" 89 | }, 90 | { 91 | "internalType": "uint160", 92 | "name": "sqrtPriceLimitX96", 93 | "type": "uint160" 94 | } 95 | ], 96 | "name": "quoteExactInputSingle", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "amountOut", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "bytes", 111 | "name": "path", 112 | "type": "bytes" 113 | }, 114 | { 115 | "internalType": "uint256", 116 | "name": "amountOut", 117 | "type": "uint256" 118 | } 119 | ], 120 | "name": "quoteExactOutput", 121 | "outputs": [ 122 | { 123 | "internalType": "uint256", 124 | "name": "amountIn", 125 | "type": "uint256" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [ 133 | { 134 | "internalType": "address", 135 | "name": "tokenIn", 136 | "type": "address" 137 | }, 138 | { 139 | "internalType": "address", 140 | "name": "tokenOut", 141 | "type": "address" 142 | }, 143 | { 144 | "internalType": "uint24", 145 | "name": "fee", 146 | "type": "uint24" 147 | }, 148 | { 149 | "internalType": "uint256", 150 | "name": "amountOut", 151 | "type": "uint256" 152 | }, 153 | { 154 | "internalType": "uint160", 155 | "name": "sqrtPriceLimitX96", 156 | "type": "uint160" 157 | } 158 | ], 159 | "name": "quoteExactOutputSingle", 160 | "outputs": [ 161 | { 162 | "internalType": "uint256", 163 | "name": "amountIn", 164 | "type": "uint256" 165 | } 166 | ], 167 | "stateMutability": "nonpayable", 168 | "type": "function" 169 | }, 170 | { 171 | "inputs": [ 172 | { 173 | "internalType": "int256", 174 | "name": "amount0Delta", 175 | "type": "int256" 176 | }, 177 | { 178 | "internalType": "int256", 179 | "name": "amount1Delta", 180 | "type": "int256" 181 | }, 182 | { 183 | "internalType": "bytes", 184 | "name": "path", 185 | "type": "bytes" 186 | } 187 | ], 188 | "name": "uniswapV3SwapCallback", 189 | "outputs": [], 190 | "stateMutability": "view", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/cvxprisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cvxprisma", 3 | "license": "MIT", 4 | "version": "1.0.0", 5 | "files": [ 6 | "generated" 7 | ], 8 | "scripts": { 9 | "codegen": "graph codegen", 10 | "build": "graph build", 11 | "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ convex-community/cvxprisma", 12 | "deploy-hosted": "graph deploy --product hosted-service convex-community/cvxprisma", 13 | "deploy-studio": "graph deploy --studio cvxprisma", 14 | "create-local": "graph create --node http://localhost:8020/ convex/cvxprisma", 15 | "remove-local": "graph remove --node http://localhost:8020/ convex/cvxprisma", 16 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex/cvxprisma" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/cvxprisma/src/services/entities.ts: -------------------------------------------------------------------------------- 1 | import { Address, BigDecimal } from '@graphprotocol/graph-ts' 2 | import { StakingBalance, StakingContract, User } from '../../generated/schema' 3 | import { CVX_PRISMA_STAKING_ADDRESS } from 'const' 4 | 5 | export function getStakingContract(contractAddress: Address): StakingContract { 6 | let contract = StakingContract.load(contractAddress.toHexString()) 7 | if (!contract) { 8 | contract = new StakingContract(contractAddress.toHexString()) 9 | contract.tokenBalance = BigDecimal.zero() 10 | contract.tvl = BigDecimal.zero() 11 | contract.peg = BigDecimal.zero() 12 | contract.rewardTokens = [] 13 | contract.depositCount = 0 14 | contract.withdrawCount = 0 15 | contract.payoutCount = 0 16 | contract.snapshotCount = 0 17 | contract.save() 18 | } 19 | return contract 20 | } 21 | 22 | export function getUser(address: Address): User { 23 | let user = User.load(address.toHexString()) 24 | if (!user) { 25 | user = new User(address.toHexString()) 26 | user.rewardRedirect = address.toHexString() 27 | user.save() 28 | } 29 | return user 30 | } 31 | 32 | export function getStakingBalance(user: User, contract: StakingContract): StakingBalance { 33 | let balance = StakingBalance.load(user.id + contract.id) 34 | if (!balance) { 35 | balance = new StakingBalance(user.id + contract.id) 36 | balance.user = user.id 37 | balance.stakingContract = contract.id 38 | balance.stakeSize = BigDecimal.zero() 39 | balance.save() 40 | } 41 | return balance 42 | } 43 | -------------------------------------------------------------------------------- /subgraphs/cvxprisma/src/services/tokens.ts: -------------------------------------------------------------------------------- 1 | import { ETH_TOKEN_ADDRESS } from '@protofire/subgraph-toolkit' 2 | import { BigInt, Address } from '@graphprotocol/graph-ts/index' 3 | import { Token, TokenPrice } from '../../generated/schema' 4 | import { ERC20 } from '../../generated/cvxPrismaStaking/ERC20' 5 | import { BigDecimal } from '@graphprotocol/graph-ts' 6 | import { 7 | BIG_INT_ONE, 8 | CVX_ADDRESS, 9 | CVX_ETH_POOL, 10 | CVX_PRISMA_TOKEN_ADDRESS, 11 | CVXPRISMA_PRISMA_CURVE_POOL, MKUSD_TOKEN_ADDRESS, 12 | PRISMA_ETH_POOL, 13 | PRISMA_TOKEN_ADDRESS, 14 | TRICRYPTONG_POOL, 15 | YPRISMA_PRISMA_CURVE_POOL, 16 | YPRISMA_TOKEN_ADDRESS 17 | } from 'const' 18 | import { toDecimal } from 'utils/maths' 19 | import { getIntervalFromTimestamp, HOUR } from 'utils/time' 20 | import { TriCryptoNg } from '../../generated/cvxPrismaStaking/TriCryptoNg' 21 | import { CurvePoolV2 } from '../../generated/cvxPrismaStaking/CurvePoolV2' 22 | import { getUsdRate } from 'utils/pricing' 23 | 24 | export function getOrCreateToken(address: Address): Token { 25 | let token = Token.load(address.toHexString()) 26 | 27 | if (token == null) { 28 | token = new Token(address.toHexString()) 29 | token.address = address 30 | 31 | if (token.id == ETH_TOKEN_ADDRESS) { 32 | token.symbol = 'ETH' 33 | token.decimals = 18 34 | } else { 35 | const erc20 = ERC20.bind(address) 36 | const symbol = erc20.try_symbol() 37 | const decimals = erc20.try_decimals() 38 | token.symbol = symbol.reverted ? '' : symbol.value.toString() 39 | token.decimals = decimals.reverted ? 18 : decimals.value 40 | } 41 | 42 | token.save() 43 | } 44 | return token 45 | } 46 | 47 | export function getEthPriceInUsd(): BigDecimal { 48 | const triCryptoContract = TriCryptoNg.bind(TRICRYPTONG_POOL) 49 | const priceResult = triCryptoContract.try_price_oracle(BIG_INT_ONE) 50 | return priceResult.reverted ? BigDecimal.zero() : toDecimal(priceResult.value, 18) 51 | } 52 | 53 | export function getPrismaPriceInEth(): BigDecimal { 54 | const prismaEthPool = CurvePoolV2.bind(PRISMA_ETH_POOL) 55 | const priceResult = prismaEthPool.try_price_oracle() 56 | return priceResult.reverted ? BigDecimal.zero() : toDecimal(priceResult.value, 18) 57 | } 58 | 59 | export function getCvxPriceInEth(): BigDecimal { 60 | const cvxEthPool = CurvePoolV2.bind(CVX_ETH_POOL) 61 | const priceResult = cvxEthPool.try_price_oracle() 62 | return priceResult.reverted ? BigDecimal.zero() : toDecimal(priceResult.value, 18) 63 | } 64 | 65 | export function getCvxPrismaPeg(): BigDecimal { 66 | const pool = CurvePoolV2.bind(CVXPRISMA_PRISMA_CURVE_POOL) 67 | const priceResult = pool.try_price_oracle() 68 | return priceResult.reverted ? BigDecimal.fromString('1') : toDecimal(priceResult.value, 18) 69 | } 70 | 71 | export function getYPrismaPeg(): BigDecimal { 72 | const pool = CurvePoolV2.bind(YPRISMA_PRISMA_CURVE_POOL) 73 | const priceResult = pool.try_price_oracle() 74 | return priceResult.reverted ? BigDecimal.fromString('1') : toDecimal(priceResult.value, 18) 75 | } 76 | 77 | export function getCvxPrismaPriceInEth(): BigDecimal { 78 | return getPrismaPriceInEth() 79 | } 80 | 81 | export function getTokenPrice(token: Address, timestamp: BigInt): TokenPrice { 82 | const hourlyTimestamp = getIntervalFromTimestamp(timestamp, HOUR) 83 | let tokenPrice = TokenPrice.load(token.toHexString() + timestamp.toString()) 84 | if (tokenPrice) { 85 | return tokenPrice 86 | } 87 | tokenPrice = new TokenPrice(token.toHexString() + timestamp.toString()) 88 | tokenPrice.token = getOrCreateToken(token).id 89 | tokenPrice.timestamp = hourlyTimestamp 90 | if (token == Address.fromString(ETH_TOKEN_ADDRESS)) { 91 | tokenPrice.price = getEthPriceInUsd() 92 | } else if (token == PRISMA_TOKEN_ADDRESS) { 93 | const ethTokenPrice = getTokenPrice(Address.fromString(ETH_TOKEN_ADDRESS), timestamp) 94 | const prismaEthPrice = getPrismaPriceInEth() 95 | tokenPrice.price = prismaEthPrice.times(ethTokenPrice.price) 96 | } else if (token == CVX_PRISMA_TOKEN_ADDRESS) { 97 | const ethTokenPrice = getTokenPrice(Address.fromString(ETH_TOKEN_ADDRESS), timestamp) 98 | const cvxPrismaEthPrice = getPrismaPriceInEth() 99 | const peg = getCvxPrismaPeg() 100 | tokenPrice.price = cvxPrismaEthPrice.times(ethTokenPrice.price).times(peg) 101 | } else if (token == YPRISMA_TOKEN_ADDRESS) { 102 | const ethTokenPrice = getTokenPrice(Address.fromString(ETH_TOKEN_ADDRESS), timestamp) 103 | const cvxPrismaEthPrice = getPrismaPriceInEth() 104 | const peg = getYPrismaPeg() 105 | tokenPrice.price = cvxPrismaEthPrice.times(ethTokenPrice.price).times(peg) 106 | } else if (token == CVX_ADDRESS) { 107 | const ethTokenPrice = getTokenPrice(Address.fromString(ETH_TOKEN_ADDRESS), timestamp) 108 | const cvxEthPrice = getCvxPriceInEth() 109 | tokenPrice.price = cvxEthPrice.times(ethTokenPrice.price) 110 | } 111 | else if (token == MKUSD_TOKEN_ADDRESS) { 112 | tokenPrice.price = BigDecimal.fromString('1') 113 | } 114 | else { 115 | tokenPrice.price = getUsdRate(token) 116 | } 117 | tokenPrice.save() 118 | return tokenPrice 119 | } 120 | -------------------------------------------------------------------------------- /subgraphs/cvxprisma/src/y-prisma-staking.ts: -------------------------------------------------------------------------------- 1 | import { 2 | RewardAdded1, 3 | RewardPaid, 4 | RewardRedirected, 5 | Staked, 6 | Withdrawn, 7 | } from '../generated/cvxPrismaStaking/cvxPrismaStaking' 8 | import { 9 | RewardPaid as RewardPaidYPrisma, 10 | RewardAdded as RewardAddedYPrisma, 11 | Withdrawn as WithdrawnYPrisma, 12 | Staked as StakedYPrisma, 13 | StakedFor, 14 | } from '../generated/yPrismaStaking/yPrismaStaking' 15 | import { 16 | Withdrawal, 17 | Stake, 18 | RewardRedirected as RewardRedirectedEntity, 19 | RewardPaid as RewardPaidEntity, 20 | User, 21 | } from '../generated/schema' 22 | import { getStakingBalance, getStakingContract, getUser } from './services/entities' 23 | import { 24 | BIG_DECIMAL_1E18, 25 | CVX_PRISMA_TOKEN_ADDRESS, MKUSD_TOKEN_ADDRESS, 26 | PRISMA_TOKEN_ADDRESS, 27 | WSTETH_TOKEN_ADDRESS, YPRISMA_STAKING_ADDRESS, 28 | YPRISMA_TOKEN_ADDRESS 29 | } from 'const' 30 | import { toDecimal } from 'utils/maths' 31 | import { getOrCreateToken, getTokenPrice } from './services/tokens' 32 | import { takeSnapshot } from './services/snapshots' 33 | import { getIntervalFromTimestamp, HOUR } from 'utils/time' 34 | import { ethereum } from '@graphprotocol/graph-ts/index' 35 | import { Address, BigDecimal, BigInt } from '@graphprotocol/graph-ts' 36 | import { 37 | handleRewardAddedGeneric, 38 | handleRewardGeneric, 39 | handleStakedGeneric, 40 | handleWithdrawnGeneric 41 | } from './cvx-prisma-staking' 42 | 43 | 44 | export function handleRewardPaidYPrisma(event: RewardPaidYPrisma): void { 45 | handleRewardGeneric(event, event.params.reward, getUser(event.params.user), YPRISMA_TOKEN_ADDRESS) 46 | } 47 | 48 | export function handleStakedYPrisma(event: StakedYPrisma): void { 49 | handleStakedGeneric(event, event.params.amount, event.params.user, event.params.user, YPRISMA_TOKEN_ADDRESS) 50 | } 51 | 52 | export function handleStakedFor(event: StakedFor): void { 53 | handleStakedGeneric(event, event.params.amount, event.transaction.from, event.params.user, YPRISMA_TOKEN_ADDRESS) 54 | } 55 | 56 | export function handleWithdrawnYPrisma(event: WithdrawnYPrisma): void { 57 | handleWithdrawnGeneric(event, event.params.amount, event.params.user, YPRISMA_TOKEN_ADDRESS) 58 | } 59 | 60 | export function handleRewardAddedYPrisma(event: RewardAddedYPrisma): void { 61 | if (event.address == YPRISMA_STAKING_ADDRESS) 62 | { 63 | handleRewardAddedGeneric(event, WSTETH_TOKEN_ADDRESS) 64 | } 65 | else { 66 | handleRewardAddedGeneric(event, MKUSD_TOKEN_ADDRESS) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /subgraphs/locker/abis/ERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] -------------------------------------------------------------------------------- /subgraphs/locker/abis/UniswapV2Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_feeToSetter", 7 | "type": "address" 8 | } 9 | ], 10 | "payable": false, 11 | "stateMutability": "nonpayable", 12 | "type": "constructor" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "token0", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "token1", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "address", 32 | "name": "pair", 33 | "type": "address" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "name": "PairCreated", 43 | "type": "event" 44 | }, 45 | { 46 | "constant": true, 47 | "inputs": [ 48 | { 49 | "internalType": "uint256", 50 | "name": "", 51 | "type": "uint256" 52 | } 53 | ], 54 | "name": "allPairs", 55 | "outputs": [ 56 | { 57 | "internalType": "address", 58 | "name": "", 59 | "type": "address" 60 | } 61 | ], 62 | "payable": false, 63 | "stateMutability": "view", 64 | "type": "function" 65 | }, 66 | { 67 | "constant": true, 68 | "inputs": [], 69 | "name": "allPairsLength", 70 | "outputs": [ 71 | { 72 | "internalType": "uint256", 73 | "name": "", 74 | "type": "uint256" 75 | } 76 | ], 77 | "payable": false, 78 | "stateMutability": "view", 79 | "type": "function" 80 | }, 81 | { 82 | "constant": false, 83 | "inputs": [ 84 | { 85 | "internalType": "address", 86 | "name": "tokenA", 87 | "type": "address" 88 | }, 89 | { 90 | "internalType": "address", 91 | "name": "tokenB", 92 | "type": "address" 93 | } 94 | ], 95 | "name": "createPair", 96 | "outputs": [ 97 | { 98 | "internalType": "address", 99 | "name": "pair", 100 | "type": "address" 101 | } 102 | ], 103 | "payable": false, 104 | "stateMutability": "nonpayable", 105 | "type": "function" 106 | }, 107 | { 108 | "constant": true, 109 | "inputs": [], 110 | "name": "feeTo", 111 | "outputs": [ 112 | { 113 | "internalType": "address", 114 | "name": "", 115 | "type": "address" 116 | } 117 | ], 118 | "payable": false, 119 | "stateMutability": "view", 120 | "type": "function" 121 | }, 122 | { 123 | "constant": true, 124 | "inputs": [], 125 | "name": "feeToSetter", 126 | "outputs": [ 127 | { 128 | "internalType": "address", 129 | "name": "", 130 | "type": "address" 131 | } 132 | ], 133 | "payable": false, 134 | "stateMutability": "view", 135 | "type": "function" 136 | }, 137 | { 138 | "constant": true, 139 | "inputs": [ 140 | { 141 | "internalType": "address", 142 | "name": "", 143 | "type": "address" 144 | }, 145 | { 146 | "internalType": "address", 147 | "name": "", 148 | "type": "address" 149 | } 150 | ], 151 | "name": "getPair", 152 | "outputs": [ 153 | { 154 | "internalType": "address", 155 | "name": "", 156 | "type": "address" 157 | } 158 | ], 159 | "payable": false, 160 | "stateMutability": "view", 161 | "type": "function" 162 | }, 163 | { 164 | "constant": false, 165 | "inputs": [ 166 | { 167 | "internalType": "address", 168 | "name": "_feeTo", 169 | "type": "address" 170 | } 171 | ], 172 | "name": "setFeeTo", 173 | "outputs": [], 174 | "payable": false, 175 | "stateMutability": "nonpayable", 176 | "type": "function" 177 | }, 178 | { 179 | "constant": false, 180 | "inputs": [ 181 | { 182 | "internalType": "address", 183 | "name": "_feeToSetter", 184 | "type": "address" 185 | } 186 | ], 187 | "name": "setFeeToSetter", 188 | "outputs": [], 189 | "payable": false, 190 | "stateMutability": "nonpayable", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/locker/abis/UniswapV3Quoter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_factory", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_WETH9", 12 | "type": "address" 13 | } 14 | ], 15 | "stateMutability": "nonpayable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "inputs": [], 20 | "name": "WETH9", 21 | "outputs": [ 22 | { 23 | "internalType": "address", 24 | "name": "", 25 | "type": "address" 26 | } 27 | ], 28 | "stateMutability": "view", 29 | "type": "function" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "factory", 34 | "outputs": [ 35 | { 36 | "internalType": "address", 37 | "name": "", 38 | "type": "address" 39 | } 40 | ], 41 | "stateMutability": "view", 42 | "type": "function" 43 | }, 44 | { 45 | "inputs": [ 46 | { 47 | "internalType": "bytes", 48 | "name": "path", 49 | "type": "bytes" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "amountIn", 54 | "type": "uint256" 55 | } 56 | ], 57 | "name": "quoteExactInput", 58 | "outputs": [ 59 | { 60 | "internalType": "uint256", 61 | "name": "amountOut", 62 | "type": "uint256" 63 | } 64 | ], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "tokenIn", 73 | "type": "address" 74 | }, 75 | { 76 | "internalType": "address", 77 | "name": "tokenOut", 78 | "type": "address" 79 | }, 80 | { 81 | "internalType": "uint24", 82 | "name": "fee", 83 | "type": "uint24" 84 | }, 85 | { 86 | "internalType": "uint256", 87 | "name": "amountIn", 88 | "type": "uint256" 89 | }, 90 | { 91 | "internalType": "uint160", 92 | "name": "sqrtPriceLimitX96", 93 | "type": "uint160" 94 | } 95 | ], 96 | "name": "quoteExactInputSingle", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "amountOut", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "bytes", 111 | "name": "path", 112 | "type": "bytes" 113 | }, 114 | { 115 | "internalType": "uint256", 116 | "name": "amountOut", 117 | "type": "uint256" 118 | } 119 | ], 120 | "name": "quoteExactOutput", 121 | "outputs": [ 122 | { 123 | "internalType": "uint256", 124 | "name": "amountIn", 125 | "type": "uint256" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [ 133 | { 134 | "internalType": "address", 135 | "name": "tokenIn", 136 | "type": "address" 137 | }, 138 | { 139 | "internalType": "address", 140 | "name": "tokenOut", 141 | "type": "address" 142 | }, 143 | { 144 | "internalType": "uint24", 145 | "name": "fee", 146 | "type": "uint24" 147 | }, 148 | { 149 | "internalType": "uint256", 150 | "name": "amountOut", 151 | "type": "uint256" 152 | }, 153 | { 154 | "internalType": "uint160", 155 | "name": "sqrtPriceLimitX96", 156 | "type": "uint160" 157 | } 158 | ], 159 | "name": "quoteExactOutputSingle", 160 | "outputs": [ 161 | { 162 | "internalType": "uint256", 163 | "name": "amountIn", 164 | "type": "uint256" 165 | } 166 | ], 167 | "stateMutability": "nonpayable", 168 | "type": "function" 169 | }, 170 | { 171 | "inputs": [ 172 | { 173 | "internalType": "int256", 174 | "name": "amount0Delta", 175 | "type": "int256" 176 | }, 177 | { 178 | "internalType": "int256", 179 | "name": "amount1Delta", 180 | "type": "int256" 181 | }, 182 | { 183 | "internalType": "bytes", 184 | "name": "path", 185 | "type": "bytes" 186 | } 187 | ], 188 | "name": "uniswapV3SwapCallback", 189 | "outputs": [], 190 | "stateMutability": "view", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/locker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "locker", 3 | "license": "MIT", 4 | "version": "1.0.0", 5 | "files": [ 6 | "generated" 7 | ], 8 | "scripts": { 9 | "codegen": "graph codegen", 10 | "build": "graph build", 11 | "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ convex-community/locker", 12 | "deploy-hosted": "graph deploy --product hosted-service convex-community/locker", 13 | "deploy-studio": "graph deploy --studio convex-locker", 14 | "create-local": "graph create --node http://localhost:8020/ convex/locker", 15 | "remove-local": "graph remove --node http://localhost:8020/ convex/locker", 16 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex/locker" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/locker/schema.graphql: -------------------------------------------------------------------------------- 1 | type Token @entity { 2 | id: ID! 3 | address: Bytes! 4 | decimals: BigInt! 5 | name: String 6 | symbol: String 7 | } 8 | 9 | type User @entity { 10 | id: ID! 11 | address: Bytes! 12 | receivedRewards: [ReceivedReward!] @derivedFrom(field: "user") 13 | locks: [Lock!] @derivedFrom(field: "user") 14 | withdrawals: [Withdrawal!] @derivedFrom(field: "user") 15 | totalLocked: BigInt! 16 | totalLockedUSD: BigDecimal! 17 | } 18 | 19 | type Lock @entity { 20 | id: ID! 21 | user: User! 22 | lockAmount: BigInt! 23 | boostedAmount: BigInt! 24 | amountUSD: BigDecimal! 25 | time: BigInt! 26 | } 27 | 28 | type Withdrawal @entity { 29 | id: ID! 30 | user: User! 31 | amount: BigInt! 32 | amountUSD: BigDecimal! 33 | time: BigInt! 34 | } 35 | 36 | type ReceivedReward @entity { 37 | id: ID! 38 | user: User! 39 | token: Token! 40 | kickReward: Boolean! 41 | amount: BigInt! 42 | amountUSD: BigDecimal! 43 | time: BigInt! 44 | } 45 | 46 | type AddedReward @entity { 47 | id: ID! 48 | token: Token! 49 | amount: BigInt! 50 | amountUSD: BigDecimal! 51 | time: BigInt! 52 | } 53 | 54 | type DailyReward @entity { 55 | id: ID! 56 | token: Token! 57 | count: BigInt! 58 | amount: BigInt! 59 | amountUSD: BigDecimal! 60 | time: BigInt! 61 | } 62 | 63 | type WeeklyReward @entity { 64 | id: ID! 65 | token: Token! 66 | count: BigInt! 67 | amount: BigInt! 68 | amountUSD: BigDecimal! 69 | time: BigInt! 70 | } 71 | 72 | type DailyLock @entity { 73 | id: ID! 74 | count: BigInt! 75 | amount: BigInt! 76 | amountUSD: BigDecimal! 77 | time: BigInt! 78 | } 79 | 80 | type WeeklyLock @entity { 81 | id: ID! 82 | count: BigInt! 83 | amount: BigInt! 84 | amountUSD: BigDecimal! 85 | time: BigInt! 86 | } 87 | 88 | type DailyWithdrawal @entity { 89 | id: ID! 90 | count: BigInt! 91 | amount: BigInt! 92 | amountUSD: BigDecimal! 93 | time: BigInt! 94 | } 95 | 96 | type WeeklyWithdrawal @entity { 97 | id: ID! 98 | count: BigInt! 99 | amount: BigInt! 100 | amountUSD: BigDecimal! 101 | time: BigInt! 102 | } 103 | -------------------------------------------------------------------------------- /subgraphs/locker/src/extraMapping.ts: -------------------------------------------------------------------------------- 1 | import { RewardAdded, RewardPaid } from '../generated/vlCvxExtraRewardDistribution/vlCvxExtraRewardDistribution' 2 | import { AddedReward, ReceivedReward } from '../generated/schema' 3 | import { getUser } from './services/users' 4 | import { 5 | getEventId, 6 | updateAggregatedRewards, 7 | } from './services/events' 8 | import { getOrCreateToken } from './services/tokens' 9 | import { CVX_ADDRESS } from 'const' 10 | import { getUsdRate } from 'utils/pricing' 11 | import { Address } from '@graphprotocol/graph-ts' 12 | import { exponentToBigDecimal } from 'utils/maths' 13 | 14 | const cvx = getOrCreateToken(CVX_ADDRESS) 15 | 16 | export function handleRewardPaid(event: RewardPaid): void { 17 | const user = getUser(event.params._user) 18 | const reward = new ReceivedReward(getEventId(event)) 19 | reward.user = user.id 20 | reward.amount = event.params._reward 21 | const token = getOrCreateToken(event.params._rewardsToken) 22 | reward.amountUSD = getUsdRate(Address.fromString(token.id)).times( 23 | reward.amount.toBigDecimal().div(exponentToBigDecimal(token.decimals)) 24 | ) 25 | reward.token = token.id 26 | reward.time = event.block.timestamp 27 | reward.kickReward = false 28 | reward.save() 29 | 30 | updateAggregatedRewards(reward.time, token, reward.amount, reward.amountUSD) 31 | } 32 | 33 | export function handleRewardAdded(event: RewardAdded): void { 34 | const reward = new AddedReward(getEventId(event)) 35 | reward.amount = event.params._reward 36 | const token = getOrCreateToken(event.params._token) 37 | reward.amountUSD = getUsdRate(Address.fromString(token.id)).times( 38 | reward.amount.toBigDecimal().div(exponentToBigDecimal(token.decimals)) 39 | ) 40 | reward.token = token.id 41 | reward.time = event.block.timestamp 42 | reward.save() 43 | } 44 | -------------------------------------------------------------------------------- /subgraphs/locker/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { KickReward, RewardAdded, RewardPaid, Staked, Withdrawn } from '../generated/CvxLocker/CvxLocker' 2 | import { AddedReward, Lock, ReceivedReward, Withdrawal } from '../generated/schema' 3 | import { getUser } from './services/users' 4 | import { 5 | getEventId, 6 | updateAggregatedLocks, 7 | updateAggregatedRewards, 8 | updateAggregatedWithdrawals, 9 | } from './services/events' 10 | import { getOrCreateToken } from './services/tokens' 11 | import { CVX_ADDRESS } from 'const' 12 | import { getUsdRate } from 'utils/pricing' 13 | import { Address } from '@graphprotocol/graph-ts' 14 | import { exponentToBigDecimal } from 'utils/maths' 15 | 16 | const cvx = getOrCreateToken(CVX_ADDRESS) 17 | 18 | export function handleKickReward(event: KickReward): void { 19 | const user = getUser(event.params._user) 20 | const reward = new ReceivedReward(getEventId(event)) 21 | reward.user = user.id 22 | reward.amount = event.params._reward 23 | reward.amountUSD = getUsdRate(CVX_ADDRESS).times(reward.amount.toBigDecimal().div(exponentToBigDecimal(cvx.decimals))) 24 | reward.token = cvx.id 25 | reward.time = event.block.timestamp 26 | reward.kickReward = true 27 | reward.save() 28 | 29 | updateAggregatedRewards(reward.time, cvx, reward.amount, reward.amountUSD) 30 | } 31 | 32 | export function handleRewardPaid(event: RewardPaid): void { 33 | const user = getUser(event.params._user) 34 | const reward = new ReceivedReward(getEventId(event)) 35 | reward.user = user.id 36 | reward.amount = event.params._reward 37 | const token = getOrCreateToken(event.params._rewardsToken) 38 | reward.amountUSD = getUsdRate(Address.fromString(token.id)).times( 39 | reward.amount.toBigDecimal().div(exponentToBigDecimal(token.decimals)) 40 | ) 41 | reward.token = token.id 42 | reward.time = event.block.timestamp 43 | reward.kickReward = false 44 | reward.save() 45 | 46 | updateAggregatedRewards(reward.time, token, reward.amount, reward.amountUSD) 47 | } 48 | 49 | export function handleStaked(event: Staked): void { 50 | const user = getUser(event.params._user) 51 | const lock = new Lock(getEventId(event)) 52 | lock.user = user.id 53 | lock.lockAmount = event.params._lockedAmount 54 | lock.amountUSD = getUsdRate(CVX_ADDRESS).times(lock.lockAmount.toBigDecimal().div(exponentToBigDecimal(cvx.decimals))) 55 | lock.boostedAmount = event.params._boostedAmount 56 | lock.time = event.block.timestamp 57 | user.totalLocked = user.totalLocked.plus(lock.lockAmount) 58 | user.totalLockedUSD = user.totalLockedUSD.plus(lock.amountUSD) 59 | user.save() 60 | lock.save() 61 | updateAggregatedLocks(lock.time, lock.lockAmount, lock.amountUSD) 62 | } 63 | 64 | export function handleRewardAdded(event: RewardAdded): void { 65 | const reward = new AddedReward(getEventId(event)) 66 | reward.amount = event.params._reward 67 | const token = getOrCreateToken(event.params._token) 68 | reward.amountUSD = getUsdRate(Address.fromString(token.id)).times( 69 | reward.amount.toBigDecimal().div(exponentToBigDecimal(token.decimals)) 70 | ) 71 | reward.token = token.id 72 | reward.time = event.block.timestamp 73 | reward.save() 74 | } 75 | 76 | export function handleWithdrawn(event: Withdrawn): void { 77 | const user = getUser(event.params._user) 78 | const withdrawal = new Withdrawal(getEventId(event)) 79 | withdrawal.user = user.id 80 | withdrawal.amount = event.params._amount 81 | withdrawal.amountUSD = getUsdRate(CVX_ADDRESS).times( 82 | withdrawal.amount.toBigDecimal().div(exponentToBigDecimal(cvx.decimals)) 83 | ) 84 | withdrawal.time = event.block.timestamp 85 | user.totalLocked = user.totalLocked.minus(withdrawal.amount) 86 | user.save() 87 | withdrawal.save() 88 | updateAggregatedWithdrawals(withdrawal.time, withdrawal.amount, withdrawal.amountUSD) 89 | } 90 | -------------------------------------------------------------------------------- /subgraphs/locker/src/services/events.ts: -------------------------------------------------------------------------------- 1 | import { ethereum } from '@graphprotocol/graph-ts/index' 2 | import { DAY, getIntervalFromTimestamp, WEEK } from 'utils/time' 3 | import { 4 | DailyLock, 5 | DailyReward, 6 | DailyWithdrawal, 7 | Token, 8 | WeeklyLock, 9 | WeeklyReward, 10 | WeeklyWithdrawal, 11 | } from '../../generated/schema' 12 | import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' 13 | import { BIG_INT_ONE, BIG_INT_ZERO } from 'const' 14 | 15 | export function getEventId(event: ethereum.Event): string { 16 | return event.transaction.hash.toHexString() + '-' + event.logIndex.toString() 17 | } 18 | 19 | export function getDailyLocks(timestamp: BigInt): DailyLock { 20 | const day = getIntervalFromTimestamp(timestamp, DAY) 21 | let dailyLocks = DailyLock.load(day.toString()) 22 | if (!dailyLocks) { 23 | dailyLocks = new DailyLock(day.toString()) 24 | dailyLocks.time = day 25 | dailyLocks.count = BIG_INT_ZERO 26 | } 27 | return dailyLocks 28 | } 29 | 30 | export function getWeeklyLocks(timestamp: BigInt): WeeklyLock { 31 | const week = getIntervalFromTimestamp(timestamp, WEEK) 32 | let weeklyLocks = WeeklyLock.load(week.toString()) 33 | if (!weeklyLocks) { 34 | weeklyLocks = new WeeklyLock(week.toString()) 35 | weeklyLocks.time = week 36 | weeklyLocks.count = BIG_INT_ZERO 37 | } 38 | return weeklyLocks 39 | } 40 | 41 | export function getDailyWithdrawals(timestamp: BigInt): DailyWithdrawal { 42 | const day = getIntervalFromTimestamp(timestamp, DAY) 43 | let dailyWithdrawals = DailyWithdrawal.load(day.toString()) 44 | if (!dailyWithdrawals) { 45 | dailyWithdrawals = new DailyWithdrawal(day.toString()) 46 | dailyWithdrawals.time = day 47 | dailyWithdrawals.count = BIG_INT_ZERO 48 | } 49 | return dailyWithdrawals 50 | } 51 | 52 | export function getWeeklyWithdrawals(timestamp: BigInt): WeeklyWithdrawal { 53 | const week = getIntervalFromTimestamp(timestamp, WEEK) 54 | let weeklyWithdrawals = WeeklyWithdrawal.load(week.toString()) 55 | if (!weeklyWithdrawals) { 56 | weeklyWithdrawals = new WeeklyWithdrawal(week.toString()) 57 | weeklyWithdrawals.time = week 58 | weeklyWithdrawals.count = BIG_INT_ZERO 59 | } 60 | return weeklyWithdrawals 61 | } 62 | 63 | export function getDailyRewards(timestamp: BigInt, token: Token): DailyReward { 64 | const day = getIntervalFromTimestamp(timestamp, DAY) 65 | let dailyRewards = DailyReward.load(day.toString()) 66 | if (!dailyRewards) { 67 | dailyRewards = new DailyReward(day.toString()) 68 | dailyRewards.token = token.id 69 | dailyRewards.time = day 70 | } 71 | return dailyRewards 72 | } 73 | 74 | export function getWeeklyRewards(timestamp: BigInt, token: Token): WeeklyReward { 75 | const week = getIntervalFromTimestamp(timestamp, WEEK) 76 | let weeklyRewards = WeeklyReward.load(week.toString()) 77 | if (!weeklyRewards) { 78 | weeklyRewards = new WeeklyReward(week.toString()) 79 | weeklyRewards.token = token.id 80 | weeklyRewards.time = week 81 | } 82 | return weeklyRewards 83 | } 84 | 85 | export function updateAggregatedRewards(timestamp: BigInt, token: Token, amount: BigInt, amountUSD: BigDecimal): void { 86 | const dailyRewards = getDailyRewards(timestamp, token) 87 | dailyRewards.amount = dailyRewards.amount.plus(amount) 88 | dailyRewards.amountUSD = dailyRewards.amountUSD.plus(amountUSD) 89 | dailyRewards.count = dailyRewards.count.plus(BIG_INT_ONE) 90 | dailyRewards.save() 91 | const weeklyRewards = getWeeklyRewards(timestamp, token) 92 | weeklyRewards.count = weeklyRewards.count.plus(BIG_INT_ONE) 93 | weeklyRewards.amount = weeklyRewards.amount.plus(amount) 94 | weeklyRewards.amountUSD = weeklyRewards.amountUSD.plus(amountUSD) 95 | weeklyRewards.save() 96 | } 97 | 98 | export function updateAggregatedWithdrawals(timestamp: BigInt, amount: BigInt, amountUSD: BigDecimal): void { 99 | const dailyWithdrawals = getDailyWithdrawals(timestamp) 100 | dailyWithdrawals.amount = dailyWithdrawals.amount.plus(amount) 101 | dailyWithdrawals.amountUSD = dailyWithdrawals.amountUSD.plus(amountUSD) 102 | dailyWithdrawals.count = dailyWithdrawals.count.plus(BIG_INT_ONE) 103 | dailyWithdrawals.save() 104 | const weeklyWithdrawals = getWeeklyWithdrawals(timestamp) 105 | weeklyWithdrawals.amount = weeklyWithdrawals.amount.plus(amount) 106 | weeklyWithdrawals.count = weeklyWithdrawals.count.plus(BIG_INT_ONE) 107 | weeklyWithdrawals.amountUSD = weeklyWithdrawals.amountUSD.plus(amountUSD) 108 | weeklyWithdrawals.save() 109 | } 110 | 111 | export function updateAggregatedLocks(timestamp: BigInt, amount: BigInt, amountUSD: BigDecimal): void { 112 | const dailyLocks = getDailyLocks(timestamp) 113 | dailyLocks.amount = dailyLocks.amount.plus(amount) 114 | dailyLocks.amountUSD = dailyLocks.amountUSD.plus(amountUSD) 115 | dailyLocks.count = dailyLocks.count.plus(BIG_INT_ONE) 116 | dailyLocks.save() 117 | const weeklyLocks = getWeeklyLocks(timestamp) 118 | weeklyLocks.amount = weeklyLocks.amount.plus(amount) 119 | weeklyLocks.count = weeklyLocks.count.plus(BIG_INT_ONE) 120 | weeklyLocks.amountUSD = weeklyLocks.amountUSD.plus(amountUSD) 121 | weeklyLocks.save() 122 | } 123 | -------------------------------------------------------------------------------- /subgraphs/locker/src/services/tokens.ts: -------------------------------------------------------------------------------- 1 | import { ETH_TOKEN_ADDRESS } from '@protofire/subgraph-toolkit' 2 | import { BigInt, Address } from '@graphprotocol/graph-ts/index' 3 | import { Token } from '../../generated/schema' 4 | import { ERC20 } from 'convex/generated/Booster/ERC20' 5 | 6 | class TokenInfo { 7 | constructor(readonly name: string | null, readonly symbol: string | null, readonly decimals: BigInt) {} 8 | } 9 | 10 | export function getOrCreateToken(address: Address): Token { 11 | let token = Token.load(address.toHexString()) 12 | 13 | if (token == null) { 14 | token = new Token(address.toHexString()) 15 | token.address = address 16 | 17 | if (token.id == ETH_TOKEN_ADDRESS) { 18 | token.name = 'Ether' 19 | token.symbol = 'ETH' 20 | token.decimals = new BigInt(18) 21 | } else { 22 | const info = getTokenInfo(address) 23 | 24 | token.name = info.name 25 | token.symbol = info.symbol 26 | token.decimals = info.decimals 27 | } 28 | 29 | token.save() 30 | } 31 | return token 32 | } 33 | 34 | function getTokenInfo(address: Address): TokenInfo { 35 | const erc20 = ERC20.bind(address) 36 | 37 | const name = erc20.try_name() 38 | const symbol = erc20.try_symbol() 39 | const decimals = erc20.try_decimals() 40 | 41 | return new TokenInfo( 42 | name.reverted ? '' : name.value.toString(), 43 | symbol.reverted ? '' : symbol.value.toString(), 44 | decimals.reverted ? new BigInt(18) : BigInt.fromI32(decimals.value) 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /subgraphs/locker/src/services/users.ts: -------------------------------------------------------------------------------- 1 | import {Address} from "@graphprotocol/graph-ts/index"; 2 | import {User} from "../../generated/schema"; 3 | 4 | export function getUser(address: Address): User { 5 | 6 | let user = User.load(address.toHexString()) 7 | if (!user) { 8 | user = new User(address.toHexString()); 9 | user.address = address; 10 | user.save(); 11 | } 12 | return user 13 | 14 | } -------------------------------------------------------------------------------- /subgraphs/locker/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.2 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | - kind: ethereum/contract 6 | name: CvxLocker 7 | network: mainnet 8 | source: 9 | address: "0xD18140b4B819b895A3dba5442F959fA44994AF50" 10 | abi: CvxLocker 11 | startBlock: 13153663 12 | mapping: 13 | kind: ethereum/events 14 | apiVersion: 0.0.5 15 | language: wasm/assemblyscript 16 | entities: 17 | - KickReward 18 | - RewardPaid 19 | - Staked 20 | - Withdrawn 21 | - DailyLock 22 | - WeeklyLock 23 | - DailyWithdrawal 24 | - WeeklyWithdrawal 25 | - DailyReward 26 | - WeeklyReward 27 | abis: 28 | - name: CvxLocker 29 | file: ./abis/CvxLocker.json 30 | - name: ERC20 31 | file: ../../abis/ERC20.json 32 | - name: Factory 33 | file: ../../abis/UniswapV2Factory.json 34 | - name: Pair 35 | file: ../../abis/UniswapV2Pair.json 36 | - name: FactoryV3 37 | file: ../../abis/UniswapV3Factory.json 38 | - name: Quoter 39 | file: ../../abis/UniswapV3Quoter.json 40 | eventHandlers: 41 | - event: KickReward(indexed address,indexed address,uint256) 42 | handler: handleKickReward 43 | - event: RewardPaid(indexed address,indexed address,uint256) 44 | handler: handleRewardPaid 45 | - event: Staked(indexed address,uint256,uint256,uint256) 46 | handler: handleStaked 47 | - event: Withdrawn(indexed address,uint256,bool) 48 | handler: handleWithdrawn 49 | - event: RewardAdded(indexed address,uint256) 50 | handler: handleRewardAdded 51 | file: ./src/mapping.ts 52 | 53 | - kind: ethereum/contract 54 | name: vlCvxExtraRewardDistribution 55 | network: mainnet 56 | source: 57 | address: "0xDecc7d761496d30F30b92Bdf764fb8803c79360D" 58 | abi: vlCvxExtraRewardDistribution 59 | startBlock: 13375314 60 | mapping: 61 | kind: ethereum/events 62 | apiVersion: 0.0.5 63 | language: wasm/assemblyscript 64 | entities: 65 | - AddedReward 66 | - ReceivedReward 67 | - User 68 | - Token 69 | abis: 70 | - name: vlCvxExtraRewardDistribution 71 | file: ./abis/vlCvxExtraRewardDistribution.json 72 | - name: ERC20 73 | file: ../../abis/ERC20.json 74 | - name: Factory 75 | file: ../../abis/UniswapV2Factory.json 76 | - name: Pair 77 | file: ../../abis/UniswapV2Pair.json 78 | - name: FactoryV3 79 | file: ../../abis/UniswapV3Factory.json 80 | - name: Quoter 81 | file: ../../abis/UniswapV3Quoter.json 82 | eventHandlers: 83 | - event: RewardAdded(indexed address,indexed uint256,uint256) 84 | handler: handleRewardAdded 85 | - event: RewardPaid(indexed address,indexed address,uint256) 86 | handler: handleRewardPaid 87 | file: ./src/extraMapping.ts 88 | 89 | -------------------------------------------------------------------------------- /subgraphs/staking/abis/ERC20.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] -------------------------------------------------------------------------------- /subgraphs/staking/abis/UniswapV2Factory.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_feeToSetter", 7 | "type": "address" 8 | } 9 | ], 10 | "payable": false, 11 | "stateMutability": "nonpayable", 12 | "type": "constructor" 13 | }, 14 | { 15 | "anonymous": false, 16 | "inputs": [ 17 | { 18 | "indexed": true, 19 | "internalType": "address", 20 | "name": "token0", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": true, 25 | "internalType": "address", 26 | "name": "token1", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "address", 32 | "name": "pair", 33 | "type": "address" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "name": "PairCreated", 43 | "type": "event" 44 | }, 45 | { 46 | "constant": true, 47 | "inputs": [ 48 | { 49 | "internalType": "uint256", 50 | "name": "", 51 | "type": "uint256" 52 | } 53 | ], 54 | "name": "allPairs", 55 | "outputs": [ 56 | { 57 | "internalType": "address", 58 | "name": "", 59 | "type": "address" 60 | } 61 | ], 62 | "payable": false, 63 | "stateMutability": "view", 64 | "type": "function" 65 | }, 66 | { 67 | "constant": true, 68 | "inputs": [], 69 | "name": "allPairsLength", 70 | "outputs": [ 71 | { 72 | "internalType": "uint256", 73 | "name": "", 74 | "type": "uint256" 75 | } 76 | ], 77 | "payable": false, 78 | "stateMutability": "view", 79 | "type": "function" 80 | }, 81 | { 82 | "constant": false, 83 | "inputs": [ 84 | { 85 | "internalType": "address", 86 | "name": "tokenA", 87 | "type": "address" 88 | }, 89 | { 90 | "internalType": "address", 91 | "name": "tokenB", 92 | "type": "address" 93 | } 94 | ], 95 | "name": "createPair", 96 | "outputs": [ 97 | { 98 | "internalType": "address", 99 | "name": "pair", 100 | "type": "address" 101 | } 102 | ], 103 | "payable": false, 104 | "stateMutability": "nonpayable", 105 | "type": "function" 106 | }, 107 | { 108 | "constant": true, 109 | "inputs": [], 110 | "name": "feeTo", 111 | "outputs": [ 112 | { 113 | "internalType": "address", 114 | "name": "", 115 | "type": "address" 116 | } 117 | ], 118 | "payable": false, 119 | "stateMutability": "view", 120 | "type": "function" 121 | }, 122 | { 123 | "constant": true, 124 | "inputs": [], 125 | "name": "feeToSetter", 126 | "outputs": [ 127 | { 128 | "internalType": "address", 129 | "name": "", 130 | "type": "address" 131 | } 132 | ], 133 | "payable": false, 134 | "stateMutability": "view", 135 | "type": "function" 136 | }, 137 | { 138 | "constant": true, 139 | "inputs": [ 140 | { 141 | "internalType": "address", 142 | "name": "", 143 | "type": "address" 144 | }, 145 | { 146 | "internalType": "address", 147 | "name": "", 148 | "type": "address" 149 | } 150 | ], 151 | "name": "getPair", 152 | "outputs": [ 153 | { 154 | "internalType": "address", 155 | "name": "", 156 | "type": "address" 157 | } 158 | ], 159 | "payable": false, 160 | "stateMutability": "view", 161 | "type": "function" 162 | }, 163 | { 164 | "constant": false, 165 | "inputs": [ 166 | { 167 | "internalType": "address", 168 | "name": "_feeTo", 169 | "type": "address" 170 | } 171 | ], 172 | "name": "setFeeTo", 173 | "outputs": [], 174 | "payable": false, 175 | "stateMutability": "nonpayable", 176 | "type": "function" 177 | }, 178 | { 179 | "constant": false, 180 | "inputs": [ 181 | { 182 | "internalType": "address", 183 | "name": "_feeToSetter", 184 | "type": "address" 185 | } 186 | ], 187 | "name": "setFeeToSetter", 188 | "outputs": [], 189 | "payable": false, 190 | "stateMutability": "nonpayable", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/staking/abis/UniswapV3Quoter.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_factory", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "address", 11 | "name": "_WETH9", 12 | "type": "address" 13 | } 14 | ], 15 | "stateMutability": "nonpayable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "inputs": [], 20 | "name": "WETH9", 21 | "outputs": [ 22 | { 23 | "internalType": "address", 24 | "name": "", 25 | "type": "address" 26 | } 27 | ], 28 | "stateMutability": "view", 29 | "type": "function" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "factory", 34 | "outputs": [ 35 | { 36 | "internalType": "address", 37 | "name": "", 38 | "type": "address" 39 | } 40 | ], 41 | "stateMutability": "view", 42 | "type": "function" 43 | }, 44 | { 45 | "inputs": [ 46 | { 47 | "internalType": "bytes", 48 | "name": "path", 49 | "type": "bytes" 50 | }, 51 | { 52 | "internalType": "uint256", 53 | "name": "amountIn", 54 | "type": "uint256" 55 | } 56 | ], 57 | "name": "quoteExactInput", 58 | "outputs": [ 59 | { 60 | "internalType": "uint256", 61 | "name": "amountOut", 62 | "type": "uint256" 63 | } 64 | ], 65 | "stateMutability": "nonpayable", 66 | "type": "function" 67 | }, 68 | { 69 | "inputs": [ 70 | { 71 | "internalType": "address", 72 | "name": "tokenIn", 73 | "type": "address" 74 | }, 75 | { 76 | "internalType": "address", 77 | "name": "tokenOut", 78 | "type": "address" 79 | }, 80 | { 81 | "internalType": "uint24", 82 | "name": "fee", 83 | "type": "uint24" 84 | }, 85 | { 86 | "internalType": "uint256", 87 | "name": "amountIn", 88 | "type": "uint256" 89 | }, 90 | { 91 | "internalType": "uint160", 92 | "name": "sqrtPriceLimitX96", 93 | "type": "uint160" 94 | } 95 | ], 96 | "name": "quoteExactInputSingle", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "amountOut", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "bytes", 111 | "name": "path", 112 | "type": "bytes" 113 | }, 114 | { 115 | "internalType": "uint256", 116 | "name": "amountOut", 117 | "type": "uint256" 118 | } 119 | ], 120 | "name": "quoteExactOutput", 121 | "outputs": [ 122 | { 123 | "internalType": "uint256", 124 | "name": "amountIn", 125 | "type": "uint256" 126 | } 127 | ], 128 | "stateMutability": "nonpayable", 129 | "type": "function" 130 | }, 131 | { 132 | "inputs": [ 133 | { 134 | "internalType": "address", 135 | "name": "tokenIn", 136 | "type": "address" 137 | }, 138 | { 139 | "internalType": "address", 140 | "name": "tokenOut", 141 | "type": "address" 142 | }, 143 | { 144 | "internalType": "uint24", 145 | "name": "fee", 146 | "type": "uint24" 147 | }, 148 | { 149 | "internalType": "uint256", 150 | "name": "amountOut", 151 | "type": "uint256" 152 | }, 153 | { 154 | "internalType": "uint160", 155 | "name": "sqrtPriceLimitX96", 156 | "type": "uint160" 157 | } 158 | ], 159 | "name": "quoteExactOutputSingle", 160 | "outputs": [ 161 | { 162 | "internalType": "uint256", 163 | "name": "amountIn", 164 | "type": "uint256" 165 | } 166 | ], 167 | "stateMutability": "nonpayable", 168 | "type": "function" 169 | }, 170 | { 171 | "inputs": [ 172 | { 173 | "internalType": "int256", 174 | "name": "amount0Delta", 175 | "type": "int256" 176 | }, 177 | { 178 | "internalType": "int256", 179 | "name": "amount1Delta", 180 | "type": "int256" 181 | }, 182 | { 183 | "internalType": "bytes", 184 | "name": "path", 185 | "type": "bytes" 186 | } 187 | ], 188 | "name": "uniswapV3SwapCallback", 189 | "outputs": [], 190 | "stateMutability": "view", 191 | "type": "function" 192 | } 193 | ] -------------------------------------------------------------------------------- /subgraphs/staking/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "staking", 3 | "license": "MIT", 4 | "version": "1.0.0", 5 | "files": [ 6 | "generated" 7 | ], 8 | "scripts": { 9 | "codegen": "graph codegen", 10 | "build": "graph build", 11 | "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ convex-community/convex-staking", 12 | "deploy-hosted": "graph deploy --product hosted-service convex-community/convex-staking", 13 | "deploy-studio": "graph deploy --studio convex-staking", 14 | "create-local": "graph create --node http://localhost:8020/ convex/convex-staking", 15 | "remove-local": "graph remove --node http://localhost:8020/ convex/convex-staking", 16 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex/convex-staking" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/staking/schema.graphql: -------------------------------------------------------------------------------- 1 | type StakingContract @entity { 2 | id: ID! 3 | name: String! 4 | tokenBalance: BigInt! 5 | snapshots: [DailySnapshot!] @derivedFrom(field: "contract") 6 | } 7 | 8 | type DailySnapshot @entity { 9 | id: ID! 10 | contract: StakingContract! 11 | tokenBalance: BigInt! 12 | tvl: BigDecimal! 13 | crvApr: BigDecimal! 14 | cvxApr: BigDecimal! 15 | extraRewardsApr: [ExtraRewardApr!]! @derivedFrom(field: "snapshot") 16 | timestamp: BigInt! 17 | } 18 | 19 | 20 | type ExtraRewardApr @entity { 21 | id: ID! 22 | snapshot: DailySnapshot! 23 | token: Bytes! #address 24 | tokenName: String! 25 | apr: BigDecimal! 26 | } 27 | 28 | type Deposit @entity { 29 | id: ID! 30 | user: User! # address 31 | contract: StakingContract! 32 | amount: BigInt! # uint256 33 | timestamp: BigInt! 34 | } 35 | 36 | type Withdrawal @entity { 37 | id: ID! 38 | user: User! # address 39 | contract: StakingContract! 40 | amount: BigInt! # uint256 41 | timestamp: BigInt! 42 | } 43 | 44 | type User @entity { 45 | id: ID! 46 | address: Bytes! 47 | withdrawals: [Withdrawal!] @derivedFrom(field: "user") 48 | deposits: [Deposit!] @derivedFrom(field: "user") 49 | } -------------------------------------------------------------------------------- /subgraphs/staking/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { Address } from '@graphprotocol/graph-ts' 2 | import { Staked, Withdrawn } from '../generated/CvxCrvStakingRewards/BaseRewardPool' 3 | import { getStakingContract } from './services/contracts' 4 | import { Deposit, Withdrawal } from '../generated/schema' 5 | 6 | import { getUsdRate } from 'utils/pricing' 7 | import { BIG_DECIMAL_1E18, STAKING_TOKENS } from 'const' 8 | import { createSnapShot } from './services/snapshot' 9 | import { User } from '../../locker/generated/schema' 10 | 11 | export function handleStaked(event: Staked): void { 12 | const contract = getStakingContract(event.address) 13 | const deposit = new Deposit(event.transaction.hash.toHex() + '-' + event.logIndex.toString()) 14 | deposit.user = getUser(event.params.user.toHexString()).id 15 | deposit.amount = event.params.amount 16 | deposit.timestamp = event.block.timestamp 17 | deposit.contract = contract.id 18 | deposit.save() 19 | 20 | const snapshot = createSnapShot(contract, event.block.timestamp) 21 | const stakingTokenPrice = getUsdRate(Address.fromString(STAKING_TOKENS.get(event.address.toHexString()))) 22 | contract.tokenBalance = contract.tokenBalance.plus(event.params.amount) 23 | snapshot.tokenBalance = contract.tokenBalance 24 | snapshot.tvl = contract.tokenBalance.toBigDecimal().times(stakingTokenPrice).div(BIG_DECIMAL_1E18) 25 | snapshot.timestamp = event.block.timestamp 26 | snapshot.save() 27 | contract.save() 28 | } 29 | 30 | export function handleWithdrawn(event: Withdrawn): void { 31 | const contract = getStakingContract(event.address) 32 | const withdrawal = new Withdrawal(event.transaction.hash.toHex() + '-' + event.logIndex.toString()) 33 | withdrawal.user = getUser(event.params.user.toHexString()).id 34 | withdrawal.amount = event.params.amount 35 | withdrawal.timestamp = event.block.timestamp 36 | withdrawal.contract = contract.id 37 | withdrawal.save() 38 | 39 | const snapshot = createSnapShot(contract, event.block.timestamp) 40 | const stakingTokenPrice = getUsdRate(Address.fromString(STAKING_TOKENS.get(event.address.toHexString()))) 41 | contract.tokenBalance = contract.tokenBalance.minus(event.params.amount) 42 | snapshot.tokenBalance = contract.tokenBalance 43 | snapshot.tvl = contract.tokenBalance.toBigDecimal().times(stakingTokenPrice).div(BIG_DECIMAL_1E18) 44 | snapshot.timestamp = event.block.timestamp 45 | snapshot.save() 46 | contract.save() 47 | } 48 | 49 | export function getUser(address: string): User { 50 | let user = User.load(address) 51 | if (!user) { 52 | user = new User(address) 53 | user.save() 54 | } 55 | return user 56 | } 57 | -------------------------------------------------------------------------------- /subgraphs/staking/src/services/apr.ts: -------------------------------------------------------------------------------- 1 | import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' 2 | import { 3 | BIG_DECIMAL_1E18, 4 | BIG_DECIMAL_ZERO, 5 | CRV_ADDRESS, 6 | CVX_ADDRESS, 7 | CVX_REWARDS_ADDRESS, 8 | CVXCRV_REWARDS_ADDRESS, 9 | LOCK_FEES_ADDRESS, 10 | SECONDS_PER_YEAR, 11 | THREEPOOL_ADDRESS, 12 | } from 'const' 13 | import { getUsdRate } from 'utils/pricing' 14 | import { getCvxMintAmount } from 'utils/convex' 15 | import { VirtualBalanceRewardPool } from '../../generated/CvxCrvStakingRewards/VirtualBalanceRewardPool' 16 | import { BaseRewardPool } from '../../generated/CvxCrvStakingRewards/BaseRewardPool' 17 | import { CurvePool } from '../../generated/CvxCrvStakingRewards/CurvePool' 18 | 19 | export function getRewardRate(rewardContract: BaseRewardPool, timestamp: BigInt): BigDecimal { 20 | const periodFinish = rewardContract.periodFinish() 21 | if (timestamp >= periodFinish) { 22 | return BIG_DECIMAL_ZERO 23 | } 24 | return rewardContract.rewardRate().toBigDecimal().div(BIG_DECIMAL_1E18) 25 | } 26 | 27 | export function getCvxStakingApr(timestamp: BigInt): BigDecimal { 28 | const rewardContract = BaseRewardPool.bind(CVX_REWARDS_ADDRESS) 29 | //TODO: move getRewardRate to utils 30 | let rate = getRewardRate(rewardContract, timestamp) 31 | let supply = rewardContract.totalSupply().toBigDecimal().div(BIG_DECIMAL_1E18) 32 | const crvPrice = getUsdRate(CRV_ADDRESS) 33 | const cvxPrice = getUsdRate(CVX_ADDRESS) 34 | supply = supply.times(cvxPrice) 35 | rate = rate.div(supply) 36 | const crvPerYear = rate.times(SECONDS_PER_YEAR) 37 | const crvApr = crvPerYear.times(crvPrice) 38 | return crvApr 39 | } 40 | 41 | export function getCvxCrvStakingApr(timestamp: BigInt): Array { 42 | const rewardContract = BaseRewardPool.bind(CVXCRV_REWARDS_ADDRESS) 43 | const threePoolStakeContract = VirtualBalanceRewardPool.bind(LOCK_FEES_ADDRESS) 44 | const threePoolSwapContract = CurvePool.bind(THREEPOOL_ADDRESS) 45 | 46 | let rate = getRewardRate(rewardContract, timestamp) 47 | let threePoolRate = threePoolStakeContract.rewardRate().toBigDecimal().div(BIG_DECIMAL_1E18) 48 | let supply = rewardContract.totalSupply().toBigDecimal().div(BIG_DECIMAL_1E18) 49 | 50 | const virtualPrice = threePoolSwapContract.get_virtual_price().toBigDecimal().div(BIG_DECIMAL_1E18) 51 | const cvxPrice = getUsdRate(CVX_ADDRESS) 52 | const crvPrice = getUsdRate(CRV_ADDRESS) 53 | supply = supply.times(crvPrice) 54 | rate = rate.div(supply) 55 | threePoolRate = threePoolRate.div(supply) 56 | 57 | const crvPerYear = rate.times(SECONDS_PER_YEAR) 58 | const cvxPerYear = getCvxMintAmount(crvPerYear) 59 | const threePoolPerYear = threePoolRate.times(SECONDS_PER_YEAR) 60 | 61 | const crvApr = crvPerYear.times(crvPrice) 62 | const cvxApr = cvxPerYear.times(cvxPrice) 63 | const threeCrvApr = threePoolPerYear.times(virtualPrice) 64 | 65 | return [crvApr, cvxApr, threeCrvApr] 66 | } 67 | -------------------------------------------------------------------------------- /subgraphs/staking/src/services/contracts.ts: -------------------------------------------------------------------------------- 1 | import { Address } from '@graphprotocol/graph-ts' 2 | import { StakingContract } from '../../generated/schema' 3 | import { STAKING_CONTRACTS } from 'const' 4 | 5 | export function getStakingContract(address: Address): StakingContract { 6 | let contract = StakingContract.load(address.toHexString()) 7 | if (!contract) { 8 | contract = new StakingContract(address.toHexString()) 9 | contract.name = STAKING_CONTRACTS.get(address.toHexString().toLowerCase()) 10 | } 11 | return contract 12 | } 13 | -------------------------------------------------------------------------------- /subgraphs/staking/src/services/snapshot.ts: -------------------------------------------------------------------------------- 1 | import { DailySnapshot, ExtraRewardApr, StakingContract } from '../../generated/schema' 2 | import { Address, BigInt, log } from '@graphprotocol/graph-ts' 3 | import { DAY, getIntervalFromTimestamp } from 'utils/time' 4 | import { getCvxStakingApr, getCvxCrvStakingApr } from './apr' 5 | import { BIG_DECIMAL_ZERO, CVX_REWARDS, CVXCRV_REWARDS, THREE_CRV_TOKEN } from 'const' 6 | 7 | export function createSnapShot(contract: StakingContract, timestamp: BigInt): DailySnapshot { 8 | const day = getIntervalFromTimestamp(timestamp, DAY) 9 | const snapId = contract.name + '-' + day.toString() 10 | let snapshot = DailySnapshot.load(snapId) 11 | if (!snapshot) { 12 | snapshot = new DailySnapshot(snapId) 13 | snapshot.contract = contract.id 14 | snapshot.timestamp = timestamp 15 | snapshot = setSnapshotAprs(contract.id, snapshot) 16 | } 17 | return snapshot 18 | } 19 | 20 | export function setSnapshotAprs(contract: string, snapshot: DailySnapshot): DailySnapshot { 21 | log.debug('Creating APR Snapshot for {}:', [contract]) 22 | if (contract == CVXCRV_REWARDS) { 23 | return setStakedCvxCrvSnapshotApr(snapshot) 24 | } else if (contract == CVX_REWARDS) { 25 | return setStakedCvxSnapshotApr(snapshot) 26 | } 27 | return snapshot 28 | } 29 | 30 | export function setStakedCvxSnapshotApr(snapshot: DailySnapshot): DailySnapshot { 31 | const apr = getCvxStakingApr(snapshot.timestamp) 32 | snapshot.crvApr = apr 33 | snapshot.cvxApr = BIG_DECIMAL_ZERO 34 | return snapshot 35 | } 36 | 37 | export function setStakedCvxCrvSnapshotApr(snapshot: DailySnapshot): DailySnapshot { 38 | const aprs = getCvxCrvStakingApr(snapshot.timestamp) 39 | snapshot.crvApr = aprs[0] 40 | snapshot.cvxApr = aprs[1] 41 | const threeCrvApr = aprs[2] 42 | const extra = new ExtraRewardApr(snapshot.id + '-' + THREE_CRV_TOKEN) 43 | extra.snapshot = snapshot.id 44 | extra.token = Address.fromString(THREE_CRV_TOKEN) 45 | extra.tokenName = '3Crv' 46 | extra.apr = threeCrvApr 47 | extra.save() 48 | return snapshot 49 | } 50 | -------------------------------------------------------------------------------- /subgraphs/staking/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.2 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | - kind: ethereum/contract 6 | name: CvxCrvStakingRewards 7 | network: mainnet 8 | source: 9 | address: "0x3fe65692bfcd0e6cf84cb1e7d24108e434a7587e" 10 | abi: BaseRewardPool 11 | startBlock: 12451039 12 | mapping: 13 | kind: ethereum/events 14 | apiVersion: 0.0.5 15 | language: wasm/assemblyscript 16 | entities: 17 | - StakingContract 18 | - DailySnapshot 19 | - ExtraRewardApr 20 | - Staked 21 | - Withdrawn 22 | abis: 23 | - name: BaseRewardPool 24 | file: ../../abis/BaseRewardPool.json 25 | - name: VirtualBalanceRewardPool 26 | file: ../../abis/VirtualBalanceRewardPool.json 27 | - name: CurvePool 28 | file: ../../abis/CurvePool.json 29 | - name: ERC20 30 | file: ../../abis/ERC20.json 31 | - name: Factory 32 | file: ../../abis/UniswapV2Factory.json 33 | - name: Pair 34 | file: ../../abis/UniswapV2Pair.json 35 | - name: FactoryV3 36 | file: ../../abis/UniswapV3Factory.json 37 | - name: Quoter 38 | file: ../../abis/UniswapV3Quoter.json 39 | eventHandlers: 40 | - event: Staked(indexed address,uint256) 41 | handler: handleStaked 42 | - event: Withdrawn(indexed address,uint256) 43 | handler: handleWithdrawn 44 | file: ./src/mapping.ts 45 | 46 | - kind: ethereum/contract 47 | name: cvxRewardPool 48 | network: mainnet 49 | source: 50 | address: "0xcf50b810e57ac33b91dcf525c6ddd9881b139332" 51 | abi: CvxRewardPool 52 | startBlock: 12451040 53 | mapping: 54 | kind: ethereum/events 55 | apiVersion: 0.0.5 56 | language: wasm/assemblyscript 57 | entities: 58 | - StakingContract 59 | - DailySnapshot 60 | - ExtraRewardApr 61 | - Staked 62 | - Withdrawn 63 | abis: 64 | - name: CvxRewardPool 65 | file: ./abis/CvxRewardPool.json 66 | - name: ERC20 67 | file: ../../abis/ERC20.json 68 | - name: Factory 69 | file: ../../abis/UniswapV2Factory.json 70 | - name: Pair 71 | file: ../../abis/UniswapV2Pair.json 72 | - name: FactoryV3 73 | file: ../../abis/UniswapV3Factory.json 74 | - name: Quoter 75 | file: ../../abis/UniswapV3Quoter.json 76 | - name: BaseRewardPool 77 | file: ../../abis/BaseRewardPool.json 78 | eventHandlers: 79 | - event: Staked(indexed address,uint256) 80 | handler: handleStaked 81 | - event: Withdrawn(indexed address,uint256) 82 | handler: handleWithdrawn 83 | file: ./src/mapping.ts 84 | 85 | -------------------------------------------------------------------------------- /subgraphs/votium-fxn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "votium-v2", 3 | "license": "UNLICENSED", 4 | "scripts": { 5 | "codegen": "graph codegen", 6 | "build": "graph build", 7 | "deploy": "graph deploy --node https://api.thegraph.com/deploy/ convex-community/fxn-subgraph", 8 | "create-local": "graph create --node http://localhost:8020/ convex-community/fxn-subgraph", 9 | "remove-local": "graph remove --node http://localhost:8020/ convex-community/fxn-subgraph", 10 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex-community/fxn-subgraph", 11 | "test": "graph test" 12 | }, 13 | "dependencies": { 14 | "@graphprotocol/graph-cli": "0.50.1", 15 | "@graphprotocol/graph-ts": "0.30.0" 16 | }, 17 | "devDependencies": { "matchstick-as": "0.5.0" } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/votium-fxn/schema.graphql: -------------------------------------------------------------------------------- 1 | type Round @entity { 2 | id: ID! 3 | initiatedAt: BigInt! 4 | bribeCount: BigInt! 5 | incentives: [Incentive!]! @derivedFrom(field: "round") 6 | } 7 | 8 | type Incentive @entity { 9 | id: ID! 10 | token: Bytes! 11 | round: Round! 12 | gauge: Bytes! 13 | index: BigInt! 14 | amount: BigInt! 15 | maxPerVote: BigInt! 16 | createdAt: BigInt! 17 | updatedAt: BigInt 18 | originalIncentive: NewIncentive! @derivedFrom(field: "incentive") 19 | withdrawals: [WithdrawUnprocessed!] @derivedFrom(field: "incentive") 20 | increases: [IncreasedIncentive!] @derivedFrom(field: "incentive") 21 | } 22 | 23 | 24 | type IncreasedIncentive @entity(immutable: true) { 25 | id: ID! 26 | index: BigInt! 27 | token: Bytes! # address 28 | total: BigInt! # uint256 29 | increase: BigInt! # uint256 30 | round: BigInt! # uint256 31 | gauge: Bytes! # address 32 | incentive: Incentive! 33 | maxPerVote: BigInt! # uint256 34 | blockNumber: BigInt! 35 | blockTimestamp: BigInt! 36 | transactionHash: Bytes! 37 | } 38 | 39 | type NewIncentive @entity(immutable: true) { 40 | id: ID! 41 | index: BigInt! 42 | token: Bytes! # address 43 | amount: BigInt! # uint256 44 | round: BigInt! # uint256 45 | gauge: Bytes! # address 46 | maxPerVote: BigInt! # uint256 47 | depositor: Bytes! # address 48 | recycled: Boolean! # bool 49 | incentive: Incentive! 50 | blockNumber: BigInt! 51 | blockTimestamp: BigInt! 52 | transactionHash: Bytes! 53 | } 54 | 55 | 56 | type WithdrawUnprocessed @entity(immutable: true) { 57 | id: ID! 58 | index: BigInt! 59 | round: BigInt! # uint256 60 | gauge: Bytes! # address 61 | amount: BigInt! # uint256 62 | incentive: Incentive! 63 | blockNumber: BigInt! 64 | blockTimestamp: BigInt! 65 | transactionHash: Bytes! 66 | } 67 | 68 | type UpdatedFee @entity(immutable: true) { 69 | id: ID! 70 | amount: BigInt! # uint256 71 | blockNumber: BigInt! 72 | blockTimestamp: BigInt! 73 | transactionHash: Bytes! 74 | } 75 | -------------------------------------------------------------------------------- /subgraphs/votium-fxn/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IncreasedIncentive as IncreasedIncentiveEvent, 3 | NewIncentive as NewIncentiveEvent, 4 | UpdatedFee as UpdatedFeeEvent, 5 | WithdrawUnprocessed as WithdrawUnprocessedEvent, 6 | } from '../generated/VotiumVlCVXFXN/VotiumVlCVXFXN' 7 | import { 8 | Incentive, 9 | IncreasedIncentive, 10 | NewIncentive, 11 | Round, 12 | UpdatedFee, 13 | WithdrawUnprocessed, 14 | } from '../generated/schema' 15 | import { BigInt } from '@graphprotocol/graph-ts' 16 | 17 | export function getRound(roundNumber: BigInt, timestamp: BigInt): Round { 18 | let round = Round.load(roundNumber.toString()) 19 | if (!round) { 20 | round = new Round(roundNumber.toString()) 21 | round.bribeCount = BigInt.zero() 22 | round.initiatedAt = timestamp 23 | round.save() 24 | } 25 | return round 26 | } 27 | 28 | export function getIncentive(gauge: string, round: string, index: string, timestamp: BigInt): Incentive { 29 | let incentive = Incentive.load(gauge + '-' + round + '-' + index) 30 | if (!incentive) { 31 | incentive = new Incentive(gauge + '-' + round + '-' + index) 32 | incentive.createdAt = timestamp 33 | } 34 | return incentive 35 | } 36 | 37 | export function handleIncreasedIncentive(event: IncreasedIncentiveEvent): void { 38 | const increase = new IncreasedIncentive(event.transaction.hash.toHexString() + event.logIndex.toString()) 39 | const incentive = getIncentive( 40 | event.params._gauge.toHexString(), 41 | event.params._round.toString(), 42 | event.params._index.toString(), 43 | event.block.timestamp 44 | ) 45 | 46 | increase.token = event.params._token 47 | increase.total = event.params._total 48 | increase.increase = event.params._increase 49 | increase.round = event.params._round 50 | increase.gauge = event.params._gauge 51 | increase.maxPerVote = event.params._maxPerVote 52 | increase.incentive = incentive.id 53 | 54 | increase.blockNumber = event.block.number 55 | increase.blockTimestamp = event.block.timestamp 56 | increase.transactionHash = event.transaction.hash 57 | 58 | incentive.amount = incentive.amount.plus(increase.increase) 59 | incentive.updatedAt = event.block.timestamp 60 | 61 | incentive.save() 62 | increase.save() 63 | } 64 | 65 | export function handleNewIncentive(event: NewIncentiveEvent): void { 66 | const newIncentive = new NewIncentive(event.transaction.hash.toHexString() + event.logIndex.toString()) 67 | const incentive = getIncentive( 68 | event.params._gauge.toHexString(), 69 | event.params._round.toString(), 70 | event.params._index.toString(), 71 | event.block.timestamp 72 | ) 73 | const round = getRound(event.params._round, event.block.timestamp) 74 | round.bribeCount = round.bribeCount.plus(BigInt.fromI32(1)) 75 | round.save() 76 | 77 | newIncentive.index = event.params._index 78 | newIncentive.token = event.params._token 79 | newIncentive.amount = event.params._amount 80 | newIncentive.depositor = event.params._depositor 81 | newIncentive.round = event.params._round 82 | newIncentive.gauge = event.params._gauge 83 | newIncentive.maxPerVote = event.params._maxPerVote 84 | newIncentive.recycled = event.params._recycled 85 | newIncentive.incentive = incentive.id 86 | 87 | newIncentive.blockNumber = event.block.number 88 | newIncentive.blockTimestamp = event.block.timestamp 89 | newIncentive.transactionHash = event.transaction.hash 90 | 91 | incentive.token = event.params._token 92 | incentive.amount = event.params._amount 93 | incentive.index = event.params._index 94 | incentive.round = round.id 95 | incentive.gauge = event.params._gauge 96 | incentive.maxPerVote = event.params._maxPerVote 97 | incentive.save() 98 | newIncentive.save() 99 | } 100 | 101 | export function handleUpdatedFee(event: UpdatedFeeEvent): void { 102 | const feeUpdate = new UpdatedFee(event.transaction.hash.toHexString() + '-' + event.logIndex.toString()) 103 | 104 | feeUpdate.amount = event.params._feeAmount 105 | 106 | feeUpdate.blockNumber = event.block.number 107 | feeUpdate.blockTimestamp = event.block.timestamp 108 | feeUpdate.transactionHash = event.transaction.hash 109 | 110 | feeUpdate.save() 111 | } 112 | 113 | export function handleWithdrawUnprocessed(event: WithdrawUnprocessedEvent): void { 114 | const withdrawal = new WithdrawUnprocessed(event.transaction.hash.toHexString() + event.logIndex.toString()) 115 | withdrawal.round = event.params._round 116 | withdrawal.gauge = event.params._gauge 117 | withdrawal.index = event.params._index 118 | withdrawal.amount = event.params._amount 119 | 120 | withdrawal.blockNumber = event.block.number 121 | withdrawal.blockTimestamp = event.block.timestamp 122 | withdrawal.transactionHash = event.transaction.hash 123 | 124 | const incentive = getIncentive( 125 | event.params._gauge.toHexString(), 126 | event.params._round.toString(), 127 | event.params._index.toString(), 128 | event.block.timestamp 129 | ) 130 | incentive.amount = incentive.amount.minus(withdrawal.amount) 131 | incentive.updatedAt = event.block.timestamp 132 | withdrawal.incentive = incentive.id 133 | incentive.save() 134 | withdrawal.save() 135 | } 136 | -------------------------------------------------------------------------------- /subgraphs/votium-fxn/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.5 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | - kind: ethereum 6 | name: VotiumVlCVXFXN 7 | network: mainnet 8 | source: 9 | address: "0x2272B9a1ce6503f9428E4179eBcdc2690eF28469" 10 | abi: VotiumVlCVXFXN 11 | startBlock: 19386277 12 | mapping: 13 | kind: ethereum/events 14 | apiVersion: 0.0.7 15 | language: wasm/assemblyscript 16 | entities: 17 | - IncreasedIncentive 18 | - NewIncentive 19 | - Incentive 20 | - Round 21 | - UpdatedFee 22 | - WithdrawUnprocessed 23 | abis: 24 | - name: VotiumVlCVXFXN 25 | file: ./abis/VotiumVlCVXFXN.json 26 | eventHandlers: 27 | - event: IncreasedIncentive(uint256,address,uint256,uint256,indexed uint256,indexed address,uint256) 28 | handler: handleIncreasedIncentive 29 | - event: NewIncentive(uint256,address,uint256,indexed uint256,indexed address,uint256,address[],indexed address,bool) 30 | handler: handleNewIncentive 31 | - event: UpdatedFee(uint256) 32 | handler: handleUpdatedFee 33 | - event: WithdrawUnprocessed(uint256,indexed uint256,indexed address,uint256) 34 | handler: handleWithdrawUnprocessed 35 | file: ./src/mapping.ts 36 | -------------------------------------------------------------------------------- /subgraphs/votium-prisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "votium-v2", 3 | "license": "UNLICENSED", 4 | "scripts": { 5 | "codegen": "graph codegen", 6 | "build": "graph build", 7 | "deploy": "graph deploy --node https://api.thegraph.com/deploy/ convex-community/votium-prisma", 8 | "create-local": "graph create --node http://localhost:8020/ convex-community/votium-prisma", 9 | "remove-local": "graph remove --node http://localhost:8020/ convex-community/votium-prisma", 10 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex-community/votium-prisma", 11 | "test": "graph test" 12 | }, 13 | "dependencies": { 14 | "@graphprotocol/graph-cli": "0.50.1", 15 | "@graphprotocol/graph-ts": "0.30.0" 16 | }, 17 | "devDependencies": { "matchstick-as": "0.5.0" } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/votium-prisma/schema.graphql: -------------------------------------------------------------------------------- 1 | type Round @entity { 2 | id: ID! 3 | initiatedAt: BigInt! 4 | bribeCount: BigInt! 5 | incentives: [Incentive!]! @derivedFrom(field: "round") 6 | } 7 | 8 | type Incentive @entity { 9 | id: ID! 10 | token: Bytes! 11 | round: Round! 12 | gauge: BigInt! 13 | index: BigInt! 14 | amount: BigInt! 15 | maxPerVote: BigInt! 16 | createdAt: BigInt! 17 | updatedAt: BigInt 18 | originalIncentive: NewIncentive! @derivedFrom(field: "incentive") 19 | withdrawals: [WithdrawUnprocessed!] @derivedFrom(field: "incentive") 20 | increases: [IncreasedIncentive!] @derivedFrom(field: "incentive") 21 | } 22 | 23 | 24 | type IncreasedIncentive @entity(immutable: true) { 25 | id: ID! 26 | index: BigInt! 27 | token: Bytes! # address 28 | total: BigInt! # uint256 29 | increase: BigInt! # uint256 30 | round: BigInt! # uint256 31 | gauge: BigInt! # address 32 | incentive: Incentive! 33 | maxPerVote: BigInt! # uint256 34 | blockNumber: BigInt! 35 | blockTimestamp: BigInt! 36 | transactionHash: Bytes! 37 | } 38 | 39 | type NewIncentive @entity(immutable: true) { 40 | id: ID! 41 | index: BigInt! 42 | token: Bytes! # address 43 | amount: BigInt! # uint256 44 | round: BigInt! # uint256 45 | gauge: BigInt! # address 46 | maxPerVote: BigInt! # uint256 47 | depositor: Bytes! # address 48 | recycled: Boolean! # bool 49 | incentive: Incentive! 50 | blockNumber: BigInt! 51 | blockTimestamp: BigInt! 52 | transactionHash: Bytes! 53 | } 54 | 55 | 56 | type WithdrawUnprocessed @entity(immutable: true) { 57 | id: ID! 58 | index: BigInt! 59 | round: BigInt! # uint256 60 | gauge: BigInt! # address 61 | amount: BigInt! # uint256 62 | incentive: Incentive! 63 | blockNumber: BigInt! 64 | blockTimestamp: BigInt! 65 | transactionHash: Bytes! 66 | } 67 | 68 | type UpdatedFee @entity(immutable: true) { 69 | id: ID! 70 | amount: BigInt! # uint256 71 | blockNumber: BigInt! 72 | blockTimestamp: BigInt! 73 | transactionHash: Bytes! 74 | } 75 | -------------------------------------------------------------------------------- /subgraphs/votium-prisma/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IncreasedIncentive as IncreasedIncentiveEvent, 3 | NewIncentive as NewIncentiveEvent, 4 | UpdatedFee as UpdatedFeeEvent, 5 | WithdrawUnprocessed as WithdrawUnprocessedEvent, 6 | } from '../generated/VotiumVlCVXPrisma/VotiumVlCVXPrisma' 7 | import { 8 | Incentive, 9 | IncreasedIncentive, 10 | NewIncentive, 11 | Round, 12 | UpdatedFee, 13 | WithdrawUnprocessed, 14 | } from '../generated/schema' 15 | import { BigInt } from '@graphprotocol/graph-ts' 16 | 17 | export function getRound(roundNumber: BigInt, timestamp: BigInt): Round { 18 | let round = Round.load(roundNumber.toString()) 19 | if (!round) { 20 | round = new Round(roundNumber.toString()) 21 | round.bribeCount = BigInt.zero() 22 | round.initiatedAt = timestamp 23 | round.save() 24 | } 25 | return round 26 | } 27 | 28 | export function getIncentive(gauge: string, round: string, index: string, timestamp: BigInt): Incentive { 29 | let incentive = Incentive.load(gauge + '-' + round + '-' + index) 30 | if (!incentive) { 31 | incentive = new Incentive(gauge + '-' + round + '-' + index) 32 | incentive.createdAt = timestamp 33 | } 34 | return incentive 35 | } 36 | 37 | export function handleIncreasedIncentive(event: IncreasedIncentiveEvent): void { 38 | const increase = new IncreasedIncentive(event.transaction.hash.toHexString() + event.logIndex.toString()) 39 | const incentive = getIncentive( 40 | event.params._gauge.toHexString(), 41 | event.params._round.toString(), 42 | event.params._index.toString(), 43 | event.block.timestamp 44 | ) 45 | 46 | increase.token = event.params._token 47 | increase.total = event.params._total 48 | increase.increase = event.params._increase 49 | increase.round = event.params._round 50 | increase.gauge = event.params._gauge 51 | increase.maxPerVote = event.params._maxPerVote 52 | increase.incentive = incentive.id 53 | 54 | increase.blockNumber = event.block.number 55 | increase.blockTimestamp = event.block.timestamp 56 | increase.transactionHash = event.transaction.hash 57 | 58 | incentive.amount = incentive.amount.plus(increase.increase) 59 | incentive.updatedAt = event.block.timestamp 60 | 61 | incentive.save() 62 | increase.save() 63 | } 64 | 65 | export function handleNewIncentive(event: NewIncentiveEvent): void { 66 | const newIncentive = new NewIncentive(event.transaction.hash.toHexString() + event.logIndex.toString()) 67 | const incentive = getIncentive( 68 | event.params._gauge.toHexString(), 69 | event.params._round.toString(), 70 | event.params._index.toString(), 71 | event.block.timestamp 72 | ) 73 | const round = getRound(event.params._round, event.block.timestamp) 74 | round.bribeCount = round.bribeCount.plus(BigInt.fromI32(1)) 75 | round.save() 76 | 77 | newIncentive.index = event.params._index 78 | newIncentive.token = event.params._token 79 | newIncentive.amount = event.params._amount 80 | newIncentive.depositor = event.params._depositor 81 | newIncentive.round = event.params._round 82 | newIncentive.gauge = event.params._gauge 83 | newIncentive.maxPerVote = event.params._maxPerVote 84 | newIncentive.recycled = event.params._recycled 85 | newIncentive.incentive = incentive.id 86 | 87 | newIncentive.blockNumber = event.block.number 88 | newIncentive.blockTimestamp = event.block.timestamp 89 | newIncentive.transactionHash = event.transaction.hash 90 | 91 | incentive.token = event.params._token 92 | incentive.amount = event.params._amount 93 | incentive.index = event.params._index 94 | incentive.round = round.id 95 | incentive.gauge = event.params._gauge 96 | incentive.maxPerVote = event.params._maxPerVote 97 | incentive.save() 98 | newIncentive.save() 99 | } 100 | 101 | export function handleUpdatedFee(event: UpdatedFeeEvent): void { 102 | const feeUpdate = new UpdatedFee(event.transaction.hash.toHexString() + '-' + event.logIndex.toString()) 103 | 104 | feeUpdate.amount = event.params._feeAmount 105 | 106 | feeUpdate.blockNumber = event.block.number 107 | feeUpdate.blockTimestamp = event.block.timestamp 108 | feeUpdate.transactionHash = event.transaction.hash 109 | 110 | feeUpdate.save() 111 | } 112 | 113 | export function handleWithdrawUnprocessed(event: WithdrawUnprocessedEvent): void { 114 | const withdrawal = new WithdrawUnprocessed(event.transaction.hash.toHexString() + event.logIndex.toString()) 115 | withdrawal.round = event.params._round 116 | withdrawal.gauge = event.params._gauge 117 | withdrawal.index = event.params._index 118 | withdrawal.amount = event.params._amount 119 | 120 | withdrawal.blockNumber = event.block.number 121 | withdrawal.blockTimestamp = event.block.timestamp 122 | withdrawal.transactionHash = event.transaction.hash 123 | 124 | const incentive = getIncentive( 125 | event.params._gauge.toHexString(), 126 | event.params._round.toString(), 127 | event.params._index.toString(), 128 | event.block.timestamp 129 | ) 130 | incentive.amount = incentive.amount.minus(withdrawal.amount) 131 | incentive.updatedAt = event.block.timestamp 132 | withdrawal.incentive = incentive.id 133 | incentive.save() 134 | withdrawal.save() 135 | } 136 | -------------------------------------------------------------------------------- /subgraphs/votium-prisma/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.5 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | - kind: ethereum 6 | name: VotiumVlCVXPrisma 7 | network: mainnet 8 | source: 9 | address: "0xB5F6322163F71d0733767cc0eA219422De51b5C9" 10 | abi: VotiumVlCVXPrisma 11 | startBlock: 18897821 12 | mapping: 13 | kind: ethereum/events 14 | apiVersion: 0.0.7 15 | language: wasm/assemblyscript 16 | entities: 17 | - IncreasedIncentive 18 | - NewIncentive 19 | - Incentive 20 | - Round 21 | - UpdatedFee 22 | - WithdrawUnprocessed 23 | abis: 24 | - name: VotiumVlCVXPrisma 25 | file: ./abis/VotiumVlCVXPrisma.json 26 | eventHandlers: 27 | - event: IncreasedIncentive(uint256,address,uint256,uint256,indexed uint256,indexed uint256,uint256) 28 | handler: handleIncreasedIncentive 29 | - event: NewIncentive(uint256,address,uint256,indexed uint256,indexed uint256,uint256,address[],indexed address,bool) 30 | handler: handleNewIncentive 31 | - event: UpdatedFee(uint256) 32 | handler: handleUpdatedFee 33 | - event: WithdrawUnprocessed(uint256,indexed uint256,indexed uint256,uint256) 34 | handler: handleWithdrawUnprocessed 35 | file: ./src/mapping.ts 36 | -------------------------------------------------------------------------------- /subgraphs/votium/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "votium", 3 | "license": "MIT", 4 | "version": "1.0.0", 5 | "files": [ 6 | "generated" 7 | ], 8 | "scripts": { 9 | "codegen": "graph codegen", 10 | "build": "graph build", 11 | "deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ convex-community/votium-bribes", 12 | "deploy-hosted": "graph deploy --product hosted-service convex-community/votium-bribes", 13 | "deploy-studio": "graph deploy --studio votium-bribes", 14 | "create-local": "graph create --node http://localhost:8020/ convex/votium", 15 | "remove-local": "graph remove --node http://localhost:8020/ convex/votium", 16 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex/votium" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/votium/schema.graphql: -------------------------------------------------------------------------------- 1 | type Epoch @entity { 2 | id: ID! 3 | deadline: BigInt! 4 | initiatedAt: BigInt! 5 | bribeCount: BigInt! 6 | bribes: [Bribe!]! @derivedFrom(field: "epoch") 7 | } 8 | 9 | type Bribe @entity { 10 | id: ID! 11 | epoch: Epoch! 12 | token: Bytes! 13 | choiceIndex: BigInt! 14 | amount: BigInt! 15 | } 16 | 17 | type Fee @entity { 18 | id: ID! 19 | amount: BigInt! 20 | } -------------------------------------------------------------------------------- /subgraphs/votium/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { BigInt } from '@graphprotocol/graph-ts' 2 | import { Bribed, UpdatedFee, InitiateProposalCall } from '../generated/VotiumBribe/VotiumBribe' 3 | import { Bribe, Epoch, Fee } from '../generated/schema' 4 | import { BIG_INT_ONE, VOTIUM_BRIBE_CONTRACT } from 'const' 5 | 6 | export function getPlatformFee(): Fee { 7 | let fee = Fee.load(VOTIUM_BRIBE_CONTRACT) 8 | if (!fee) { 9 | fee = new Fee(VOTIUM_BRIBE_CONTRACT) 10 | fee.amount = BigInt.fromI32(400) 11 | fee.save() 12 | } 13 | return fee 14 | } 15 | 16 | export function handleUpdatedFee(event: UpdatedFee): void { 17 | const fee = getPlatformFee() 18 | fee.amount = event.params._feeAmount 19 | fee.save() 20 | } 21 | 22 | export function handleBribed(event: Bribed): void { 23 | const bribe = new Bribe( 24 | event.transaction.hash.toHexString() + 25 | '-' + 26 | event.params._token.toHexString() + 27 | '-' + 28 | event.params._choiceIndex.toString() + 29 | event.params._amount.toString() 30 | ) 31 | 32 | bribe.epoch = event.params._proposal.toHexString() 33 | bribe.amount = event.params._amount 34 | bribe.choiceIndex = event.params._choiceIndex 35 | bribe.token = event.params._token 36 | bribe.save() 37 | 38 | const epoch = Epoch.load(bribe.epoch) 39 | if (epoch) { 40 | epoch.bribeCount = epoch.bribeCount.plus(BIG_INT_ONE) 41 | epoch.save() 42 | } 43 | } 44 | 45 | export function handleInitiated(call: InitiateProposalCall): void { 46 | const epoch = new Epoch(call.inputs._proposal.toHexString()) 47 | epoch.deadline = call.inputs._deadline 48 | epoch.initiatedAt = call.block.timestamp 49 | epoch.save() 50 | } 51 | -------------------------------------------------------------------------------- /subgraphs/votium/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.2 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | - kind: ethereum/contract 6 | name: VotiumBribe 7 | network: mainnet 8 | source: 9 | address: "0x19BBC3463Dd8d07f55438014b021Fb457EBD4595" 10 | abi: VotiumBribe 11 | startBlock: 13209937 12 | mapping: 13 | kind: ethereum/events 14 | apiVersion: 0.0.5 15 | language: wasm/assemblyscript 16 | entities: 17 | - Payment 18 | - Epoch 19 | - BribeFee 20 | abis: 21 | - name: VotiumBribe 22 | file: ./abis/VotiumBribe.json 23 | eventHandlers: 24 | - event: Bribed(address,uint256,indexed bytes32,uint256) 25 | handler: handleBribed 26 | - event: UpdatedFee(uint256) 27 | handler: handleUpdatedFee 28 | callHandlers: 29 | - function: initiateProposal(bytes32,uint256,uint256) 30 | handler: handleInitiated 31 | file: ./src/mapping.ts 32 | -------------------------------------------------------------------------------- /subgraphs/votiumv2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "votium-v2", 3 | "license": "UNLICENSED", 4 | "scripts": { 5 | "codegen": "graph codegen", 6 | "build": "graph build", 7 | "deploy": "graph deploy --node https://api.thegraph.com/deploy/ convex-community/votium-v2", 8 | "create-local": "graph create --node http://localhost:8020/ convex-community/votium-v2", 9 | "remove-local": "graph remove --node http://localhost:8020/ convex-community/votium-v2", 10 | "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 convex-community/votium-v2", 11 | "test": "graph test" 12 | }, 13 | "dependencies": { 14 | "@graphprotocol/graph-cli": "0.50.1", 15 | "@graphprotocol/graph-ts": "0.30.0" 16 | }, 17 | "devDependencies": { "matchstick-as": "0.5.0" } 18 | } 19 | -------------------------------------------------------------------------------- /subgraphs/votiumv2/schema.graphql: -------------------------------------------------------------------------------- 1 | type Round @entity { 2 | id: ID! 3 | initiatedAt: BigInt! 4 | bribeCount: BigInt! 5 | incentives: [Incentive!]! @derivedFrom(field: "round") 6 | } 7 | 8 | type Incentive @entity { 9 | id: ID! 10 | token: Bytes! 11 | round: Round! 12 | gauge: Bytes! 13 | index: BigInt! 14 | amount: BigInt! 15 | maxPerVote: BigInt! 16 | createdAt: BigInt! 17 | updatedAt: BigInt 18 | originalIncentive: NewIncentive! @derivedFrom(field: "incentive") 19 | withdrawals: [WithdrawUnprocessed!] @derivedFrom(field: "incentive") 20 | increases: [IncreasedIncentive!] @derivedFrom(field: "incentive") 21 | } 22 | 23 | 24 | type IncreasedIncentive @entity(immutable: true) { 25 | id: ID! 26 | index: BigInt! 27 | token: Bytes! # address 28 | total: BigInt! # uint256 29 | increase: BigInt! # uint256 30 | round: BigInt! # uint256 31 | gauge: Bytes! # address 32 | incentive: Incentive! 33 | maxPerVote: BigInt! # uint256 34 | blockNumber: BigInt! 35 | blockTimestamp: BigInt! 36 | transactionHash: Bytes! 37 | } 38 | 39 | type NewIncentive @entity(immutable: true) { 40 | id: ID! 41 | index: BigInt! 42 | token: Bytes! # address 43 | amount: BigInt! # uint256 44 | round: BigInt! # uint256 45 | gauge: Bytes! # address 46 | maxPerVote: BigInt! # uint256 47 | depositor: Bytes! # address 48 | recycled: Boolean! # bool 49 | incentive: Incentive! 50 | blockNumber: BigInt! 51 | blockTimestamp: BigInt! 52 | transactionHash: Bytes! 53 | } 54 | 55 | 56 | type WithdrawUnprocessed @entity(immutable: true) { 57 | id: ID! 58 | index: BigInt! 59 | round: BigInt! # uint256 60 | gauge: Bytes! # address 61 | amount: BigInt! # uint256 62 | incentive: Incentive! 63 | blockNumber: BigInt! 64 | blockTimestamp: BigInt! 65 | transactionHash: Bytes! 66 | } 67 | 68 | type UpdatedFee @entity(immutable: true) { 69 | id: ID! 70 | amount: BigInt! # uint256 71 | blockNumber: BigInt! 72 | blockTimestamp: BigInt! 73 | transactionHash: Bytes! 74 | } 75 | -------------------------------------------------------------------------------- /subgraphs/votiumv2/src/mapping.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IncreasedIncentive as IncreasedIncentiveEvent, 3 | NewIncentive as NewIncentiveEvent, 4 | UpdatedFee as UpdatedFeeEvent, 5 | WithdrawUnprocessed as WithdrawUnprocessedEvent, 6 | } from '../generated/VotiumV2/VotiumV2' 7 | import { 8 | Incentive, 9 | IncreasedIncentive, 10 | NewIncentive, 11 | Round, 12 | UpdatedFee, 13 | WithdrawUnprocessed, 14 | } from '../generated/schema' 15 | import { BigInt } from '@graphprotocol/graph-ts' 16 | 17 | export function getRound(roundNumber: BigInt, timestamp: BigInt): Round { 18 | let round = Round.load(roundNumber.toString()) 19 | if (!round) { 20 | round = new Round(roundNumber.toString()) 21 | round.bribeCount = BigInt.zero() 22 | round.initiatedAt = timestamp 23 | round.save() 24 | } 25 | return round 26 | } 27 | 28 | export function getIncentive(gauge: string, round: string, index: string, timestamp: BigInt): Incentive { 29 | let incentive = Incentive.load(gauge + '-' + round + '-' + index) 30 | if (!incentive) { 31 | incentive = new Incentive(gauge + '-' + round + '-' + index) 32 | incentive.createdAt = timestamp 33 | } 34 | return incentive 35 | } 36 | 37 | export function handleIncreasedIncentive(event: IncreasedIncentiveEvent): void { 38 | const increase = new IncreasedIncentive(event.transaction.hash.toHexString() + event.logIndex.toString()) 39 | const incentive = getIncentive( 40 | event.params._gauge.toHexString(), 41 | event.params._round.toString(), 42 | event.params._index.toString(), 43 | event.block.timestamp 44 | ) 45 | 46 | increase.token = event.params._token 47 | increase.total = event.params._total 48 | increase.increase = event.params._increase 49 | increase.round = event.params._round 50 | increase.gauge = event.params._gauge 51 | increase.maxPerVote = event.params._maxPerVote 52 | increase.incentive = incentive.id 53 | 54 | increase.blockNumber = event.block.number 55 | increase.blockTimestamp = event.block.timestamp 56 | increase.transactionHash = event.transaction.hash 57 | 58 | incentive.amount = incentive.amount.plus(increase.increase) 59 | incentive.updatedAt = event.block.timestamp 60 | 61 | incentive.save() 62 | increase.save() 63 | } 64 | 65 | export function handleNewIncentive(event: NewIncentiveEvent): void { 66 | const newIncentive = new NewIncentive(event.transaction.hash.toHexString() + event.logIndex.toString()) 67 | const incentive = getIncentive( 68 | event.params._gauge.toHexString(), 69 | event.params._round.toString(), 70 | event.params._index.toString(), 71 | event.block.timestamp 72 | ) 73 | const round = getRound(event.params._round, event.block.timestamp) 74 | round.bribeCount = round.bribeCount.plus(BigInt.fromI32(1)) 75 | round.save() 76 | 77 | newIncentive.index = event.params._index 78 | newIncentive.token = event.params._token 79 | newIncentive.amount = event.params._amount 80 | newIncentive.depositor = event.params._depositor 81 | newIncentive.round = event.params._round 82 | newIncentive.gauge = event.params._gauge 83 | newIncentive.maxPerVote = event.params._maxPerVote 84 | newIncentive.recycled = event.params._recycled 85 | newIncentive.incentive = incentive.id 86 | 87 | newIncentive.blockNumber = event.block.number 88 | newIncentive.blockTimestamp = event.block.timestamp 89 | newIncentive.transactionHash = event.transaction.hash 90 | 91 | incentive.token = event.params._token 92 | incentive.amount = event.params._amount 93 | incentive.index = event.params._index 94 | incentive.round = round.id 95 | incentive.gauge = event.params._gauge 96 | incentive.maxPerVote = event.params._maxPerVote 97 | incentive.save() 98 | newIncentive.save() 99 | } 100 | 101 | export function handleUpdatedFee(event: UpdatedFeeEvent): void { 102 | const feeUpdate = new UpdatedFee(event.transaction.hash.toHexString() + '-' + event.logIndex.toString()) 103 | 104 | feeUpdate.amount = event.params._feeAmount 105 | 106 | feeUpdate.blockNumber = event.block.number 107 | feeUpdate.blockTimestamp = event.block.timestamp 108 | feeUpdate.transactionHash = event.transaction.hash 109 | 110 | feeUpdate.save() 111 | } 112 | 113 | export function handleWithdrawUnprocessed(event: WithdrawUnprocessedEvent): void { 114 | const withdrawal = new WithdrawUnprocessed(event.transaction.hash.toHexString() + event.logIndex.toString()) 115 | withdrawal.round = event.params._round 116 | withdrawal.gauge = event.params._gauge 117 | withdrawal.index = event.params._index 118 | withdrawal.amount = event.params._amount 119 | 120 | withdrawal.blockNumber = event.block.number 121 | withdrawal.blockTimestamp = event.block.timestamp 122 | withdrawal.transactionHash = event.transaction.hash 123 | 124 | const incentive = getIncentive( 125 | event.params._gauge.toHexString(), 126 | event.params._round.toString(), 127 | event.params._index.toString(), 128 | event.block.timestamp 129 | ) 130 | incentive.amount = incentive.amount.minus(withdrawal.amount) 131 | incentive.updatedAt = event.block.timestamp 132 | withdrawal.incentive = incentive.id 133 | incentive.save() 134 | withdrawal.save() 135 | } 136 | -------------------------------------------------------------------------------- /subgraphs/votiumv2/subgraph.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.5 2 | schema: 3 | file: ./schema.graphql 4 | dataSources: 5 | - kind: ethereum 6 | name: VotiumV2 7 | network: mainnet 8 | source: 9 | address: "0x63942E31E98f1833A234077f47880A66136a2D1e" 10 | abi: VotiumV2 11 | startBlock: 17862211 12 | mapping: 13 | kind: ethereum/events 14 | apiVersion: 0.0.7 15 | language: wasm/assemblyscript 16 | entities: 17 | - IncreasedIncentive 18 | - NewIncentive 19 | - Incentive 20 | - Round 21 | - UpdatedFee 22 | - WithdrawUnprocessed 23 | abis: 24 | - name: VotiumV2 25 | file: ./abis/VotiumV2.json 26 | eventHandlers: 27 | - event: IncreasedIncentive(uint256,address,uint256,uint256,indexed uint256,indexed address,uint256) 28 | handler: handleIncreasedIncentive 29 | - event: NewIncentive(uint256,address,uint256,indexed uint256,indexed address,uint256,address[],indexed address,bool) 30 | handler: handleNewIncentive 31 | - event: UpdatedFee(uint256) 32 | handler: handleUpdatedFee 33 | - event: WithdrawUnprocessed(uint256,uint256,address,uint256) 34 | handler: handleWithdrawUnprocessed 35 | file: ./src/mapping.ts 36 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/@graphprotocol/graph-ts/tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["@graphprotocol/graph-ts"] 5 | } 6 | } --------------------------------------------------------------------------------