Add check to avoid proof reusage
arnaucube root@arnaucube.com
Sat, 09 May 2020 23:10:38 +0200
4 files changed,
80 insertions(+),
9 deletions(-)
M
contracts/Miksi.sol
→
contracts/Miksi.sol
@@ -14,6 +14,7 @@
struct Deposit { uint256 coinCode; uint256 amount; + bool used; } function deposit(@@ -21,7 +22,7 @@ uint256 coinCode,
// uint256 amount, uint256 commitment ) public payable { - deposits[commitment] = Deposit(coinCode, msg.value); + deposits[commitment] = Deposit(coinCode, msg.value, false); } function getDeposit(@@ -49,6 +50,8 @@ uint256(_address)
]; require(verifier.verifyProof(a, b, c, input), "zkProof withdraw could not be verified"); // zk verification passed, proceed with the withdraw + require(!deposits[commitment].used, "deposit already withdrawed"); + deposits[commitment].used = true; _address.send(deposits[commitment].amount); // _address.call.value(deposits[commitment].amount).gas(20317)();
M
package-lock.json
→
package-lock.json
@@ -555,7 +555,18 @@ "version": "0.0.5",
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.5.tgz", "integrity": "sha512-WEZHnRO1AJIDI2w1yX6rq4G1/MMKnExT3qirjBQR7x43i9Ww3E/wusBHTbXWLb8aYyxsBU07LGy0YXPywPGYvA==", "requires": { + "ffjavascript": "0.1.0", "fnv-plus": "^1.3.1" + }, + "dependencies": { + "ffjavascript": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz", + "integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==", + "requires": { + "big-integer": "^1.6.48" + } + } } }, "circomlib": {@@ -566,6 +577,7 @@ "requires": {
"blake-hash": "^1.1.0", "blake2b": "^2.1.3", "circom": "0.5.9", + "ffjavascript": "0.1.0", "web3": "^1.2.6" }, "dependencies": {@@ -578,11 +590,20 @@ "chai": "^4.2.0",
"circom_runtime": "0.0.5", "fastfile": "0.0.1", "ffiasm": "0.0.2", + "ffjavascript": "0.1.0", "ffwasm": "0.0.7", "fnv-plus": "^1.3.1", "r1csfile": "0.0.5", "tmp-promise": "^2.0.2", "wasmbuilder": "0.0.10" + } + }, + "ffjavascript": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz", + "integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==", + "requires": { + "big-integer": "^1.6.48" } } }@@ -1797,6 +1818,12 @@ "requires": {
"p-locate": "^4.1.0" } }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",@@ -2360,7 +2387,18 @@ "version": "0.0.5",
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.5.tgz", "integrity": "sha512-B+BdKPb/WUTp4N/3X4d1Spgx9Ojx5tFVejGZRJxpTtzq34mC8Vi/czWfiPj85V8kud31lCfYcZ16z7+czvM0Sw==", "requires": { - "fastfile": "0.0.1" + "fastfile": "0.0.1", + "ffjavascript": "0.1.0" + }, + "dependencies": { + "ffjavascript": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz", + "integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==", + "requires": { + "big-integer": "^1.6.48" + } + } } }, "ramda": {@@ -3099,6 +3137,16 @@ "requires": {
"app-module-path": "^2.2.0", "mocha": "5.2.0", "original-require": "1.0.1" + } + }, + "truffle-assertions": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/truffle-assertions/-/truffle-assertions-0.9.2.tgz", + "integrity": "sha512-9g2RhaxU2F8DeWhqoGQvL/bV8QVoSnQ6PY+ZPvYRP5eF7+/8LExb4mjLx/FeliLTjc3Tv1SABG05Gu5qQ/ErmA==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "lodash.isequal": "^4.5.0" } }, "ts-node": {
M
package.json
→
package.json
@@ -15,20 +15,21 @@ "dependencies": {
"circomlib": "0.2.2" }, "devDependencies": { + "@types/chai": "^4.1.7", + "@types/mocha": "^5.2.6", "@types/node": "^12.12.0", + "chai": "^4.2.0", "circom": "0.5.10", "eslint-plugin-mocha": "^6.1.0", - "snarkjs": "^0.1.31", "ffjavascript": "0.1.3", - "@types/chai": "^4.1.7", - "@types/mocha": "^5.2.6", - "chai": "^4.2.0", "mocha": "^5.2.0", "mocha-steps": "^1.3.0", + "snarkjs": "^0.1.31", + "truffle": "^5.0.0-beta.0", + "truffle-assertions": "^0.9.2", "ts-node": "^7.0.1", "tslint": "^5.18.0", "typescript": "^3.5.3", - "truffle": "^5.0.0-beta.0", "web3": "^1.0.0-beta.30" } }
M
test/contracts/miksi.test.ts
→
test/contracts/miksi.test.ts
@@ -3,6 +3,7 @@ const Miksi = artifacts.require("../../contracts/Miksi.sol");
const chai = require("chai"); const expect = chai.expect; +const truffleAssert = require('truffle-assertions'); const fs = require("fs"); const { groth } = require('snarkjs');@@ -49,7 +50,7 @@ await insMiksi.deposit(coinCode, commitment, {from: addr1, value: amount});
balance_wei = await web3.eth.getBalance(addr1); console.log("Balance at " + addr1, web3.utils.fromWei(balance_wei, 'ether')); - expect(balance_wei).to.be.equal('99499141300000000000'); + expect(balance_wei).to.be.equal('99499107180000000000'); // getDeposit data const res = await insMiksi.getDeposit(commitment);@@ -80,7 +81,7 @@ const {proof, publicSignals} = groth.genProof(provingKey, witness);
// withdraw console.log("Withdraw of " + ethAmount + " ETH to " + addr2); - const resW = await insMiksi.withdraw( + let resW = await insMiksi.withdraw( commitment, addr2, [proof.pi_a[0].toString(), proof.pi_a[1].toString()],@@ -94,6 +95,24 @@ // console.log("resW", resW);
balance_wei = await web3.eth.getBalance(addr2); console.log("Balance at " + addr2, web3.utils.fromWei(balance_wei, 'ether')); + expect(balance_wei).to.be.equal('100500000000000000000'); + + console.log("Try to reuse the zkproof and expect revert"); + await truffleAssert.fails( + insMiksi.withdraw( + commitment, + addr2, + [proof.pi_a[0].toString(), proof.pi_a[1].toString()], + [ + [proof.pi_b[0][1].toString(), proof.pi_b[0][0].toString()], + [proof.pi_b[1][1].toString(), proof.pi_b[1][0].toString()] + ], + [proof.pi_c[0].toString(), proof.pi_c[1].toString()] + ), + truffleAssert.ErrorType.REVERT, + "deposit already withdrawed" + ); + balance_wei = await web3.eth.getBalance(addr2); expect(balance_wei).to.be.equal('100500000000000000000'); }); });