diff --git a/.gitignore b/.gitignore index 2058ab1..2bfbfbb 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ yarn-error.log .DS_STORE /cache /artifacts +/coverage +/out +lcov.info diff --git a/README.md b/README.md index 311ed2e..94f2e39 100644 --- a/README.md +++ b/README.md @@ -125,3 +125,4 @@ npm run benchmark ## Additional information If you are using Visual Studio Code, you may need to link the OpenZeppelin libraries. Refer to [here](https://github.com/juanfranblanco/vscode-solidity#openzeppelin) for more information. +Install lcov for test coverage report. diff --git a/package-lock.json b/package-lock.json index 17faa22..21de5ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,6 +52,7 @@ "lodash": "^4.17.21", "prettier": "^2.3.2", "prettier-plugin-solidity": "^1.0.0-beta.17", + "rimraf": "^5.0.5", "semantic-release": "^17.4.2", "solhint": "^3.3.4", "solhint-plugin-prettier": "^0.0.5", @@ -3440,6 +3441,102 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3710,6 +3807,21 @@ "node": ">=8" } }, + "node_modules/@jest/core/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@jest/core/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5236,6 +5348,16 @@ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@resolver-engine/core": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.2.1.tgz", @@ -9426,6 +9548,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/del/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/del/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -9696,6 +9833,12 @@ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", "dev": true }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -12314,6 +12457,21 @@ "node": ">=12.0.0" } }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -12377,6 +12535,34 @@ "node": ">=0.10.0" } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -16064,6 +16250,24 @@ "node": ">= 4" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/java-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", @@ -23688,6 +23892,40 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -25123,20 +25361,78 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -29138,6 +29434,30 @@ "node": ">=4" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", @@ -29216,6 +29536,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -32052,6 +32385,80 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", diff --git a/package.json b/package.json index e42d6b3..fb8eacb 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore", "prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore", "test": "forge test", - "test:coverage": "forge coverage", + "test:coverage": "rimraf coverage && mkdir coverage && forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage", "test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage" }, "jest": { @@ -98,6 +98,7 @@ "lodash": "^4.17.21", "prettier": "^2.3.2", "prettier-plugin-solidity": "^1.0.0-beta.17", + "rimraf": "^5.0.5", "semantic-release": "^17.4.2", "solhint": "^3.3.4", "solhint-plugin-prettier": "^0.0.5", diff --git a/src/DocumentStore.sol b/src/DocumentStore.sol index f7c1482..ab0927e 100644 --- a/src/DocumentStore.sol +++ b/src/DocumentStore.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.23 <0.9.0; -import "./BaseDocumentStore.sol"; +import "./base/BaseDocumentStore.sol"; /** * @title DocumentStore @@ -11,11 +11,11 @@ import "./BaseDocumentStore.sol"; contract DocumentStore is BaseDocumentStore { /** * @notice Initialises the contract with a name and initial admin - * @param _name The name of the contract + * @param name The name of the contract * @param initAdmin The initial admin of the contract */ - constructor(string memory _name, address initAdmin) { - initialize(_name, initAdmin); + constructor(string memory name, address initAdmin) { + initialize(name, initAdmin); } /** diff --git a/src/BaseDocumentStore.sol b/src/base/BaseDocumentStore.sol similarity index 59% rename from src/BaseDocumentStore.sol rename to src/base/BaseDocumentStore.sol index b6f0af5..299f639 100644 --- a/src/BaseDocumentStore.sol +++ b/src/base/BaseDocumentStore.sol @@ -6,8 +6,9 @@ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol"; -import "./interfaces/IDocumentStoreBatchable.sol"; -import "./base/DocumentStoreAccessControl.sol"; +import "../interfaces/IDocumentStoreBatchable.sol"; +import "./DocumentStoreAccessControl.sol"; +import "../interfaces/IDocumentStoreErrors.sol"; /** * @title BaseDocumentStore @@ -16,25 +17,31 @@ import "./base/DocumentStoreAccessControl.sol"; abstract contract BaseDocumentStore is Initializable, MulticallUpgradeable, - IDocumentStoreBatchable, - DocumentStoreAccessControl + DocumentStoreAccessControl, + IDocumentStoreErrors, + IDocumentStoreBatchable { using MerkleProof for bytes32[]; - /** - * @notice The name of the contract - */ - string public name; - - /** - * @notice A mapping of the document hash to the block number that was issued - */ - mapping(bytes32 => uint256) internal documentIssued; + /// @custom:storage-location erc7201:openattestation.storage.DocumentStore + struct DocumentStoreStorage { + /** + * @notice The name of the contract + */ + string name; + /** + * @notice A mapping of the document hash to the block number that was issued + */ + mapping(bytes32 => bool) documentIssued; + /** + * @notice A mapping of the hash of the claim being revoked to the revocation block number + */ + mapping(bytes32 => bool) documentRevoked; + } - /** - * @notice A mapping of the hash of the claim being revoked to the revocation block number - */ - mapping(bytes32 => uint256) internal documentRevoked; + // keccak256(abi.encode(uint256(keccak256("openattestation.storage.DocumentStore")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant _DocumentStoreStorageSlot = + 0xdf77e5ba4c86e3660e034f5231accc53aa8d4a8fbd82cd78b21cae09c866db00; /** * @notice Initialises the contract with a name @@ -42,14 +49,20 @@ abstract contract BaseDocumentStore is */ function __BaseDocumentStore_init(string memory _name, address initAdmin) internal onlyInitializing { __DocumentStoreAccessControl_init(initAdmin); - name = _name; + _getStorage().name = _name; + } + + function name() external view returns (string memory) { + return _getStorage().name; } /** * @notice Issues a document * @param documentRoot The hash of the document to issue */ - function issue(bytes32 documentRoot) external onlyRole(ISSUER_ROLE) { + function issue( + bytes32 documentRoot + ) external onlyValidDocument(documentRoot, documentRoot, new bytes32[](0)) onlyRole(ISSUER_ROLE) { _issue(documentRoot); } @@ -70,10 +83,7 @@ abstract contract BaseDocumentStore is bytes32 document, bytes32[] memory proof ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { - if (documentRoot == document && proof.length == 0) { - return documentIssued[document] != 0; - } - return documentIssued[documentRoot] != 0; + return _isIssued(documentRoot, document, proof); } function isIssued(bytes32 documentRoot) public view returns (bool) { @@ -85,7 +95,7 @@ abstract contract BaseDocumentStore is bytes32 document, bytes32[] memory proof ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { - if (!isIssued(documentRoot, document, proof)) { + if (!_isIssued(documentRoot, document, proof)) { revert DocumentNotIssued(documentRoot, document); } return _isRevoked(documentRoot, document, proof); @@ -100,8 +110,12 @@ abstract contract BaseDocumentStore is return isRevoked(documentRoot, documentRoot, new bytes32[](0)); } - function isActive(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) public view returns (bool) { - if (!isIssued(documentRoot, document, proof)) { + function isActive( + bytes32 documentRoot, + bytes32 document, + bytes32[] memory proof + ) public view onlyValidDocument(documentRoot, document, proof) returns (bool) { + if (!_isIssued(documentRoot, document, proof)) { revert DocumentNotIssued(documentRoot, document); } return !_isRevoked(documentRoot, document, proof); @@ -123,11 +137,11 @@ abstract contract BaseDocumentStore is * @param documentRoot The hash of the document to issue */ function _issue(bytes32 documentRoot) internal { - if (isIssued(documentRoot)) { + if (_isIssued(documentRoot, documentRoot, new bytes32[](0))) { revert DocumentExists(documentRoot); } - documentIssued[documentRoot] = block.number; + _setDocumentIssued(documentRoot, true); emit DocumentIssued(documentRoot); } @@ -137,15 +151,44 @@ abstract contract BaseDocumentStore is if (!active) { revert InactiveDocument(documentRoot, document); } - documentRevoked[document] = block.number; + _setDocumentRevoked(document, true); emit DocumentRevoked(documentRoot, document); } + function _isIssued(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal view returns (bool) { + if (documentRoot == document && proof.length == 0) { + return _getDocumentIssued(document); + } + return _getDocumentIssued(documentRoot); + } + function _isRevoked(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) internal view returns (bool) { if (documentRoot == document && proof.length == 0) { - return documentRevoked[document] != 0; + return _getDocumentRevoked(document); } - return documentRevoked[documentRoot] != 0 || documentRevoked[document] != 0; + return _getDocumentRevoked(documentRoot) || _getDocumentRevoked(document); + } + + function _getStorage() private pure returns (DocumentStoreStorage storage $) { + assembly { + $.slot := _DocumentStoreStorageSlot + } + } + + function _getDocumentIssued(bytes32 document) internal view returns (bool) { + return _getStorage().documentIssued[document]; + } + + function _setDocumentIssued(bytes32 document, bool issued) internal { + _getStorage().documentIssued[document] = issued; + } + + function _getDocumentRevoked(bytes32 document) internal view returns (bool) { + return _getStorage().documentRevoked[document]; + } + + function _setDocumentRevoked(bytes32 document, bool revoked) internal { + _getStorage().documentRevoked[document] = revoked; } modifier onlyValidDocument( diff --git a/src/interfaces/IDocumentStore.sol b/src/interfaces/IDocumentStore.sol index d2a0e69..6f35f59 100644 --- a/src/interfaces/IDocumentStore.sol +++ b/src/interfaces/IDocumentStore.sol @@ -2,15 +2,7 @@ pragma solidity >=0.8.23 <0.9.0; interface IDocumentStore { - error InactiveDocument(bytes32 documentRoot, bytes32 document); - error DocumentExists(bytes32 document); - - error ZeroDocument(); - - error InvalidDocument(bytes32 documentRoot, bytes32 document); - - error DocumentNotIssued(bytes32 documentRoot, bytes32 document); /** * @notice Emitted when a document is issued @@ -26,8 +18,6 @@ interface IDocumentStore { function name() external view returns (string memory); - function issue(bytes32 documentRoot) external; - function revoke(bytes32 documentRoot) external; function isIssued(bytes32 documentRoot) external view returns (bool); diff --git a/src/interfaces/IDocumentStoreBatchable.sol b/src/interfaces/IDocumentStoreBatchable.sol index 1eb490f..94978b9 100644 --- a/src/interfaces/IDocumentStoreBatchable.sol +++ b/src/interfaces/IDocumentStoreBatchable.sol @@ -3,6 +3,8 @@ pragma solidity >=0.8.23 <0.9.0; import "./IDocumentStore.sol"; interface IDocumentStoreBatchable is IDocumentStore { + function issue(bytes32 documentRoot) external; + function revoke(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external; function isIssued(bytes32 documentRoot, bytes32 document, bytes32[] memory proof) external view returns (bool); diff --git a/src/interfaces/IDocumentStoreErrors.sol b/src/interfaces/IDocumentStoreErrors.sol new file mode 100644 index 0000000..309cfe3 --- /dev/null +++ b/src/interfaces/IDocumentStoreErrors.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.23 <0.9.0; + +interface IDocumentStoreErrors { + error InactiveDocument(bytes32 documentRoot, bytes32 document); + + error DocumentExists(bytes32 document); + + error ZeroDocument(); + + error InvalidDocument(bytes32 documentRoot, bytes32 document); + + error DocumentNotIssued(bytes32 documentRoot, bytes32 document); + + error DocumentIsRevoked(bytes32 documentRoot, bytes32 document); +} diff --git a/test/CommonTest.t.sol b/test/CommonTest.t.sol index 1d4e7dc..1173f97 100644 --- a/test/CommonTest.t.sol +++ b/test/CommonTest.t.sol @@ -5,17 +5,24 @@ import "forge-std/Test.sol"; import "../src/DocumentStore.sol"; import "./fixtures/DocumentStoreFixture.sol"; +import "../src/OwnableDocumentStore.sol"; abstract contract CommonTest is Test { - string public storeName = "DocumentStore Test"; - address public owner = vm.addr(1); address public issuer = vm.addr(2); address public revoker = vm.addr(3); + function setUp() public virtual {} +} + +abstract contract DocumentStoreCommonTest is CommonTest { DocumentStore public documentStore; - function setUp() public virtual { + string public storeName = "DocumentStore Test"; + + function setUp() public virtual override { + super.setUp(); + vm.startPrank(owner); documentStore = new DocumentStore(storeName, owner); @@ -26,7 +33,7 @@ abstract contract CommonTest is Test { } } -abstract contract DocumentStore_Initializer is CommonTest { +abstract contract DocumentStore_Initializer is DocumentStoreCommonTest { bytes32[] public documents; DocumentStoreFixture private _fixture; @@ -48,7 +55,7 @@ abstract contract DocumentStore_Initializer is CommonTest { } } -abstract contract DocumentStoreBatchable_Initializer is CommonTest { +abstract contract DocumentStoreBatchable_Initializer is DocumentStoreCommonTest { bytes32 public docRoot; bytes32[] public documents = new bytes32[](3); bytes32[][] public proofs = new bytes32[][](3); @@ -71,7 +78,7 @@ abstract contract DocumentStoreBatchable_Initializer is CommonTest { } } -abstract contract DocumentStore_multicall_revoke_Base is CommonTest { +abstract contract DocumentStore_multicall_revoke_Base is DocumentStoreCommonTest { bytes[] public bulkRevokeData; function docRoots() public view virtual returns (bytes32[] memory); @@ -145,7 +152,7 @@ abstract contract DocumentStore_multicall_revoke_Base is CommonTest { bulkRevokeData[1] = abi.encodeCall(IDocumentStoreBatchable.revoke, (docRoots()[0], documents()[0], proofs()[0])); // It should revert that document0 is already inactive - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InactiveDocument.selector, docRoots()[0], documents()[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InactiveDocument.selector, docRoots()[0], documents()[0])); vm.prank(revoker); documentStore.multicall(bulkRevokeData); @@ -225,3 +232,24 @@ abstract contract DocumentStore_multicall_revoke_Initializer is DocumentStore_mu documentStore.multicall(issueData); } } + +abstract contract OwnableDocumentStoreCommonTest is CommonTest { + OwnableDocumentStore public documentStore; + + string public storeName = "OwnableDocumentStore Test"; + string public storeSymbol = "XYZ"; + + address public recipient = vm.addr(4); + + function setUp() public virtual override { + super.setUp(); + + vm.startPrank(owner); + + documentStore = new OwnableDocumentStore(storeName, storeSymbol, owner); + documentStore.grantRole(documentStore.ISSUER_ROLE(), issuer); + documentStore.grantRole(documentStore.REVOKER_ROLE(), revoker); + + vm.stopPrank(); + } +} diff --git a/test/DocumentStore.t.sol b/test/DocumentStore.t.sol index ad97053..759f89b 100644 --- a/test/DocumentStore.t.sol +++ b/test/DocumentStore.t.sol @@ -10,7 +10,7 @@ import "../src/interfaces/IDocumentStore.sol"; import "../src/interfaces/IDocumentStoreBatchable.sol"; import "./CommonTest.t.sol"; -contract DocumentStore_init_Test is CommonTest { +contract DocumentStore_init_Test is DocumentStoreCommonTest { function testDocumentName() public { assertEq(documentStore.name(), storeName); } @@ -32,7 +32,7 @@ contract DocumentStore_init_Test is CommonTest { } } -contract DocumentStore_issue_Test is CommonTest { +contract DocumentStore_issue_Test is DocumentStoreCommonTest { function setUp() public override { super.setUp(); } @@ -96,21 +96,35 @@ contract DocumentStore_issue_Test is CommonTest { vm.startPrank(issuer); documentStore.issue(docHash); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentExists.selector, bytes32(docHash))); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.DocumentExists.selector, bytes32(docHash))); documentStore.issue(docHash); vm.stopPrank(); } + function testIssueRevokedDocumentRevert(bytes32 docHash) public { + vm.assume(docHash != bytes32(0)); + + vm.startPrank(owner); + documentStore.issue(docHash); + documentStore.revoke(docHash); + vm.stopPrank(); + + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.DocumentExists.selector, bytes32(docHash))); + + vm.prank(issuer); + documentStore.issue(docHash); + } + function testIssueZeroDocument() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); vm.prank(issuer); documentStore.issue(0x0); } } -contract DocumentStore_multicall_Issue_Test is CommonTest { +contract DocumentStore_multicall_Issue_Test is DocumentStoreCommonTest { bytes32[] public docHashes; bytes[] public bulkIssueData; @@ -123,8 +137,8 @@ contract DocumentStore_multicall_Issue_Test is CommonTest { docHashes[1] = "0x5678"; bulkIssueData = new bytes[](2); - bulkIssueData[0] = abi.encodeCall(IDocumentStore.issue, (docHashes[0])); - bulkIssueData[1] = abi.encodeCall(IDocumentStore.issue, (docHashes[1])); + bulkIssueData[0] = abi.encodeCall(IDocumentStoreBatchable.issue, (docHashes[0])); + bulkIssueData[1] = abi.encodeCall(IDocumentStoreBatchable.issue, (docHashes[1])); } function testBulkIssueByIssuer() public { @@ -157,9 +171,9 @@ contract DocumentStore_multicall_Issue_Test is CommonTest { function testBulkIssueWithDuplicatesRevert() public { docHashes[1] = docHashes[0]; - bulkIssueData[1] = abi.encodeCall(IDocumentStore.issue, (docHashes[0])); + bulkIssueData[1] = abi.encodeCall(IDocumentStoreBatchable.issue, (docHashes[0])); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentExists.selector, bytes32(docHashes[1]))); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.DocumentExists.selector, bytes32(docHashes[1]))); vm.prank(issuer); documentStore.multicall(bulkIssueData); @@ -172,7 +186,7 @@ contract DocumentStore_isIssued_Test is DocumentStoreBatchable_Initializer { } function testIsRootIssuedWithZeroRoot() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isIssued(0x0); } @@ -188,22 +202,22 @@ contract DocumentStore_isIssued_Test is DocumentStoreBatchable_Initializer { } function testIsIssuedWithInvalidProof() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[1])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[1])); documentStore.isIssued(docRoot, documents[1], proofs[0]); } function testIsIssuedWithInvalidEmptyProof() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[1])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[1])); documentStore.isIssued(docRoot, documents[1], new bytes32[](0)); } function testIsIssuedWithZeroDocument() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isIssued(0x0, documents[0], proofs[0]); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isIssued(docRoot, 0x0, proofs[0]); } } @@ -266,7 +280,7 @@ contract DocumentStore_revoke_Test is DocumentStore_Initializer { } function testRevokeWithZeroRoot() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); vm.prank(revoker); documentStore.revoke(0x0); @@ -276,7 +290,7 @@ contract DocumentStore_revoke_Test is DocumentStore_Initializer { vm.startPrank(revoker); documentStore.revoke(targetDoc); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InactiveDocument.selector, targetDoc, targetDoc)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InactiveDocument.selector, targetDoc, targetDoc)); documentStore.revoke(targetDoc); vm.stopPrank(); @@ -285,7 +299,9 @@ contract DocumentStore_revoke_Test is DocumentStore_Initializer { function testRevokeNotIssuedRootRevert() public { bytes32 nonIssuedRoot = "0x1234"; - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, nonIssuedRoot, nonIssuedRoot)); + vm.expectRevert( + abi.encodeWithSelector(IDocumentStoreErrors.DocumentNotIssued.selector, nonIssuedRoot, nonIssuedRoot) + ); vm.prank(revoker); documentStore.revoke(nonIssuedRoot); @@ -324,7 +340,7 @@ contract DocumentStore_isRevoked_Test is DocumentStore_Initializer { } function testIsRevokedWithZeroDocumentRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isRevoked(0x0); } @@ -332,7 +348,9 @@ contract DocumentStore_isRevoked_Test is DocumentStore_Initializer { function testIsRevokedWithNotIssuedDocumentRevert() public { bytes32 notIssuedRoot = "0x1234"; - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedRoot, notIssuedRoot)); + vm.expectRevert( + abi.encodeWithSelector(IDocumentStoreErrors.DocumentNotIssued.selector, notIssuedRoot, notIssuedRoot) + ); documentStore.isRevoked(notIssuedRoot); } @@ -355,20 +373,22 @@ contract DocumentStore_isActive_Test is DocumentStore_Initializer { } function testIsActiveWithZeroDocumentRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isActive(0x0); } function testIsActiveWithNotIssuedDocumentRevert() public { bytes32 notIssuedDoc = "0x1234"; - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedDoc, notIssuedDoc)); + vm.expectRevert( + abi.encodeWithSelector(IDocumentStoreErrors.DocumentNotIssued.selector, notIssuedDoc, notIssuedDoc) + ); documentStore.isActive(notIssuedDoc); } } -contract DocumentStore_supportsInterface_Test is CommonTest { +contract DocumentStore_supportsInterface_Test is DocumentStoreCommonTest { function testSupportsInterface() public { assertTrue(documentStore.supportsInterface(type(IDocumentStore).interfaceId)); assertTrue(documentStore.supportsInterface(type(IDocumentStoreBatchable).interfaceId)); diff --git a/test/DocumentStoreBatchable.t.sol b/test/DocumentStoreBatchable.t.sol index 229ac80..e28f192 100644 --- a/test/DocumentStoreBatchable.t.sol +++ b/test/DocumentStoreBatchable.t.sol @@ -60,14 +60,14 @@ contract DocumentStoreBatchable_revoke_Test is DocumentStoreBatchable_Initialize } function testRevokeWithInvalidProofRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[0])); vm.prank(revoker); documentStore.revoke(docRoot, documents[0], proofs[1]); } function testRevokeWithEmptyProofRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[0])); vm.prank(revoker); documentStore.revoke(docRoot, documents[0], new bytes32[](0)); @@ -76,10 +76,10 @@ contract DocumentStoreBatchable_revoke_Test is DocumentStoreBatchable_Initialize function testRevokeWithZeroDocument() public { vm.startPrank(revoker); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.revoke(0x0, documents[0], proofs[0]); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.revoke(docRoot, 0x0, proofs[0]); vm.stopPrank(); @@ -90,7 +90,7 @@ contract DocumentStoreBatchable_revoke_Test is DocumentStoreBatchable_Initialize documentStore.revoke(docRoot, documents[0], proofs[0]); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InactiveDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InactiveDocument.selector, docRoot, documents[0])); documentStore.revoke(docRoot, documents[0], proofs[0]); @@ -102,7 +102,7 @@ contract DocumentStoreBatchable_revoke_Test is DocumentStoreBatchable_Initialize documentStore.revoke(docRoot); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InactiveDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InactiveDocument.selector, docRoot, documents[0])); documentStore.revoke(docRoot, documents[0], proofs[0]); @@ -112,7 +112,9 @@ contract DocumentStoreBatchable_revoke_Test is DocumentStoreBatchable_Initialize function testRevokeNotIssuedDocumentRevert() public { bytes32 nonIssuedRoot = "0x1234"; - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, nonIssuedRoot, nonIssuedRoot)); + vm.expectRevert( + abi.encodeWithSelector(IDocumentStoreErrors.DocumentNotIssued.selector, nonIssuedRoot, nonIssuedRoot) + ); vm.prank(revoker); documentStore.revoke(nonIssuedRoot); @@ -154,29 +156,29 @@ contract DocumentStoreBatchable_isRevoked_Test is DocumentStoreBatchable_Initial } function testIsRevokedWithInvalidProofRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[0])); documentStore.isRevoked(docRoot, documents[0], proofs[1]); } function testIsRevokedWithEmptyProofRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[0])); documentStore.isRevoked(docRoot, documents[0], new bytes32[](0)); } function testIsRevokedWithZeroDocumentRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isRevoked(docRoot, 0x0, proofs[0]); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isRevoked(0x0, documents[0], proofs[0]); } function testIsRevokedWithNotIssuedDocumentRevert() public { bytes32 notIssuedDoc = "0x1234"; - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, notIssuedDoc)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, notIssuedDoc)); documentStore.isRevoked(docRoot, notIssuedDoc, proofs[0]); } @@ -199,29 +201,31 @@ contract DocumentStoreBatchable_isActive_Test is DocumentStoreBatchable_Initiali } function testIsActiveWithInvalidProofRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[0])); documentStore.isActive(docRoot, documents[0], proofs[1]); } function testIsActiveWithEmptyProofRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.InvalidDocument.selector, docRoot, documents[0])); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.InvalidDocument.selector, docRoot, documents[0])); documentStore.isActive(docRoot, documents[0], new bytes32[](0)); } function testIsActiveWithZeroDocumentRevert() public { - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isActive(docRoot, 0x0, proofs[0]); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.ZeroDocument.selector)); + vm.expectRevert(abi.encodeWithSelector(IDocumentStoreErrors.ZeroDocument.selector)); documentStore.isActive(0x0, documents[0], proofs[0]); } function testIsActiveWithNotIssuedDocumentRevert(bytes32 notIssuedDoc) public { vm.assume(notIssuedDoc != docRoot && notIssuedDoc != bytes32(0)); - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedDoc, notIssuedDoc)); + vm.expectRevert( + abi.encodeWithSelector(IDocumentStoreErrors.DocumentNotIssued.selector, notIssuedDoc, notIssuedDoc) + ); documentStore.isActive(notIssuedDoc, notIssuedDoc, new bytes32[](0)); } @@ -233,7 +237,9 @@ contract DocumentStoreBatchable_isActive_Test is DocumentStoreBatchable_Initiali bytes32[] memory proofs = new bytes32[](1); proofs[0] = 0x9800b3feae3c44fe4263f6cbb2d8dd529c26c3a1c3ca7208a30cfa5efbc362e7; - vm.expectRevert(abi.encodeWithSelector(IDocumentStore.DocumentNotIssued.selector, notIssuedRoot, notIssuedDoc)); + vm.expectRevert( + abi.encodeWithSelector(IDocumentStoreErrors.DocumentNotIssued.selector, notIssuedRoot, notIssuedDoc) + ); documentStore.isActive(notIssuedRoot, notIssuedDoc, proofs); }