light relayer
This commit is contained in:
parent
2da481cf16
commit
803a104a93
@ -1,8 +1,5 @@
|
|||||||
NET_ID=1
|
NET_ID=56
|
||||||
HTTP_RPC_URL=https://mainnet.infura.io
|
HTTP_RPC_URL=https://bsc-dataseed1.ninicoin.io/
|
||||||
WS_RPC_URL=wss://mainnet.infura.io/ws/v3/
|
|
||||||
# ORACLE_RPC_URL should always point to the mainnet
|
|
||||||
ORACLE_RPC_URL=https://mainnet.infura.io
|
|
||||||
REDIS_URL=redis://127.0.0.1:6379
|
REDIS_URL=redis://127.0.0.1:6379
|
||||||
|
|
||||||
# DNS settings
|
# DNS settings
|
||||||
@ -14,10 +11,8 @@ APP_PORT=8000
|
|||||||
PRIVATE_KEY=
|
PRIVATE_KEY=
|
||||||
# 0.05 means 0.05%
|
# 0.05 means 0.05%
|
||||||
REGULAR_TORNADO_WITHDRAW_FEE=0.05
|
REGULAR_TORNADO_WITHDRAW_FEE=0.05
|
||||||
MINING_SERVICE_FEE=0.05
|
|
||||||
REWARD_ACCOUNT=
|
REWARD_ACCOUNT=
|
||||||
CONFIRMATIONS=4
|
CONFIRMATIONS=4
|
||||||
|
|
||||||
# in GWEI
|
# in GWEI
|
||||||
MAX_GAS_PRICE=1000
|
MAX_GAS_PRICE=1000
|
||||||
AGGREGATOR=0x8cb1436F64a3c33aD17bb42F94e255c4c0E871b2
|
|
||||||
|
@ -1,319 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32[]",
|
|
||||||
"name": "domains",
|
|
||||||
"type": "bytes32[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "bulkResolve",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address[]",
|
|
||||||
"name": "result",
|
|
||||||
"type": "address[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract Governance",
|
|
||||||
"name": "governance",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getAllProposals",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"components": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "proposer",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "target",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "startTime",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "endTime",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "forVotes",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "againstVotes",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "executed",
|
|
||||||
"type": "bool"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "extended",
|
|
||||||
"type": "bool"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "enum Governance.ProposalState",
|
|
||||||
"name": "state",
|
|
||||||
"type": "uint8"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"internalType": "struct GovernanceAggregator.Proposal[]",
|
|
||||||
"name": "proposals",
|
|
||||||
"type": "tuple[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract Governance",
|
|
||||||
"name": "governance",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address[]",
|
|
||||||
"name": "accs",
|
|
||||||
"type": "address[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getGovernanceBalances",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "amounts",
|
|
||||||
"type": "uint256[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address[]",
|
|
||||||
"name": "fromTokens",
|
|
||||||
"type": "address[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "oneUnitAmounts",
|
|
||||||
"type": "uint256[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getPricesInETH",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "prices",
|
|
||||||
"type": "uint256[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract Governance",
|
|
||||||
"name": "governance",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "account",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getUserData",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "balance",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "latestProposalId",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "latestProposalIdState",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "timelock",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "delegatee",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract Miner",
|
|
||||||
"name": "miner",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address[]",
|
|
||||||
"name": "instances",
|
|
||||||
"type": "address[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "minerRates",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "_rates",
|
|
||||||
"type": "uint256[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "node",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "resolve",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract RewardSwap",
|
|
||||||
"name": "swap",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "swapState",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "balance",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "poolWeight",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract Miner",
|
|
||||||
"name": "miner",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address[]",
|
|
||||||
"name": "instances",
|
|
||||||
"type": "address[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "contract RewardSwap",
|
|
||||||
"name": "swap",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "miningData",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "_rates",
|
|
||||||
"type": "uint256[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "balance",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "poolWeight",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address[]",
|
|
||||||
"name": "fromTokens",
|
|
||||||
"type": "address[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "oneUnitAmounts",
|
|
||||||
"type": "uint256[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "contract RewardSwap",
|
|
||||||
"name": "swap",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "marketData",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256[]",
|
|
||||||
"name": "prices",
|
|
||||||
"type": "uint256[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "balance",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,12 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{ "internalType": "contract IERC20", "name": "srcToken", "type": "address" },
|
|
||||||
{ "internalType": "contract IERC20", "name": "dstToken", "type": "address" }
|
|
||||||
],
|
|
||||||
"name": "getRate",
|
|
||||||
"outputs": [{ "internalType": "uint256", "name": "weightedRate", "type": "uint256" }],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
}
|
|
||||||
]
|
|
1077
abis/mining.abi.json
1077
abis/mining.abi.json
File diff suppressed because it is too large
Load Diff
105
abis/proxyLightABI.json
Normal file
105
abis/proxyLightABI.json
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "sender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "bytes",
|
||||||
|
"name": "encryptedNote",
|
||||||
|
"type": "bytes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "EncryptedNote",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bytes[]",
|
||||||
|
"name": "_encryptedNotes",
|
||||||
|
"type": "bytes[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "backupNotes",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract ITornadoInstance",
|
||||||
|
"name": "_tornado",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes32",
|
||||||
|
"name": "_commitment",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "bytes",
|
||||||
|
"name": "_encryptedNote",
|
||||||
|
"type": "bytes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "deposit",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "payable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract ITornadoInstance",
|
||||||
|
"name": "_tornado",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
@ -1,252 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_torn",
|
|
||||||
"type": "bytes32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_miner",
|
|
||||||
"type": "bytes32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "_miningCap",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "_initialLiquidity",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "constructor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"indexed": false,
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "newWeight",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "PoolWeightUpdated",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"indexed": true,
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "recipient",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"indexed": false,
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "pTORN",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"indexed": false,
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "TORN",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "Swap",
|
|
||||||
"type": "event"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "DURATION",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "initialLiquidity",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "liquidity",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "miner",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "poolWeight",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "node",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "resolve",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "startTimestamp",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "tokensSold",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "torn",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract IERC20",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "recipient",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "amount",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "swap",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "amount",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "getExpectedReturn",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "tornVirtualBalance",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "newWeight",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "setPoolWeight",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,498 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "_newOperator",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "changeOperator",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "nullifierHashes",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"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": [],
|
|
||||||
"payable": true,
|
|
||||||
"stateMutability": "payable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "verifier",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract IVerifier",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_left",
|
|
||||||
"type": "bytes32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_right",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "hashLeftRight",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "pure",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "FIELD_SIZE",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "levels",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint32",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "operator",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_root",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "isKnownRoot",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "commitments",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "denomination",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "currentRootIndex",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint32",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "_newVerifier",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "updateVerifier",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_commitment",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "deposit",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": true,
|
|
||||||
"stateMutability": "payable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "getLastRoot",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "roots",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "ROOT_HISTORY_SIZE",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint32",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_nullifierHash",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "isSpent",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "zeros",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "ZERO_VALUE",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "filledSubtrees",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "nextIndex",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "uint32",
|
|
||||||
"name": "",
|
|
||||||
"type": "uint32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract IVerifier",
|
|
||||||
"name": "_verifier",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint256",
|
|
||||||
"name": "_denomination",
|
|
||||||
"type": "uint256"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "uint32",
|
|
||||||
"name": "_merkleTreeHeight",
|
|
||||||
"type": "uint32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "_operator",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "constructor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,171 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_tornadoTrees",
|
|
||||||
"type": "bytes32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "_governance",
|
|
||||||
"type": "bytes32"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "contract ITornado[]",
|
|
||||||
"name": "_instances",
|
|
||||||
"type": "address[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "constructor"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "governance",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract ITornado",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "instances",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "node",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "resolve",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "address",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [],
|
|
||||||
"name": "tornadoTrees",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract ITornadoTrees",
|
|
||||||
"name": "",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"stateMutability": "view",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract ITornado",
|
|
||||||
"name": "tornado",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bytes32",
|
|
||||||
"name": "commitment",
|
|
||||||
"type": "bytes32"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "deposit",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "payable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract ITornado",
|
|
||||||
"name": "instance",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"internalType": "bool",
|
|
||||||
"name": "update",
|
|
||||||
"type": "bool"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "updateInstances",
|
|
||||||
"outputs": [],
|
|
||||||
"stateMutability": "nonpayable",
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"internalType": "contract ITornado",
|
|
||||||
"name": "tornado",
|
|
||||||
"type": "address"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
@ -15,19 +15,10 @@ services:
|
|||||||
nginx_proxy_read_timeout: 600
|
nginx_proxy_read_timeout: 600
|
||||||
depends_on: [redis]
|
depends_on: [redis]
|
||||||
|
|
||||||
treeWatcher:
|
healthWatcher:
|
||||||
image: tornadocash/relayer
|
image: tornadocash/relayer
|
||||||
restart: always
|
restart: always
|
||||||
command: treeWatcher
|
command: healthWatcher
|
||||||
env_file: .env
|
|
||||||
environment:
|
|
||||||
REDIS_URL: redis://redis/0
|
|
||||||
depends_on: [redis]
|
|
||||||
|
|
||||||
priceWatcher:
|
|
||||||
image: tornadocash/relayer
|
|
||||||
restart: always
|
|
||||||
command: priceWatcher
|
|
||||||
env_file: .env
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
REDIS_URL: redis://redis/0
|
REDIS_URL: redis://redis/0
|
||||||
|
@ -2,7 +2,7 @@ version: '2'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
server:
|
server:
|
||||||
image: tornadocash/relayer:mining
|
image: tornadocash/relayer:light
|
||||||
restart: always
|
restart: always
|
||||||
command: server
|
command: server
|
||||||
env_file: .env
|
env_file: .env
|
||||||
@ -11,26 +11,8 @@ services:
|
|||||||
nginx_proxy_read_timeout: 600
|
nginx_proxy_read_timeout: 600
|
||||||
depends_on: [redis]
|
depends_on: [redis]
|
||||||
|
|
||||||
treeWatcher:
|
|
||||||
image: tornadocash/relayer:mining
|
|
||||||
restart: always
|
|
||||||
command: treeWatcher
|
|
||||||
env_file: .env
|
|
||||||
environment:
|
|
||||||
REDIS_URL: redis://redis/0
|
|
||||||
depends_on: [redis]
|
|
||||||
|
|
||||||
priceWatcher:
|
|
||||||
image: tornadocash/relayer:mining
|
|
||||||
restart: always
|
|
||||||
command: priceWatcher
|
|
||||||
env_file: .env
|
|
||||||
environment:
|
|
||||||
REDIS_URL: redis://redis/0
|
|
||||||
depends_on: [redis]
|
|
||||||
|
|
||||||
healthWatcher:
|
healthWatcher:
|
||||||
image: tornadocash/relayer:mining
|
image: tornadocash/relayer:light
|
||||||
restart: always
|
restart: always
|
||||||
command: healthWatcher
|
command: healthWatcher
|
||||||
env_file: .env
|
env_file: .env
|
||||||
@ -39,7 +21,7 @@ services:
|
|||||||
depends_on: [redis]
|
depends_on: [redis]
|
||||||
|
|
||||||
worker1:
|
worker1:
|
||||||
image: tornadocash/relayer:mining
|
image: tornadocash/relayer:light
|
||||||
restart: always
|
restart: always
|
||||||
command: worker
|
command: worker
|
||||||
env_file: .env
|
env_file: .env
|
||||||
@ -48,7 +30,7 @@ services:
|
|||||||
depends_on: [redis]
|
depends_on: [redis]
|
||||||
|
|
||||||
# worker2:
|
# worker2:
|
||||||
# image: tornadocash/relayer:mining
|
# image: tornadocash/relayer:light
|
||||||
# restart: always
|
# restart: always
|
||||||
# command: worker
|
# command: worker
|
||||||
# env_file: .env
|
# env_file: .env
|
||||||
|
647134
keys/TreeUpdate.json
647134
keys/TreeUpdate.json
File diff suppressed because one or more lines are too long
Binary file not shown.
16
package.json
16
package.json
@ -5,36 +5,26 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"server": "node src/server.js",
|
"server": "node src/server.js",
|
||||||
"worker": "node src/worker",
|
"worker": "node src/worker",
|
||||||
"treeWatcher": "node src/treeWatcher",
|
|
||||||
"priceWatcher": "node src/priceWatcher",
|
|
||||||
"healthWatcher": "node src/healthWatcher",
|
"healthWatcher": "node src/healthWatcher",
|
||||||
"eslint": "eslint --ext .js --ignore-path .gitignore .",
|
"eslint": "eslint --ext .js --ignore-path .gitignore .",
|
||||||
"prettier:check": "npx prettier --check . --config .prettierrc",
|
"prettier:check": "npx prettier --check . --config .prettierrc",
|
||||||
"prettier:fix": "npx prettier --write . --config .prettierrc",
|
"prettier:fix": "npx prettier --write . --config .prettierrc",
|
||||||
"lint": "yarn eslint && yarn prettier:check",
|
"lint": "yarn eslint && yarn prettier:check",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"start": "yarn server & yarn priceWatcher & yarn treeWatcher & yarn worker & yarn healthWatcher"
|
"start": "yarn server & yarn worker & yarn healthWatcher"
|
||||||
},
|
},
|
||||||
"author": "tornado.cash",
|
"author": "tornado.cash",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.5",
|
"ajv": "^6.12.5",
|
||||||
"async-mutex": "^0.2.4",
|
|
||||||
"bull": "^3.12.1",
|
"bull": "^3.12.1",
|
||||||
"circomlib": "git+https://github.com/tornadocash/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
|
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"eth-ens-namehash": "^2.0.8",
|
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"fixed-merkle-tree": "^0.4.0",
|
"gas-price-oracle": "^0.3.1",
|
||||||
"gas-price-oracle": "^0.2.2",
|
|
||||||
"ioredis": "^4.14.1",
|
"ioredis": "^4.14.1",
|
||||||
"node-fetch": "^2.6.0",
|
"tx-manager": "^0.3.0",
|
||||||
"torn-token": "1.0.4",
|
|
||||||
"tornado-anonymity-mining": "^2.1.2",
|
|
||||||
"tx-manager": "^0.2.9",
|
|
||||||
"uuid": "^8.3.0",
|
"uuid": "^8.3.0",
|
||||||
"web3": "^1.3.0",
|
"web3": "^1.3.0",
|
||||||
"web3-core-promievent": "^1.3.0",
|
|
||||||
"web3-utils": "^1.2.2"
|
"web3-utils": "^1.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1,29 +1,26 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
|
||||||
const { jobType } = require('./constants')
|
const { jobType, networkConfig } = require('./constants')
|
||||||
const tornConfig = require('torn-token')
|
|
||||||
|
const netId = Number(process.env.NET_ID) || 56
|
||||||
|
const { instances, gasPrices, nativeCurrency, proxyLight } = networkConfig[`netId${netId}`]
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
netId: Number(process.env.NET_ID) || 1,
|
netId,
|
||||||
redisUrl: process.env.REDIS_URL || 'redis://127.0.0.1:6379',
|
redisUrl: process.env.REDIS_URL || 'redis://127.0.0.1:6379',
|
||||||
httpRpcUrl: process.env.HTTP_RPC_URL,
|
httpRpcUrl: process.env.HTTP_RPC_URL,
|
||||||
wsRpcUrl: process.env.WS_RPC_URL,
|
|
||||||
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/',
|
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/',
|
||||||
offchainOracleAddress: '0x080AB73787A8B13EC7F40bd7d00d6CC07F9b24d0',
|
|
||||||
aggregatorAddress: process.env.AGGREGATOR,
|
|
||||||
minerMerkleTreeHeight: 20,
|
minerMerkleTreeHeight: 20,
|
||||||
privateKey: process.env.PRIVATE_KEY,
|
privateKey: process.env.PRIVATE_KEY,
|
||||||
instances: tornConfig.instances,
|
instances,
|
||||||
torn: tornConfig,
|
|
||||||
port: process.env.APP_PORT || 8000,
|
port: process.env.APP_PORT || 8000,
|
||||||
tornadoServiceFee: Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE),
|
tornadoServiceFee: Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE),
|
||||||
miningServiceFee: Number(process.env.MINING_SERVICE_FEE),
|
|
||||||
rewardAccount: process.env.REWARD_ACCOUNT,
|
rewardAccount: process.env.REWARD_ACCOUNT,
|
||||||
tornadoGoerliProxy: '0x454d870a72e29d5E5697f635128D18077BD04C60',
|
gasPrices,
|
||||||
gasLimits: {
|
gasLimits: {
|
||||||
[jobType.TORNADO_WITHDRAW]: 390000,
|
[jobType.TORNADO_WITHDRAW]: 390000,
|
||||||
WITHDRAW_WITH_EXTRA: 480000,
|
|
||||||
[jobType.MINING_REWARD]: 455000,
|
|
||||||
[jobType.MINING_WITHDRAW]: 400000,
|
|
||||||
},
|
},
|
||||||
minimumBalance: '1000000000000000000',
|
proxyLight,
|
||||||
|
nativeCurrency,
|
||||||
|
minimumBalance: '500000000000000000', // 0.5
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
const jobType = Object.freeze({
|
const jobType = Object.freeze({
|
||||||
TORNADO_WITHDRAW: 'TORNADO_WITHDRAW',
|
TORNADO_WITHDRAW: 'TORNADO_WITHDRAW',
|
||||||
MINING_REWARD: 'MINING_REWARD',
|
|
||||||
MINING_WITHDRAW: 'MINING_WITHDRAW',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const status = Object.freeze({
|
const status = Object.freeze({
|
||||||
@ -14,7 +12,30 @@ const status = Object.freeze({
|
|||||||
FAILED: 'FAILED',
|
FAILED: 'FAILED',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const networkConfig = {
|
||||||
|
netId56: {
|
||||||
|
gasPrices: {
|
||||||
|
instant: 5,
|
||||||
|
fast: 5,
|
||||||
|
standard: 5,
|
||||||
|
low: 5,
|
||||||
|
},
|
||||||
|
nativeCurrency: 'bnb',
|
||||||
|
instances: {
|
||||||
|
bnb: {
|
||||||
|
instanceAddress: {
|
||||||
|
0.1: '0x0Ce22770451A8acAD1220D9d1678656b4fAe4a1d',
|
||||||
|
},
|
||||||
|
symbol: 'BNB',
|
||||||
|
decimals: 18,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
proxyLight: '0x5D595DB16eb6d074E0e7E7f0bE37E7e75f23BEc7',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
jobType,
|
jobType,
|
||||||
status,
|
status,
|
||||||
|
networkConfig,
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
const {
|
const {
|
||||||
getTornadoWithdrawInputError,
|
getTornadoWithdrawInputError,
|
||||||
getMiningRewardInputError,
|
|
||||||
getMiningWithdrawInputError,
|
|
||||||
} = require('./validator')
|
} = require('./validator')
|
||||||
const { postJob } = require('./queue')
|
const { postJob } = require('./queue')
|
||||||
const { jobType } = require('./constants')
|
const { jobType } = require('./constants')
|
||||||
@ -20,36 +18,6 @@ async function tornadoWithdraw(req, res) {
|
|||||||
return res.json({ id })
|
return res.json({ id })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function miningReward(req, res) {
|
|
||||||
const inputError = getMiningRewardInputError(req.body)
|
|
||||||
if (inputError) {
|
|
||||||
console.log('Invalid input:', inputError)
|
|
||||||
return res.status(400).json({ error: inputError })
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = await postJob({
|
|
||||||
type: jobType.MINING_REWARD,
|
|
||||||
request: req.body,
|
|
||||||
})
|
|
||||||
return res.json({ id })
|
|
||||||
}
|
|
||||||
|
|
||||||
async function miningWithdraw(req, res) {
|
|
||||||
const inputError = getMiningWithdrawInputError(req.body)
|
|
||||||
if (inputError) {
|
|
||||||
console.log('Invalid input:', inputError)
|
|
||||||
return res.status(400).json({ error: inputError })
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = await postJob({
|
|
||||||
type: jobType.MINING_WITHDRAW,
|
|
||||||
request: req.body,
|
|
||||||
})
|
|
||||||
return res.json({ id })
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
tornadoWithdraw,
|
tornadoWithdraw,
|
||||||
miningReward,
|
|
||||||
miningWithdraw,
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,14 @@ const Redis = require('ioredis')
|
|||||||
const { toBN, fromWei } = require('web3-utils')
|
const { toBN, fromWei } = require('web3-utils')
|
||||||
|
|
||||||
const { setSafeInterval } = require('./utils')
|
const { setSafeInterval } = require('./utils')
|
||||||
const { redisUrl, httpRpcUrl, privateKey, minimumBalance } = require('./config')
|
const {
|
||||||
|
redisUrl,
|
||||||
|
httpRpcUrl,
|
||||||
|
privateKey,
|
||||||
|
minimumBalance,
|
||||||
|
nativeCurrency,
|
||||||
|
instances,
|
||||||
|
} = require('./config')
|
||||||
|
|
||||||
const web3 = new Web3(httpRpcUrl)
|
const web3 = new Web3(httpRpcUrl)
|
||||||
const redis = new Redis(redisUrl)
|
const redis = new Redis(redisUrl)
|
||||||
@ -14,7 +21,8 @@ async function main() {
|
|||||||
const balance = await web3.eth.getBalance(address)
|
const balance = await web3.eth.getBalance(address)
|
||||||
|
|
||||||
if (toBN(balance).lt(toBN(minimumBalance))) {
|
if (toBN(balance).lt(toBN(minimumBalance))) {
|
||||||
throw new Error(`Not enough balance, less than ${fromWei(minimumBalance)} ETH`)
|
const currency = instances[nativeCurrency].symbol
|
||||||
|
throw new Error(`Not enough balance, less than ${fromWei(minimumBalance)} ${currency}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
await redis.hset('health', { status: true, error: '' })
|
await redis.hset('health', { status: true, error: '' })
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
const Redis = require('ioredis')
|
|
||||||
const { redisUrl, offchainOracleAddress, oracleRpcUrl } = require('./config')
|
|
||||||
const { getArgsForOracle, setSafeInterval } = require('./utils')
|
|
||||||
const redis = new Redis(redisUrl)
|
|
||||||
const Web3 = require('web3')
|
|
||||||
const web3 = new Web3(
|
|
||||||
new Web3.providers.HttpProvider(oracleRpcUrl, {
|
|
||||||
timeout: 200000, // ms
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const offchainOracleABI = require('../abis/OffchainOracle.abi.json')
|
|
||||||
|
|
||||||
const offchainOracle = new web3.eth.Contract(offchainOracleABI, offchainOracleAddress)
|
|
||||||
const { tokenAddresses, oneUintAmount, currencyLookup } = getArgsForOracle()
|
|
||||||
|
|
||||||
const { toBN } = require('web3-utils')
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
try {
|
|
||||||
const ethPrices = {}
|
|
||||||
for (let i = 0; i < tokenAddresses.length; i++) {
|
|
||||||
try {
|
|
||||||
const price = await offchainOracle.methods
|
|
||||||
.getRate(tokenAddresses[i], '0x0000000000000000000000000000000000000000')
|
|
||||||
.call()
|
|
||||||
const numerator = toBN(oneUintAmount[i])
|
|
||||||
const denominator = toBN(10).pow(toBN(18)) // eth decimals
|
|
||||||
const priceFormatted = toBN(price).mul(numerator).div(denominator)
|
|
||||||
|
|
||||||
ethPrices[currencyLookup[tokenAddresses[i]]] = priceFormatted.toString()
|
|
||||||
} catch (e) {
|
|
||||||
console.error('cant get price of ', tokenAddresses[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await redis.hmset('prices', ethPrices)
|
|
||||||
console.log('Wrote following prices to redis', ethPrices)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('priceWatcher error', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setSafeInterval(main, 30 * 1000)
|
|
@ -1,30 +0,0 @@
|
|||||||
const { httpRpcUrl, aggregatorAddress } = require('./config')
|
|
||||||
const Web3 = require('web3')
|
|
||||||
const web3 = new Web3(httpRpcUrl)
|
|
||||||
const aggregator = new web3.eth.Contract(require('../abis/Aggregator.abi.json'), aggregatorAddress)
|
|
||||||
const ens = require('eth-ens-namehash')
|
|
||||||
|
|
||||||
class ENSResolver {
|
|
||||||
constructor() {
|
|
||||||
this.addresses = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
async resolve(domains) {
|
|
||||||
if (!Array.isArray(domains)) {
|
|
||||||
domains = [domains]
|
|
||||||
}
|
|
||||||
|
|
||||||
const unresolved = domains.filter(d => !this.addresses[d])
|
|
||||||
if (unresolved.length) {
|
|
||||||
const resolved = await aggregator.methods.bulkResolve(unresolved.map(ens.hash)).call()
|
|
||||||
for (let i = 0; i < resolved.length; i++) {
|
|
||||||
this.addresses[domains[i]] = resolved[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const addresses = domains.map(domain => this.addresses[domain])
|
|
||||||
return addresses.length === 1 ? addresses[0] : addresses
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = ENSResolver
|
|
@ -30,8 +30,6 @@ app.get('/v1/jobs/:id', status.getJob)
|
|||||||
app.post('/v1/tornadoWithdraw', controller.tornadoWithdraw)
|
app.post('/v1/tornadoWithdraw', controller.tornadoWithdraw)
|
||||||
app.get('/status', status.status)
|
app.get('/status', status.status)
|
||||||
app.post('/relay', controller.tornadoWithdraw)
|
app.post('/relay', controller.tornadoWithdraw)
|
||||||
app.post('/v1/miningReward', controller.miningReward)
|
|
||||||
app.post('/v1/miningWithdraw', controller.miningWithdraw)
|
|
||||||
|
|
||||||
if (!isAddress(rewardAccount)) {
|
if (!isAddress(rewardAccount)) {
|
||||||
throw new Error('No REWARD_ACCOUNT specified')
|
throw new Error('No REWARD_ACCOUNT specified')
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
const queue = require('./queue')
|
const queue = require('./queue')
|
||||||
const { netId, tornadoServiceFee, miningServiceFee, instances, redisUrl, rewardAccount } = require('./config')
|
const { netId, tornadoServiceFee, instances, redisUrl, rewardAccount } = require('./config')
|
||||||
const { version } = require('../package.json')
|
const { version } = require('../package.json')
|
||||||
const Redis = require('ioredis')
|
const Redis = require('ioredis')
|
||||||
const redis = new Redis(redisUrl)
|
const redis = new Redis(redisUrl)
|
||||||
|
|
||||||
async function status(req, res) {
|
async function status(req, res) {
|
||||||
const ethPrices = await redis.hgetall('prices')
|
|
||||||
const health = await redis.hgetall('health')
|
const health = await redis.hgetall('health')
|
||||||
|
|
||||||
const { waiting: currentQueue } = await queue.queue.getJobCounts()
|
const { waiting: currentQueue } = await queue.queue.getJobCounts()
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
rewardAccount,
|
rewardAccount,
|
||||||
instances: instances[`netId${netId}`],
|
instances,
|
||||||
netId,
|
netId,
|
||||||
ethPrices,
|
|
||||||
tornadoServiceFee,
|
tornadoServiceFee,
|
||||||
miningServiceFee,
|
|
||||||
version,
|
version,
|
||||||
health,
|
health,
|
||||||
currentQueue,
|
currentQueue,
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
const MerkleTree = require('fixed-merkle-tree')
|
|
||||||
const { redisUrl, wsRpcUrl, minerMerkleTreeHeight, torn } = require('./config')
|
|
||||||
const { poseidonHash2 } = require('./utils')
|
|
||||||
const { toBN } = require('web3-utils')
|
|
||||||
const Redis = require('ioredis')
|
|
||||||
const redis = new Redis(redisUrl)
|
|
||||||
const ENSResolver = require('./resolver')
|
|
||||||
const resolver = new ENSResolver()
|
|
||||||
const Web3 = require('web3')
|
|
||||||
const web3 = new Web3(
|
|
||||||
new Web3.providers.WebsocketProvider(wsRpcUrl, {
|
|
||||||
clientConfig: {
|
|
||||||
maxReceivedFrameSize: 100000000,
|
|
||||||
maxReceivedMessageSize: 100000000,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
const MinerABI = require('../abis/mining.abi.json')
|
|
||||||
let contract
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let tree, eventSubscription, blockSubscription
|
|
||||||
|
|
||||||
// todo handle the situation when we have two rewards in one block
|
|
||||||
async function fetchEvents(from = 0, to = 'latest') {
|
|
||||||
try {
|
|
||||||
const events = await contract.getPastEvents('NewAccount', {
|
|
||||||
fromBlock: from,
|
|
||||||
toBlock: to,
|
|
||||||
})
|
|
||||||
return events
|
|
||||||
.sort((a, b) => a.returnValues.index - b.returnValues.index)
|
|
||||||
.map(e => toBN(e.returnValues.commitment))
|
|
||||||
} catch (e) {
|
|
||||||
console.error('error fetching events', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processNewEvent(err, event) {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(`Event handler error: ${err}`)
|
|
||||||
// console.error(err)
|
|
||||||
// return
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`New account event
|
|
||||||
Index: ${event.returnValues.index}
|
|
||||||
Commitment: ${event.returnValues.commitment}
|
|
||||||
Nullifier: ${event.returnValues.nullifier}
|
|
||||||
EncAcc: ${event.returnValues.encryptedAccount}`,
|
|
||||||
)
|
|
||||||
const { commitment, index } = event.returnValues
|
|
||||||
if (tree.elements().length === Number(index)) {
|
|
||||||
tree.insert(toBN(commitment))
|
|
||||||
await updateRedis()
|
|
||||||
} else if (tree.elements().length === Number(index) + 1) {
|
|
||||||
console.log('Replacing element', index)
|
|
||||||
tree.update(index, toBN(commitment))
|
|
||||||
await updateRedis()
|
|
||||||
} else {
|
|
||||||
console.log(`Invalid element index ${index}, rebuilding tree`)
|
|
||||||
rebuild()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processNewBlock(err) {
|
|
||||||
if (err) {
|
|
||||||
throw new Error(`Event handler error: ${err}`)
|
|
||||||
// console.error(err)
|
|
||||||
// return
|
|
||||||
}
|
|
||||||
// what if updateRedis takes more than 15 sec?
|
|
||||||
await updateRedis()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateRedis() {
|
|
||||||
const rootOnContract = await contract.methods.getLastAccountRoot().call()
|
|
||||||
if (!tree.root().eq(toBN(rootOnContract))) {
|
|
||||||
console.log(`Invalid tree root: ${tree.root()} != ${toBN(rootOnContract)}, rebuilding tree`)
|
|
||||||
rebuild()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const rootInRedis = await redis.get('tree:root')
|
|
||||||
if (!rootInRedis || !tree.root().eq(toBN(rootInRedis))) {
|
|
||||||
const serializedTree = JSON.stringify(tree.serialize())
|
|
||||||
await redis.set('tree:elements', serializedTree)
|
|
||||||
await redis.set('tree:root', tree.root().toString())
|
|
||||||
await redis.publish('treeUpdate', tree.root().toString())
|
|
||||||
console.log('Updated tree in redis, new root:', tree.root().toString())
|
|
||||||
} else {
|
|
||||||
console.log('Tree in redis is up to date, skipping update')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function rebuild() {
|
|
||||||
process.exit(1)
|
|
||||||
// await eventSubscription.unsubscribe()
|
|
||||||
// await blockSubscription.unsubscribe()
|
|
||||||
// setTimeout(init, 3000)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
try {
|
|
||||||
console.log('Initializing')
|
|
||||||
const miner = await resolver.resolve(torn.miningV2.address)
|
|
||||||
contract = new web3.eth.Contract(MinerABI, miner)
|
|
||||||
const block = await web3.eth.getBlockNumber()
|
|
||||||
const events = await fetchEvents(0, block)
|
|
||||||
tree = new MerkleTree(minerMerkleTreeHeight, events, { hashFunction: poseidonHash2 })
|
|
||||||
await updateRedis()
|
|
||||||
console.log(`Rebuilt tree with ${events.length} elements, root: ${tree.root()}`)
|
|
||||||
eventSubscription = contract.events.NewAccount({ fromBlock: block + 1 }, processNewEvent)
|
|
||||||
blockSubscription = web3.eth.subscribe('newBlockHeaders', processNewBlock)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('error on init treeWatcher', e.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init()
|
|
||||||
|
|
||||||
process.on('unhandledRejection', error => {
|
|
||||||
console.error('Unhandled promise rejection', error)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
62
src/utils.js
62
src/utils.js
@ -1,23 +1,11 @@
|
|||||||
const { instances, netId } = require('./config')
|
const { instances } = require('./config')
|
||||||
const { poseidon } = require('circomlib')
|
const { toChecksumAddress, BN } = require('web3-utils')
|
||||||
const { toBN, toChecksumAddress, BN } = require('web3-utils')
|
|
||||||
|
|
||||||
const TOKENS = {
|
|
||||||
torn: {
|
|
||||||
tokenAddress: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
|
|
||||||
symbol: 'TORN',
|
|
||||||
decimals: 18,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const sleep = ms => new Promise(res => setTimeout(res, ms))
|
|
||||||
|
|
||||||
function getInstance(address) {
|
function getInstance(address) {
|
||||||
address = toChecksumAddress(address)
|
address = toChecksumAddress(address)
|
||||||
const inst = instances[`netId${netId}`]
|
for (const currency of Object.keys(instances)) {
|
||||||
for (const currency of Object.keys(inst)) {
|
for (const amount of Object.keys(instances[currency].instanceAddress)) {
|
||||||
for (const amount of Object.keys(inst[currency].instanceAddress)) {
|
if (instances[currency].instanceAddress[amount] === address) {
|
||||||
if (inst[currency].instanceAddress[amount] === address) {
|
|
||||||
return { currency, amount }
|
return { currency, amount }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,9 +13,6 @@ function getInstance(address) {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const poseidonHash = items => toBN(poseidon(items).toString())
|
|
||||||
const poseidonHash2 = (a, b) => poseidonHash([a, b])
|
|
||||||
|
|
||||||
function setSafeInterval(func, interval) {
|
function setSafeInterval(func, interval) {
|
||||||
func()
|
func()
|
||||||
.catch(console.error)
|
.catch(console.error)
|
||||||
@ -36,39 +21,6 @@ function setSafeInterval(func, interval) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A promise that resolves when the source emits specified event
|
|
||||||
*/
|
|
||||||
function when(source, event) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
source
|
|
||||||
.once(event, payload => {
|
|
||||||
resolve(payload)
|
|
||||||
})
|
|
||||||
.on('error', error => {
|
|
||||||
reject(error)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getArgsForOracle() {
|
|
||||||
const tokens = {
|
|
||||||
...instances.netId1,
|
|
||||||
...TOKENS,
|
|
||||||
}
|
|
||||||
const tokenAddresses = []
|
|
||||||
const oneUintAmount = []
|
|
||||||
const currencyLookup = {}
|
|
||||||
Object.entries(tokens).map(([currency, data]) => {
|
|
||||||
if (currency !== 'eth') {
|
|
||||||
tokenAddresses.push(data.tokenAddress)
|
|
||||||
oneUintAmount.push(toBN('10').pow(toBN(data.decimals.toString())).toString())
|
|
||||||
currencyLookup[data.tokenAddress] = currency
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return { tokenAddresses, oneUintAmount, currencyLookup }
|
|
||||||
}
|
|
||||||
|
|
||||||
function fromDecimals(value, decimals) {
|
function fromDecimals(value, decimals) {
|
||||||
value = value.toString()
|
value = value.toString()
|
||||||
let ether = value.toString()
|
let ether = value.toString()
|
||||||
@ -121,9 +73,5 @@ function fromDecimals(value, decimals) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
getInstance,
|
getInstance,
|
||||||
setSafeInterval,
|
setSafeInterval,
|
||||||
poseidonHash2,
|
|
||||||
sleep,
|
|
||||||
when,
|
|
||||||
getArgsForOracle,
|
|
||||||
fromDecimals,
|
fromDecimals,
|
||||||
}
|
}
|
||||||
|
252
src/worker.js
252
src/worker.js
@ -1,96 +1,50 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { toBN, toWei, fromWei, toChecksumAddress } = require('web3-utils')
|
|
||||||
const MerkleTree = require('fixed-merkle-tree')
|
|
||||||
const Redis = require('ioredis')
|
|
||||||
const { GasPriceOracle } = require('gas-price-oracle')
|
const { GasPriceOracle } = require('gas-price-oracle')
|
||||||
const { Utils, Controller } = require('tornado-anonymity-mining')
|
const { toBN, toWei, fromWei } = require('web3-utils')
|
||||||
|
|
||||||
const swapABI = require('../abis/swap.abi.json')
|
const proxyLightABI = require('../abis/proxyLightABI.json')
|
||||||
const miningABI = require('../abis/mining.abi.json')
|
|
||||||
const tornadoABI = require('../abis/tornadoABI.json')
|
|
||||||
const tornadoProxyABI = require('../abis/tornadoProxyABI.json')
|
|
||||||
const { queue } = require('./queue')
|
const { queue } = require('./queue')
|
||||||
const { poseidonHash2, getInstance, fromDecimals, sleep } = require('./utils')
|
const { getInstance, fromDecimals } = require('./utils')
|
||||||
const { jobType, status } = require('./constants')
|
const { jobType, status } = require('./constants')
|
||||||
const {
|
const {
|
||||||
torn,
|
|
||||||
netId,
|
netId,
|
||||||
redisUrl,
|
gasPrices,
|
||||||
gasLimits,
|
gasLimits,
|
||||||
instances,
|
instances,
|
||||||
privateKey,
|
privateKey,
|
||||||
|
proxyLight,
|
||||||
httpRpcUrl,
|
httpRpcUrl,
|
||||||
oracleRpcUrl,
|
|
||||||
miningServiceFee,
|
|
||||||
tornadoServiceFee,
|
tornadoServiceFee,
|
||||||
tornadoGoerliProxy,
|
|
||||||
} = require('./config')
|
} = require('./config')
|
||||||
const ENSResolver = require('./resolver')
|
|
||||||
const resolver = new ENSResolver()
|
|
||||||
const { TxManager } = require('tx-manager')
|
const { TxManager } = require('tx-manager')
|
||||||
|
|
||||||
let web3
|
let web3
|
||||||
let currentTx
|
let currentTx
|
||||||
let currentJob
|
let currentJob
|
||||||
let tree
|
|
||||||
let txManager
|
let txManager
|
||||||
let controller
|
let gasPriceOracle
|
||||||
let swap
|
|
||||||
let minerContract
|
|
||||||
const redis = new Redis(redisUrl)
|
|
||||||
const redisSubscribe = new Redis(redisUrl)
|
|
||||||
const gasPriceOracle = new GasPriceOracle({ defaultRpc: oracleRpcUrl })
|
|
||||||
|
|
||||||
async function fetchTree() {
|
function start() {
|
||||||
const elements = await redis.get('tree:elements')
|
|
||||||
const convert = (_, val) => (typeof val === 'string' ? toBN(val) : val)
|
|
||||||
tree = MerkleTree.deserialize(JSON.parse(elements, convert), poseidonHash2)
|
|
||||||
|
|
||||||
if (currentTx && currentJob && ['MINING_REWARD', 'MINING_WITHDRAW'].includes(currentJob.data.type)) {
|
|
||||||
const { proof, args } = currentJob.data
|
|
||||||
if (toBN(args.account.inputRoot).eq(toBN(tree.root()))) {
|
|
||||||
console.log('Account root is up to date. Skipping Root Update operation...')
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
console.log('Account root is outdated. Starting Root Update operation...')
|
|
||||||
}
|
|
||||||
|
|
||||||
const update = await controller.treeUpdate(args.account.outputCommitment, tree)
|
|
||||||
|
|
||||||
const minerAddress = await resolver.resolve(torn.miningV2.address)
|
|
||||||
const instance = new web3.eth.Contract(miningABI, minerAddress)
|
|
||||||
const data =
|
|
||||||
currentJob.data.type === 'MINING_REWARD'
|
|
||||||
? instance.methods.reward(proof, args, update.proof, update.args).encodeABI()
|
|
||||||
: instance.methods.withdraw(proof, args, update.proof, update.args).encodeABI()
|
|
||||||
await currentTx.replace({
|
|
||||||
to: minerAddress,
|
|
||||||
data,
|
|
||||||
})
|
|
||||||
console.log('replaced pending tx')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function start() {
|
|
||||||
try {
|
try {
|
||||||
web3 = new Web3(httpRpcUrl)
|
web3 = new Web3(httpRpcUrl)
|
||||||
const { CONFIRMATIONS, MAX_GAS_PRICE } = process.env
|
const { CONFIRMATIONS, MAX_GAS_PRICE } = process.env
|
||||||
|
let gasPriceOracleConfig = {}
|
||||||
|
|
||||||
|
if (netId === 56) {
|
||||||
|
gasPriceOracleConfig = {
|
||||||
|
chainId: netId,
|
||||||
|
defaultFallbackGasPrices: gasPrices,
|
||||||
|
}
|
||||||
|
gasPriceOracle = new GasPriceOracle(gasPriceOracleConfig)
|
||||||
|
}
|
||||||
|
|
||||||
txManager = new TxManager({
|
txManager = new TxManager({
|
||||||
privateKey,
|
privateKey,
|
||||||
rpcUrl: httpRpcUrl,
|
rpcUrl: httpRpcUrl,
|
||||||
config: { CONFIRMATIONS, MAX_GAS_PRICE, THROW_ON_REVERT: false },
|
config: { CONFIRMATIONS, MAX_GAS_PRICE, THROW_ON_REVERT: false },
|
||||||
|
gasPriceOracleConfig,
|
||||||
})
|
})
|
||||||
swap = new web3.eth.Contract(swapABI, await resolver.resolve(torn.rewardSwap.address))
|
|
||||||
minerContract = new web3.eth.Contract(miningABI, await resolver.resolve(torn.miningV2.address))
|
|
||||||
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
|
||||||
await fetchTree()
|
|
||||||
const provingKeys = {
|
|
||||||
treeUpdateCircuit: require('../keys/TreeUpdate.json'),
|
|
||||||
treeUpdateProvingKey: fs.readFileSync('./keys/TreeUpdate_proving_key.bin').buffer,
|
|
||||||
}
|
|
||||||
controller = new Controller({ provingKeys })
|
|
||||||
await controller.init()
|
|
||||||
queue.process(processJob)
|
queue.process(processJob)
|
||||||
console.log('Worker started')
|
console.log('Worker started')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -98,39 +52,23 @@ async function start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFee({ data }) {
|
|
||||||
if (data.type === jobType.TORNADO_WITHDRAW) {
|
|
||||||
return checkTornadoFee(data)
|
|
||||||
}
|
|
||||||
return checkMiningFee(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkTornadoFee({ args, contract }) {
|
async function checkTornadoFee({ args, contract }) {
|
||||||
const { currency, amount } = getInstance(contract)
|
const { currency, amount } = getInstance(contract)
|
||||||
const { decimals } = instances[`netId${netId}`][currency]
|
const { decimals } = instances[currency]
|
||||||
const [fee, refund] = [args[4], args[5]].map(toBN)
|
const fee = toBN(args[4])
|
||||||
const { fast } = await gasPriceOracle.gasPrices()
|
let { fast } = gasPrices
|
||||||
|
|
||||||
|
if (gasPriceOracle) {
|
||||||
|
// eslint-disable-next-line no-extra-semi
|
||||||
|
;({ fast } = await gasPriceOracle.gasPrices())
|
||||||
|
}
|
||||||
|
|
||||||
const ethPrice = await redis.hget('prices', currency)
|
|
||||||
const expense = toBN(toWei(fast.toString(), 'gwei')).mul(toBN(gasLimits[jobType.TORNADO_WITHDRAW]))
|
const expense = toBN(toWei(fast.toString(), 'gwei')).mul(toBN(gasLimits[jobType.TORNADO_WITHDRAW]))
|
||||||
const feePercent = toBN(fromDecimals(amount, decimals))
|
const feePercent = toBN(fromDecimals(amount, decimals))
|
||||||
.mul(toBN(parseInt(tornadoServiceFee * 1e10)))
|
.mul(toBN(parseInt(tornadoServiceFee * 1e10)))
|
||||||
.div(toBN(1e10 * 100))
|
.div(toBN(1e10 * 100))
|
||||||
let desiredFee
|
const desiredFee = expense.add(feePercent)
|
||||||
switch (currency) {
|
|
||||||
case 'eth': {
|
|
||||||
desiredFee = expense.add(feePercent)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
desiredFee = expense
|
|
||||||
.add(refund)
|
|
||||||
.mul(toBN(10 ** decimals))
|
|
||||||
.div(toBN(ethPrice))
|
|
||||||
desiredFee = desiredFee.add(feePercent)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(
|
console.log(
|
||||||
'sent fee, desired fee, feePercent',
|
'sent fee, desired fee, feePercent',
|
||||||
fromWei(fee.toString()),
|
fromWei(fee.toString()),
|
||||||
@ -142,99 +80,16 @@ async function checkTornadoFee({ args, contract }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkMiningFee({ args }) {
|
function getTxObject({ data }) {
|
||||||
const { fast } = await gasPriceOracle.gasPrices()
|
const contract = new web3.eth.Contract(proxyLightABI, proxyLight)
|
||||||
const ethPrice = await redis.hget('prices', 'torn')
|
|
||||||
const isMiningReward = currentJob.data.type === jobType.MINING_REWARD
|
|
||||||
const providedFee = isMiningReward ? toBN(args.fee) : toBN(args.extData.fee)
|
|
||||||
|
|
||||||
const expense = toBN(toWei(fast.toString(), 'gwei')).mul(toBN(gasLimits[currentJob.data.type]))
|
const calldata = contract.methods.withdraw(data.contract, data.proof, ...data.args).encodeABI()
|
||||||
const expenseInTorn = expense.mul(toBN(1e18)).div(toBN(ethPrice))
|
|
||||||
// todo make aggregator for ethPrices and rewardSwap data
|
|
||||||
const balance = await swap.methods.tornVirtualBalance().call()
|
|
||||||
const poolWeight = await swap.methods.poolWeight().call()
|
|
||||||
const expenseInPoints = Utils.reverseTornadoFormula({ balance, tokens: expenseInTorn, poolWeight })
|
|
||||||
/* eslint-disable */
|
|
||||||
const serviceFeePercent = isMiningReward
|
|
||||||
? toBN(0)
|
|
||||||
: toBN(args.amount)
|
|
||||||
.sub(providedFee) // args.amount includes fee
|
|
||||||
.mul(toBN(parseInt(miningServiceFee * 1e10)))
|
|
||||||
.div(toBN(1e10 * 100))
|
|
||||||
/* eslint-enable */
|
|
||||||
const desiredFee = expenseInPoints.add(serviceFeePercent) // in points
|
|
||||||
console.log(
|
|
||||||
'user provided fee, desired fee, serviceFeePercent',
|
|
||||||
providedFee.toString(),
|
|
||||||
desiredFee.toString(),
|
|
||||||
serviceFeePercent.toString(),
|
|
||||||
)
|
|
||||||
if (toBN(providedFee).lt(desiredFee)) {
|
|
||||||
throw new Error('Provided fee is not enough. Probably it is a Gas Price spike, try to resubmit.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getProxyContract() {
|
|
||||||
let proxyAddress
|
|
||||||
|
|
||||||
if (netId === 5) {
|
|
||||||
proxyAddress = tornadoGoerliProxy
|
|
||||||
} else {
|
|
||||||
proxyAddress = await resolver.resolve(torn.tornadoProxy.address)
|
|
||||||
}
|
|
||||||
|
|
||||||
const contract = new web3.eth.Contract(tornadoProxyABI, proxyAddress)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
contract,
|
value: data.args[5],
|
||||||
isOldProxy: checkOldProxy(proxyAddress),
|
to: contract._address,
|
||||||
}
|
data: calldata,
|
||||||
}
|
gasLimit: gasLimits[jobType.TORNADO_WITHDRAW],
|
||||||
|
|
||||||
function checkOldProxy(address) {
|
|
||||||
const OLD_PROXY = '0x905b63Fff465B9fFBF41DeA908CEb12478ec7601'
|
|
||||||
return toChecksumAddress(address) === toChecksumAddress(OLD_PROXY)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getTxObject({ data }) {
|
|
||||||
if (data.type === jobType.TORNADO_WITHDRAW) {
|
|
||||||
let { contract, isOldProxy } = await getProxyContract()
|
|
||||||
|
|
||||||
let calldata = contract.methods.withdraw(data.contract, data.proof, ...data.args).encodeABI()
|
|
||||||
|
|
||||||
if (isOldProxy && getInstance(data.contract).currency !== 'eth') {
|
|
||||||
contract = new web3.eth.Contract(tornadoABI, data.contract)
|
|
||||||
calldata = contract.methods.withdraw(data.proof, ...data.args).encodeABI()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
value: data.args[5],
|
|
||||||
to: contract._address,
|
|
||||||
data: calldata,
|
|
||||||
gasLimit: gasLimits['WITHDRAW_WITH_EXTRA'],
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const method = data.type === jobType.MINING_REWARD ? 'reward' : 'withdraw'
|
|
||||||
const calldata = minerContract.methods[method](data.proof, data.args).encodeABI()
|
|
||||||
return {
|
|
||||||
to: minerContract._address,
|
|
||||||
data: calldata,
|
|
||||||
gasLimit: gasLimits[data.type],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function isOutdatedTreeRevert(receipt, currentTx) {
|
|
||||||
try {
|
|
||||||
await web3.eth.call(currentTx.tx, receipt.blockNumber)
|
|
||||||
console.log('Simulated call successful')
|
|
||||||
return false
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Decoded revert reason:', e.message)
|
|
||||||
return (
|
|
||||||
e.message.indexOf('Outdated account merkle root') !== -1 ||
|
|
||||||
e.message.indexOf('Outdated tree update merkle root') !== -1
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,14 +109,10 @@ async function processJob(job) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitTx(job, retry = 0) {
|
async function submitTx(job) {
|
||||||
await checkFee(job)
|
await checkTornadoFee(job.data)
|
||||||
currentTx = await txManager.createTx(await getTxObject(job))
|
currentTx = await txManager.createTx(await getTxObject(job))
|
||||||
|
|
||||||
if (job.data.type !== jobType.TORNADO_WITHDRAW) {
|
|
||||||
await fetchTree()
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const receipt = await currentTx
|
const receipt = await currentTx
|
||||||
.send()
|
.send()
|
||||||
@ -278,35 +129,12 @@ async function submitTx(job, retry = 0) {
|
|||||||
if (receipt.status === 1) {
|
if (receipt.status === 1) {
|
||||||
await updateStatus(status.CONFIRMED)
|
await updateStatus(status.CONFIRMED)
|
||||||
} else {
|
} else {
|
||||||
if (job.data.type !== jobType.TORNADO_WITHDRAW && (await isOutdatedTreeRevert(receipt, currentTx))) {
|
throw new Error('Submitted transaction failed')
|
||||||
if (retry < 3) {
|
|
||||||
await updateStatus(status.RESUBMITTED)
|
|
||||||
await submitTx(job, retry + 1)
|
|
||||||
} else {
|
|
||||||
throw new Error('Tree update retry limit exceeded')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error('Submitted transaction failed')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// todo this could result in duplicated error logs
|
// todo this could result in duplicated error logs
|
||||||
// todo handle a case where account tree is still not up to date (wait and retry)?
|
// todo handle a case where account tree is still not up to date (wait and retry)?
|
||||||
if (
|
throw new Error(`Revert by smart contract ${e.message}`)
|
||||||
job.data.type !== jobType.TORNADO_WITHDRAW &&
|
|
||||||
(e.message.indexOf('Outdated account merkle root') !== -1 ||
|
|
||||||
e.message.indexOf('Outdated tree update merkle root') !== -1)
|
|
||||||
) {
|
|
||||||
if (retry < 5) {
|
|
||||||
await sleep(3000)
|
|
||||||
console.log('Tree is still not up to date, resubmitting')
|
|
||||||
await submitTx(job, retry + 1)
|
|
||||||
} else {
|
|
||||||
throw new Error('Tree update retry limit exceeded')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error(`Revert by smart contract ${e.message}`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ require('chai').should()
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
getTornadoWithdrawInputError,
|
getTornadoWithdrawInputError,
|
||||||
getMiningRewardInputError,
|
|
||||||
getMiningWithdrawInputError,
|
|
||||||
} = require('../src/validator')
|
} = require('../src/validator')
|
||||||
|
|
||||||
describe('Validator', () => {
|
describe('Validator', () => {
|
||||||
@ -35,56 +33,6 @@ describe('Validator', () => {
|
|||||||
malformedData.contract = withdrawData.contract
|
malformedData.contract = withdrawData.contract
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#getMiningRewardInputError', () => {
|
|
||||||
it('should work', () => {
|
|
||||||
getMiningRewardInputError(rewardData)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should throw for incorrect proof', () => {
|
|
||||||
const malformedData = { ...rewardData }
|
|
||||||
malformedData.proof = '0xbeef'
|
|
||||||
getMiningRewardInputError(malformedData).should.be.equal(
|
|
||||||
'.proof should match pattern "^0x[a-fA-F0-9]{512}$"',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should throw something is missing', () => {
|
|
||||||
const malformedData = { ...rewardData }
|
|
||||||
delete malformedData.proof
|
|
||||||
getMiningRewardInputError(malformedData).should.be.equal(" should have required property 'proof'")
|
|
||||||
malformedData.proof = rewardData.proof
|
|
||||||
|
|
||||||
delete malformedData.args
|
|
||||||
getMiningRewardInputError(malformedData).should.be.equal(" should have required property 'args'")
|
|
||||||
malformedData.args = rewardData.args
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#getMiningWithdrawInputError', () => {
|
|
||||||
it('should work', () => {
|
|
||||||
getMiningWithdrawInputError(miningWithdrawData)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should throw for incorrect proof', () => {
|
|
||||||
const malformedData = { ...miningWithdrawData }
|
|
||||||
malformedData.proof = '0xbeef'
|
|
||||||
getMiningWithdrawInputError(malformedData).should.be.equal(
|
|
||||||
'.proof should match pattern "^0x[a-fA-F0-9]{512}$"',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should throw something is missing', () => {
|
|
||||||
const malformedData = { ...miningWithdrawData }
|
|
||||||
delete malformedData.proof
|
|
||||||
getMiningWithdrawInputError(malformedData).should.be.equal(" should have required property 'proof'")
|
|
||||||
malformedData.proof = miningWithdrawData.proof
|
|
||||||
|
|
||||||
delete malformedData.args
|
|
||||||
getMiningWithdrawInputError(malformedData).should.be.equal(" should have required property 'args'")
|
|
||||||
malformedData.args = miningWithdrawData.args
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const withdrawData = {
|
const withdrawData = {
|
||||||
@ -100,52 +48,3 @@ const withdrawData = {
|
|||||||
],
|
],
|
||||||
contract: '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936',
|
contract: '0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936',
|
||||||
}
|
}
|
||||||
|
|
||||||
const rewardData = {
|
|
||||||
proof:
|
|
||||||
'0x2e0f4c76b35ce3275bf57492cbe12ddc76fae4eabdbeaacdcc7cd5255d0abb2325bd80b2a867f9c1bab854de5d7c443a18eb9ad796943dd53c30c04e8f0a37ae164916c932776b3c28dd49808a5d5e1648d8bc9006b2386096b88757644ce8f102f7e2f1505bb66385a1d53a101922a17d8ab653694dedd7d150ec71d543202e0f0a67e5d59904d75af1c52bef4dfac0a302c2beb2ca3bb29b6bbbe1038368702e5ba8d6d829d74968a94e321cc91cccbc0654f5df6460a0a6ad73b06c42b7d1289ff36655fc7106b5538bd2c6617dd0c313919331e63bcb4de9c9b45dc2207b098a5729efbecf79a4cab39ade3c99e5772bfbe5ae75d932facbf9e0910a34ae',
|
|
||||||
args: {
|
|
||||||
rate: '0x000000000000000000000000000000000000000000000000000000000000000a',
|
|
||||||
fee: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
||||||
instance: '0x8b3f5393bA08c24cc7ff5A66a832562aAB7bC95f',
|
|
||||||
rewardNullifier: '0x08fdc416b85c76d246925994ae0c0df539789fd1669c45b57104907c7ef8b0b5',
|
|
||||||
extDataHash: '0x006c5f12c20933beab10cfffab31ea0c9d736cf9aa868ee29eed3047d4ea4c2e',
|
|
||||||
depositRoot: '0x0405962838a47fb25ffd75d80d53b268654a06bc1bdde7e5ad94c675c2f2f0ff',
|
|
||||||
withdrawalRoot: '0x1cd83f5df5dbc826fecbf6be87f05db9c9dc617a3f1b1f3a421b1335c1ff7dbf',
|
|
||||||
extData: {
|
|
||||||
relayer: '0x0000000000000000000000000000000000000000',
|
|
||||||
encryptedAccount:
|
|
||||||
'0x6a8494fca4c433ef323d03f0db3fede90c3d2c6f216d73345ffc77ceec79622f327a83c4254063a3027620c262835e335fa32c33600a70547a53b2aa311d3ff35cf943e8f9e8f321f60d4266f680e0606a5837d78deb4d74c8b4fa3e9b67414513c71b73e38995cd8d57fd08aa9e135b342cecaf4128d4cfbb26148022e7a87da8b2423440b62034be202a6a48b45baa9736def6455771b442baaf2358fc52aa6c1d14a9a452b064d280fafd69f2a3ba416c10c1d8276f1c3810c664b24e0f1eefc75d63',
|
|
||||||
},
|
|
||||||
account: {
|
|
||||||
inputRoot: '0x22e875e5e54d8569fb40d0c568984e87b4c97da6383d8d8a334a79e22b48fd54',
|
|
||||||
inputNullifierHash: '0x24be972a00e3938a58f44ea6f8ead271ecdd6ab2cab42d1910fb7190b5816188',
|
|
||||||
outputRoot: '0x04a3cd1e37487dcee5da51cbce4245742903262a5824aef77fb7aff84a3cb053',
|
|
||||||
outputPathIndices: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
||||||
outputCommitment: '0x0ae58c1605312bd42fffdfc41d5e0f9a364ad458717c522bf9338068ab258601',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const miningWithdrawData = {
|
|
||||||
proof:
|
|
||||||
'0x087c02cdc5946b44f295e1adb8b65341708fe43854e44f05f205da6e46e2e4c4248b2dd5ee30236e7be2ea657265765b4e43dae263d67ff43190bb806faaafc10dd0a771f9d589b5061ddf0a713f27fc0b496d1b136dc4e98838b88f60efb072087c3018fa5c25b1f78b4bb968291b9afa3966d976e961d0a86719a8e07d771209dad29620f3bc2fc21c00510749a19e7ff369ade6b9fd1a7f05b74e70faee771fd839c710bd983927c9d3d5f39bb5e839a2ece19e899c4d50a91b29d5ac3f1a0e8faf7eeb2f6f672561bfba39bcb1d851f6c97d5c14b7fce6661cf315af3468119855a426fc4df511e848011bcdb704369deba20541a7651ab4d5813a60c056',
|
|
||||||
args: {
|
|
||||||
amount: '0x000000000000000000000000000000000000000000000000000000000000000f',
|
|
||||||
fee: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
||||||
extDataHash: '0x00d95a201b89061613b5bc539bcf8fdee63a400ea80f1f5e813d6aacfee3ec67',
|
|
||||||
extData: {
|
|
||||||
recipient: '0xf17f52151ebef6c7334fad080c5704d77216b732',
|
|
||||||
relayer: '0x0000000000000000000000000000000000000000',
|
|
||||||
encryptedAccount:
|
|
||||||
'0x4bd7f84edab796b390181d8b1dd850c418c8b3fe41d63b9677b7b99a2fadc505dcc70df336a42847dc00fa39175d16ddfec0d80dc166282e024b5371f561467651ed94e71524fa2e365a8330b053d5cff7c3bcc3564b335fb9e74fb805a3a6e760b811db60e5d6b4e154376196c3cb61457bac6d5ea804f63208a389555cde72f40ab1b94705e728f692e699fc441504b9df34390b3992a1a1eac160dcf0df0b5c5a9ec9cd6c0c8f5f8aa11627fdf2b3bedece5836e9ca38b09d70ff7ba06702971d245d',
|
|
||||||
},
|
|
||||||
account: {
|
|
||||||
inputRoot: '0x1a756aeee7f7d05f276b20c8ca83150e110e1a436c2d959e501ab306420ab536',
|
|
||||||
inputNullifierHash: '0x0dc8ea0330171a1f868ef5f3f9f92e919d7be754846f6145c5e7819e87738e65',
|
|
||||||
outputRoot: '0x0d9d85371bd8c941400ae54815491799e98d1f335a9d263e41f0b81f22b55aa8',
|
|
||||||
outputPathIndices: '0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
||||||
outputCommitment: '0x1ebd38a8bc53f47386687386397c8b5cefd33d55341b62a2a576b39d9bcec57c',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user