arnaucube
arnaucube/miksi-corePublic Self-hosted repository
Add check to avoid proof reusage
arnaucube root@arnaucube.com
Sat, 09 May 2020 23:10:38 +0200
commit

e466578ddc78a613b4db01e4e51dce7c8133e85d

parent

d6568e9f0a98672339f56cd63c9e0ae89e7fdaa5

4 files changed, 80 insertions(+), 9 deletions(-)

jump to
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'); }); });