Compare commits

1 Commits
main ... main

Author SHA1 Message Date
913eb3ad4e Add more Governance & Relayer Registry handlers 2025-07-06 13:57:50 +00:00
23 changed files with 6794 additions and 2539 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Tornado Cash
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

142
QUERY.md Normal file
View File

@@ -0,0 +1,142 @@
{
statsHourlies(first: 5, orderBy: timestamp, orderDirection: desc) {
id
timestamp
blockNumber
ethUsdPrice
tornUsdPrice
totalSupply
lockedSupply
burnedSupply
rewardedSupply
}
stakeBurns(first: 5, orderBy: timestamp, orderDirection: desc) {
id
timestamp
blockNumber
logIndex
transactionHash
relayer
amountBurned
amountBurnedUSD
instance
relayerFee
}
stakeDailyBurns(first:5, orderBy: date, orderDirection: desc) {
id
date
dailyAmountBurned
dailyAmountBurnedUSD
}
balances(first: 5, orderBy: balance, orderDirection: desc) {
id
address
balance
lockedBalance
claimedRewards
}
transfers(first: 5, orderBy: value, orderDirection: desc) {
id
timestamp
type
from
to
value
usdValue
}
relayers(first:5, orderBy: burnBalance, orderDirection: desc) {
id
address
ensName
ensHash
workers
stakeBalance
burnBalance
blockRegistration
registerTimestamp
registerTx
registerLogIndex
blockUnregisteration
unregisterTimestamp
unregisterTx
unregisterLogIndex
}
withdrawals(first: 5, orderBy: timestamp, orderDirection: desc) {
id
timestamp
blockNumber
logIndex
transactionHash
instance
to
nullifierHash
relayer
fee
}
dataFeeds {
id
name
usdPrice
lastBlock
lastTimestamp
live
deprecatedBlock
}
tornPairs {
id
name
ethPrice
lastBlock
lastTimestamp
}
proposals(first: 5, orderBy: timestamp, orderDirection: desc) {
id
timestamp
proposalId
proposer
target
startTime
endTime
forVotes
againstVotes
description
executed
}
votes(first: 5, orderBy: timestamp, orderDirection: desc) {
id
timestamp
proposalId
voter
support
votes
from
input
}
delegates(first:5) {
id
delegateTx
undelegateTx
account
delegatedTo
delegatedFrom
}
_meta {
block {
number
hash
timestamp
}
deployment
hasIndexingErrors
}
}

41
README.md Normal file
View File

@@ -0,0 +1,41 @@
# Tornado Governance Subgraph
Tornado Cash Governance, Relayer Registry & TORN Subgraph
Designed for replacement of [tornado-relayer-registry-subgraph](https://github.com/tornadocash/tornado-relayer-registry-subgraph)
### About
This subgraph will index Tornado Cash Governance, Relayer Registry & TORN Contract
This subgraph is intended to index lightweight, without requirement of indexing third party contracts or making historic contract calls and thus has no guarantees of accuracy for using those data to calculate APYs, relayer status because those value would be only accurate by static contract calls ( in short we only mimic contract's flow and credit balances ).
This subgraph would likely break when implementation contract is changed by governance vote or when changes from governance proposals doesn't emit contract events correctly. It would be the obligation of the proposer to maintain this subgraph to match values.
### Features
+ Integrated features of [tornado-relayer-registry-subgraph](https://github.com/tornadocash/tornado-relayer-registry-subgraph) with additional properties like staked balance for relayers
+ Using [Chainlink](https://data.chain.link/feeds/ethereum/mainnet/eth-usd) to fetch ETH/USD price (because they would less emit than Uniswap V3 ETH/USDC pair and would be more accurate)
+ Using Uniswap V3 TORN/ETH price because they are also used to calculate relayer fees from governance so it must be accurate
+ Historic Proposals & Votes for Tornado Governance
+ Historic Locks & Reward claims for staking TORN
+ Historic Transfers & Rich List for TORN balance / staking balances
+ Historic TORN price in USD & ETH
+ Historic TORN Staking APYs
+ Historic Relayer Burns ( Can not index if relayer cheats because if it does it wouldn't emit burn events, I would recommend coding custom backend to index those rather than making inefficient subgraph )
Price and TORN supply ( including total locked and burned balances ) are snapshotted hourly basis
For relayer TORN burns they are snapshotted daily basis ( and can be used to build UI or TG bots for TORN APY statistics )
### Getting Started
Refer [./QUERY.md](./QUERY.md) for an example GraphQL query object

View File

@@ -0,0 +1,555 @@
[
{
"inputs": [
{ "internalType": "uint32", "name": "_maximumGasPrice", "type": "uint32" },
{ "internalType": "uint32", "name": "_reasonableGasPrice", "type": "uint32" },
{ "internalType": "uint32", "name": "_microLinkPerEth", "type": "uint32" },
{ "internalType": "uint32", "name": "_linkGweiPerObservation", "type": "uint32" },
{ "internalType": "uint32", "name": "_linkGweiPerTransmission", "type": "uint32" },
{ "internalType": "address", "name": "_link", "type": "address" },
{ "internalType": "int192", "name": "_minAnswer", "type": "int192" },
{ "internalType": "int192", "name": "_maxAnswer", "type": "int192" },
{ "internalType": "contract AccessControllerInterface", "name": "_billingAccessController", "type": "address" },
{ "internalType": "contract AccessControllerInterface", "name": "_requesterAccessController", "type": "address" },
{ "internalType": "uint8", "name": "_decimals", "type": "uint8" },
{ "internalType": "string", "name": "description", "type": "string" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [{ "indexed": false, "internalType": "address", "name": "user", "type": "address" }],
"name": "AddedAccess",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "int256", "name": "current", "type": "int256" },
{ "indexed": true, "internalType": "uint256", "name": "roundId", "type": "uint256" },
{ "indexed": false, "internalType": "uint256", "name": "updatedAt", "type": "uint256" }
],
"name": "AnswerUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "contract AccessControllerInterface", "name": "old", "type": "address" },
{ "indexed": false, "internalType": "contract AccessControllerInterface", "name": "current", "type": "address" }
],
"name": "BillingAccessControllerSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "uint32", "name": "maximumGasPrice", "type": "uint32" },
{ "indexed": false, "internalType": "uint32", "name": "reasonableGasPrice", "type": "uint32" },
{ "indexed": false, "internalType": "uint32", "name": "microLinkPerEth", "type": "uint32" },
{ "indexed": false, "internalType": "uint32", "name": "linkGweiPerObservation", "type": "uint32" },
{ "indexed": false, "internalType": "uint32", "name": "linkGweiPerTransmission", "type": "uint32" }
],
"name": "BillingSet",
"type": "event"
},
{ "anonymous": false, "inputs": [], "name": "CheckAccessDisabled", "type": "event" },
{ "anonymous": false, "inputs": [], "name": "CheckAccessEnabled", "type": "event" },
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "uint32", "name": "previousConfigBlockNumber", "type": "uint32" },
{ "indexed": false, "internalType": "uint64", "name": "configCount", "type": "uint64" },
{ "indexed": false, "internalType": "address[]", "name": "signers", "type": "address[]" },
{ "indexed": false, "internalType": "address[]", "name": "transmitters", "type": "address[]" },
{ "indexed": false, "internalType": "uint8", "name": "threshold", "type": "uint8" },
{ "indexed": false, "internalType": "uint64", "name": "encodedConfigVersion", "type": "uint64" },
{ "indexed": false, "internalType": "bytes", "name": "encoded", "type": "bytes" }
],
"name": "ConfigSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "uint256", "name": "roundId", "type": "uint256" },
{ "indexed": true, "internalType": "address", "name": "startedBy", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "startedAt", "type": "uint256" }
],
"name": "NewRound",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "uint32", "name": "aggregatorRoundId", "type": "uint32" },
{ "indexed": false, "internalType": "int192", "name": "answer", "type": "int192" },
{ "indexed": false, "internalType": "address", "name": "transmitter", "type": "address" },
{ "indexed": false, "internalType": "int192[]", "name": "observations", "type": "int192[]" },
{ "indexed": false, "internalType": "bytes", "name": "observers", "type": "bytes" },
{ "indexed": false, "internalType": "bytes32", "name": "rawReportContext", "type": "bytes32" }
],
"name": "NewTransmission",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address", "name": "transmitter", "type": "address" },
{ "indexed": false, "internalType": "address", "name": "payee", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }
],
"name": "OraclePaid",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "from", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "to", "type": "address" }
],
"name": "OwnershipTransferRequested",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "from", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "to", "type": "address" }
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "transmitter", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "current", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "proposed", "type": "address" }
],
"name": "PayeeshipTransferRequested",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "transmitter", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "previous", "type": "address" },
{ "indexed": true, "internalType": "address", "name": "current", "type": "address" }
],
"name": "PayeeshipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [{ "indexed": false, "internalType": "address", "name": "user", "type": "address" }],
"name": "RemovedAccess",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "contract AccessControllerInterface", "name": "old", "type": "address" },
{ "indexed": false, "internalType": "contract AccessControllerInterface", "name": "current", "type": "address" }
],
"name": "RequesterAccessControllerSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": true, "internalType": "address", "name": "requester", "type": "address" },
{ "indexed": false, "internalType": "bytes16", "name": "configDigest", "type": "bytes16" },
{ "indexed": false, "internalType": "uint32", "name": "epoch", "type": "uint32" },
{ "indexed": false, "internalType": "uint8", "name": "round", "type": "uint8" }
],
"name": "RoundRequested",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "contract AggregatorValidatorInterface",
"name": "previousValidator",
"type": "address"
},
{ "indexed": false, "internalType": "uint32", "name": "previousGasLimit", "type": "uint32" },
{
"indexed": true,
"internalType": "contract AggregatorValidatorInterface",
"name": "currentValidator",
"type": "address"
},
{ "indexed": false, "internalType": "uint32", "name": "currentGasLimit", "type": "uint32" }
],
"name": "ValidatorConfigSet",
"type": "event"
},
{
"inputs": [],
"name": "LINK",
"outputs": [{ "internalType": "contract LinkTokenInterface", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{ "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{
"inputs": [{ "internalType": "address", "name": "_transmitter", "type": "address" }],
"name": "acceptPayeeship",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_user", "type": "address" }],
"name": "addAccess",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "billingAccessController",
"outputs": [{ "internalType": "contract AccessControllerInterface", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "checkEnabled",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "description",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{ "inputs": [], "name": "disableAccessCheck", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{ "inputs": [], "name": "enableAccessCheck", "outputs": [], "stateMutability": "nonpayable", "type": "function" },
{
"inputs": [{ "internalType": "uint256", "name": "_roundId", "type": "uint256" }],
"name": "getAnswer",
"outputs": [{ "internalType": "int256", "name": "", "type": "int256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getBilling",
"outputs": [
{ "internalType": "uint32", "name": "maximumGasPrice", "type": "uint32" },
{ "internalType": "uint32", "name": "reasonableGasPrice", "type": "uint32" },
{ "internalType": "uint32", "name": "microLinkPerEth", "type": "uint32" },
{ "internalType": "uint32", "name": "linkGweiPerObservation", "type": "uint32" },
{ "internalType": "uint32", "name": "linkGweiPerTransmission", "type": "uint32" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint80", "name": "_roundId", "type": "uint80" }],
"name": "getRoundData",
"outputs": [
{ "internalType": "uint80", "name": "roundId", "type": "uint80" },
{ "internalType": "int256", "name": "answer", "type": "int256" },
{ "internalType": "uint256", "name": "startedAt", "type": "uint256" },
{ "internalType": "uint256", "name": "updatedAt", "type": "uint256" },
{ "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "_roundId", "type": "uint256" }],
"name": "getTimestamp",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "_user", "type": "address" },
{ "internalType": "bytes", "name": "_calldata", "type": "bytes" }
],
"name": "hasAccess",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestAnswer",
"outputs": [{ "internalType": "int256", "name": "", "type": "int256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestConfigDetails",
"outputs": [
{ "internalType": "uint32", "name": "configCount", "type": "uint32" },
{ "internalType": "uint32", "name": "blockNumber", "type": "uint32" },
{ "internalType": "bytes16", "name": "configDigest", "type": "bytes16" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestRound",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestRoundData",
"outputs": [
{ "internalType": "uint80", "name": "roundId", "type": "uint80" },
{ "internalType": "int256", "name": "answer", "type": "int256" },
{ "internalType": "uint256", "name": "startedAt", "type": "uint256" },
{ "internalType": "uint256", "name": "updatedAt", "type": "uint256" },
{ "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestTimestamp",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestTransmissionDetails",
"outputs": [
{ "internalType": "bytes16", "name": "configDigest", "type": "bytes16" },
{ "internalType": "uint32", "name": "epoch", "type": "uint32" },
{ "internalType": "uint8", "name": "round", "type": "uint8" },
{ "internalType": "int192", "name": "latestAnswer", "type": "int192" },
{ "internalType": "uint64", "name": "latestTimestamp", "type": "uint64" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "linkAvailableForPayment",
"outputs": [{ "internalType": "int256", "name": "availableBalance", "type": "int256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxAnswer",
"outputs": [{ "internalType": "int192", "name": "", "type": "int192" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "minAnswer",
"outputs": [{ "internalType": "int192", "name": "", "type": "int192" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_signerOrTransmitter", "type": "address" }],
"name": "oracleObservationCount",
"outputs": [{ "internalType": "uint16", "name": "", "type": "uint16" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_transmitter", "type": "address" }],
"name": "owedPayment",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address payable", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_user", "type": "address" }],
"name": "removeAccess",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "requestNewRound",
"outputs": [{ "internalType": "uint80", "name": "", "type": "uint80" }],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "requesterAccessController",
"outputs": [{ "internalType": "contract AccessControllerInterface", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint32", "name": "_maximumGasPrice", "type": "uint32" },
{ "internalType": "uint32", "name": "_reasonableGasPrice", "type": "uint32" },
{ "internalType": "uint32", "name": "_microLinkPerEth", "type": "uint32" },
{ "internalType": "uint32", "name": "_linkGweiPerObservation", "type": "uint32" },
{ "internalType": "uint32", "name": "_linkGweiPerTransmission", "type": "uint32" }
],
"name": "setBilling",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "contract AccessControllerInterface", "name": "_billingAccessController", "type": "address" }
],
"name": "setBillingAccessController",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "_signers", "type": "address[]" },
{ "internalType": "address[]", "name": "_transmitters", "type": "address[]" },
{ "internalType": "uint8", "name": "_threshold", "type": "uint8" },
{ "internalType": "uint64", "name": "_encodedConfigVersion", "type": "uint64" },
{ "internalType": "bytes", "name": "_encoded", "type": "bytes" }
],
"name": "setConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "_transmitters", "type": "address[]" },
{ "internalType": "address[]", "name": "_payees", "type": "address[]" }
],
"name": "setPayees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "contract AccessControllerInterface", "name": "_requesterAccessController", "type": "address" }
],
"name": "setRequesterAccessController",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "contract AggregatorValidatorInterface", "name": "_newValidator", "type": "address" },
{ "internalType": "uint32", "name": "_newGasLimit", "type": "uint32" }
],
"name": "setValidatorConfig",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_to", "type": "address" }],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "_transmitter", "type": "address" },
{ "internalType": "address", "name": "_proposed", "type": "address" }
],
"name": "transferPayeeship",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "bytes", "name": "_report", "type": "bytes" },
{ "internalType": "bytes32[]", "name": "_rs", "type": "bytes32[]" },
{ "internalType": "bytes32[]", "name": "_ss", "type": "bytes32[]" },
{ "internalType": "bytes32", "name": "_rawVs", "type": "bytes32" }
],
"name": "transmit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "transmitters",
"outputs": [{ "internalType": "address[]", "name": "", "type": "address[]" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "typeAndVersion",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "validatorConfig",
"outputs": [
{ "internalType": "contract AggregatorValidatorInterface", "name": "validator", "type": "address" },
{ "internalType": "uint32", "name": "gasLimit", "type": "uint32" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "_recipient", "type": "address" },
{ "internalType": "uint256", "name": "_amount", "type": "uint256" }
],
"name": "withdrawFunds",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "_transmitter", "type": "address" }],
"name": "withdrawPayment",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

530
abis/FeedRegistry.json Normal file
View File

@@ -0,0 +1,530 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "accessController",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "AccessControllerSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "denomination",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "latestAggregator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "previousAggregator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint16",
"name": "nextPhaseId",
"type": "uint16"
},
{
"indexed": false,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "FeedConfirmed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "asset",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "denomination",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "proposedAggregator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "currentAggregator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "FeedProposed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "OwnershipTransferRequested",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [],
"name": "acceptOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "address", "name": "aggregator", "type": "address" }
],
"name": "confirmFeed",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "decimals",
"outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "description",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAccessController",
"outputs": [
{
"internalType": "contract AccessControllerInterface",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint256", "name": "roundId", "type": "uint256" }
],
"name": "getAnswer",
"outputs": [
{ "internalType": "int256", "name": "answer", "type": "int256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "getCurrentPhaseId",
"outputs": [
{ "internalType": "uint16", "name": "currentPhaseId", "type": "uint16" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "getFeed",
"outputs": [
{
"internalType": "contract AggregatorV2V3Interface",
"name": "aggregator",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint80", "name": "roundId", "type": "uint80" }
],
"name": "getNextRoundId",
"outputs": [
{ "internalType": "uint80", "name": "nextRoundId", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint16", "name": "phaseId", "type": "uint16" }
],
"name": "getPhase",
"outputs": [
{
"components": [
{ "internalType": "uint16", "name": "phaseId", "type": "uint16" },
{
"internalType": "uint80",
"name": "startingAggregatorRoundId",
"type": "uint80"
},
{
"internalType": "uint80",
"name": "endingAggregatorRoundId",
"type": "uint80"
}
],
"internalType": "struct FeedRegistryInterface.Phase",
"name": "phase",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint16", "name": "phaseId", "type": "uint16" }
],
"name": "getPhaseFeed",
"outputs": [
{
"internalType": "contract AggregatorV2V3Interface",
"name": "aggregator",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint16", "name": "phaseId", "type": "uint16" }
],
"name": "getPhaseRange",
"outputs": [
{ "internalType": "uint80", "name": "startingRoundId", "type": "uint80" },
{ "internalType": "uint80", "name": "endingRoundId", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint80", "name": "roundId", "type": "uint80" }
],
"name": "getPreviousRoundId",
"outputs": [
{ "internalType": "uint80", "name": "previousRoundId", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "getProposedFeed",
"outputs": [
{
"internalType": "contract AggregatorV2V3Interface",
"name": "proposedAggregator",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint80", "name": "_roundId", "type": "uint80" }
],
"name": "getRoundData",
"outputs": [
{ "internalType": "uint80", "name": "roundId", "type": "uint80" },
{ "internalType": "int256", "name": "answer", "type": "int256" },
{ "internalType": "uint256", "name": "startedAt", "type": "uint256" },
{ "internalType": "uint256", "name": "updatedAt", "type": "uint256" },
{ "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint80", "name": "roundId", "type": "uint80" }
],
"name": "getRoundFeed",
"outputs": [
{
"internalType": "contract AggregatorV2V3Interface",
"name": "aggregator",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint256", "name": "roundId", "type": "uint256" }
],
"name": "getTimestamp",
"outputs": [
{ "internalType": "uint256", "name": "timestamp", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "aggregator", "type": "address" }
],
"name": "isFeedEnabled",
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "latestAnswer",
"outputs": [
{ "internalType": "int256", "name": "answer", "type": "int256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "latestRound",
"outputs": [
{ "internalType": "uint256", "name": "roundId", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "latestRoundData",
"outputs": [
{ "internalType": "uint80", "name": "roundId", "type": "uint80" },
{ "internalType": "int256", "name": "answer", "type": "int256" },
{ "internalType": "uint256", "name": "startedAt", "type": "uint256" },
{ "internalType": "uint256", "name": "updatedAt", "type": "uint256" },
{ "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "latestTimestamp",
"outputs": [
{ "internalType": "uint256", "name": "timestamp", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "address", "name": "aggregator", "type": "address" }
],
"name": "proposeFeed",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" },
{ "internalType": "uint80", "name": "roundId", "type": "uint80" }
],
"name": "proposedGetRoundData",
"outputs": [
{ "internalType": "uint80", "name": "id", "type": "uint80" },
{ "internalType": "int256", "name": "answer", "type": "int256" },
{ "internalType": "uint256", "name": "startedAt", "type": "uint256" },
{ "internalType": "uint256", "name": "updatedAt", "type": "uint256" },
{ "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "proposedLatestRoundData",
"outputs": [
{ "internalType": "uint80", "name": "id", "type": "uint80" },
{ "internalType": "int256", "name": "answer", "type": "int256" },
{ "internalType": "uint256", "name": "startedAt", "type": "uint256" },
{ "internalType": "uint256", "name": "updatedAt", "type": "uint256" },
{ "internalType": "uint80", "name": "answeredInRound", "type": "uint80" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract AccessControllerInterface",
"name": "_accessController",
"type": "address"
}
],
"name": "setAccessController",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "to", "type": "address" }],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "typeAndVersion",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "base", "type": "address" },
{ "internalType": "address", "name": "quote", "type": "address" }
],
"name": "version",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]

449
abis/Instance.json Normal file
View File

@@ -0,0 +1,449 @@
[
{
"anonymous":false,
"inputs":[
{
"indexed":true,
"internalType":"bytes32",
"name":"commitment",
"type":"bytes32"
},
{
"indexed":false,
"internalType":"uint32",
"name":"leafIndex",
"type":"uint32"
},
{
"indexed":false,
"internalType":"uint256",
"name":"timestamp",
"type":"uint256"
}
],
"name":"Deposit",
"type":"event"
},
{
"anonymous":false,
"inputs":[
{
"indexed":false,
"internalType":"address",
"name":"to",
"type":"address"
},
{
"indexed":false,
"internalType":"bytes32",
"name":"nullifierHash",
"type":"bytes32"
},
{
"indexed":true,
"internalType":"address",
"name":"relayer",
"type":"address"
},
{
"indexed":false,
"internalType":"uint256",
"name":"fee",
"type":"uint256"
}
],
"name":"Withdrawal",
"type":"event"
},
{
"inputs":[
],
"name":"FIELD_SIZE",
"outputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"ROOT_HISTORY_SIZE",
"outputs":[
{
"internalType":"uint32",
"name":"",
"type":"uint32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"ZERO_VALUE",
"outputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"name":"commitments",
"outputs":[
{
"internalType":"bool",
"name":"",
"type":"bool"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"currentRootIndex",
"outputs":[
{
"internalType":"uint32",
"name":"",
"type":"uint32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"denomination",
"outputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes32",
"name":"_commitment",
"type":"bytes32"
}
],
"name":"deposit",
"outputs":[
],
"stateMutability":"payable",
"type":"function"
},
{
"inputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"name":"filledSubtrees",
"outputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"getLastRoot",
"outputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"contract IHasher",
"name":"_hasher",
"type":"address"
},
{
"internalType":"bytes32",
"name":"_left",
"type":"bytes32"
},
{
"internalType":"bytes32",
"name":"_right",
"type":"bytes32"
}
],
"name":"hashLeftRight",
"outputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"stateMutability":"pure",
"type":"function"
},
{
"inputs":[
],
"name":"hasher",
"outputs":[
{
"internalType":"contract IHasher",
"name":"",
"type":"address"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes32",
"name":"_root",
"type":"bytes32"
}
],
"name":"isKnownRoot",
"outputs":[
{
"internalType":"bool",
"name":"",
"type":"bool"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes32",
"name":"_nullifierHash",
"type":"bytes32"
}
],
"name":"isSpent",
"outputs":[
{
"internalType":"bool",
"name":"",
"type":"bool"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes32[]",
"name":"_nullifierHashes",
"type":"bytes32[]"
}
],
"name":"isSpentArray",
"outputs":[
{
"internalType":"bool[]",
"name":"spent",
"type":"bool[]"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"levels",
"outputs":[
{
"internalType":"uint32",
"name":"",
"type":"uint32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"nextIndex",
"outputs":[
{
"internalType":"uint32",
"name":"",
"type":"uint32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"name":"nullifierHashes",
"outputs":[
{
"internalType":"bool",
"name":"",
"type":"bool"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"name":"roots",
"outputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
],
"name":"verifier",
"outputs":[
{
"internalType":"contract IVerifier",
"name":"",
"type":"address"
}
],
"stateMutability":"view",
"type":"function"
},
{
"inputs":[
{
"internalType":"bytes",
"name":"_proof",
"type":"bytes"
},
{
"internalType":"bytes32",
"name":"_root",
"type":"bytes32"
},
{
"internalType":"bytes32",
"name":"_nullifierHash",
"type":"bytes32"
},
{
"internalType":"address payable",
"name":"_recipient",
"type":"address"
},
{
"internalType":"address payable",
"name":"_relayer",
"type":"address"
},
{
"internalType":"uint256",
"name":"_fee",
"type":"uint256"
},
{
"internalType":"uint256",
"name":"_refund",
"type":"uint256"
}
],
"name":"withdraw",
"outputs":[
],
"stateMutability":"payable",
"type":"function"
},
{
"inputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"name":"zeros",
"outputs":[
{
"internalType":"bytes32",
"name":"",
"type":"bytes32"
}
],
"stateMutability":"view",
"type":"function"
}
]

366
abis/InstanceRegistry.json Normal file
View File

@@ -0,0 +1,366 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_governance",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "contract ITornadoInstance",
"name": "instance",
"type": "address"
},
{
"indexed": false,
"internalType": "enum InstanceRegistry.InstanceState",
"name": "state",
"type": "uint8"
}
],
"name": "InstanceStateUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "tornadoRouter",
"type": "address"
}
],
"name": "RouterRegistered",
"type": "event"
},
{
"inputs": [],
"name": "getAllInstanceAddresses",
"outputs": [
{
"internalType": "contract ITornadoInstance[]",
"name": "result",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAllInstances",
"outputs": [
{
"components": [
{
"internalType": "contract ITornadoInstance",
"name": "addr",
"type": "address"
},
{
"components": [
{
"internalType": "bool",
"name": "isERC20",
"type": "bool"
},
{
"internalType": "contract IERC20",
"name": "token",
"type": "address"
},
{
"internalType": "enum InstanceRegistry.InstanceState",
"name": "state",
"type": "uint8"
},
{
"internalType": "uint24",
"name": "uniswapPoolSwappingFee",
"type": "uint24"
},
{
"internalType": "uint32",
"name": "protocolFeePercentage",
"type": "uint32"
}
],
"internalType": "struct InstanceRegistry.Instance",
"name": "instance",
"type": "tuple"
}
],
"internalType": "struct InstanceRegistry.Tornado[]",
"name": "result",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "instance",
"type": "address"
}
],
"name": "getPoolToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "governance",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "contract ITornadoInstance",
"name": "addr",
"type": "address"
},
{
"components": [
{
"internalType": "bool",
"name": "isERC20",
"type": "bool"
},
{
"internalType": "contract IERC20",
"name": "token",
"type": "address"
},
{
"internalType": "enum InstanceRegistry.InstanceState",
"name": "state",
"type": "uint8"
},
{
"internalType": "uint24",
"name": "uniswapPoolSwappingFee",
"type": "uint24"
},
{
"internalType": "uint32",
"name": "protocolFeePercentage",
"type": "uint32"
}
],
"internalType": "struct InstanceRegistry.Instance",
"name": "instance",
"type": "tuple"
}
],
"internalType": "struct InstanceRegistry.Tornado[]",
"name": "_instances",
"type": "tuple[]"
},
{
"internalType": "address",
"name": "_router",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "instanceIds",
"outputs": [
{
"internalType": "contract ITornadoInstance",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "",
"type": "address"
}
],
"name": "instances",
"outputs": [
{
"internalType": "bool",
"name": "isERC20",
"type": "bool"
},
{
"internalType": "contract IERC20",
"name": "token",
"type": "address"
},
{
"internalType": "enum InstanceRegistry.InstanceState",
"name": "state",
"type": "uint8"
},
{
"internalType": "uint24",
"name": "uniswapPoolSwappingFee",
"type": "uint24"
},
{
"internalType": "uint32",
"name": "protocolFeePercentage",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_instanceId",
"type": "uint256"
}
],
"name": "removeInstance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "router",
"outputs": [
{
"internalType": "contract ITornadoRouter",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract ITornadoInstance",
"name": "instance",
"type": "address"
},
{
"internalType": "uint32",
"name": "newFee",
"type": "uint32"
}
],
"name": "setProtocolFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "routerAddress",
"type": "address"
}
],
"name": "setTornadoRouter",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "contract ITornadoInstance",
"name": "addr",
"type": "address"
},
{
"components": [
{
"internalType": "bool",
"name": "isERC20",
"type": "bool"
},
{
"internalType": "contract IERC20",
"name": "token",
"type": "address"
},
{
"internalType": "enum InstanceRegistry.InstanceState",
"name": "state",
"type": "uint8"
},
{
"internalType": "uint24",
"name": "uniswapPoolSwappingFee",
"type": "uint24"
},
{
"internalType": "uint32",
"name": "protocolFeePercentage",
"type": "uint32"
}
],
"internalType": "struct InstanceRegistry.Instance",
"name": "instance",
"type": "tuple"
}
],
"internalType": "struct InstanceRegistry.Tornado",
"name": "_tornado",
"type": "tuple"
}
],
"name": "updateInstance",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

View File

@@ -87,6 +87,19 @@
"name": "RelayerRegistered",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "relayer",
"type": "address"
}
],
"name": "RelayerUnregistered",
"type": "event"
},
{
"anonymous": false,
"inputs": [

596
abis/TORN.json Normal file
View File

@@ -0,0 +1,596 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_governance",
"type": "address"
},
{
"internalType": "uint256",
"name": "_pausePeriod",
"type": "uint256"
},
{
"components": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"internalType": "struct TORN.Recipient[]",
"name": "_vestings",
"type": "tuple[]"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "target",
"type": "address"
}
],
"name": "Allowed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "target",
"type": "address"
}
],
"name": "Disallowed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "Paused",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "Unpaused",
"type": "event"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "target",
"type": "address[]"
}
],
"name": "addToAllowedList",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "allowedTransferee",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"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": "blockTimestamp",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "burnFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "canUnpauseAfter",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "chainID",
"outputs": [
{
"internalType": "uint256",
"name": "_chainID",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "decision",
"type": "bool"
}
],
"name": "changeTransferability",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "subtractedValue",
"type": "uint256"
}
],
"name": "decreaseAllowance",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "governance",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "addedValue",
"type": "uint256"
}
],
"name": "increaseAllowance",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "nonces",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "permit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "target",
"type": "address[]"
}
],
"name": "removeFromAllowedList",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IERC20",
"name": "_token",
"type": "address"
},
{
"internalType": "address payable",
"name": "_to",
"type": "address"
},
{
"internalType": "uint256",
"name": "_balance",
"type": "uint256"
}
],
"name": "rescueTokens",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]

988
abis/V3Pair.json Normal file
View File

@@ -0,0 +1,988 @@
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount",
"type": "uint128"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
}
],
"name": "Burn",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount0",
"type": "uint128"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount1",
"type": "uint128"
}
],
"name": "Collect",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount0",
"type": "uint128"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount1",
"type": "uint128"
}
],
"name": "CollectProtocol",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "paid0",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "paid1",
"type": "uint256"
}
],
"name": "Flash",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint16",
"name": "observationCardinalityNextOld",
"type": "uint16"
},
{
"indexed": false,
"internalType": "uint16",
"name": "observationCardinalityNextNew",
"type": "uint16"
}
],
"name": "IncreaseObservationCardinalityNext",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint160",
"name": "sqrtPriceX96",
"type": "uint160"
},
{
"indexed": false,
"internalType": "int24",
"name": "tick",
"type": "int24"
}
],
"name": "Initialize",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"indexed": true,
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"indexed": false,
"internalType": "uint128",
"name": "amount",
"type": "uint128"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
}
],
"name": "Mint",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint8",
"name": "feeProtocol0Old",
"type": "uint8"
},
{
"indexed": false,
"internalType": "uint8",
"name": "feeProtocol1Old",
"type": "uint8"
},
{
"indexed": false,
"internalType": "uint8",
"name": "feeProtocol0New",
"type": "uint8"
},
{
"indexed": false,
"internalType": "uint8",
"name": "feeProtocol1New",
"type": "uint8"
}
],
"name": "SetFeeProtocol",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "int256",
"name": "amount0",
"type": "int256"
},
{
"indexed": false,
"internalType": "int256",
"name": "amount1",
"type": "int256"
},
{
"indexed": false,
"internalType": "uint160",
"name": "sqrtPriceX96",
"type": "uint160"
},
{
"indexed": false,
"internalType": "uint128",
"name": "liquidity",
"type": "uint128"
},
{
"indexed": false,
"internalType": "int24",
"name": "tick",
"type": "int24"
}
],
"name": "Swap",
"type": "event"
},
{
"inputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
}
],
"name": "burn",
"outputs": [
{
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"internalType": "uint128",
"name": "amount0Requested",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "amount1Requested",
"type": "uint128"
}
],
"name": "collect",
"outputs": [
{
"internalType": "uint128",
"name": "amount0",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "amount1",
"type": "uint128"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint128",
"name": "amount0Requested",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "amount1Requested",
"type": "uint128"
}
],
"name": "collectProtocol",
"outputs": [
{
"internalType": "uint128",
"name": "amount0",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "amount1",
"type": "uint128"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "factory",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fee",
"outputs": [
{
"internalType": "uint24",
"name": "",
"type": "uint24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "feeGrowthGlobal0X128",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "feeGrowthGlobal1X128",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "flash",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint16",
"name": "observationCardinalityNext",
"type": "uint16"
}
],
"name": "increaseObservationCardinalityNext",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint160",
"name": "sqrtPriceX96",
"type": "uint160"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "liquidity",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxLiquidityPerTick",
"outputs": [
{
"internalType": "uint128",
"name": "",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "mint",
"outputs": [
{
"internalType": "uint256",
"name": "amount0",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amount1",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "observations",
"outputs": [
{
"internalType": "uint32",
"name": "blockTimestamp",
"type": "uint32"
},
{
"internalType": "int56",
"name": "tickCumulative",
"type": "int56"
},
{
"internalType": "uint160",
"name": "secondsPerLiquidityCumulativeX128",
"type": "uint160"
},
{
"internalType": "bool",
"name": "initialized",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint32[]",
"name": "secondsAgos",
"type": "uint32[]"
}
],
"name": "observe",
"outputs": [
{
"internalType": "int56[]",
"name": "tickCumulatives",
"type": "int56[]"
},
{
"internalType": "uint160[]",
"name": "secondsPerLiquidityCumulativeX128s",
"type": "uint160[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "key",
"type": "bytes32"
}
],
"name": "positions",
"outputs": [
{
"internalType": "uint128",
"name": "_liquidity",
"type": "uint128"
},
{
"internalType": "uint256",
"name": "feeGrowthInside0LastX128",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "feeGrowthInside1LastX128",
"type": "uint256"
},
{
"internalType": "uint128",
"name": "tokensOwed0",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "tokensOwed1",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "protocolFees",
"outputs": [
{
"internalType": "uint128",
"name": "token0",
"type": "uint128"
},
{
"internalType": "uint128",
"name": "token1",
"type": "uint128"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint8",
"name": "feeProtocol0",
"type": "uint8"
},
{
"internalType": "uint8",
"name": "feeProtocol1",
"type": "uint8"
}
],
"name": "setFeeProtocol",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "slot0",
"outputs": [
{
"internalType": "uint160",
"name": "sqrtPriceX96",
"type": "uint160"
},
{
"internalType": "int24",
"name": "tick",
"type": "int24"
},
{
"internalType": "uint16",
"name": "observationIndex",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "observationCardinality",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "observationCardinalityNext",
"type": "uint16"
},
{
"internalType": "uint8",
"name": "feeProtocol",
"type": "uint8"
},
{
"internalType": "bool",
"name": "unlocked",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"name": "snapshotCumulativesInside",
"outputs": [
{
"internalType": "int56",
"name": "tickCumulativeInside",
"type": "int56"
},
{
"internalType": "uint160",
"name": "secondsPerLiquidityInsideX128",
"type": "uint160"
},
{
"internalType": "uint32",
"name": "secondsInside",
"type": "uint32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "bool",
"name": "zeroForOne",
"type": "bool"
},
{
"internalType": "int256",
"name": "amountSpecified",
"type": "int256"
},
{
"internalType": "uint160",
"name": "sqrtPriceLimitX96",
"type": "uint160"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "swap",
"outputs": [
{
"internalType": "int256",
"name": "amount0",
"type": "int256"
},
{
"internalType": "int256",
"name": "amount1",
"type": "int256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "int16",
"name": "wordPosition",
"type": "int16"
}
],
"name": "tickBitmap",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tickSpacing",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "int24",
"name": "tick",
"type": "int24"
}
],
"name": "ticks",
"outputs": [
{
"internalType": "uint128",
"name": "liquidityGross",
"type": "uint128"
},
{
"internalType": "int128",
"name": "liquidityNet",
"type": "int128"
},
{
"internalType": "uint256",
"name": "feeGrowthOutside0X128",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "feeGrowthOutside1X128",
"type": "uint256"
},
{
"internalType": "int56",
"name": "tickCumulativeOutside",
"type": "int56"
},
{
"internalType": "uint160",
"name": "secondsPerLiquidityOutsideX128",
"type": "uint160"
},
{
"internalType": "uint32",
"name": "secondsOutside",
"type": "uint32"
},
{
"internalType": "bool",
"name": "initialized",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "token0",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "token1",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@@ -1,6 +1,9 @@
{
"name": "tornado-governance-subgraph",
"version": "1.0.0",
"description": "Tornado Cash Governance & Relayer Registry Subgraph",
"license": "MIT",
"author": "Tornado Cash",
"scripts": {
"codegen": "graph codegen",
"build": "graph build",
@@ -8,10 +11,7 @@
"deploy": "graph deploy --node http://127.0.0.1:8020 --ipfs http://127.0.0.1:5001 tornadocash/tornado-governance"
},
"dependencies": {
"@graphprotocol/graph-cli": "0.27.0",
"@graphprotocol/graph-ts": "0.24.1"
},
"resolutions": {
"concat-stream": "2.0.0"
"@graphprotocol/graph-cli": "^0.97.1",
"@graphprotocol/graph-ts": "^0.38.1"
}
}

View File

@@ -1,4 +1,4 @@
type Proposal @entity {
type Proposal @entity(immutable: false) {
id: ID!
timestamp: Int!
blockNumber: Int!
@@ -10,11 +10,25 @@ type Proposal @entity {
target: Bytes!
startTime: Int!
endTime: Int!
forVotes: BigDecimal!
againstVotes: BigDecimal!
description: String!
executed: Boolean!
}
type Vote @entity {
type Receipt @entity(immutable: false) {
id: ID!
proposalId: Int!
voter: Bytes!
support: Boolean!
votes: BigDecimal!
}
type Vote @entity(immutable: true) {
id: ID!
timestamp: Int!
blockNumber: Int!
@@ -24,12 +38,30 @@ type Vote @entity {
proposalId: Int!
voter: Bytes!
support: Boolean!
votes: BigInt!
votes: BigDecimal!
from: Bytes!
input: Bytes!
}
type Delegate @entity {
type Delegate @entity(immutable: false) {
id: ID!
delegateTimestamp: Int!
delegateBlock: Int!
delegateTx: Bytes!
delegateLogIndex: Int!
undelegateTimestamp: Int!
undelegateBlock: Int!
undelegateTx: Bytes!
undelegateLogIndex: Int!
account: Bytes!
delegatedTo: Bytes!
delegatedFrom: [Bytes!]!
}
type DelegateEvent @entity(immutable: true) {
id: ID!
timestamp: Int!
blockNumber: Int!
@@ -40,7 +72,7 @@ type Delegate @entity {
delegateTo: Bytes!
}
type Undelegate @entity {
type UndelegateEvent @entity(immutable: true) {
id: ID!
timestamp: Int!
blockNumber: Int!
@@ -51,7 +83,28 @@ type Undelegate @entity {
delegateFrom: Bytes!
}
type StakeBurn @entity {
type Relayer @entity(immutable: false) {
id: ID!
address: Bytes!
ensName: String!
ensHash: Bytes!
workers: [Bytes!]!
stakeBalance: BigDecimal!
burnBalance: BigDecimal!
blockRegistration: Int!
registerTimestamp: Int!
registerTx: Bytes!
registerLogIndex: Int!
blockUnregisteration: Int!
unregisterTimestamp: Int!
unregisterTx: Bytes!
unregisterLogIndex: Int!
}
type StakeBurn @entity(immutable: false) {
id: ID!
timestamp: Int!
blockNumber: Int!
@@ -59,11 +112,118 @@ type StakeBurn @entity {
transactionHash: Bytes!
relayer: Bytes!
amountBurned: BigInt!
amountBurned: BigDecimal!
amountBurnedUSD: BigDecimal!
instance: Bytes!
relayerFee: BigInt!
}
type StakeDailyBurn @entity {
type StakeDailyBurn @entity(immutable: false) {
id: ID!
date: Int!
dailyAmountBurned: BigInt!
dailyAmountBurned: BigDecimal!
dailyAmountBurnedUSD: BigDecimal!
}
type RelayerDailyBurn @entity(immutable: false) {
id: ID!
relayer: Bytes!
date: Int!
dailyAmountBurned: BigDecimal!
dailyAmountBurnedUSD: BigDecimal!
}
type Instance @entity(immutable: true) {
id: ID!
timestamp: Int!
blockNumber: Int!
logIndex: Int!
transactionHash: Bytes!
address: Bytes!
}
type Withdrawal @entity(immutable: true) {
id: ID!
timestamp: Int!
blockNumber: Int!
logIndex: Int!
transactionHash: Bytes!
instance: Bytes!
to: Bytes!
nullifierHash: Bytes!
relayer: Bytes!
fee: BigInt!
}
type Balance @entity(immutable: false) {
id: ID!
address: Bytes!
balance: BigDecimal!
lockedBalance: BigDecimal!
claimedRewards: BigDecimal!
}
type Transfer @entity(immutable: true) {
id: ID!
timestamp: Int!
blockNumber: Int!
logIndex: Int!
transactionHash: Bytes!
type: String!
from: Bytes!
to: Bytes!
value: BigDecimal!
usdValue: BigDecimal!
}
type DataFeed @entity(immutable: false) {
id: ID!
name: String!
usdPrice: BigDecimal!
lastBlock: Int!
lastTimestamp: Int!
live: Boolean!
deprecatedBlock: Int!
}
type TornPair @entity(immutable: false) {
id: ID!
name: String!
ethPrice: BigDecimal!
lastBlock: Int!
lastTimestamp: Int!
}
type Stats @entity(immutable: false) {
id: ID!
timestamp: Int!
blockNumber: Int!
ethUsdPrice: BigDecimal!
tornUsdPrice: BigDecimal!
totalSupply: BigDecimal!
lockedSupply: BigDecimal!
burnedSupply: BigDecimal!
rewardedSupply: BigDecimal!
}
type StatsHourly @entity(immutable: false) {
id: ID!
timestamp: Int!
blockNumber: Int!
ethUsdPrice: BigDecimal!
tornUsdPrice: BigDecimal!
totalSupply: BigDecimal!
lockedSupply: BigDecimal!
burnedSupply: BigDecimal!
rewardedSupply: BigDecimal!
}

69
src/chainlink.ts Normal file
View File

@@ -0,0 +1,69 @@
/**
* Should update ETH/USD from Chainlink Pricefeed
*/
import { DataSourceContext } from '@graphprotocol/graph-ts';
import { FeedConfirmed as FeedConfirmedEvent } from '../generated/FeedRegistry/FeedRegistry';
import { AnswerUpdated as AnswerUpdatedEvent } from '../generated/FeedRegistry/AccessControlledOffchainAggregator';
import { DataFeed } from '../generated/schema';
import { DataFeed as DataFeedTemplate } from '../generated/templates';
import { convertAnswerToDecimal, ZERO_ADDRESS, ZERO_BD } from './utils';
import { CHAINLINK_BASE, CHAINLINK_PAIR, CHAINLINK_QUOTE } from './constants';
import { loadStats, saveStats } from './stats';
export function handleFeedConfirmed(event: FeedConfirmedEvent): void {
// Should only update ETH/USD data feed
if (!(event.params.asset.equals(CHAINLINK_BASE) && event.params.denomination.equals(CHAINLINK_QUOTE))) {
return;
}
// Feed Confirmed event is emitted when a feed is added, updated, or removed
let prevFeed = DataFeed.load(event.params.previousAggregator.toHex());
// if we haven't since this previous feed before, or the next feed is not the zero address, then this is a new feed and we need to create it
if (prevFeed === null || !event.params.latestAggregator.equals(ZERO_ADDRESS)) {
// if previous aggregator is null, then this is a new feed
let dataFeed = new DataFeed(event.params.latestAggregator.toHex());
dataFeed.name = CHAINLINK_PAIR;
dataFeed.usdPrice = ZERO_BD;
dataFeed.lastBlock = event.block.number.toI32();
dataFeed.lastTimestamp = event.block.timestamp.toI32();
dataFeed.live = true;
dataFeed.deprecatedBlock = 0;
dataFeed.save();
// Create the new Price Data Feed Template
let context = new DataSourceContext();
context.setString('id', event.params.latestAggregator.toHex());
DataFeedTemplate.createWithContext(event.params.latestAggregator, context);
// Deprecate prev feed
} else if (prevFeed !== null) {
prevFeed.live = false;
prevFeed.deprecatedBlock = event.block.number.toI32();
prevFeed.save();
}
}
export function handleAnswerUpdated(event: AnswerUpdatedEvent): void {
let priceFeed = DataFeed.load(event.address.toHex());
if (priceFeed === null || !priceFeed.live) {
return;
}
priceFeed.usdPrice = convertAnswerToDecimal(event.params.current);
priceFeed.lastBlock = event.block.number.toI32();
priceFeed.lastTimestamp = event.block.timestamp.toI32();
priceFeed.save();
// Save stats
let stats = loadStats();
stats.ethUsdPrice = priceFeed.usdPrice;
saveStats(stats, event.block);
}

51
src/constants.ts Normal file
View File

@@ -0,0 +1,51 @@
import { Address, Bytes, TypedMap } from '@graphprotocol/graph-ts';
// Base (Asset) & Quote (Denomination) to find ETH/USD proposedAggregator from Chainlink Feed Registry
export let CHAINLINK_BASE = Address.fromHexString('0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee');
export let CHAINLINK_QUOTE = Address.fromHexString('0x0000000000000000000000000000000000000348');
export let CHAINLINK_PAIR = 'ETH/USD';
export let UNISWAP_PAIR = 'TORN/ETH';
export let MAX_VOTE_INPUT_LENGTH = 800;
export class TornadoInfo {
tornDecimals: i32;
tornEthPair: Bytes;
tornEthPairToken0: boolean;
governance: Bytes;
governanceVault: Bytes;
stakingRewards: Bytes;
constructor(
tornDecimals: i32,
tornEthPair: string,
tornEthPairToken0: boolean,
governance: string,
governanceVault: string,
stakingRewards: string
) {
this.tornDecimals = tornDecimals;
this.tornEthPair = Address.fromString(tornEthPair);
this.tornEthPairToken0 = tornEthPairToken0;
this.governance = Address.fromHexString(governance);
this.governanceVault = Address.fromHexString(governanceVault);
this.stakingRewards = Address.fromHexString(stakingRewards);
}
}
export const AllTornadoInfo = new TypedMap<string, TornadoInfo>();
AllTornadoInfo.set(
'mainnet',
new TornadoInfo(
18,
'0x97a5a0B2D7Ed3accb7FD6404A1f5CA29320905AF',
true,
'0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
'0x2F50508a8a3D323B91336FA3eA6ae50E55f32185',
'0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29'
)
);

70
src/instance.ts Normal file
View File

@@ -0,0 +1,70 @@
import { DataSourceContext } from '@graphprotocol/graph-ts';
import { InstanceStateUpdated } from '../generated/InstanceRegistry/InstanceRegistry';
import { Instance, Relayer, StakeBurn, Withdrawal } from '../generated/schema';
import { Instance as InstanceTemplate } from '../generated/templates';
import { Withdrawal as WithdrawalEvent } from '../generated/templates/Instance/Instance';
import { ZERO_BI } from './utils';
export function handleInstanceStateUpdated(event: InstanceStateUpdated): void {
let instance = Instance.load(event.params.instance.toHex());
if (instance === null) {
instance = new Instance(event.params.instance.toHex());
instance.timestamp = event.block.timestamp.toI32();
instance.blockNumber = event.block.number.toI32();
instance.logIndex = event.logIndex.toI32();
instance.transactionHash = event.transaction.hash;
instance.address = event.params.instance;
instance.save();
let context = new DataSourceContext();
context.setString('id', event.params.instance.toHex());
InstanceTemplate.createWithContext(event.params.instance, context);
}
}
export function handleWithdrawal(event: WithdrawalEvent): void {
let id = '';
let index = 0;
while (index < 20) {
id = event.transaction.hash.toHex() + '_' + index.toString();
let withdrawal = Withdrawal.load(id);
if (withdrawal === null) {
break;
}
index++;
}
let stakeBurned = StakeBurn.load(id);
let relayer = Relayer.load(event.params.relayer.toHex());
if (stakeBurned === null || relayer === null || event.params.fee.equals(ZERO_BI)) {
return;
}
let withdrawal = new Withdrawal(id);
withdrawal.timestamp = event.block.timestamp.toI32();
withdrawal.blockNumber = event.block.number.toI32();
withdrawal.logIndex = event.logIndex.toI32();
withdrawal.transactionHash = event.transaction.hash;
withdrawal.logIndex = event.logIndex.toI32();
withdrawal.instance = event.address;
withdrawal.to = event.params.to;
withdrawal.nullifierHash = event.params.nullifierHash;
withdrawal.relayer = event.params.relayer;
withdrawal.fee = event.params.fee;
withdrawal.save();
stakeBurned.instance = event.address;
stakeBurned.relayerFee = event.params.fee;
stakeBurned.save();
}

View File

@@ -1,24 +1,21 @@
import { BigInt } from "@graphprotocol/graph-ts";
import { Bytes, Address } from '@graphprotocol/graph-ts';
import { convertTokenToDecimal, ZERO_BD } from './utils';
import {
Proposal,
Receipt,
Vote,
DelegateEvent,
UndelegateEvent,
Delegate,
Undelegate,
StakeBurn,
StakeDailyBurn,
} from "../generated/schema";
} from '../generated/schema';
import {
ProposalCreated,
ProposalExecuted,
Voted,
Delegated,
Undelegated,
} from "../generated/Governance/Governance";
import {
StakeBurned
} from "../generated/RelayerRegistry/RelayerRegistry";
export let ZERO_BI = BigInt.fromI32(0);
} from '../generated/Governance/Governance';
import { MAX_VOTE_INPUT_LENGTH } from './constants';
export function handleProposalCreated(event: ProposalCreated): void {
let proposal = Proposal.load(event.params.id.toString());
@@ -35,6 +32,10 @@ export function handleProposalCreated(event: ProposalCreated): void {
proposal.target = event.params.target;
proposal.startTime = event.params.startTime.toI32();
proposal.endTime = event.params.endTime.toI32();
proposal.forVotes = ZERO_BD;
proposal.againstVotes = ZERO_BD;
proposal.description = event.params.description;
proposal.executed = false;
proposal.save();
@@ -51,30 +52,72 @@ export function handleProposalExecuted(event: ProposalExecuted): void {
}
export function handleVoted(event: Voted): void {
let voted = Vote.load(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
let id = event.transaction.hash.toHex() + '_' + event.logIndex.toString();
let proposalId = event.params.proposalId.toI32();
let receiptId = event.params.proposalId.toString() + '_' + event.params.voter.toHex();
if (voted === null) {
voted = new Vote(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
voted.timestamp = event.block.timestamp.toI32();
let proposal = Proposal.load(proposalId.toString());
let receipt = Receipt.load(receiptId);
let voted = Vote.load(id);
if (voted === null && proposal !== null) {
let timestamp = event.block.timestamp.toI32();
let votes = convertTokenToDecimal(event.params.votes);
voted = new Vote(id);
voted.timestamp = timestamp;
voted.blockNumber = event.block.number.toI32();
voted.logIndex = event.logIndex.toI32();
voted.transactionHash = event.transaction.hash;
voted.proposalId = event.params.proposalId.toI32();
voted.proposalId = proposalId;
voted.voter = event.params.voter;
voted.support = event.params.support;
voted.votes = event.params.votes;
voted.votes = votes;
voted.from = event.transaction.from;
voted.input = event.transaction.input;
voted.input = event.transaction.input.length < MAX_VOTE_INPUT_LENGTH
? event.transaction.input
: Bytes.fromHexString('0x');
voted.save();
let isSupport = event.params.support === true;
if (receipt !== null) {
if (isSupport) {
proposal.forVotes = proposal.forVotes.minus(receipt.votes);
} else {
proposal.againstVotes = proposal.againstVotes.minus(receipt.votes);
}
}
if (isSupport) {
proposal.forVotes = proposal.forVotes.plus(votes);
} else {
proposal.againstVotes = proposal.againstVotes.plus(votes);
}
proposal.save();
if (receipt === null) {
receipt = new Receipt(receiptId);
receipt.proposalId = proposalId;
receipt.voter = event.params.voter;
}
receipt.support = event.params.support;
receipt.votes = votes;
receipt.save();
}
}
export function handleDelegated(event: Delegated): void {
let delegated = Delegate.load(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
let id = event.transaction.hash.toHex() + '_' + event.logIndex.toString();
let delegated = DelegateEvent.load(id);
if (delegated === null) {
delegated = new Delegate(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
delegated = new DelegateEvent(id);
delegated.timestamp = event.block.timestamp.toI32();
delegated.blockNumber = event.block.number.toI32();
delegated.logIndex = event.logIndex.toI32();
@@ -84,13 +127,63 @@ export function handleDelegated(event: Delegated): void {
delegated.delegateTo = event.params.to;
delegated.save();
}
let from = Delegate.load(event.params.account.toHex());
if (from === null) {
from = new Delegate(event.params.account.toHex());
from.delegateTimestamp = event.block.timestamp.toI32();
from.delegateBlock = event.block.number.toI32();
from.delegateTx = event.transaction.hash;
from.delegateLogIndex = event.logIndex.toI32();
from.undelegateTimestamp = 0;
from.undelegateBlock = 0;
from.undelegateTx = Bytes.fromHexString('0x');
from.undelegateLogIndex = 0;
from.account = event.params.account;
from.delegatedFrom = [];
}
from.delegatedTo = event.params.account;
from.save();
let to = Delegate.load(event.params.to.toHex());
if (to === null) {
to = new Delegate(event.params.to.toHex());
to.delegateTimestamp = 0;
to.delegateBlock = 0;
to.delegateTx = Bytes.fromHexString('0x');
to.delegateLogIndex = 0;
to.undelegateTimestamp = 0;
to.undelegateBlock = 0;
to.undelegateTx = Bytes.fromHexString('0x');
to.undelegateLogIndex = 0;
to.account = event.params.to;
to.delegatedTo = Address.fromHexString('0x');
to.delegatedFrom = [];
}
if (!to.delegatedFrom.includes(event.params.account)) {
to.delegatedFrom.push(event.params.account);
}
to.save();
}
export function handleUndelegated(event: Undelegated): void {
let undelegated = Undelegate.load(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
let id = event.transaction.hash.toHex() + '_' + event.logIndex.toString();
let undelegated = UndelegateEvent.load(id);
if (undelegated === null) {
undelegated = new Undelegate(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
undelegated = new UndelegateEvent(id);
undelegated.timestamp = event.block.timestamp.toI32();
undelegated.blockNumber = event.block.number.toI32();
undelegated.logIndex = event.logIndex.toI32();
@@ -100,35 +193,30 @@ export function handleUndelegated(event: Undelegated): void {
undelegated.delegateFrom = event.params.from;
undelegated.save();
}
}
export function handleStakeBurned(event: StakeBurned): void {
let stakeBurned = StakeBurn.load(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
let from = Delegate.load(event.params.account.toHex());
if (stakeBurned === null) {
stakeBurned = new StakeBurn(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
stakeBurned.timestamp = event.block.timestamp.toI32();
stakeBurned.blockNumber = event.block.number.toI32();
stakeBurned.logIndex = event.logIndex.toI32();
stakeBurned.transactionHash = event.transaction.hash;
if (from !== null) {
from.undelegateTimestamp = event.block.timestamp.toI32();
from.undelegateBlock = event.block.number.toI32();
from.undelegateTx = event.transaction.hash;
from.undelegateLogIndex = event.logIndex.toI32();
stakeBurned.relayer = event.params.relayer;
stakeBurned.amountBurned = event.params.amountBurned;
stakeBurned.save();
from.delegatedTo = Address.fromHexString('0x');
from.save();
}
let timestamp = event.block.timestamp.toI32();
let dayID = timestamp / 86400;
let dayStartTimestamp = dayID * 86400;
let dailyBurned = StakeDailyBurn.load(dayStartTimestamp.toString());
let to = Delegate.load(event.params.from.toHex());
if (dailyBurned === null) {
dailyBurned = new StakeDailyBurn(dayStartTimestamp.toString());
dailyBurned.date = dayStartTimestamp;
dailyBurned.dailyAmountBurned = ZERO_BI;
if (to !== null) {
// filter function is not implemented so we just iterate over
let delegatedFrom: Bytes[] = [];
for (let i = 0; i < to.delegatedFrom.length; ++i) {
if (!to.delegatedFrom[i].equals(event.params.account)) {
delegatedFrom.push(to.delegatedFrom[i]);
}
}
dailyBurned.dailyAmountBurned = dailyBurned.dailyAmountBurned.plus(event.params.amountBurned);
dailyBurned.save();
to.delegatedFrom = delegatedFrom;
to.save();
}
}

205
src/relayer.ts Normal file
View File

@@ -0,0 +1,205 @@
import { Bytes } from '@graphprotocol/graph-ts';
import { convertTokenToDecimal, ZERO_ADDRESS, ZERO_BD, ZERO_BI } from './utils';
import {
Relayer,
RelayerDailyBurn,
StakeBurn,
StakeDailyBurn,
} from '../generated/schema';
import {
RelayerBalanceNullified,
RelayerRegistered,
RelayerUnregistered,
StakeAddedToRelayer,
StakeBurned,
WorkerRegistered,
WorkerUnregistered
} from '../generated/RelayerRegistry/RelayerRegistry';
import { loadStats, saveStats } from './stats';
export function handleRelayerRegistered(event: RelayerRegistered): void {
// Regardless of existance (because balance is being inserted ahead of register event) we update relayer info per event params
let relayer = Relayer.load(event.params.relayerAddress.toHex());
// Init info
if (relayer === null) {
relayer = new Relayer(event.params.relayerAddress.toHex());
relayer.workers = [];
relayer.burnBalance = ZERO_BD;
}
relayer.address = event.params.relayerAddress;
relayer.ensName = event.params.ensName;
relayer.ensHash = event.params.relayer;
relayer.stakeBalance = relayer.stakeBalance.equals(ZERO_BD)
? convertTokenToDecimal(event.params.stakedAmount)
: relayer.stakeBalance;
relayer.blockRegistration = event.block.number.toI32();
relayer.registerTimestamp = event.block.timestamp.toI32();
relayer.registerTx = event.transaction.hash;
relayer.registerLogIndex = event.logIndex.toI32();
relayer.blockUnregisteration = 0;
relayer.unregisterTimestamp = 0;
relayer.unregisterTx = new Bytes(32);
relayer.unregisterLogIndex = 0;
relayer.save();
}
export function handleRelayerUnregistered(event: RelayerUnregistered): void {
let relayer = Relayer.load(event.params.relayer.toHex());
if (relayer !== null) {
relayer.stakeBalance = ZERO_BD;
relayer.blockUnregisteration = event.block.number.toI32();
relayer.unregisterTimestamp = event.block.timestamp.toI32();
relayer.unregisterTx = event.transaction.hash;
relayer.unregisterLogIndex = event.logIndex.toI32();
relayer.save();
}
}
export function handleRelayerBalanceNullified(event: RelayerBalanceNullified): void {
let relayer = Relayer.load(event.params.relayer.toHex());
if (relayer !== null) {
relayer.stakeBalance = ZERO_BD;
relayer.save();
}
}
export function handleWorkerRegistered(event: WorkerRegistered): void {
let relayer = Relayer.load(event.params.relayer.toHex());
if (relayer !== null) {
relayer.workers.push(event.params.worker);
relayer.save();
}
}
export function handleWorkerUnregistered(event: WorkerUnregistered): void {
let relayer = Relayer.load(event.params.relayer.toHex());
if (relayer !== null) {
// filter function is not implemented so we just iterate over
let workers: Bytes[] = [];
for (let i = 0; i < relayer.workers.length; ++i) {
if (!relayer.workers[i].equals(event.params.worker)) {
workers.push(relayer.workers[i]);
}
}
relayer.workers = workers;
relayer.save();
}
}
export function handleStakeAddedToRelayer(event: StakeAddedToRelayer): void {
let relayer = Relayer.load(event.params.relayer.toHex());
// Relayer info is actually pushed here according to RelayerRegistry contract
if (relayer === null) {
relayer = new Relayer(event.params.relayer.toHex());
relayer.address = event.params.relayer;
relayer.ensName = '';
relayer.ensHash = new Bytes(32);
relayer.workers = [];
relayer.stakeBalance = ZERO_BD;
relayer.burnBalance = ZERO_BD;
relayer.blockRegistration = event.block.number.toI32();
relayer.registerTimestamp = event.block.timestamp.toI32();
relayer.registerTx = event.transaction.hash;
relayer.registerLogIndex = event.logIndex.toI32();
relayer.blockUnregisteration = 0;
relayer.unregisterTimestamp = 0;
relayer.unregisterTx = new Bytes(32);
relayer.unregisterLogIndex = 0;
}
relayer.stakeBalance = relayer.stakeBalance.plus(convertTokenToDecimal(event.params.amountStakeAdded));
relayer.save();
}
export function handleStakeBurned(event: StakeBurned): void {
let id = '';
let index = 0;
while (index < 20) {
id = event.transaction.hash.toHex() + '_' + index.toString();
let stakeBurned = StakeBurn.load(id);
if (stakeBurned === null) {
break;
}
index++;
}
let amountBurned = convertTokenToDecimal(event.params.amountBurned);
let stats = loadStats();
let stakeBurned = new StakeBurn(id);
stakeBurned.timestamp = event.block.timestamp.toI32();
stakeBurned.blockNumber = event.block.number.toI32();
stakeBurned.logIndex = event.logIndex.toI32();
stakeBurned.transactionHash = event.transaction.hash;
stakeBurned.relayer = event.params.relayer;
stakeBurned.amountBurned = amountBurned;
stakeBurned.amountBurnedUSD = amountBurned.times(stats.tornUsdPrice);
stakeBurned.instance = ZERO_ADDRESS;
stakeBurned.relayerFee = ZERO_BI;
stakeBurned.save();
let timestamp = event.block.timestamp.toI32();
let dayID = timestamp / 86400;
let dayStartTimestamp = dayID * 86400;
let dailyBurned = StakeDailyBurn.load(dayStartTimestamp.toString());
if (dailyBurned === null) {
dailyBurned = new StakeDailyBurn(dayStartTimestamp.toString());
dailyBurned.date = dayStartTimestamp;
dailyBurned.dailyAmountBurned = ZERO_BD;
}
dailyBurned.dailyAmountBurned = dailyBurned.dailyAmountBurned.plus(amountBurned);
dailyBurned.dailyAmountBurnedUSD = dailyBurned.dailyAmountBurned.times(stats.tornUsdPrice);
dailyBurned.save();
let relayer = Relayer.load(event.params.relayer.toHex());
if (relayer !== null && relayer.stakeBalance.ge(amountBurned)) {
relayer.stakeBalance = relayer.stakeBalance.minus(amountBurned);
relayer.burnBalance = relayer.burnBalance.plus(amountBurned);
relayer.save();
}
let dailyBurnId = event.params.relayer.toHex() + '_' + dayStartTimestamp.toString();
let relayerDailyBurned = RelayerDailyBurn.load(dailyBurnId);
if (relayerDailyBurned === null) {
relayerDailyBurned = new RelayerDailyBurn(dailyBurnId);
relayerDailyBurned.relayer = event.params.relayer;
relayerDailyBurned.date = dayStartTimestamp;
relayerDailyBurned.dailyAmountBurned = ZERO_BD;
}
relayerDailyBurned.dailyAmountBurned = relayerDailyBurned.dailyAmountBurned.plus(amountBurned);
relayerDailyBurned.dailyAmountBurnedUSD = relayerDailyBurned.dailyAmountBurned.times(stats.tornUsdPrice);
relayerDailyBurned.save();
// Save Stats
stats.burnedSupply = stats.burnedSupply.plus(amountBurned);
saveStats(stats, event.block);
}

52
src/stats.ts Normal file
View File

@@ -0,0 +1,52 @@
import { ethereum } from '@graphprotocol/graph-ts';
import { Stats, StatsHourly } from '../generated/schema';
import { ZERO_BD } from './utils';
export function loadStats(): Stats {
let stats = Stats.load('1');
if (stats === null) {
stats = new Stats('1');
stats.ethUsdPrice = ZERO_BD;
stats.tornUsdPrice = ZERO_BD;
stats.totalSupply = ZERO_BD;
// Supply staked by users
stats.lockedSupply = ZERO_BD;
// Supply paid by relayers for user reward
stats.burnedSupply = ZERO_BD;
// Supply claimed by users (reward: (burnedSupply - rewardedSupply) / lockedSupply)
stats.rewardedSupply = ZERO_BD;
}
return stats;
}
export function saveStats(stats: Stats, block: ethereum.Block): void {
stats.timestamp = block.timestamp.toI32();
stats.blockNumber = block.number.toI32();
stats.save();
// Dump current stats for hourly report
let hourID = block.timestamp.toI32() / 3600;
let hourStartTimestamp = hourID * 3600;
let hourlyBurned = StatsHourly.load(hourStartTimestamp.toString());
if (hourlyBurned === null) {
hourlyBurned = new StatsHourly(hourStartTimestamp.toString());
}
hourlyBurned.timestamp = stats.timestamp;
hourlyBurned.blockNumber = stats.blockNumber;
hourlyBurned.ethUsdPrice = stats.ethUsdPrice;
hourlyBurned.tornUsdPrice = stats.tornUsdPrice;
hourlyBurned.totalSupply = stats.totalSupply;
hourlyBurned.lockedSupply = stats.lockedSupply;
hourlyBurned.burnedSupply = stats.burnedSupply;
hourlyBurned.rewardedSupply = stats.rewardedSupply;
hourlyBurned.save();
}

112
src/torn.ts Normal file
View File

@@ -0,0 +1,112 @@
import { BigDecimal, Bytes } from '@graphprotocol/graph-ts';
import { convertTokenToDecimal, getTornadoInfo, ZERO_ADDRESS, ZERO_BD } from './utils';
import {
Balance,
Transfer,
} from '../generated/schema';
import {
Transfer as TransferEvent,
} from '../generated/TORN/TORN';
import { loadStats, saveStats } from './stats';
export function loadBalance(address: Bytes, value: BigDecimal, from: boolean): Balance | null {
if (address.equals(ZERO_ADDRESS)) {
return null;
}
let balance = Balance.load(address.toHex());
if (balance === null) {
balance = new Balance(address.toHex());
balance.address = address;
balance.balance = ZERO_BD;
balance.lockedBalance = ZERO_BD;
balance.claimedRewards = ZERO_BD;
}
if (from && balance.balance.ge(value)) {
balance.balance = balance.balance.minus(value);
} else if (!from) {
balance.balance = balance.balance.plus(value);
}
return balance;
}
export function handleTransfer(event: TransferEvent): void {
let transfer = new Transfer(event.transaction.hash.toHex() + '_' + event.logIndex.toString());
let value = convertTokenToDecimal(event.params.value);
let stats = loadStats();
transfer.timestamp = event.block.timestamp.toI32();
transfer.blockNumber = event.block.number.toI32();
transfer.logIndex = event.logIndex.toI32();
transfer.transactionHash = event.transaction.hash;
transfer.type = 'Transfer';
transfer.from = event.params.from;
transfer.to = event.params.to;
transfer.value = value;
transfer.usdValue = value.times(stats.tornUsdPrice);
let from = loadBalance(event.params.from, value, true);
let to = loadBalance(event.params.to, value, false);
let tornadoInfo = getTornadoInfo();
// Mint
if (from === null && to !== null) {
transfer.type = 'Mint';
stats.totalSupply = stats.totalSupply.plus(value);
to.save();
}
// Burn
if (from !== null && to === null) {
transfer.type = 'Burn';
stats.totalSupply = stats.totalSupply.minus(value);
from.save();
}
// Skip on Mint or Burn event
if (from === null || to === null) {
transfer.save();
saveStats(stats, event.block);
return;
}
// Handle lock
if (
event.params.to.equals(tornadoInfo.governanceVault) &&
!event.params.from.equals(tornadoInfo.governance)
) {
transfer.type = 'Lock';
from.lockedBalance = from.lockedBalance.plus(value);
stats.lockedSupply = stats.lockedSupply.plus(value);
}
// Handle unlock
if (
event.params.from.equals(tornadoInfo.governanceVault) &&
to.lockedBalance.ge(value)
) {
transfer.type = 'Unlock';
to.lockedBalance = to.lockedBalance.minus(value);
stats.lockedSupply = stats.lockedSupply.minus(value);
}
// Handle reward claims
if (
event.params.from.equals(tornadoInfo.stakingRewards)
) {
transfer.type = 'Claim';
to.claimedRewards = to.claimedRewards.plus(value);
stats.rewardedSupply = stats.rewardedSupply.plus(value);
}
from.save();
to.save();
transfer.save();
saveStats(stats, event.block);
}

36
src/uniswap.ts Normal file
View File

@@ -0,0 +1,36 @@
/**
* Should update TORN/ETH from Uniswap V3 pair
*/
import { Swap as SwapEvent } from '../generated/TornPair/V3Pair';
import { TornPair } from '../generated/schema';
import { sqrtPriceX96ToTokenPrices, getTornadoInfo } from './utils';
import { UNISWAP_PAIR } from './constants';
import { loadStats, saveStats } from './stats';
export function handleSwap(event: SwapEvent): void {
let pool = TornPair.load(event.address.toHex());
if (pool === null) {
pool = new TornPair(event.address.toHex());
pool.name = UNISWAP_PAIR;
}
let tornadoInfo = getTornadoInfo();
let decimals0 = tornadoInfo.tornEthPairToken0 ? tornadoInfo.tornDecimals : 18;
let decimals1 = tornadoInfo.tornEthPairToken0 ? 18 : tornadoInfo.tornDecimals;
let prices = sqrtPriceX96ToTokenPrices(event.params.sqrtPriceX96, decimals0, decimals1);
pool.ethPrice = tornadoInfo.tornEthPairToken0 ? prices[1] : prices[0];
pool.lastBlock = event.block.number.toI32();
pool.lastTimestamp = event.block.timestamp.toI32();
pool.save();
// Save stats
let stats = loadStats();
stats.tornUsdPrice = stats.ethUsdPrice.times(pool.ethPrice);
saveStats(stats, event.block);
}

55
src/utils.ts Normal file
View File

@@ -0,0 +1,55 @@
import { BigInt, BigDecimal, dataSource, Address, Bytes } from '@graphprotocol/graph-ts';
import { TornadoInfo, AllTornadoInfo } from './constants';
export let ONE_BI = BigInt.fromI32(1);
export let ZERO_BI = BigInt.fromI32(0);
export let ZERO_BD = BigDecimal.fromString('0');
export let CHAINLINK_BD: BigDecimal = BigInt.fromI32(10).pow(8 as u8).toBigDecimal();
export let ZERO_ADDRESS = Address.fromBytes(new Bytes(20));
export let Q192 = BigInt.fromI32(2).pow(192 as u8);
export function tenPow(decimals: i32): BigInt {
if (decimals > 255) {
return BigInt.fromI32(10).pow(255);
}
return BigInt.fromI32(10).pow(decimals as u8);
}
export function safeDiv(amount0: BigDecimal, amount1: BigDecimal): BigDecimal {
if (amount1.equals(ZERO_BD)) {
return ZERO_BD;
}
return amount0.div(amount1);
}
// for Uniswap V3 oracle from V3 subgraph
export function sqrtPriceX96ToTokenPrices(sqrtPriceX96: BigInt, decimals0: i32, decimals1: i32): BigDecimal[] {
let num = sqrtPriceX96.times(sqrtPriceX96).toBigDecimal();
let denom = BigDecimal.fromString(Q192.toString());
let price1 = safeDiv(
safeDiv(num, denom).times(tenPow(decimals0).toBigDecimal()),
tenPow(decimals1).toBigDecimal()
);
let price0 = safeDiv(BigDecimal.fromString('1'), price1);
return [price0, price1];
}
export function getTornadoInfo(): TornadoInfo {
return (AllTornadoInfo.get(dataSource.network()) || AllTornadoInfo.get('mainnet')) as TornadoInfo;
}
export function convertTokenToDecimal(tokenAmount: BigInt): BigDecimal {
return tokenAmount.toBigDecimal().div(
tenPow(getTornadoInfo().tornDecimals).toBigDecimal()
);
}
export function convertAnswerToDecimal(answer: BigInt): BigDecimal {
return answer.toBigDecimal().div(CHAINLINK_BD);
}

View File

@@ -1,4 +1,8 @@
specVersion: 0.0.2
specVersion: 1.3.0
description: Tornado Cash Governance
repository: https://codeberg.org/tornadocash/tornado-governance-subgraph
indexerHints:
prune: auto
schema:
file: ./schema.graphql
dataSources:
@@ -11,13 +15,15 @@ dataSources:
startBlock: 11474695
mapping:
kind: ethereum/events
apiVersion: 0.0.5
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- Proposal
- Voted
- Delegated
- Undelegated
- Receipt
- Vote
- Delegate
- DelegateEvent
- UndelegateEvent
abis:
- name: Governance
file: ./abis/Governance.json
@@ -33,6 +39,7 @@ dataSources:
- event: Undelegated(indexed address,indexed address)
handler: handleUndelegated
file: ./src/mapping.ts
- kind: ethereum
name: RelayerRegistry
network: mainnet
@@ -42,14 +49,156 @@ dataSources:
startBlock: 14173129
mapping:
kind: ethereum/events
apiVersion: 0.0.5
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- StakeBurned
- Relayer
- StakeBurn
- StakeDailyBurn
- RelayerDailyBurn
abis:
- name: RelayerRegistry
file: ./abis/RelayerRegistry.json
eventHandlers:
- event: RelayerRegistered(bytes32,string,address,uint256)
handler: handleRelayerRegistered
- event: RelayerUnregistered(address)
handler: handleRelayerUnregistered
- event: RelayerBalanceNullified(address)
handler: handleRelayerBalanceNullified
- event: WorkerRegistered(address,address)
handler: handleWorkerRegistered
- event: WorkerUnregistered(address,address)
handler: handleWorkerUnregistered
- event: StakeAddedToRelayer(address,uint256)
handler: handleStakeAddedToRelayer
- event: StakeBurned(address,uint256)
handler: handleStakeBurned
file: ./src/mapping.ts
file: ./src/relayer.ts
- kind: ethereum
name: InstanceRegistry
network: mainnet
source:
address: "0xB20c66C4DE72433F3cE747b58B86830c459CA911"
abi: InstanceRegistry
startBlock: 14173395
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- Instance
abis:
- name: InstanceRegistry
file: ./abis/InstanceRegistry.json
eventHandlers:
- event: InstanceStateUpdated(indexed address,uint8)
handler: handleInstanceStateUpdated
file: ./src/instance.ts
- kind: ethereum
name: TORN
network: mainnet
source:
address: "0x77777FeDdddFfC19Ff86DB637967013e6C6A116C"
abi: TORN
startBlock: 11474599
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- Balance
- Transfer
abis:
- name: TORN
file: ./abis/TORN.json
eventHandlers:
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
file: ./src/torn.ts
- kind: ethereum
name: TornPair
network: mainnet
source:
address: "0x97a5a0B2D7Ed3accb7FD6404A1f5CA29320905AF"
abi: V3Pair
startBlock: 12386774
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- TornPair
abis:
- name: V3Pair
file: ./abis/V3Pair.json
eventHandlers:
- event: Swap(indexed address,indexed address,int256,int256,uint160,uint128,int24)
handler: handleSwap
file: ./src/uniswap.ts
- kind: ethereum
name: FeedRegistry
network: mainnet
source:
address: "0x47fb2585d2c56fe188d0e6ec628a38b74fceeedf"
abi: FeedRegistry
startBlock: 12864088
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- DataFeed
abis:
- name: FeedRegistry
file: ./abis/FeedRegistry.json
- name: AccessControlledOffchainAggregator
file: ./abis/AccessControlledOffchainAggregator.json
eventHandlers:
- event: FeedConfirmed(indexed address,indexed address,indexed address,address,uint16,address)
handler: handleFeedConfirmed
file: ./src/chainlink.ts
templates:
- name: DataFeed
kind: ethereum/contract
network: mainnet
source:
abi: AccessControlledOffchainAggregator
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- DataFeed
abis:
- name: AccessControlledOffchainAggregator
file: ./abis/AccessControlledOffchainAggregator.json
eventHandlers:
- event: AnswerUpdated(indexed int256,indexed uint256,uint256)
handler: handleAnswerUpdated
file: ./src/chainlink.ts
- name: Instance
kind: ethereum/contract
network: mainnet
source:
abi: Instance
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- Instance
- Withdrawal
abis:
- name: Instance
file: ./abis/Instance.json
eventHandlers:
- event: Withdrawal(address,bytes32,indexed address,uint256)
handler: handleWithdrawal
file: ./src/instance.ts

4449
yarn.lock

File diff suppressed because it is too large Load Diff