mirror of
				https://github.com/tornadocash/tornado-core.git
				synced 2025-10-30 22:18:54 -04:00 
			
		
		
		
	typed withdraw inputs
This commit is contained in:
		
							parent
							
								
									e9c2055bb4
								
							
						
					
					
						commit
						74913e67b2
					
				
					 5 changed files with 195 additions and 62 deletions
				
			
		
							
								
								
									
										31
									
								
								cli.js
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								cli.js
									
										
									
									
									
								
							|  | @ -113,11 +113,19 @@ async function withdrawErc20(note, receiver, relayer) { | |||
|   console.log('Generating SNARK proof') | ||||
|   console.time('Proof time') | ||||
|   const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|   const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|   const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
|   console.timeEnd('Proof time') | ||||
| 
 | ||||
|   console.log('Submitting withdraw transaction') | ||||
|   await erc20mixer.methods.withdraw(proof, publicSignals).send({ from: (await web3.eth.getAccounts())[0], gas: 1e6 }) | ||||
|   const args = [ | ||||
|     toHex(input.root), | ||||
|     toHex(input.nullifierHash), | ||||
|     toHex(input.receiver, 20), | ||||
|     toHex(input.relayer, 20), | ||||
|     toHex(input.fee), | ||||
|     toHex(input.refund) | ||||
|   ] | ||||
|   await erc20mixer.methods.withdraw(proof, ...args).send({ from: (await web3.eth.getAccounts())[0], gas: 1e6 }) | ||||
|   console.log('Done') | ||||
| } | ||||
| 
 | ||||
|  | @ -138,6 +146,13 @@ async function getBalanceErc20(receiver, relayer) { | |||
|   console.log('Relayer token Balance is ', web3.utils.fromWei(tokenBalanceRelayer.toString())) | ||||
| } | ||||
| 
 | ||||
| function toHex(number, length = 32) { | ||||
|   let str = bigInt(number).toString(16) | ||||
|   while (str.length < length * 2) str = '0' + str | ||||
|   str = '0x' + str | ||||
|   return str | ||||
| } | ||||
| 
 | ||||
| async function withdraw(note, receiver) { | ||||
|   // Decode hex string and restore the deposit object
 | ||||
|   let buf = Buffer.from(note.slice(2), 'hex') | ||||
|  | @ -188,11 +203,19 @@ async function withdraw(note, receiver) { | |||
|   console.log('Generating SNARK proof') | ||||
|   console.time('Proof time') | ||||
|   const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|   const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|   const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
|   console.timeEnd('Proof time') | ||||
| 
 | ||||
|   console.log('Submitting withdraw transaction') | ||||
|   await mixer.methods.withdraw(proof, publicSignals).send({ from: (await web3.eth.getAccounts())[0], gas: 1e6 }) | ||||
|   const args = [ | ||||
|     toHex(input.root), | ||||
|     toHex(input.nullifierHash), | ||||
|     toHex(input.receiver, 20), | ||||
|     toHex(input.relayer, 20), | ||||
|     toHex(input.fee), | ||||
|     toHex(input.refund) | ||||
|   ] | ||||
|   await mixer.methods.withdraw(proof, ...args).send({ from: (await web3.eth.getAccounts())[0], gas: 1e6 }) | ||||
|   console.log('Done') | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ pragma solidity ^0.5.8; | |||
| import "./MerkleTreeWithHistory.sol"; | ||||
| 
 | ||||
| contract IVerifier { | ||||
|   function verifyProof(uint256[8] memory _proof, uint256[6] memory _input) public returns(bool); | ||||
|   function verifyProof(bytes memory _proof, uint256[6] memory _input) public returns(bool); | ||||
| } | ||||
| 
 | ||||
| contract Mixer is MerkleTreeWithHistory { | ||||
|  | @ -64,6 +64,7 @@ contract Mixer is MerkleTreeWithHistory { | |||
|   function deposit(uint256 _commitment) public payable { | ||||
|     require(!isDepositsDisabled, "deposits are disabled"); | ||||
|     require(!commitments[_commitment], "The commitment has been submitted"); | ||||
| 
 | ||||
|     uint32 insertedIndex = _insert(_commitment); | ||||
|     commitments[_commitment] = true; | ||||
|     _processDeposit(); | ||||
|  | @ -82,21 +83,15 @@ contract Mixer is MerkleTreeWithHistory { | |||
|       - the receiver of funds | ||||
|       - optional fee that goes to the transaction sender (usually a relay) | ||||
|   */ | ||||
|   function withdraw(uint256[8] memory _proof, uint256[6] memory _input) public payable { | ||||
|     uint256 root = _input[0]; | ||||
|     uint256 nullifierHash = _input[1]; | ||||
|     address payable receiver = address(_input[2]); | ||||
|     address payable relayer = address(_input[3]); | ||||
|     uint256 fee = _input[4]; | ||||
|     uint256 refund = _input[5]; | ||||
|     require(fee <= denomination, "Fee exceeds transfer value"); | ||||
|     require(!nullifierHashes[nullifierHash], "The note has been already spent"); | ||||
|   function withdraw(bytes memory _proof, uint256 _root, uint256 _nullifierHash, address payable _receiver, address payable _relayer, uint256 _fee, uint256 _refund) public payable { | ||||
|     require(_fee <= denomination, "Fee exceeds transfer value"); | ||||
|     require(!nullifierHashes[_nullifierHash], "The note has been already spent"); | ||||
|     require(isKnownRoot(_root), "Cannot find your merkle root"); // Make sure to use a recent one | ||||
|     require(verifier.verifyProof(_proof, [_root, _nullifierHash, uint256(_receiver), uint256(_relayer), _fee, _refund]), "Invalid withdraw proof"); | ||||
| 
 | ||||
|     require(isKnownRoot(root), "Cannot find your merkle root"); // Make sure to use a recent one | ||||
|     require(verifier.verifyProof(_proof, _input), "Invalid withdraw proof"); | ||||
|     nullifierHashes[nullifierHash] = true; | ||||
|     _processWithdraw(receiver, relayer, fee, refund); | ||||
|     emit Withdrawal(receiver, nullifierHash, relayer, fee); | ||||
|     nullifierHashes[_nullifierHash] = true; | ||||
|     _processWithdraw(_receiver, _relayer, _fee, _refund); | ||||
|     emit Withdrawal(_receiver, _nullifierHash, _relayer, _fee); | ||||
|   } | ||||
| 
 | ||||
|   /** @dev this function is defined in a child contract */ | ||||
|  |  | |||
|  | @ -36,14 +36,14 @@ | |||
|     "dotenv": "^8.0.0", | ||||
|     "eslint": "^6.2.2", | ||||
|     "ganache-cli": "^6.4.5", | ||||
|     "snarkjs": "git+https://github.com/peppersec/snarkjs.git#0e2f8ab28092ee6d922dc4d3ac7afc8ef5a25154", | ||||
|     "snarkjs": "git+https://github.com/peppersec/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5", | ||||
|     "truffle": "^5.0.27", | ||||
|     "truffle-artifactor": "^4.0.23", | ||||
|     "truffle-contract": "^4.0.24", | ||||
|     "truffle-hdwallet-provider": "^1.0.14", | ||||
|     "web3": "^1.0.0-beta.55", | ||||
|     "web3-utils": "^1.0.0-beta.55", | ||||
|     "websnark": "git+https://github.com/peppersec/websnark.git#966eafc47df639195c98374d3c366c32acd6f231" | ||||
|     "websnark": "git+https://github.com/peppersec/websnark.git#c254b5962287b788081be1047fa0041c2885b39f" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "truffle-flattener": "^1.4.0" | ||||
|  |  | |||
|  | @ -43,6 +43,13 @@ function getRandomReceiver() { | |||
|   return receiver | ||||
| } | ||||
| 
 | ||||
| function toFixedHex(number, length = 32) { | ||||
|   let str = bigInt(number).toString(16) | ||||
|   while (str.length < length * 2) str = '0' + str | ||||
|   str = '0x' + str | ||||
|   return str | ||||
| } | ||||
| 
 | ||||
| contract('ERC20Mixer', accounts => { | ||||
|   let mixer | ||||
|   let token | ||||
|  | @ -147,7 +154,7 @@ contract('ERC20Mixer', accounts => { | |||
| 
 | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       const balanceMixerBefore = await token.balanceOf(mixer.address) | ||||
|       const balanceRelayerBefore = await token.balanceOf(relayer) | ||||
|  | @ -161,7 +168,15 @@ contract('ERC20Mixer', accounts => { | |||
|       // Uncomment to measure gas usage
 | ||||
|       // gas = await mixer.withdraw.estimateGas(proof, publicSignals, { from: relayer, gasPrice: '0' })
 | ||||
|       // console.log('withdraw gas:', gas)
 | ||||
|       const { logs } = await mixer.withdraw(proof, publicSignals, { value: refund, from: relayer, gasPrice: '0' }) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const { logs } = await mixer.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' }) | ||||
| 
 | ||||
|       const balanceMixerAfter = await token.balanceOf(mixer.address) | ||||
|       const balanceRelayerAfter = await token.balanceOf(relayer) | ||||
|  | @ -215,13 +230,21 @@ contract('ERC20Mixer', accounts => { | |||
| 
 | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       let { reason } = await mixer.withdraw(proof, publicSignals, { value: 1, from: relayer, gasPrice: '0' }).should.be.rejected | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       let { reason } = await mixer.withdraw(proof, ...args, { value: 1, from: relayer, gasPrice: '0' }).should.be.rejected | ||||
|       reason.should.be.equal('Incorrect refund amount received by the contract') | ||||
| 
 | ||||
| 
 | ||||
|       ;({ reason } = await mixer.withdraw(proof, publicSignals, { value: toBN(refund).mul(toBN(2)), from: relayer, gasPrice: '0' }).should.be.rejected) | ||||
|       ;({ reason } = await mixer.withdraw(proof, ...args, { value: toBN(refund).mul(toBN(2)), from: relayer, gasPrice: '0' }).should.be.rejected) | ||||
|       reason.should.be.equal('Incorrect refund amount received by the contract') | ||||
|     }) | ||||
| 
 | ||||
|  | @ -274,7 +297,7 @@ contract('ERC20Mixer', accounts => { | |||
| 
 | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       const balanceMixerBefore = await usdtToken.balanceOf(mixer.address) | ||||
|       const balanceRelayerBefore = await usdtToken.balanceOf(relayer) | ||||
|  | @ -287,7 +310,15 @@ contract('ERC20Mixer', accounts => { | |||
|       // Uncomment to measure gas usage
 | ||||
|       // gas = await mixer.withdraw.estimateGas(proof, publicSignals, { from: relayer, gasPrice: '0' })
 | ||||
|       // console.log('withdraw gas:', gas)
 | ||||
|       const { logs } = await mixer.withdraw(proof, publicSignals, { value: refund, from: relayer, gasPrice: '0' }) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const { logs } = await mixer.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' }) | ||||
| 
 | ||||
|       const balanceMixerAfter = await usdtToken.balanceOf(mixer.address) | ||||
|       const balanceRelayerAfter = await usdtToken.balanceOf(relayer) | ||||
|  | @ -355,7 +386,7 @@ contract('ERC20Mixer', accounts => { | |||
| 
 | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       const balanceMixerBefore = await token.balanceOf(mixer.address) | ||||
|       const balanceRelayerBefore = await token.balanceOf(relayer) | ||||
|  | @ -368,7 +399,15 @@ contract('ERC20Mixer', accounts => { | |||
|       // Uncomment to measure gas usage
 | ||||
|       // gas = await mixer.withdraw.estimateGas(proof, publicSignals, { from: relayer, gasPrice: '0' })
 | ||||
|       // console.log('withdraw gas:', gas)
 | ||||
|       const { logs } = await mixer.withdraw(proof, publicSignals, { value: refund, from: relayer, gasPrice: '0' }) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const { logs } = await mixer.withdraw(proof, ...args, { value: refund, from: relayer, gasPrice: '0' }) | ||||
|       console.log('withdraw done') | ||||
| 
 | ||||
|       const balanceMixerAfter = await token.balanceOf(mixer.address) | ||||
|  |  | |||
|  | @ -57,6 +57,13 @@ function snarkVerify(proof) { | |||
|   return snarkjs['groth'].isValid(verification_key, proof, proof.publicSignals) | ||||
| } | ||||
| 
 | ||||
| function toFixedHex(number, length = 32) { | ||||
|   let str = bigInt(number).toString(16) | ||||
|   while (str.length < length * 2) str = '0' + str | ||||
|   str = '0x' + str | ||||
|   return str | ||||
| } | ||||
| 
 | ||||
| contract('ETHMixer', accounts => { | ||||
|   let mixer | ||||
|   const sender = accounts[0] | ||||
|  | @ -215,7 +222,7 @@ contract('ETHMixer', accounts => { | |||
| 
 | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       const balanceMixerBefore = await web3.eth.getBalance(mixer.address) | ||||
|       const balanceRelayerBefore = await web3.eth.getBalance(relayer) | ||||
|  | @ -227,7 +234,15 @@ contract('ETHMixer', accounts => { | |||
|       // Uncomment to measure gas usage
 | ||||
|       // gas = await mixer.withdraw.estimateGas(proof, publicSignals, { from: relayer, gasPrice: '0' })
 | ||||
|       // console.log('withdraw gas:', gas)
 | ||||
|       const { logs } = await mixer.withdraw(proof, publicSignals, { from: relayer, gasPrice: '0' }) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const { logs } = await mixer.withdraw(proof, ...args, { from: relayer, gasPrice: '0' }) | ||||
| 
 | ||||
|       const balanceMixerAfter = await web3.eth.getBalance(mixer.address) | ||||
|       const balanceRelayerAfter = await web3.eth.getBalance(relayer) | ||||
|  | @ -268,9 +283,17 @@ contract('ETHMixer', accounts => { | |||
|         pathIndices: path_index, | ||||
|       }) | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.fulfilled | ||||
|       const error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       await mixer.withdraw(proof, ...args, { from: relayer }).should.be.fulfilled | ||||
|       const error = await mixer.withdraw(proof, ...args, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('The note has been already spent') | ||||
|     }) | ||||
| 
 | ||||
|  | @ -294,9 +317,16 @@ contract('ETHMixer', accounts => { | |||
|         pathIndices: path_index, | ||||
|       }) | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       publicSignals[1] ='0x' + toBN(publicSignals[1]).add(toBN('21888242871839275222246405745257275088548364400416034343698204186575808495617')).toString('hex') | ||||
|       const error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(toBN(input.nullifierHash).add(toBN('21888242871839275222246405745257275088548364400416034343698204186575808495617'))), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const error = await mixer.withdraw(proof, ...args, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('verifier-gte-snark-scalar-field') | ||||
|     }) | ||||
| 
 | ||||
|  | @ -321,8 +351,16 @@ contract('ETHMixer', accounts => { | |||
|       }) | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const error = await mixer.withdraw(proof, ...args, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('Fee exceeds transfer value') | ||||
|     }) | ||||
| 
 | ||||
|  | @ -346,12 +384,18 @@ contract('ETHMixer', accounts => { | |||
|         pathIndices: path_index, | ||||
|       }) | ||||
| 
 | ||||
|       const dummyRoot = randomHex(32) | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       publicSignals[0] = dummyRoot | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       const error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       const args = [ | ||||
|         toFixedHex(randomHex(32)), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const error = await mixer.withdraw(proof, ...args, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('Cannot find your merkle root') | ||||
|     }) | ||||
| 
 | ||||
|  | @ -375,36 +419,60 @@ contract('ETHMixer', accounts => { | |||
|         pathIndices: path_index, | ||||
|       }) | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       let { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const originalPublicSignals = publicSignals.slice() | ||||
|       let { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       let incorrectArgs | ||||
|       const originalProof = proof.slice() | ||||
| 
 | ||||
|       // receiver
 | ||||
|       publicSignals[2] = '0x0000000000000000000000007a1f9131357404ef86d7c38dbffed2da70321337' | ||||
| 
 | ||||
|       let error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       incorrectArgs = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex('0x0000000000000000000000007a1f9131357404ef86d7c38dbffed2da70321337', 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       let error = await mixer.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('Invalid withdraw proof') | ||||
| 
 | ||||
|       // fee
 | ||||
|       publicSignals = originalPublicSignals.slice() | ||||
|       publicSignals[3] = '0x000000000000000000000000000000000000000000000000015345785d8a0000' | ||||
| 
 | ||||
|       error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       incorrectArgs = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex('0x000000000000000000000000000000000000000000000000015345785d8a0000'), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       error = await mixer.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('Invalid withdraw proof') | ||||
| 
 | ||||
|       // nullifier
 | ||||
|       publicSignals = originalPublicSignals.slice() | ||||
|       publicSignals[1] = '0x00abdfc78211f8807b9c6504a6e537e71b8788b2f529a95f1399ce124a8642ad' | ||||
| 
 | ||||
|       error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       incorrectArgs = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex('0x00abdfc78211f8807b9c6504a6e537e71b8788b2f529a95f1399ce124a8642ad'), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       error = await mixer.withdraw(proof, ...incorrectArgs, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('Invalid withdraw proof') | ||||
| 
 | ||||
|       // proof itself
 | ||||
|       proof[0] = '0x261d81d8203437f29b38a88c4263476d858e6d9645cf21740461684412b31337' | ||||
|       await mixer.withdraw(proof, originalPublicSignals, { from: relayer }).should.be.rejected | ||||
|       proof = '0xbeef' + proof.substr(6) | ||||
|       await mixer.withdraw(proof, ...args, { from: relayer }).should.be.rejected | ||||
| 
 | ||||
|       // should work with original values
 | ||||
|       await mixer.withdraw(originalProof, originalPublicSignals, { from: relayer }).should.be.fulfilled | ||||
|       await mixer.withdraw(originalProof, ...args, { from: relayer }).should.be.fulfilled | ||||
|     }) | ||||
| 
 | ||||
|     it('should reject with non zero refund', async () => { | ||||
|  | @ -428,9 +496,17 @@ contract('ETHMixer', accounts => { | |||
|       }) | ||||
| 
 | ||||
|       const proofData = await websnarkUtils.genWitnessAndProve(groth16, input, circuit, proving_key) | ||||
|       const { proof, publicSignals } = websnarkUtils.toSolidityInput(proofData) | ||||
|       const { proof } = websnarkUtils.toSolidityInput(proofData) | ||||
| 
 | ||||
|       const error = await mixer.withdraw(proof, publicSignals, { from: relayer }).should.be.rejected | ||||
|       const args = [ | ||||
|         toFixedHex(input.root), | ||||
|         toFixedHex(input.nullifierHash), | ||||
|         toFixedHex(input.receiver, 20), | ||||
|         toFixedHex(input.relayer, 20), | ||||
|         toFixedHex(input.fee), | ||||
|         toFixedHex(input.refund) | ||||
|       ] | ||||
|       const error = await mixer.withdraw(proof, ...args, { from: relayer }).should.be.rejected | ||||
|       error.reason.should.be.equal('Refund value is supposed to be zero for ETH mixer') | ||||
|     }) | ||||
|   }) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 poma
						poma