From 522134caa7573ff581a5ebad9d407334226445aa Mon Sep 17 00:00:00 2001 From: aalavandhann <6264334+aalavandhan@users.noreply.github.com> Date: Fri, 17 May 2024 09:52:00 -0400 Subject: [PATCH] added subgraph to track charm vault --- package.json | 3 +- spot-staking-subgraph/.gitignore | 2 + spot-staking-subgraph/.prettierrc | 7 + spot-staking-subgraph/README.md | 15 + spot-staking-subgraph/abis/CharmVault.json | 1 + spot-staking-subgraph/abis/ERC20.json | 222 +++++++++++ spot-staking-subgraph/abis/RebasingERC20.json | 344 ++++++++++++++++++ spot-staking-subgraph/abis/UniV3Pool.json | 1 + spot-staking-subgraph/package.json | 26 ++ spot-staking-subgraph/schema.graphql | 47 +++ spot-staking-subgraph/src/mappings.ts | 211 +++++++++++ spot-staking-subgraph/subgraph.yaml | 36 ++ subgraph.yaml | 3 - yarn.lock | 16 + 14 files changed, 930 insertions(+), 4 deletions(-) create mode 100644 spot-staking-subgraph/.gitignore create mode 100644 spot-staking-subgraph/.prettierrc create mode 100644 spot-staking-subgraph/README.md create mode 100644 spot-staking-subgraph/abis/CharmVault.json create mode 100644 spot-staking-subgraph/abis/ERC20.json create mode 100644 spot-staking-subgraph/abis/RebasingERC20.json create mode 100644 spot-staking-subgraph/abis/UniV3Pool.json create mode 100644 spot-staking-subgraph/package.json create mode 100644 spot-staking-subgraph/schema.graphql create mode 100644 spot-staking-subgraph/src/mappings.ts create mode 100644 spot-staking-subgraph/subgraph.yaml delete mode 100644 subgraph.yaml diff --git a/package.json b/package.json index cd67320c..23740951 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "packageManager": "yarn@3.2.1", "workspaces": [ "spot-contracts", - "spot-subgraph" + "spot-subgraph", + "spot-staking-subgraph" ] } diff --git a/spot-staking-subgraph/.gitignore b/spot-staking-subgraph/.gitignore new file mode 100644 index 00000000..d42a8246 --- /dev/null +++ b/spot-staking-subgraph/.gitignore @@ -0,0 +1,2 @@ +build +generated \ No newline at end of file diff --git a/spot-staking-subgraph/.prettierrc b/spot-staking-subgraph/.prettierrc new file mode 100644 index 00000000..e02a9cfb --- /dev/null +++ b/spot-staking-subgraph/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": false, + "trailingComma": "all", + "singleQuote": true, + "bracketSpacing": true, + "printWidth": 99 +} diff --git a/spot-staking-subgraph/README.md b/spot-staking-subgraph/README.md new file mode 100644 index 00000000..5a04bb42 --- /dev/null +++ b/spot-staking-subgraph/README.md @@ -0,0 +1,15 @@ +# spot-staking-subgraph + +Ancillary subgraphs to keep track of spot staking. + + +``` +yarn codegen + +yarn build + +yarn graph deploy spot-staking \ + --node https://subgraphs.alchemy.com/api/subgraphs/deploy \ + --deploy-key $GRAPH_AUTH \ + --ipfs https://ipfs.satsuma.xyz +``` \ No newline at end of file diff --git a/spot-staking-subgraph/abis/CharmVault.json b/spot-staking-subgraph/abis/CharmVault.json new file mode 100644 index 00000000..56df03b3 --- /dev/null +++ b/spot-staking-subgraph/abis/CharmVault.json @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feesToVault0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesToVault1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesToProtocol0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesToProtocol1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesToManager0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesToManager1","type":"uint256"}],"name":"CollectFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"CollectManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"CollectProtocol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int24","name":"tick","type":"int24"},{"indexed":false,"internalType":"uint256","name":"totalAmount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalAmount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"Snapshot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int24","name":"threshold","type":"int24"}],"name":"UpdateBaseThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint24","name":"weight","type":"uint24"}],"name":"UpdateFullRangeWeight","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int24","name":"threshold","type":"int24"}],"name":"UpdateLimitThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"manager","type":"address"}],"name":"UpdateManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint24","name":"managerFee","type":"uint24"}],"name":"UpdateManagerFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxTotalSupply","type":"uint256"}],"name":"UpdateMaxTotalSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int24","name":"maxTwapDeviation","type":"int24"}],"name":"UpdateMaxTwapDeviation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int24","name":"minTickMove","type":"int24"}],"name":"UpdateMinTickMove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"manager","type":"address"}],"name":"UpdatePendingManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"period","type":"uint32"}],"name":"UpdatePeriod","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"delegate","type":"address"}],"name":"UpdateRebalanceDelegate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"twapDuration","type":"uint32"}],"name":"UpdateTwapDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accruedManagerFees0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accruedManagerFees1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accruedProtocolFees0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accruedProtocolFees1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseThreshold","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkCanRebalance","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"collectManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"collectProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"name":"emergencyBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract AlphaProVaultFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullRangeWeight","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fullUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"}],"name":"getPositionAmounts","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAmounts","outputs":[{"internalType":"uint256","name":"total0","type":"uint256"},{"internalType":"uint256","name":"total1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTwap","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"uint24","name":"managerFee","type":"uint24"},{"internalType":"address","name":"rebalanceDelegate","type":"address"},{"internalType":"uint256","name":"maxTotalSupply","type":"uint256"},{"internalType":"int24","name":"baseThreshold","type":"int24"},{"internalType":"int24","name":"limitThreshold","type":"int24"},{"internalType":"uint24","name":"fullRangeWeight","type":"uint24"},{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"int24","name":"minTickMove","type":"int24"},{"internalType":"int24","name":"maxTwapDeviation","type":"int24"},{"internalType":"uint32","name":"twapDuration","type":"uint32"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"internalType":"struct VaultParams","name":"_params","type":"tuple"},{"internalType":"address","name":"_factory","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTick","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitThreshold","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"managerFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTwapDeviation","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minTickMove","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingManagerFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"period","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IUniswapV3Pool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebalanceDelegate","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"_baseThreshold","type":"int24"}],"name":"setBaseThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_fullRangeWeight","type":"uint24"}],"name":"setFullRangeWeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int24","name":"_limitThreshold","type":"int24"}],"name":"setLimitThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_pendingManagerFee","type":"uint24"}],"name":"setManagerFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxTotalSupply","type":"uint256"}],"name":"setMaxTotalSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int24","name":"_maxTwapDeviation","type":"int24"}],"name":"setMaxTwapDeviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int24","name":"_minTickMove","type":"int24"}],"name":"setMinTickMove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_period","type":"uint32"}],"name":"setPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rebalanceDelegate","type":"address"}],"name":"setRebalanceDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_twapDuration","type":"uint32"}],"name":"setTwapDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tickSpacing","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapDuration","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uniswapV3MintCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/spot-staking-subgraph/abis/ERC20.json b/spot-staking-subgraph/abis/ERC20.json new file mode 100644 index 00000000..405d6b36 --- /dev/null +++ b/spot-staking-subgraph/abis/ERC20.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] diff --git a/spot-staking-subgraph/abis/RebasingERC20.json b/spot-staking-subgraph/abis/RebasingERC20.json new file mode 100644 index 00000000..09bb9cb7 --- /dev/null +++ b/spot-staking-subgraph/abis/RebasingERC20.json @@ -0,0 +1,344 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newScalar", + "type": "uint256" + } + ], + "name": "Rebase", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "epoch", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalSupply", + "type": "uint256" + } + ], + "name": "LogRebase", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rebase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "who", + "type": "address" + } + ], + "name": "scaledBalanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "scaledTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "transferAllFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/spot-staking-subgraph/abis/UniV3Pool.json b/spot-staking-subgraph/abis/UniV3Pool.json new file mode 100644 index 00000000..bd99dfb4 --- /dev/null +++ b/spot-staking-subgraph/abis/UniV3Pool.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"amount0","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"amount1","type":"uint128"}],"name":"Collect","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount0","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"amount1","type":"uint128"}],"name":"CollectProtocol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paid0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paid1","type":"uint256"}],"name":"Flash","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"observationCardinalityNextOld","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"observationCardinalityNextNew","type":"uint16"}],"name":"IncreaseObservationCardinalityNext","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"indexed":false,"internalType":"int24","name":"tick","type":"int24"}],"name":"Initialize","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"feeProtocol0Old","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"feeProtocol1Old","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"feeProtocol0New","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"feeProtocol1New","type":"uint8"}],"name":"SetFeeProtocol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"int256","name":"amount0","type":"int256"},{"indexed":false,"internalType":"int256","name":"amount1","type":"int256"},{"indexed":false,"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"indexed":false,"internalType":"uint128","name":"liquidity","type":"uint128"},{"indexed":false,"internalType":"int24","name":"tick","type":"int24"}],"name":"Swap","type":"event"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"amount0Requested","type":"uint128"},{"internalType":"uint128","name":"amount1Requested","type":"uint128"}],"name":"collect","outputs":[{"internalType":"uint128","name":"amount0","type":"uint128"},{"internalType":"uint128","name":"amount1","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint128","name":"amount0Requested","type":"uint128"},{"internalType":"uint128","name":"amount1Requested","type":"uint128"}],"name":"collectProtocol","outputs":[{"internalType":"uint128","name":"amount0","type":"uint128"},{"internalType":"uint128","name":"amount1","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeGrowthGlobal0X128","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeGrowthGlobal1X128","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"observationCardinalityNext","type":"uint16"}],"name":"increaseObservationCardinalityNext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"liquidity","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLiquidityPerTick","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint32","name":"blockTimestamp","type":"uint32"},{"internalType":"int56","name":"tickCumulative","type":"int56"},{"internalType":"uint160","name":"secondsPerLiquidityCumulativeX128","type":"uint160"},{"internalType":"bool","name":"initialized","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"secondsAgos","type":"uint32[]"}],"name":"observe","outputs":[{"internalType":"int56[]","name":"tickCumulatives","type":"int56[]"},{"internalType":"uint160[]","name":"secondsPerLiquidityCumulativeX128s","type":"uint160[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"positions","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"feeGrowthInside0LastX128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthInside1LastX128","type":"uint256"},{"internalType":"uint128","name":"tokensOwed0","type":"uint128"},{"internalType":"uint128","name":"tokensOwed1","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFees","outputs":[{"internalType":"uint128","name":"token0","type":"uint128"},{"internalType":"uint128","name":"token1","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"feeProtocol0","type":"uint8"},{"internalType":"uint8","name":"feeProtocol1","type":"uint8"}],"name":"setFeeProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slot0","outputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tick","type":"int24"},{"internalType":"uint16","name":"observationIndex","type":"uint16"},{"internalType":"uint16","name":"observationCardinality","type":"uint16"},{"internalType":"uint16","name":"observationCardinalityNext","type":"uint16"},{"internalType":"uint8","name":"feeProtocol","type":"uint8"},{"internalType":"bool","name":"unlocked","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"}],"name":"snapshotCumulativesInside","outputs":[{"internalType":"int56","name":"tickCumulativeInside","type":"int56"},{"internalType":"uint160","name":"secondsPerLiquidityInsideX128","type":"uint160"},{"internalType":"uint32","name":"secondsInside","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"zeroForOne","type":"bool"},{"internalType":"int256","name":"amountSpecified","type":"int256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[{"internalType":"int256","name":"amount0","type":"int256"},{"internalType":"int256","name":"amount1","type":"int256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int16","name":"","type":"int16"}],"name":"tickBitmap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tickSpacing","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"","type":"int24"}],"name":"ticks","outputs":[{"internalType":"uint128","name":"liquidityGross","type":"uint128"},{"internalType":"int128","name":"liquidityNet","type":"int128"},{"internalType":"uint256","name":"feeGrowthOutside0X128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthOutside1X128","type":"uint256"},{"internalType":"int56","name":"tickCumulativeOutside","type":"int56"},{"internalType":"uint160","name":"secondsPerLiquidityOutsideX128","type":"uint160"},{"internalType":"uint32","name":"secondsOutside","type":"uint32"},{"internalType":"bool","name":"initialized","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/spot-staking-subgraph/package.json b/spot-staking-subgraph/package.json new file mode 100644 index 00000000..8af2db64 --- /dev/null +++ b/spot-staking-subgraph/package.json @@ -0,0 +1,26 @@ +{ + "name": "@ampleforthorg/spot-staking-subgraph", + "version": "1.0.0", + "license": "GPL-3.0-or-later", + "scripts": { + "auth": "graph auth --studio", + "codegen": "graph codegen --output-dir ./generated", + "build": "graph build", + "lint": "yarn prettier --config .prettierrc --write '**/*.ts'", + "create-local": "graph create --node http://localhost:8020/ ampleforth/spot-staking", + "remove-local": "graph remove --node http://localhost:8020/ ampleforth/spot-staking", + "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 ampleforth/spot-staking", + "test": "echo 'TO_BE_IMPL'" + }, + "devDependencies": { + "@graphprotocol/graph-cli": "^0.21.1", + "@graphprotocol/graph-ts": "^0.20.0", + "@typescript-eslint/eslint-plugin": "^2.0.0", + "@typescript-eslint/parser": "^2.0.0", + "eslint": "^6.2.2", + "eslint-config-prettier": "^6.1.0", + "mustache": "^4.2.0", + "prettier": "^1.18.2", + "typescript": "^3.5.2" + } +} diff --git a/spot-staking-subgraph/schema.graphql b/spot-staking-subgraph/schema.graphql new file mode 100644 index 00000000..82f2139a --- /dev/null +++ b/spot-staking-subgraph/schema.graphql @@ -0,0 +1,47 @@ +type CharmVault @entity { + " the vault address " + id: ID! + pool: String! + name: String! + symbol: String! + decimals: BigInt! + token0: String! + token0Name: String! + token0Symbol: String! + token0Decimals: BigInt! + token1: String! + token1Name: String! + token1Symbol: String! + token1Decimals: BigInt! + token0Bal: BigDecimal! + token1Bal: BigDecimal! + token0BalIn: BigDecimal! + token1BalIn: BigDecimal! + token0Price: BigDecimal! + token1Price: BigDecimal! + tvl: BigDecimal! + valueIn: BigDecimal! + price: BigDecimal! + totalSupply: BigDecimal! + unusedToken0Bal: BigDecimal! + unusedToken1Bal: BigDecimal! + unusedTVL: BigDecimal! + dailyStats: [CharmVaultDailyStat!]! @derivedFrom(field: "vault") +} + +type CharmVaultDailyStat @entity { + "-" + id: ID! + vault: CharmVault! + timestamp: BigInt! + token0Bal: BigDecimal! + token1Bal: BigDecimal! + token0BalIn: BigDecimal! + token1BalIn: BigDecimal! + token0Price: BigDecimal! + token1Price: BigDecimal! + tvl: BigDecimal! + valueIn: BigDecimal! + price: BigDecimal! + totalSupply: BigDecimal! +} \ No newline at end of file diff --git a/spot-staking-subgraph/src/mappings.ts b/spot-staking-subgraph/src/mappings.ts new file mode 100644 index 00000000..04f41d72 --- /dev/null +++ b/spot-staking-subgraph/src/mappings.ts @@ -0,0 +1,211 @@ +import { log, ethereum, BigInt, BigDecimal, Address } from '@graphprotocol/graph-ts' +import { Deposit, Withdraw, Snapshot } from '../generated/CharmVault/CharmVault' +import { CharmVault as CharmVaultABI } from '../generated/CharmVault/CharmVault' +import { UniV3Pool as UniV3PoolABI } from '../generated/CharmVault/UniV3Pool' +import { ERC20 as ERC20ABI } from '../generated/CharmVault/ERC20' +import { CharmVault, CharmVaultDailyStat } from '../generated/schema' + +let BIGINT_ZERO = BigInt.fromI32(0) +let BIGDECIMAL_ZERO = BigDecimal.fromString('0') +let BIGDECIMAL_ONE = BigDecimal.fromString('1') + +let BLOCK_UPDATE_INTERVAL = BigInt.fromI32(240) +let CHARM_VAULT_ID = '0x2dcaff0f75765d7867887fc402b71c841b3a4bfb' + +const dayTimestamp = (timestamp: BigInt): BigInt => { + return timestamp.minus(timestamp % BigInt.fromI32(24 * 3600)) +} +const stringToAddress = (id: string): Address => { + return Address.fromString(id) +} +const formatBalance = (wei: BigInt, decimals: BigInt): BigDecimal => { + return wei.toBigDecimal().div( + BigInt.fromI32(10) + .pow(decimals.toI32() as u8) + .toBigDecimal(), + ) +} + +// https://github.com/Uniswap/v3-subgraph/blob/main/src/utils/index.ts#L30 +function exponentToBigDecimal(decimals: BigInt): BigDecimal { + let resultString = '1' + for (let i = 0; i < decimals.toI32(); i++) { + resultString += '0' + } + return BigDecimal.fromString(resultString) +} +function safeDiv(amount0: BigDecimal, amount1: BigDecimal): BigDecimal { + if (amount1.equals(BIGDECIMAL_ZERO)) { + return BIGDECIMAL_ZERO + } else { + return amount0.div(amount1) + } +} +function sqrtPriceX96ToTokenPrices( + sqrtPriceX96: BigInt, + token0Decimals: BigInt, + token1Decimals: BigInt, +): BigDecimal[] { + let Q192 = BigInt.fromI32(2).pow(192 as u8) + let num = sqrtPriceX96.times(sqrtPriceX96).toBigDecimal() + let denom = BigDecimal.fromString(Q192.toString()) + let price1 = num + .div(denom) + .times(exponentToBigDecimal(token0Decimals)) + .div(exponentToBigDecimal(token1Decimals)) + let price0 = safeDiv(BigDecimal.fromString('1'), price1) + return [price0, price1] +} + +function fetchCharmVault(address: Address): CharmVault { + let id = address.toHexString() + let vault = CharmVault.load(id) + if (vault === null) { + vault = new CharmVault(id) + let vaultContract = CharmVaultABI.bind(address) + vault.pool = vaultContract.pool().toHexString() + vault.name = vaultContract.name() + vault.symbol = vaultContract.symbol() + vault.decimals = BigInt.fromI32(vaultContract.decimals()) + + let token0Address = vaultContract.token0() + let token0Contract = ERC20ABI.bind(token0Address) + vault.token0 = token0Address.toHexString() + vault.token0Name = token0Contract.name() + vault.token0Symbol = token0Contract.symbol() + vault.token0Decimals = BigInt.fromI32(token0Contract.decimals()) + + let token1Address = vaultContract.token1() + let token1Contract = ERC20ABI.bind(token1Address) + vault.token1 = token1Address.toHexString() + vault.token1Name = token1Contract.name() + vault.token1Symbol = token1Contract.symbol() + vault.token1Decimals = BigInt.fromI32(token1Contract.decimals()) + + vault.token0Bal = BIGDECIMAL_ZERO + vault.token1Bal = BIGDECIMAL_ZERO + vault.token0BalIn = BIGDECIMAL_ZERO + vault.token1BalIn = BIGDECIMAL_ZERO + vault.token0Price = BIGDECIMAL_ZERO + vault.token1Price = BIGDECIMAL_ZERO + vault.tvl = BIGDECIMAL_ZERO + vault.valueIn = BIGDECIMAL_ZERO + vault.price = BIGDECIMAL_ZERO + vault.totalSupply = BIGDECIMAL_ZERO + vault.unusedToken0Bal = BIGDECIMAL_ZERO + vault.unusedToken1Bal = BIGDECIMAL_ZERO + vault.unusedTVL = BIGDECIMAL_ZERO + vault.save() + } + return vault as CharmVault +} + +function fetchCharmVaultDailyStat(vault: CharmVault, timestamp: BigInt): CharmVaultDailyStat { + let id = vault.id.concat('-').concat(timestamp.toString()) + let dailyStat = CharmVaultDailyStat.load(id) + if (dailyStat === null) { + dailyStat = new CharmVaultDailyStat(id) + dailyStat.vault = vault.id + dailyStat.timestamp = timestamp + dailyStat.token0Bal = BIGDECIMAL_ZERO + dailyStat.token1Bal = BIGDECIMAL_ZERO + dailyStat.token0BalIn = BIGDECIMAL_ZERO + dailyStat.token1BalIn = BIGDECIMAL_ZERO + dailyStat.token0Price = BIGDECIMAL_ZERO + dailyStat.token1Price = BIGDECIMAL_ZERO + dailyStat.tvl = BIGDECIMAL_ZERO + dailyStat.valueIn = BIGDECIMAL_ZERO + dailyStat.price = BIGDECIMAL_ZERO + dailyStat.totalSupply = BIGDECIMAL_ZERO + dailyStat.save() + } + return dailyStat as CharmVaultDailyStat +} + +function refreshCharmVaultStats(vault: CharmVault, dailyStat: CharmVaultDailyStat): void { + let vaultContract = CharmVaultABI.bind(stringToAddress(vault.id)) + let tokenBals = vaultContract.getTotalAmounts() + let uniPoolContract = UniV3PoolABI.bind(stringToAddress(vault.pool)) + let slot0 = uniPoolContract.slot0() + let sqrtPrice = slot0.value0 + let prices = sqrtPriceX96ToTokenPrices(sqrtPrice, vault.token0Decimals, vault.token1Decimals) + + vault.token0Bal = formatBalance(tokenBals.value0, vault.token0Decimals) + vault.token1Bal = formatBalance(tokenBals.value1, vault.token1Decimals) + vault.token0Price = prices[0] + vault.token1Price = prices[1] + vault.tvl = vault.token0Bal.plus(vault.token1Bal.times(vault.token0Price)) + vault.totalSupply = formatBalance(vaultContract.totalSupply(), vault.decimals) + vault.price = vault.tvl.div(vault.totalSupply) + vault.unusedToken0Bal = formatBalance(vaultContract.getBalance0(), vault.token0Decimals) + vault.unusedToken1Bal = formatBalance(vaultContract.getBalance1(), vault.token1Decimals) + vault.unusedTVL = vault.unusedToken0Bal.plus(vault.unusedToken1Bal.times(vault.token0Price)) + vault.save() + + dailyStat.token0Bal = vault.token0Bal + dailyStat.token1Bal = vault.token1Bal + dailyStat.token0Price = vault.token0Price + dailyStat.token1Price = vault.token1Price + dailyStat.tvl = vault.tvl + dailyStat.totalSupply = vault.totalSupply + dailyStat.price = vault.price + dailyStat.save() +} + +export function handleDeposit(event: Deposit): void { + log.debug('triggered deposit', []) + let vault = fetchCharmVault(event.address) + let dailyStat = fetchCharmVaultDailyStat(vault, dayTimestamp(event.block.timestamp)) + refreshCharmVaultStats(vault, dailyStat) + vault.token0BalIn = vault.token0BalIn.plus( + formatBalance(event.params.amount0, vault.token0Decimals), + ) + vault.token1BalIn = vault.token1BalIn.plus( + formatBalance(event.params.amount1, vault.token1Decimals), + ) + vault.valueIn = vault.token0BalIn.plus(vault.token1BalIn.times(vault.token0Price)) + vault.save() + + dailyStat.token0BalIn = vault.token0BalIn + dailyStat.token1BalIn = vault.token1BalIn + dailyStat.valueIn = vault.valueIn + dailyStat.save() +} + +export function handleWithdraw(event: Withdraw): void { + log.debug('triggered withdraw', []) + let vault = fetchCharmVault(event.address) + let dailyStat = fetchCharmVaultDailyStat(vault, dayTimestamp(event.block.timestamp)) + refreshCharmVaultStats(vault, dailyStat) + vault.token0BalIn = vault.token0BalIn.minus( + formatBalance(event.params.amount0, vault.token0Decimals), + ) + vault.token1BalIn = vault.token1BalIn.minus( + formatBalance(event.params.amount1, vault.token1Decimals), + ) + vault.valueIn = vault.token0BalIn.plus(vault.token1BalIn.times(vault.token0Price)) + vault.save() + + dailyStat.token0BalIn = vault.token0BalIn + dailyStat.token1BalIn = vault.token1BalIn + dailyStat.valueIn = vault.valueIn + dailyStat.save() + dailyStat.save() +} + +export function handleSnapshot(event: Snapshot): void { + log.debug('triggered snapshot', []) + let vault = fetchCharmVault(event.address) + let dailyStat = fetchCharmVaultDailyStat(vault, dayTimestamp(event.block.timestamp)) + refreshCharmVaultStats(vault, dailyStat) +} + +export function refreshStore(block: ethereum.Block): void { + let timeForUpdate = block.number.mod(BLOCK_UPDATE_INTERVAL).equals(BIGINT_ZERO) + if (timeForUpdate) { + log.debug('triggered store refresh', []) + let vault = fetchCharmVault(stringToAddress(CHARM_VAULT_ID)) + let dailyStat = fetchCharmVaultDailyStat(vault, dayTimestamp(block.timestamp)) + refreshCharmVaultStats(vault, dailyStat) + } +} diff --git a/spot-staking-subgraph/subgraph.yaml b/spot-staking-subgraph/subgraph.yaml new file mode 100644 index 00000000..4481e065 --- /dev/null +++ b/spot-staking-subgraph/subgraph.yaml @@ -0,0 +1,36 @@ +specVersion: 0.0.4 +description: Subgraph to keep track of spot staking +repository: http://github.com/ampleforth/spot +schema: + file: ./schema.graphql +dataSources: + - kind: ethereum/contract + name: CharmVault + network: mainnet + source: + address: "0x2dcaff0f75765d7867887fc402b71c841b3a4bfb" + abi: CharmVault + startBlock: 19792510 + mapping: + kind: ethereum/events + apiVersion: 0.0.4 + language: wasm/assemblyscript + entities: + - CharmVault + - UniV3Pool + - ERC20 + abis: + - name: CharmVault + file: ./abis/CharmVault.json + - name: UniV3Pool + file: ./abis/UniV3Pool.json + - name: ERC20 + file: ./abis/ERC20.json + eventHandlers: + - event: Deposit(indexed address,indexed address,uint256,uint256,uint256) + handler: handleDeposit + - event: Withdraw(indexed address,indexed address,uint256,uint256,uint256) + handler: handleWithdraw + - event: Snapshot(int24,uint256,uint256,uint256) + handler: handleSnapshot + file: ./src/mappings.ts \ No newline at end of file diff --git a/subgraph.yaml b/subgraph.yaml deleted file mode 100644 index 3d981a92..00000000 --- a/subgraph.yaml +++ /dev/null @@ -1,3 +0,0 @@ -Usage Error: Couldn't find a script named "mustache". - -$ yarn run [--inspect] [--inspect-brk] [-T,--top-level] [-B,--binaries-only] ... diff --git a/yarn.lock b/yarn.lock index b576ca51..ba4c0fe0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -71,6 +71,22 @@ __metadata: languageName: unknown linkType: soft +"@ampleforthorg/spot-staking-subgraph@workspace:spot-staking-subgraph": + version: 0.0.0-use.local + resolution: "@ampleforthorg/spot-staking-subgraph@workspace:spot-staking-subgraph" + dependencies: + "@graphprotocol/graph-cli": ^0.21.1 + "@graphprotocol/graph-ts": ^0.20.0 + "@typescript-eslint/eslint-plugin": ^2.0.0 + "@typescript-eslint/parser": ^2.0.0 + eslint: ^6.2.2 + eslint-config-prettier: ^6.1.0 + mustache: ^4.2.0 + prettier: ^1.18.2 + typescript: ^3.5.2 + languageName: unknown + linkType: soft + "@ampleforthorg/spot-subgraph@workspace:spot-subgraph": version: 0.0.0-use.local resolution: "@ampleforthorg/spot-subgraph@workspace:spot-subgraph"