From a13fa03057ed5f4b4352ef72a0fcac5986d0bf40 Mon Sep 17 00:00:00 2001 From: sveitser Date: Fri, 3 Jun 2022 15:58:52 +0200 Subject: [PATCH 01/24] Remove solc compiler warnings --- contracts/contracts.svg | 2 +- contracts/contracts/CAPE.sol | 8 +++++--- contracts/contracts/RescueNonOptimized.sol | 4 ++-- contracts/contracts/mocks/TestRescue.sol | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/contracts/contracts.svg b/contracts/contracts.svg index 3796a8fd..39f3b72a 100644 --- a/contracts/contracts.svg +++ b/contracts/contracts.svg @@ -123,7 +123,7 @@    constructor(nRoots: uint64, verifierAddr: address, recordsMerkleTreeAddr: address)    faucetSetupForTestnet(faucetManagerAddress: EdOnBN254.EdOnBN254Point, faucetManagerEncKey: bytes32)    depositErc20(ro: RecordOpening, erc20Address: address) -    submitCapeBlockWithMemos(newBlock: CapeBlock, extraData: bytes) +    submitCapeBlockWithMemos(newBlock: CapeBlock, bytes)    submitCapeBlock(newBlock: CapeBlock)    getRootValue(): uint256 diff --git a/contracts/contracts/CAPE.sol b/contracts/contracts/CAPE.sol index e8eff92a..9ce4deb1 100644 --- a/contracts/contracts/CAPE.sol +++ b/contracts/contracts/CAPE.sol @@ -249,9 +249,11 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { /// @notice Submit a new block with extra data to the CAPE contract. /// @param newBlock block to be processed by the CAPE contract - /// @param extraData extra data to be stored in calldata; this data is ignored by the contract function - // solhint-disable-next-line no-unused-vars - function submitCapeBlockWithMemos(CapeBlock memory newBlock, bytes calldata extraData) public { + /// @param {bytes} extraData data to be stored in calldata; this data is ignored by the contract function + function submitCapeBlockWithMemos( + CapeBlock memory newBlock, + bytes calldata /* extraData */ + ) public { submitCapeBlock(newBlock); } diff --git a/contracts/contracts/RescueNonOptimized.sol b/contracts/contracts/RescueNonOptimized.sol index f3bb6b21..b8d0539a 100644 --- a/contracts/contracts/RescueNonOptimized.sol +++ b/contracts/contracts/RescueNonOptimized.sol @@ -293,7 +293,7 @@ contract RescueNonOptimized { uint256 a, uint256 b, uint256 c - ) public returns (uint256) { + ) public view returns (uint256) { uint256[_STATE_SIZE] memory input; uint256[_STATE_SIZE] memory state; @@ -307,7 +307,7 @@ contract RescueNonOptimized { return state[0]; } - function commit(uint256[15] memory inputs) public returns (uint256) { + function commit(uint256[15] memory inputs) public view returns (uint256) { uint256 a = inputs[0]; uint256 b = inputs[1]; uint256 c = inputs[2]; diff --git a/contracts/contracts/mocks/TestRescue.sol b/contracts/contracts/mocks/TestRescue.sol index 79d98921..71297642 100644 --- a/contracts/contracts/mocks/TestRescue.sol +++ b/contracts/contracts/mocks/TestRescue.sol @@ -19,11 +19,11 @@ contract TestRescue { uint256 a, uint256 b, uint256 c - ) public returns (uint256) { + ) public view returns (uint256) { return RescueLib.hash(a, b, c); } - function commit(uint256[15] memory inputs) public returns (uint256) { + function commit(uint256[15] memory inputs) public view returns (uint256) { return RescueLib.commit(inputs); } } From c0cd81bafee2310fa9a79aa182d8cb5372085a59 Mon Sep 17 00:00:00 2001 From: sveitser Date: Fri, 3 Jun 2022 17:04:21 +0200 Subject: [PATCH 02/24] Try slither github action --- .github/workflows/slither.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/slither.yml diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml new file mode 100644 index 00000000..144d2c82 --- /dev/null +++ b/.github/workflows/slither.yml @@ -0,0 +1,31 @@ +name: Slither Analysis + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + analyze: + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Run Slither + uses: crytic/slither-action@v0.1.1 + continue-on-error: true + id: slither + with: + node-version: 16 + sarif: results.sarif + target: ./contracts + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ steps.slither.outputs.sarif }} From 7da37461e1ad4934e432369eb5358e92547714f8 Mon Sep 17 00:00:00 2001 From: sveitser Date: Fri, 3 Jun 2022 17:11:59 +0200 Subject: [PATCH 03/24] master -> main --- .github/workflows/slither.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml index 144d2c82..93a76829 100644 --- a/.github/workflows/slither.yml +++ b/.github/workflows/slither.yml @@ -2,9 +2,9 @@ name: Slither Analysis on: push: - branches: [master] + branches: + - main pull_request: - branches: [master] jobs: analyze: From 08a6065d33bc47170bf97197dc4048e49a71aa85 Mon Sep 17 00:00:00 2001 From: sveitser Date: Fri, 3 Jun 2022 18:07:14 +0200 Subject: [PATCH 04/24] WIP: trying to make sense of slither config file --- .github/workflows/build.yml | 9 +++++++++ .github/workflows/slither.yml | 31 ------------------------------- .gitignore | 3 +++ bin/run-slither | 3 +-- slither.config.json | 4 ++++ 5 files changed, 17 insertions(+), 33 deletions(-) delete mode 100644 .github/workflows/slither.yml create mode 100644 slither.config.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2e1ab882..0c7790dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,6 +44,15 @@ jobs: - name: Initialize Nix Shell run: nix-shell --run "echo Init" + - name: Run slither + run: slither ./contracts + continue-on-error: true + + - name: Upload slither SARIF file + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: slither.sarif + - name: Cache cargo uses: actions/cache@v2 with: diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml deleted file mode 100644 index 93a76829..00000000 --- a/.github/workflows/slither.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Slither Analysis - -on: - push: - branches: - - main - pull_request: - -jobs: - analyze: - runs-on: ubuntu-latest - permissions: - contents: read - security-events: write - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Run Slither - uses: crytic/slither-action@v0.1.1 - continue-on-error: true - id: slither - with: - node-version: 16 - sarif: results.sarif - target: ./contracts - - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: ${{ steps.slither.outputs.sarif }} diff --git a/.gitignore b/.gitignore index 5524ea61..949ddce4 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ __pycache__/ .*.sw* scratch/ + +# Slither analysis results +slither.sarif diff --git a/bin/run-slither b/bin/run-slither index 6eeb4cd9..65001748 100755 --- a/bin/run-slither +++ b/bin/run-slither @@ -9,5 +9,4 @@ set -euo pipefail -slither --solc-remaps @openzeppelin/=`pwd`/node_modules/.pnpm/@openzeppelin+contracts@4.3.3/node_modules/@openzeppelin/,@rari-capital/=`pwd`/node_modules/.pnpm/@rari-capital+solmate@6.2.0/node_modules/@rari-capital/,solidity-bytes-utils/=`pwd`/node_modules/.pnpm/solidity-bytes-utils@0.8.0/node_modules/solidity_bytes_utils/ contracts - +slither contracts diff --git a/slither.config.json b/slither.config.json new file mode 100644 index 00000000..fa8f75dc --- /dev/null +++ b/slither.config.json @@ -0,0 +1,4 @@ +{ + "filter_paths": "Token.sol,mocks", + "sarif": "slither.sarif" +} From a69fb1da16048525cb3e0f78e4eba6f49ff9ef1e Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 13:02:15 +0200 Subject: [PATCH 05/24] CI: run slither in nix-shell --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0c7790dd..9512d44a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: run: nix-shell --run "echo Init" - name: Run slither - run: slither ./contracts + run: nix-shell --run "slither ./contracts" continue-on-error: true - name: Upload slither SARIF file From ca71daab8c667affcd244e2488d0f0bb7631e07d Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 13:47:53 +0200 Subject: [PATCH 06/24] [WIP] Slither configurations - Disable external and test contracts - Disable some noisy detectors --- contracts/contracts/CAPE.sol | 7 ++++++- slither.config.json | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/contracts/contracts/CAPE.sol b/contracts/contracts/CAPE.sol index 9ce4deb1..4e0da260 100644 --- a/contracts/contracts/CAPE.sol +++ b/contracts/contracts/CAPE.sol @@ -198,7 +198,10 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { uint256[] memory recordCommitments = new uint256[](1); recordCommitments[0] = _deriveRecordCommitment(ro); - // insert the record into record accumulator + // Insert the record into record accumulator. + // + // This is a call to our own contract, not an arbitrary external contract. + // slither-disable-next-line reentrancy-no-eth _recordsMerkleTree.updateRecordsMerkleTree(recordCommitments); _addRoot(_recordsMerkleTree.getRootValue()); @@ -367,6 +370,8 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { // Only update the merkle tree and add the root if the list of records commitments is non empty if (!commitments.isEmpty()) { + // This is a call to our own contract, not an arbitrary external contract. + // slither-disable-next-line reentrancy-no-eth _recordsMerkleTree.updateRecordsMerkleTree(commitments.items); _addRoot(_recordsMerkleTree.getRootValue()); } diff --git a/slither.config.json b/slither.config.json index fa8f75dc..1c880937 100644 --- a/slither.config.json +++ b/slither.config.json @@ -1,4 +1,5 @@ { - "filter_paths": "Token.sol,mocks", + "filter_paths": "ERC20.sol|Token.sol|USDC|mocks|Test|RescueNonOptimized|BytesLib", + "detectors_to_exclude": "assembly,similar-names,too-many-digits,naming-convention,write-after-write,solc-version", "sarif": "slither.sarif" } From c7aa808c255493ed973817c54b252533490dcfb2 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 16:29:23 +0200 Subject: [PATCH 07/24] Add slither pre-commit hook --- flake.nix | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/flake.nix b/flake.nix index 6009d222..12999489 100644 --- a/flake.nix +++ b/flake.nix @@ -172,6 +172,13 @@ pass_filenames = false; types = [ "solidity" ]; }; + slither = { + enable = true; + description = "Solidity static analysis"; + entry = "slither ./contracts"; + pass_filenames = false; + types = [ "solidity" ]; + }; }; }; }; From f6eec03a24898581983f7505fe344a67cc94276f Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 16:29:42 +0200 Subject: [PATCH 08/24] slither: don't output sarif file on local runs --- .github/workflows/build.yml | 2 +- slither.config.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9512d44a..2648f400 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,7 +45,7 @@ jobs: run: nix-shell --run "echo Init" - name: Run slither - run: nix-shell --run "slither ./contracts" + run: nix-shell --run "slither ./contracts --sarif slither.sarif" continue-on-error: true - name: Upload slither SARIF file diff --git a/slither.config.json b/slither.config.json index 1c880937..cea214aa 100644 --- a/slither.config.json +++ b/slither.config.json @@ -1,5 +1,4 @@ { "filter_paths": "ERC20.sol|Token.sol|USDC|mocks|Test|RescueNonOptimized|BytesLib", - "detectors_to_exclude": "assembly,similar-names,too-many-digits,naming-convention,write-after-write,solc-version", - "sarif": "slither.sarif" + "detectors_to_exclude": "assembly,similar-names,too-many-digits,naming-convention,write-after-write,solc-version" } From d8a2f78a494dba8caef3713a507aacd3e6d6d08c Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 16:35:33 +0200 Subject: [PATCH 09/24] Fix slither warnings - Initialize local variables. - Don't import hardhat console. - Make enum if statements exhaustive. --- contracts/contracts/CAPE.sol | 2 -- contracts/contracts/RecordsMerkleTree.sol | 24 ++++++++----------- contracts/contracts/libraries/BN254.sol | 2 +- contracts/contracts/libraries/EdOnBN254.sol | 2 +- contracts/contracts/libraries/RescueLib.sol | 1 + .../contracts/verifier/PlonkVerifier.sol | 2 +- contracts/contracts/verifier/Transcript.sol | 1 - 7 files changed, 14 insertions(+), 20 deletions(-) diff --git a/contracts/contracts/CAPE.sol b/contracts/contracts/CAPE.sol index 4e0da260..1f38ad7a 100644 --- a/contracts/contracts/CAPE.sol +++ b/contracts/contracts/CAPE.sol @@ -13,8 +13,6 @@ pragma solidity ^0.8.0; /// CAPE provides auditable anonymous payments on Ethereum. /// @author Espresso Systems -import "hardhat/console.sol"; - import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@rari-capital/solmate/src/utils/SafeTransferLib.sol"; diff --git a/contracts/contracts/RecordsMerkleTree.sol b/contracts/contracts/RecordsMerkleTree.sol index bca6628a..3aa36961 100644 --- a/contracts/contracts/RecordsMerkleTree.sol +++ b/contracts/contracts/RecordsMerkleTree.sol @@ -9,7 +9,6 @@ pragma solidity ^0.8.0; -import "hardhat/console.sol"; import "./libraries/RescueLib.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; @@ -81,16 +80,15 @@ contract RecordsMerkleTree is Ownable { // indexFirstSibling = cursor - 2; // indexSecondSibling = cursor - 1; - Node memory node; if (posSibling == Position.LEFT) { - node = Node(0, cursor - 3, cursor - 2, cursor - 1); + return Node(0, cursor - 3, cursor - 2, cursor - 1); } else if (posSibling == Position.MIDDLE) { - node = Node(0, cursor - 2, cursor - 3, cursor - 1); + return Node(0, cursor - 2, cursor - 3, cursor - 1); } else if (posSibling == Position.RIGHT) { - node = Node(0, cursor - 2, cursor - 1, cursor - 3); + return Node(0, cursor - 2, cursor - 1, cursor - 3); + } else { + revert("unreachable"); } - - return node; } /// @dev Create a Merkle tree from the given frontier. @@ -155,17 +153,15 @@ contract RecordsMerkleTree is Ownable { uint64 nodeIndex, Position pos ) private pure returns (uint64) { - uint64 res; - if (pos == Position.LEFT) { - res = nodes[nodeIndex].left; + return nodes[nodeIndex].left; } else if (pos == Position.MIDDLE) { - res = nodes[nodeIndex].middle; + return nodes[nodeIndex].middle; } else if (pos == Position.RIGHT) { - res = nodes[nodeIndex].right; + return nodes[nodeIndex].right; + } else { + revert("unreachable"); } - - return res; } /// @dev Update the child of a node based on the position (which child to select) and an index to the new child. diff --git a/contracts/contracts/libraries/BN254.sol b/contracts/contracts/libraries/BN254.sol index 52a7f74c..b4902ac3 100644 --- a/contracts/contracts/libraries/BN254.sol +++ b/contracts/contracts/libraries/BN254.sol @@ -284,7 +284,7 @@ library BN254 { } function g1Serialize(G1Point memory point) internal pure returns (bytes memory) { - uint256 mask; + uint256 mask = 0; // Set the 254-th bit to 1 for infinity // https://docs.rs/ark-serialize/0.3.0/src/ark_serialize/flags.rs.html#117 diff --git a/contracts/contracts/libraries/EdOnBN254.sol b/contracts/contracts/libraries/EdOnBN254.sol index 56c343dd..f6fb69f8 100644 --- a/contracts/contracts/libraries/EdOnBN254.sol +++ b/contracts/contracts/libraries/EdOnBN254.sol @@ -41,7 +41,7 @@ library EdOnBN254 { } function serialize(EdOnBN254Point memory point) internal pure returns (bytes memory res) { - uint256 mask; + uint256 mask = 0; // Edward curve does not have an infinity flag. // Set the 255-th bit to 1 for positive Y // See: https://github.com/arkworks-rs/algebra/blob/d6365c3a0724e5d71322fe19cbdb30f979b064c8/serialize/src/flags.rs#L148 diff --git a/contracts/contracts/libraries/RescueLib.sol b/contracts/contracts/libraries/RescueLib.sol index dfefd567..3a66360f 100644 --- a/contracts/contracts/libraries/RescueLib.sol +++ b/contracts/contracts/libraries/RescueLib.sol @@ -169,6 +169,7 @@ library RescueLib { uint256 ) { + // slither-disable-next-line uninitialized-local uint256[6] memory alphaInvScratch; _expAlphaInv4Setup(alphaInvScratch); diff --git a/contracts/contracts/verifier/PlonkVerifier.sol b/contracts/contracts/verifier/PlonkVerifier.sol index 5078509d..a3732c54 100644 --- a/contracts/contracts/verifier/PlonkVerifier.sol +++ b/contracts/contracts/verifier/PlonkVerifier.sol @@ -10,7 +10,6 @@ pragma solidity ^0.8.0; import {BN254} from "../libraries/BN254.sol"; -import "hardhat/console.sol"; import "../interfaces/IPlonkVerifier.sol"; import {PolynomialEval as Poly} from "../libraries/PolynomialEval.sol"; import "./Transcript.sol"; @@ -212,6 +211,7 @@ contract PlonkVerifier is IPlonkVerifier { transcript.appendGroupElement(proof.wire4); // have to compute tau, but not really used anywhere + // slither-disable-next-line unused-return transcript.getAndAppendChallenge(); res.beta = transcript.getAndAppendChallenge(); res.gamma = transcript.getAndAppendChallenge(); diff --git a/contracts/contracts/verifier/Transcript.sol b/contracts/contracts/verifier/Transcript.sol index 393dbe56..d3387fbe 100644 --- a/contracts/contracts/verifier/Transcript.sol +++ b/contracts/contracts/verifier/Transcript.sol @@ -10,7 +10,6 @@ pragma solidity ^0.8.0; import "solidity-bytes-utils/contracts/BytesLib.sol"; -import "hardhat/console.sol"; import "../libraries/Utils.sol"; import {BN254} from "../libraries/BN254.sol"; import {IPlonkVerifier} from "../interfaces/IPlonkVerifier.sol"; From 1e7bb368e379afe536267b69d3f213d07b7a61f8 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 16:47:36 +0200 Subject: [PATCH 10/24] Remove false positive variable scopes warnings --- contracts/contracts/verifier/PlonkVerifier.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/contracts/verifier/PlonkVerifier.sol b/contracts/contracts/verifier/PlonkVerifier.sol index a3732c54..2e952334 100644 --- a/contracts/contracts/verifier/PlonkVerifier.sol +++ b/contracts/contracts/verifier/PlonkVerifier.sol @@ -505,6 +505,7 @@ contract PlonkVerifier is IPlonkVerifier { uint256 s = pcsInfos[i].commScalars[j]; uint256 tmp; assembly { + // slither-disable-next-line variable-scope tmp := mulmod(rBase, s, p) } scalars[idx] = tmp; @@ -518,6 +519,7 @@ contract PlonkVerifier is IPlonkVerifier { uint256 evalPoint = pcsInfos[i].evalPoint; uint256 tmp; assembly { + // slither-disable-next-line variable-scope tmp := mulmod(rBase, evalPoint, p) } scalars[idx] = tmp; @@ -531,6 +533,7 @@ contract PlonkVerifier is IPlonkVerifier { uint256 nextEvalPoint = pcsInfos[i].nextEvalPoint; uint256 tmp; assembly { + // slither-disable-next-line variable-scope tmp := mulmod(rBase, mulmod(u, nextEvalPoint, p), p) } scalars[idx] = tmp; From 088e68959e84a315d83aca32beaf04f9ab2f04aa Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 16:54:15 +0200 Subject: [PATCH 11/24] Remove false positive calls in loop warnings --- contracts/contracts/CAPE.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/contracts/CAPE.sol b/contracts/contracts/CAPE.sol index 1f38ad7a..c20c27be 100644 --- a/contracts/contracts/CAPE.sol +++ b/contracts/contracts/CAPE.sol @@ -524,6 +524,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { ) { // load the correct (hardcoded) vk + // slither-disable-next-line calls-loop vk = VerifyingKeys.getVkById( VerifyingKeys.getEncodedId( uint8(NoteType.TRANSFER), @@ -605,6 +606,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { ) { // load the correct (hardcoded) vk + // slither-disable-next-line calls-loop vk = VerifyingKeys.getVkById( VerifyingKeys.getEncodedId( uint8(NoteType.MINT), @@ -666,6 +668,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { ) { // load the correct (hardcoded) vk + // slither-disable-next-line calls-loop vk = VerifyingKeys.getVkById( VerifyingKeys.getEncodedId( uint8(NoteType.FREEZE), From bb5163507e65e3de48a8214f70f5a0b790f04642 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 17:06:41 +0200 Subject: [PATCH 12/24] Remove false positive reentrancy warnings --- contracts/contracts/CAPE.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/contracts/CAPE.sol b/contracts/contracts/CAPE.sol index c20c27be..5ac5033d 100644 --- a/contracts/contracts/CAPE.sol +++ b/contracts/contracts/CAPE.sol @@ -201,8 +201,10 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { // This is a call to our own contract, not an arbitrary external contract. // slither-disable-next-line reentrancy-no-eth _recordsMerkleTree.updateRecordsMerkleTree(recordCommitments); + // slither-disable-next-line reentrancy-benign _addRoot(_recordsMerkleTree.getRootValue()); + // slither-disable-next-line reentrancy-events emit FaucetInitialized(abi.encode(ro)); faucetInitialized = true; } @@ -371,6 +373,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { // This is a call to our own contract, not an arbitrary external contract. // slither-disable-next-line reentrancy-no-eth _recordsMerkleTree.updateRecordsMerkleTree(commitments.items); + // slither-disable-next-line reentrancy-benign _addRoot(_recordsMerkleTree.getRootValue()); } @@ -378,6 +381,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { blockHeight += 1; // Inform clients about the new block and the processed deposits. + // slither-disable-next-line reentrancy-events _emitBlockEvent(newBlock); // Empty the queue now that the record commitments have been inserted From 09a05dfdc14ebef94be7d63e3e76edbf696bce03 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 17:15:59 +0200 Subject: [PATCH 13/24] Disable and explain costly-loop warning --- contracts/contracts/RecordsMerkleTree.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contracts/contracts/RecordsMerkleTree.sol b/contracts/contracts/RecordsMerkleTree.sol index 3aa36961..d148c47d 100644 --- a/contracts/contracts/RecordsMerkleTree.sol +++ b/contracts/contracts/RecordsMerkleTree.sol @@ -261,6 +261,14 @@ contract RecordsMerkleTree is Ownable { _updateChildNode(nodes[previousNodeIndex], newNodeIndex, Position(localPos)); // Increment the number of leaves + // + // This operation is costly and happens in a loop. However, for now the + // merkle tree is usually updated with a single new element. In this + // case we would not save gas by moving the update of _numLeaves. The + // gas cost is also likely negligible compared to the whole operation of + // inserting an element. + // + // slither-disable-next-line costly-loop _numLeaves += 1; // Return the new value of maxIndex From ef1c7943d41189f9c8580f55daaf5b1ff3a37fd1 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 17:19:57 +0200 Subject: [PATCH 14/24] Remove dead code --- contracts/contracts/RecordsMerkleTree.sol | 7 ------- contracts/contracts/libraries/EdOnBN254.sol | 12 ------------ 2 files changed, 19 deletions(-) diff --git a/contracts/contracts/RecordsMerkleTree.sol b/contracts/contracts/RecordsMerkleTree.sol index d148c47d..55d4a336 100644 --- a/contracts/contracts/RecordsMerkleTree.sol +++ b/contracts/contracts/RecordsMerkleTree.sol @@ -50,13 +50,6 @@ contract RecordsMerkleTree is Ownable { return (node.left == 0) && (node.middle == 0) && (node.right == 0); } - /// @dev Does the given node have children? - /// @param node A node - /// @return _ True if the node has at least one child, false otherwise - function _hasChildren(Node memory node) private pure returns (bool) { - return !_isTerminal(node); - } - /// @dev Is the given node null? /// @param node A node /// @return _ True if the node is NULL, false otherwise diff --git a/contracts/contracts/libraries/EdOnBN254.sol b/contracts/contracts/libraries/EdOnBN254.sol index f6fb69f8..539ada7a 100644 --- a/contracts/contracts/libraries/EdOnBN254.sol +++ b/contracts/contracts/libraries/EdOnBN254.sol @@ -23,18 +23,6 @@ library EdOnBN254 { uint256 y; } - /// @dev check if a G1 point is Infinity - /// @notice precompile bn256Add at address(6) takes (0, 0) as Point of Infinity, - /// some crypto libraries (such as arkwork) uses a boolean flag to mark PoI, and - /// just use (0, 1) as affine coordinates (not on curve) to represents PoI. - function isInfinity(EdOnBN254Point memory point) internal pure returns (bool result) { - assembly { - let x := mload(point) - let y := mload(add(point, 0x20)) - result := and(iszero(x), iszero(y)) - } - } - /// @dev Check if y-coordinate of G1 point is negative. function isYNegative(EdOnBN254Point memory point) internal pure returns (bool) { return (point.y << 1) < P_MOD; From 73cb3f82845edfe51a540ec902a314da7e915f0d Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 17:26:51 +0200 Subject: [PATCH 15/24] Remove unused constants --- contracts/contracts/libraries/RescueLib.sol | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/contracts/contracts/libraries/RescueLib.sol b/contracts/contracts/libraries/RescueLib.sol index 3a66360f..aec62690 100644 --- a/contracts/contracts/libraries/RescueLib.sol +++ b/contracts/contracts/libraries/RescueLib.sol @@ -13,18 +13,17 @@ library RescueLib { /// The constants are obtained from the Sage script /// https://github.com/EspressoSystems/Marvellous/blob/fcd4c41672f485ac2f62526bc87a16789d4d0459/rescue254.sage - uint256 private constant _N_ROUNDS = 12; - uint256 private constant _STATE_SIZE = 4; - uint256 private constant _SCHEDULED_KEY_SIZE = (2 * _N_ROUNDS + 1) * _STATE_SIZE; + // These constants are no longer used, left here for readability. + // uint256 private constant _N_ROUNDS = 12; + // uint256 private constant _STATE_SIZE = 4; + // uint256 private constant _SCHEDULED_KEY_SIZE = (2 * _N_ROUNDS + 1) * _STATE_SIZE; + // uint256 private constant _ALPHA = 5; // Obtained by running KeyScheduling([0,0,0,0]). See Algorithm 2 of AT specification document. - // solhint-disable-next-line var-name-mixedcase uint256 private constant _PRIME = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint256 private constant _ALPHA = 5; - uint256 private constant _ALPHA_INV = 17510594297471420177797124596205820070838691520332827474958563349260646796493; From 17679f92957eba6f507f09c3ba0e8a5c83d4d939 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 18:04:15 +0200 Subject: [PATCH 16/24] Remove Greeter --- contracts/contracts/Greeter.sol | 30 ----------------------------- contracts/rust/src/types.rs | 10 +++++----- contracts/test/greeter.spec.ts | 34 --------------------------------- 3 files changed, 5 insertions(+), 69 deletions(-) delete mode 100644 contracts/contracts/Greeter.sol delete mode 100644 contracts/test/greeter.spec.ts diff --git a/contracts/contracts/Greeter.sol b/contracts/contracts/Greeter.sol deleted file mode 100644 index a5ecd5cd..00000000 --- a/contracts/contracts/Greeter.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// -// Copyright (c) 2022 Espresso Systems (espressosys.com) -// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library. -// -// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// You should have received a copy of the GNU General Public License along with this program. If not, see . - -pragma solidity ^0.8.0; - -import "hardhat/console.sol"; - -contract Greeter { - string private _greeting; - - constructor(string memory greeting) { - console.log("Deploying a Greeter with _greeting:", greeting); - _greeting = greeting; - } - - function greet() public view returns (string memory) { - return _greeting; - } - - function setGreeting(string memory greeting) public { - console.log("Changing _greeting from '%s' to '%s'", _greeting, greeting); - _greeting = greeting; - } -} diff --git a/contracts/rust/src/types.rs b/contracts/rust/src/types.rs index b1cc6080..47c5d22e 100644 --- a/contracts/rust/src/types.rs +++ b/contracts/rust/src/types.rs @@ -28,11 +28,11 @@ use std::convert::TryInto; pub use crate::bindings::{ cape_mod::BlockCommittedFilter, AssetDefinition, AssetPolicy, AssetRegistry, AuditMemo, BurnNote, CAPEEvents, CapeBlock, Challenges, EdOnBN254Point, EvalData, EvalDomain, - FreezeAuxInfo, FreezeNote, G1Point, G2Point, Greeter, MaliciousToken, MintAuxInfo, MintNote, - PcsInfo, PlonkProof, RecordOpening, RecordsMerkleTree, SimpleToken, TestBN254, TestCAPE, - TestCAPEEvents, TestCapeTypes, TestEdOnBN254, TestPlonkVerifier, TestPolynomialEval, - TestRescue, TestRootStore, TestTranscript, TestVerifyingKeys, TranscriptData, TransferAuxInfo, - TransferNote, VerifyingKey, CAPE, ERC20, + FreezeAuxInfo, FreezeNote, G1Point, G2Point, MaliciousToken, MintAuxInfo, MintNote, PcsInfo, + PlonkProof, RecordOpening, RecordsMerkleTree, SimpleToken, TestBN254, TestCAPE, TestCAPEEvents, + TestCapeTypes, TestEdOnBN254, TestPlonkVerifier, TestPolynomialEval, TestRescue, TestRootStore, + TestTranscript, TestVerifyingKeys, TranscriptData, TransferAuxInfo, TransferNote, VerifyingKey, + CAPE, ERC20, }; // The number of input wires of TurboPlonk. diff --git a/contracts/test/greeter.spec.ts b/contracts/test/greeter.spec.ts deleted file mode 100644 index 7ebcc6cc..00000000 --- a/contracts/test/greeter.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2022 Espresso Systems (espressosys.com) -// This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library. -// -// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// You should have received a copy of the GNU General Public License along with this program. If not, see . - -import { expect } from "chai"; -import { ethers } from "hardhat"; - -/* -import { Greeter } from "../typechain-types"; -*/ - -describe("Greeter (typescript)", function () { - let greeter: any; - - beforeEach(async () => { - const greeterFactory = await ethers.getContractFactory("Greeter"); - greeter = await greeterFactory.deploy("Hello, world!"); - }); - - it("Should return the new greeting once it's changed", async function () { - expect(await greeter.greet()).to.equal("Hello, world!"); - - const setGreetingTx = await greeter.setGreeting("Hola, mundo!"); - - // wait until the transaction is mined - await setGreetingTx.wait(); - - let greeting_str = await greeter.greet(); - expect(greeting_str).to.equal("Hola, mundo!"); - }); -}); From dfa4a21505c3747647317241f0aa8b6862d6e8b8 Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 18:13:51 +0200 Subject: [PATCH 17/24] Make external functions external (not public) --- contracts/contracts/AssetRegistry.sol | 2 +- contracts/contracts/CAPE.sol | 8 ++++---- contracts/contracts/RecordsMerkleTree.sol | 6 +++--- contracts/contracts/libraries/RescueLib.sol | 7 ++++--- slither.config.json | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/contracts/contracts/AssetRegistry.sol b/contracts/contracts/AssetRegistry.sol index 6717d523..cb29fabd 100644 --- a/contracts/contracts/AssetRegistry.sol +++ b/contracts/contracts/AssetRegistry.sol @@ -68,7 +68,7 @@ contract AssetRegistry { /// registered or the ERC-20 token address is zero. /// @param erc20Address An ERC-20 token address /// @param newAsset An asset type to be registered in the contract - function sponsorCapeAsset(address erc20Address, AssetDefinition memory newAsset) public { + function sponsorCapeAsset(address erc20Address, AssetDefinition memory newAsset) external { require(erc20Address != address(0), "Bad asset address"); require(!isCapeAssetRegistered(newAsset), "Asset already registered"); diff --git a/contracts/contracts/CAPE.sol b/contracts/contracts/CAPE.sol index 5ac5033d..6bb2dacc 100644 --- a/contracts/contracts/CAPE.sol +++ b/contracts/contracts/CAPE.sol @@ -178,7 +178,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { function faucetSetupForTestnet( EdOnBN254.EdOnBN254Point memory faucetManagerAddress, bytes32 faucetManagerEncKey - ) public { + ) external { // faucet can only be set up once by the manager require(msg.sender == deployer, "Only invocable by deployer"); require(!faucetInitialized, "Faucet already set up"); @@ -230,7 +230,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { /// @notice Wraps ERC-20 tokens into a CAPE asset defined in the record opening. /// @param ro record opening that will be inserted in the records merkle tree once the deposit is validated /// @param erc20Address address of the ERC-20 token corresponding to the deposit - function depositErc20(RecordOpening memory ro, address erc20Address) public nonReentrant { + function depositErc20(RecordOpening memory ro, address erc20Address) external nonReentrant { require(isCapeAssetRegistered(ro.assetDef), "Asset definition not registered"); require(lookup(ro.assetDef) == erc20Address, "Wrong ERC20 address"); @@ -256,7 +256,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { function submitCapeBlockWithMemos( CapeBlock memory newBlock, bytes calldata /* extraData */ - ) public { + ) external { submitCapeBlock(newBlock); } @@ -708,7 +708,7 @@ contract CAPE is RootStore, AssetRegistry, ReentrancyGuard { transcriptInitMsg = EdOnBN254.serialize(note.auxInfo.txnMemoVerKey); } - function getRootValue() public view returns (uint256) { + function getRootValue() external view returns (uint256) { return _recordsMerkleTree.getRootValue(); } } diff --git a/contracts/contracts/RecordsMerkleTree.sol b/contracts/contracts/RecordsMerkleTree.sol index 55d4a336..cfbee729 100644 --- a/contracts/contracts/RecordsMerkleTree.sol +++ b/contracts/contracts/RecordsMerkleTree.sol @@ -331,17 +331,17 @@ contract RecordsMerkleTree is Ownable { } /// @notice Returns the root value of the Merkle tree. - function getRootValue() public view returns (uint256) { + function getRootValue() external view returns (uint256) { return _rootValue; } /// @notice Returns the height of the Merkle tree. - function getHeight() public view returns (uint8) { + function getHeight() external view returns (uint8) { return _merkleTreeHeight; } /// @notice Returns the number of leaves of the Merkle tree. - function getNumLeaves() public view returns (uint64) { + function getNumLeaves() external view returns (uint64) { return _numLeaves; } diff --git a/contracts/contracts/libraries/RescueLib.sol b/contracts/contracts/libraries/RescueLib.sol index aec62690..f61291fa 100644 --- a/contracts/contracts/libraries/RescueLib.sol +++ b/contracts/contracts/libraries/RescueLib.sol @@ -709,9 +709,10 @@ library RescueLib { } } - // Must be public so it doesn't get inlined into CAPE.sol and blow - // the size limit - function commit(uint256[15] memory inputs) public view returns (uint256) { + // This function is external to ensure that the solidity compiler generates + // a separate library contract. This is required to reduce the size of the + // CAPE contract. + function commit(uint256[15] memory inputs) external view returns (uint256) { checkBounded(inputs); uint256 a; diff --git a/slither.config.json b/slither.config.json index cea214aa..c70688ee 100644 --- a/slither.config.json +++ b/slither.config.json @@ -1,4 +1,4 @@ { - "filter_paths": "ERC20.sol|Token.sol|USDC|mocks|Test|RescueNonOptimized|BytesLib", + "filter_paths": "ERC20.sol|Token.sol|USDC|mocks|Test|RescueNonOptimized|BytesLib|Ownable.sol", "detectors_to_exclude": "assembly,similar-names,too-many-digits,naming-convention,write-after-write,solc-version" } From 8f062a3f73d347eaca5e03aafa0fbd3c0d82f53d Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 18:15:35 +0200 Subject: [PATCH 18/24] Fix js tests for RescueLib --- contracts/test/benchmarks/test-rescue.js | 86 +++++++++--------------- 1 file changed, 31 insertions(+), 55 deletions(-) diff --git a/contracts/test/benchmarks/test-rescue.js b/contracts/test/benchmarks/test-rescue.js index 05b3506c..6a66da8f 100644 --- a/contracts/test/benchmarks/test-rescue.js +++ b/contracts/test/benchmarks/test-rescue.js @@ -11,7 +11,9 @@ const { ethers } = require("hardhat"); describe("Rescue benchmarks", function () { describe("Gas spent for computing the Rescue function", function () { for (const contractName of ["TestRescue", "TestRescueNonOptimized"]) { - it(`checks gas usage of ${contractName}.hash`, async function () { + let rescueContract; + + beforeEach(async function () { const libraries = {}; if (contractName == "TestRescue") { let rescueLib = await (await ethers.getContractFactory("RescueLib")).deploy(); @@ -19,74 +21,48 @@ describe("Rescue benchmarks", function () { } const factory = await ethers.getContractFactory(contractName, { libraries }); - let rescueContract = await factory.deploy(); + rescueContract = await factory.deploy(); // Polling interval in ms. rescueContract.provider.pollingInterval = 20; await rescueContract.deployed(); + }); + it(`checks gas usage of ${contractName}.hash`, async function () { const doNothingTx = await rescueContract.doNothing(); const doNothingtxReceipt = await doNothingTx.wait(); - let doNothingGasUsed = doNothingtxReceipt.gasUsed; - - const rescueTx = await rescueContract.hash(10, 15, 20); - const rescueTxReceipt = await rescueTx.wait(); - let rescueGasUsed = rescueTxReceipt.gasUsed; + const doNothingGasUsed = doNothingtxReceipt.gasUsed; - let rescueOnly = rescueGasUsed - doNothingGasUsed; + const rescueGasUsed = await rescueContract.estimateGas.hash(10, 15, 20); - const commitTx = await rescueContract.commit([ - BigInt(10), - BigInt(15), - BigInt(20), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - BigInt(0), - ]); - console.log(commitTx); - const commitTxReceipt = await commitTx.wait(); - let commitGasUsed = commitTxReceipt.gasUsed; + const rescueOnly = rescueGasUsed - doNothingGasUsed; console.log("Rescue gas of ", contractName, ": ", rescueOnly); }); - it(`checks gas usage of ${contractName}.commit on a potentially overflowing input`, async function () { - const libraries = {}; - if (contractName == "TestRescue") { - let rescueLib = await (await ethers.getContractFactory("RescueLib")).deploy(); - libraries["RescueLib"] = rescueLib.address; - } - const factory = await ethers.getContractFactory(contractName, { libraries }); - - let rescueContract = await factory.deploy(); - - // Polling interval in ms. - rescueContract.provider.pollingInterval = 20; - - await rescueContract.deployed(); - - const doNothingTx = await rescueContract.doNothing(); - const doNothingtxReceipt = await doNothingTx.wait(); - let doNothingGasUsed = doNothingtxReceipt.gasUsed; - console.log("About to hash"); - - const rescueTx = await rescueContract.hash(10, 15, 20); - const rescueTxReceipt = await rescueTx.wait(); - let rescueGasUsed = rescueTxReceipt.gasUsed; - - let rescueOnly = rescueGasUsed - doNothingGasUsed; - - console.log("About to commit"); + it(`check ${contractName}.commit works for non-overflowing input`, async function () { + expect( + rescueContract.commit([ + BigInt(10), + BigInt(15), + BigInt(20), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + BigInt(0), + ]) + ).to.not.be.reverted; + }); + it(`check ${contractName}.commit reverts for potentially overflowing input`, async function () { expect( rescueContract.commit([ BigInt(10), From fea9fd0849bed3a9d67adf07a4a3b2e52ed41d0e Mon Sep 17 00:00:00 2001 From: sveitser Date: Tue, 7 Jun 2022 18:23:21 +0200 Subject: [PATCH 19/24] Update contracts diagram --- contracts/contracts.svg | 893 ++++++++++++++++++++-------------------- 1 file changed, 448 insertions(+), 445 deletions(-) diff --git a/contracts/contracts.svg b/contracts/contracts.svg index 39f3b72a..15d27fbe 100644 --- a/contracts/contracts.svg +++ b/contracts/contracts.svg @@ -4,252 +4,255 @@ - - + + UmlClassDiagram - + 0 - -AssetRegistry - -Public: -   DOM_SEP_FOREIGN_ASSET: bytes13 -   DOM_SEP_DOMESTIC_ASSET: bytes14 -   CAP_NATIVE_ASSET_CODE: uint256 -   assets: mapping(bytes32=>address) - + +AssetRegistry + +Public: +   DOM_SEP_FOREIGN_ASSET: bytes13 +   DOM_SEP_DOMESTIC_ASSET: bytes14 +   CAP_NATIVE_ASSET_CODE: uint256 +   assets: mapping(bytes32=>address) + +External: +    sponsorCapeAsset(erc20Address: address, newAsset: AssetDefinition) Public:    <<event>> AssetSponsored(erc20Address: address, assetDefinitionCode: uint256)    nativeDomesticAsset(): (assetDefinition: AssetDefinition)    lookup(assetDefinition: AssetDefinition): address    isCapeAssetRegistered(assetDefinition: AssetDefinition): bool -    sponsorCapeAsset(erc20Address: address, newAsset: AssetDefinition) 7 - -<<Library>> -BN254 - -Public: -   P_MOD: uint256 -   R_MOD: uint256 - - + +<<Library>> +BN254 + +Public: +   P_MOD: uint256 +   R_MOD: uint256 + + 0->7 - - + + 8 - -<<Library>> -EdOnBN254 - -Public: -   P_MOD: uint256 - - + +<<Library>> +EdOnBN254 + +Public: +   P_MOD: uint256 + + 0->8 - - + + 0struct0 - -<<struct>> -AssetDefinition - -code: uint256 -policy: AssetPolicy + +<<struct>> +AssetDefinition + +code: uint256 +policy: AssetPolicy 0struct0->0 - - + + 0struct1 - -<<struct>> -AssetPolicy - -auditorPk: EdOnBN254.EdOnBN254Point -credPk: EdOnBN254.EdOnBN254Point -freezerPk: EdOnBN254.EdOnBN254Point -revealMap: uint256 -revealThreshold: uint128 + +<<struct>> +AssetPolicy + +auditorPk: EdOnBN254.EdOnBN254Point +credPk: EdOnBN254.EdOnBN254Point +freezerPk: EdOnBN254.EdOnBN254Point +revealMap: uint256 +revealThreshold: uint128 0struct1->0 - - + + 1 - -CAPE - -Public: -   nullifiers: mapping(uint256=>bool) -   blockHeight: uint64 -   pendingDeposits: uint256[] -   deployer: address -   faucetInitialized: bool -   CAPE_BURN_MAGIC_BYTES: bytes -   CAPE_BURN_MAGIC_BYTES_SIZE: uint256 -   MAX_NUM_PENDING_DEPOSIT: uint256 - -Public: -    <<event>> FaucetInitialized(roBytes: bytes) -    <<event>> BlockCommitted(height: uint64, depositCommitments: uint256[], minerAddr: bytes, noteTypes: bytes, transferNotes: bytes, mintNotes: bytes, freezeNotes: bytes, burnNotes: bytes) -    <<event>> Erc20TokensDeposited(roBytes: bytes, erc20TokenAddress: address, from: address) -    constructor(nRoots: uint64, verifierAddr: address, recordsMerkleTreeAddr: address) -    faucetSetupForTestnet(faucetManagerAddress: EdOnBN254.EdOnBN254Point, faucetManagerEncKey: bytes32) -    depositErc20(ro: RecordOpening, erc20Address: address) -    submitCapeBlockWithMemos(newBlock: CapeBlock, bytes) -    submitCapeBlock(newBlock: CapeBlock) -    getRootValue(): uint256 + +CAPE + +Public: +   nullifiers: mapping(uint256=>bool) +   blockHeight: uint64 +   pendingDeposits: uint256[] +   deployer: address +   faucetInitialized: bool +   CAPE_BURN_MAGIC_BYTES: bytes +   CAPE_BURN_MAGIC_BYTES_SIZE: uint256 +   MAX_NUM_PENDING_DEPOSIT: uint256 + +External: +    faucetSetupForTestnet(faucetManagerAddress: EdOnBN254.EdOnBN254Point, faucetManagerEncKey: bytes32) +    depositErc20(ro: RecordOpening, erc20Address: address) +    submitCapeBlockWithMemos(newBlock: CapeBlock, bytes) +    getRootValue(): uint256 +Public: +    <<event>> FaucetInitialized(roBytes: bytes) +    <<event>> BlockCommitted(height: uint64, depositCommitments: uint256[], minerAddr: bytes, noteTypes: bytes, transferNotes: bytes, mintNotes: bytes, freezeNotes: bytes, burnNotes: bytes) +    <<event>> Erc20TokensDeposited(roBytes: bytes, erc20TokenAddress: address, from: address) +    constructor(nRoots: uint64, verifierAddr: address, recordsMerkleTreeAddr: address) +    submitCapeBlock(newBlock: CapeBlock) 1->0 - - + + 3 - -RootStore - - - -Public: -    constructor(nRoots: uint64) + +RootStore + + + +Public: +    constructor(nRoots: uint64) 1->3 - - + + 4 - -<<Interface>> -IPlonkVerifier - - - -External: -     batchVerify(verifyingKeys: VerifyingKey[], publicInputs: uint256[][], proofs: PlonkProof[], extraTranscriptInitMsgs: bytes[]): bool + +<<Interface>> +IPlonkVerifier + + + +External: +     batchVerify(verifyingKeys: VerifyingKey[], publicInputs: uint256[][], proofs: PlonkProof[], extraTranscriptInitMsgs: bytes[]): bool 1->4 - - + + 5 - -<<Interface>> -IRecordsMerkleTree - - - -External: -     updateRecordsMerkleTree(elements: uint256[]) -     getRootValue(): uint256 -     getHeight(): uint8 -     getNumLeaves(): uint64 + +<<Interface>> +IRecordsMerkleTree + + + +External: +     updateRecordsMerkleTree(elements: uint256[]) +     getRootValue(): uint256 +     getHeight(): uint8 +     getNumLeaves(): uint64 1->5 - - + + 6 - -<<Library>> -AccumulatingArray - - - - + +<<Library>> +AccumulatingArray + + + + 1->6 - - + + 1->8 - - + + 13 - -<<Library>> -RescueLib - - - + +<<Library>> +RescueLib + + + +External: +    commit(inputs: uint256[]): uint256 Public:    hash(a: uint256, b: uint256, c: uint256): (o: uint256) -    commit(inputs: uint256[]): uint256 1->13 - - + + 19 - -<<Library>> -VerifyingKeys - - - -External: -    getVkById(encodedId: uint256): IPlonkVerifier.VerifyingKey -Public: -    getEncodedId(noteType: uint8, numInput: uint8, numOutput: uint8, treeDepth: uint8): (encodedId: uint256) + +<<Library>> +VerifyingKeys + + + +External: +    getVkById(encodedId: uint256): IPlonkVerifier.VerifyingKey +Public: +    getEncodedId(noteType: uint8, numInput: uint8, numOutput: uint8, treeDepth: uint8): (encodedId: uint256) 1->19 - - + + @@ -264,8 +267,8 @@ 1struct0->1 - - + + @@ -283,8 +286,8 @@ 1struct1->1 - - + + @@ -299,8 +302,8 @@ 1struct2->1 - - + + @@ -322,8 +325,8 @@ 1struct3->1 - - + + @@ -340,8 +343,8 @@ 1struct4->1 - - + + @@ -359,8 +362,8 @@ 1struct5->1 - - + + @@ -376,8 +379,8 @@ 1struct6->1 - - + + @@ -393,8 +396,8 @@ 1struct7->1 - - + + @@ -413,8 +416,8 @@ 1struct8->1 - - + + @@ -433,8 +436,8 @@ 1struct9->1 - - + + @@ -451,30 +454,30 @@ 1enum0->1 - - + + 2 - -RecordsMerkleTree - - - -External: -    updateRecordsMerkleTree(elements: uint256[]) -Public: -    constructor(merkleTreeHeight: uint8) -    getRootValue(): uint256 -    getHeight(): uint8 -    getNumLeaves(): uint64 + +RecordsMerkleTree + + + +External: +    updateRecordsMerkleTree(elements: uint256[]) +    getRootValue(): uint256 +    getHeight(): uint8 +    getNumLeaves(): uint64 +Public: +    constructor(merkleTreeHeight: uint8) 2->13 - - + + @@ -491,8 +494,8 @@ 2struct0->2 - - + + @@ -508,482 +511,482 @@ 2enum0->2 - - + + 4->7 - - + + 4struct0 - -<<struct>> -PlonkProof - -wire0: BN254.G1Point -wire1: BN254.G1Point -wire2: BN254.G1Point -wire3: BN254.G1Point -wire4: BN254.G1Point -prodPerm: BN254.G1Point -split0: BN254.G1Point -split1: BN254.G1Point -split2: BN254.G1Point -split3: BN254.G1Point -split4: BN254.G1Point -zeta: BN254.G1Point -zetaOmega: BN254.G1Point -wireEval0: uint256 -wireEval1: uint256 -wireEval2: uint256 -wireEval3: uint256 -wireEval4: uint256 -sigmaEval0: uint256 -sigmaEval1: uint256 -sigmaEval2: uint256 -sigmaEval3: uint256 -prodPermZetaOmegaEval: uint256 + +<<struct>> +PlonkProof + +wire0: BN254.G1Point +wire1: BN254.G1Point +wire2: BN254.G1Point +wire3: BN254.G1Point +wire4: BN254.G1Point +prodPerm: BN254.G1Point +split0: BN254.G1Point +split1: BN254.G1Point +split2: BN254.G1Point +split3: BN254.G1Point +split4: BN254.G1Point +zeta: BN254.G1Point +zetaOmega: BN254.G1Point +wireEval0: uint256 +wireEval1: uint256 +wireEval2: uint256 +wireEval3: uint256 +wireEval4: uint256 +sigmaEval0: uint256 +sigmaEval1: uint256 +sigmaEval2: uint256 +sigmaEval3: uint256 +prodPermZetaOmegaEval: uint256 4struct0->4 - - + + 4struct1 - -<<struct>> -VerifyingKey - -domainSize: uint256 -numInputs: uint256 -sigma0: BN254.G1Point -sigma1: BN254.G1Point -sigma2: BN254.G1Point -sigma3: BN254.G1Point -sigma4: BN254.G1Point -q1: BN254.G1Point -q2: BN254.G1Point -q3: BN254.G1Point -q4: BN254.G1Point -qM12: BN254.G1Point -qM34: BN254.G1Point -qO: BN254.G1Point -qC: BN254.G1Point -qH1: BN254.G1Point -qH2: BN254.G1Point -qH3: BN254.G1Point -qH4: BN254.G1Point -qEcc: BN254.G1Point + +<<struct>> +VerifyingKey + +domainSize: uint256 +numInputs: uint256 +sigma0: BN254.G1Point +sigma1: BN254.G1Point +sigma2: BN254.G1Point +sigma3: BN254.G1Point +sigma4: BN254.G1Point +q1: BN254.G1Point +q2: BN254.G1Point +q3: BN254.G1Point +q4: BN254.G1Point +qM12: BN254.G1Point +qM34: BN254.G1Point +qO: BN254.G1Point +qC: BN254.G1Point +qH1: BN254.G1Point +qH2: BN254.G1Point +qH3: BN254.G1Point +qH4: BN254.G1Point +qEcc: BN254.G1Point 4struct1->4 - - + + 6struct0 - -<<struct>> -Data - -items: uint256[] -index: uint256 + +<<struct>> +Data + +items: uint256[] +index: uint256 6struct0->6 - - + + 18 - -<<Library>> -Utils - - - - + +<<Library>> +Utils + + + + 7->18 - - + + 7struct0 - -<<struct>> -G1Point - -x: uint256 -y: uint256 + +<<struct>> +G1Point + +x: uint256 +y: uint256 7struct0->7 - - + + 7struct1 - -<<struct>> -G2Point - -x0: uint256 -x1: uint256 -y0: uint256 -y1: uint256 + +<<struct>> +G2Point + +x0: uint256 +x1: uint256 +y0: uint256 +y1: uint256 7struct1->7 - - + + 8->8 - - + + 8->18 - - + + 8struct0 - -<<struct>> -EdOnBN254Point - -x: uint256 -y: uint256 + +<<struct>> +EdOnBN254Point + +x: uint256 +y: uint256 8struct0->8 - - + + 9 - -<<Library>> -Freeze2In2Out24DepthVk - - - - + +<<Library>> +Freeze2In2Out24DepthVk + + + + 9->4 - - + + 10 - -<<Library>> -Freeze3In3Out24DepthVk - - - - + +<<Library>> +Freeze3In3Out24DepthVk + + + + 10->4 - - + + 11 - -<<Library>> -Mint1In2Out24DepthVk - - - - + +<<Library>> +Mint1In2Out24DepthVk + + + + 11->4 - - + + 12 - -<<Library>> -PolynomialEval - - - - + +<<Library>> +PolynomialEval + + + + 12->7 - - + + 12struct0 - -<<struct>> -EvalDomain - -logSize: uint256 -size: uint256 -sizeInv: uint256 -groupGen: uint256 -groupGenInv: uint256 + +<<struct>> +EvalDomain + +logSize: uint256 +size: uint256 +sizeInv: uint256 +groupGen: uint256 +groupGenInv: uint256 12struct0->12 - - + + 12struct1 - -<<struct>> -EvalData - -vanishEval: uint256 -lagrangeOne: uint256 -piEval: uint256 + +<<struct>> +EvalData + +vanishEval: uint256 +lagrangeOne: uint256 +piEval: uint256 12struct1->12 - - + + 14 - -<<Library>> -Transfer1In2Out24DepthVk - - - - + +<<Library>> +Transfer1In2Out24DepthVk + + + + 14->4 - - + + 15 - -<<Library>> -Transfer2In2Out24DepthVk - - - - + +<<Library>> +Transfer2In2Out24DepthVk + + + + 15->4 - - + + 16 - -<<Library>> -Transfer2In3Out24DepthVk - - - - + +<<Library>> +Transfer2In3Out24DepthVk + + + + 16->4 - - + + 17 - -<<Library>> -Transfer3In3Out24DepthVk - - - - + +<<Library>> +Transfer3In3Out24DepthVk + + + + 17->4 - - + + 19->4 - - + + 19->14 - - + + 20 - -PlonkVerifier - - - -External: -    batchVerify(verifyingKeys: VerifyingKey[], publicInputs: uint256[][], proofs: PlonkProof[], extraTranscriptInitMsgs: bytes[]): bool + +PlonkVerifier + + + +External: +    batchVerify(verifyingKeys: VerifyingKey[], publicInputs: uint256[][], proofs: PlonkProof[], extraTranscriptInitMsgs: bytes[]): bool 20->4 - - + + 20->7 - - + + 21 - -<<Library>> -Transcript - - - - + +<<Library>> +Transcript + + + + 20->21 - - + + 20struct0 - -<<struct>> -PcsInfo - -u: uint256 -evalPoint: uint256 -nextEvalPoint: uint256 -eval: uint256 -commScalars: uint256[] -commBases: BN254.G1Point[] -openingProof: BN254.G1Point -shiftedOpeningProof: BN254.G1Point + +<<struct>> +PcsInfo + +u: uint256 +evalPoint: uint256 +nextEvalPoint: uint256 +eval: uint256 +commScalars: uint256[] +commBases: BN254.G1Point[] +openingProof: BN254.G1Point +shiftedOpeningProof: BN254.G1Point 20struct0->20 - - + + 20struct1 - -<<struct>> -Challenges - -alpha: uint256 -alpha2: uint256 -alpha3: uint256 -beta: uint256 -gamma: uint256 -zeta: uint256 -v: uint256 -u: uint256 + +<<struct>> +Challenges + +alpha: uint256 +alpha2: uint256 +alpha3: uint256 +beta: uint256 +gamma: uint256 +zeta: uint256 +v: uint256 +u: uint256 20struct1->20 - - + + 21->4 - - + + 21->7 - - + + 21->18 - - + + 21struct0 - -<<struct>> -TranscriptData - -transcript: bytes -state: bytes32[] + +<<struct>> +TranscriptData + +transcript: bytes +state: bytes32[] 21struct0->21 - - + + From 955ca377f3e77b9c99b7674a41947fa61e6a50c3 Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 8 Jun 2022 13:02:43 +0200 Subject: [PATCH 20/24] github actions: move slither to separate workflow --- .github/workflows/build.yml | 9 -------- .github/workflows/slither.yml | 42 +++++++++++++++++++++++++++++++++++ poetry.lock | 21 +++++++++++------- pyproject.toml | 2 +- 4 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/slither.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2648f400..2e1ab882 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,15 +44,6 @@ jobs: - name: Initialize Nix Shell run: nix-shell --run "echo Init" - - name: Run slither - run: nix-shell --run "slither ./contracts --sarif slither.sarif" - continue-on-error: true - - - name: Upload slither SARIF file - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: slither.sarif - - name: Cache cargo uses: actions/cache@v2 with: diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml new file mode 100644 index 00000000..72990bcc --- /dev/null +++ b/.github/workflows/slither.yml @@ -0,0 +1,42 @@ +name: Slither + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + slither: + runs-on: [self-hosted, X64] + container: + image: ghcr.io/espressosystems/nix:main + volumes: + - github_nix_281:/nix + steps: + - uses: styfle/cancel-workflow-action@0.9.1 + name: Cancel Outdated Builds + with: + access_token: ${{ github.token }} + + - uses: cachix/cachix-action@v10 + with: + name: espresso-systems-private + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - uses: actions/checkout@v2 + name: Checkout Repository + + - name: Work around git issue after git CVE-2022-24765 fix. + run: git config --global --add safe.directory "$PWD" + + - name: Run slither + run: nix-shell --run "slither ./contracts --sarif slither.sarif" + continue-on-error: true + + - name: Upload slither SARIF file + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: slither.sarif + diff --git a/poetry.lock b/poetry.lock index 7ef9bcee..cb7656ef 100644 --- a/poetry.lock +++ b/poetry.lock @@ -314,7 +314,7 @@ test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytes [[package]] name = "pre-commit-hooks" -version = "1.1.14" +version = "1.2.0" description = "" category = "main" optional = false @@ -329,7 +329,7 @@ python-Levenshtein-wheels = "*" type = "git" url = "https://github.com/Lucas-C/pre-commit-hooks" reference = "master" -resolved_reference = "31a29ed44815a9fb6d5ce28001ab43bcd71f973b" +resolved_reference = "be28ff2eda4a10f903d66c85b7d29f0f628306c8" [[package]] name = "prettytable" @@ -417,16 +417,23 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "slither-analyzer" version = "0.8.3" -description = "Slither is a Solidity static analysis framework written in Python 3." +description = "" category = "dev" optional = false python-versions = ">=3.6" +develop = false [package.dependencies] -crytic-compile = ">=0.2.3" +crytic-compile = "*" prettytable = ">=0.7.2" pysha3 = ">=1.0.2" +[package.source] +type = "git" +url = "https://github.com/sveitser/slither" +reference = "fix-sarif-empty-results" +resolved_reference = "b24169ae45bce0e3c4656038258359392ba05e6b" + [[package]] name = "tomli" version = "2.0.1" @@ -478,7 +485,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "3d80af9eb074a15c937a5fcbbd26fbd9110e6eb6ff9dbee8c92add6dcfc3f4c2" +content-hash = "763ac70c840d91b12dc0bd19346d38ce326223e026df1f96c9635066bc0e8e0c" [metadata.files] appnope = [ @@ -704,9 +711,7 @@ six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -slither-analyzer = [ - {file = "slither_analyzer-0.8.3-py3-none-any.whl", hash = "sha256:6216a934e45a85d2d1a8831b14e5f36a98d56dec7ee4eaf9e59194133d346697"}, -] +slither-analyzer = [] tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, diff --git a/pyproject.toml b/pyproject.toml index dc9d2e02..93fdea7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ pre-commit-hooks = {git = "https://github.com/Lucas-C/pre-commit-hooks"} black = "*" hdwallet = "^1.3.2" ipython = "^7.28.0" -slither-analyzer = "^0.8.3" +slither-analyzer = {git = "https://github.com/sveitser/slither", rev = "fix-sarif-empty-results"} [build-system] requires = ["poetry-core>=1.0.0"] From 53293c958b4631e283a7ad7127952b6d6ebb3041 Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 8 Jun 2022 14:05:46 +0200 Subject: [PATCH 21/24] Enable write-after-write detector --- contracts/contracts/libraries/RescueLib.sol | 4 ++++ contracts/contracts/verifier/PlonkVerifier.sol | 1 + slither.config.json | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/contracts/contracts/libraries/RescueLib.sol b/contracts/contracts/libraries/RescueLib.sol index f61291fa..1b7ec903 100644 --- a/contracts/contracts/libraries/RescueLib.sol +++ b/contracts/contracts/libraries/RescueLib.sol @@ -154,9 +154,13 @@ library RescueLib { // @param input input for the permutation // @return permutation output function perm( + // slither-disable-next-line write-after-write uint256 s0, + // slither-disable-next-line write-after-write uint256 s1, + // slither-disable-next-line write-after-write uint256 s2, + // slither-disable-next-line write-after-write uint256 s3 ) internal diff --git a/contracts/contracts/verifier/PlonkVerifier.sol b/contracts/contracts/verifier/PlonkVerifier.sol index 2e952334..d1a18302 100644 --- a/contracts/contracts/verifier/PlonkVerifier.sol +++ b/contracts/contracts/verifier/PlonkVerifier.sol @@ -468,6 +468,7 @@ contract PlonkVerifier is IPlonkVerifier { bases[2 * i] = pcsInfos[i].openingProof; { + // slither-disable-next-line write-after-write uint256 tmp; uint256 u = pcsInfos[i].u; assembly { diff --git a/slither.config.json b/slither.config.json index c70688ee..d81d6704 100644 --- a/slither.config.json +++ b/slither.config.json @@ -1,4 +1,4 @@ { "filter_paths": "ERC20.sol|Token.sol|USDC|mocks|Test|RescueNonOptimized|BytesLib|Ownable.sol", - "detectors_to_exclude": "assembly,similar-names,too-many-digits,naming-convention,write-after-write,solc-version" + "detectors_to_exclude": "assembly,similar-names,too-many-digits,naming-convention,solc-version" } From e042e42d85aa18c1b55f30c023dcf454847d651c Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 8 Jun 2022 14:06:09 +0200 Subject: [PATCH 22/24] Remove slither pre-commit hook We run all the pre-commit hooks on the CI but also have a separate slither workflow. Having a slither pre-commit hook would run it twice on the CI. I think it is rather slow for a pre-commit hook. --- flake.nix | 7 ------- 1 file changed, 7 deletions(-) diff --git a/flake.nix b/flake.nix index 12999489..6009d222 100644 --- a/flake.nix +++ b/flake.nix @@ -172,13 +172,6 @@ pass_filenames = false; types = [ "solidity" ]; }; - slither = { - enable = true; - description = "Solidity static analysis"; - entry = "slither ./contracts"; - pass_filenames = false; - types = [ "solidity" ]; - }; }; }; }; From 72deadfe2a7def9b1659a1efa677866fbf17cb08 Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 8 Jun 2022 14:20:52 +0200 Subject: [PATCH 23/24] Cleanup, add brief slither docs - Add slither to `run-ci-steps` script. - Remove `prepend-timestamps` script. GitHub Actions has this built in now. --- .github/workflows/build.yml | 8 ++++---- .github/workflows/slow-tests.yml | 4 ++-- .gitlab-ci.yml | 6 +++--- Slither.md | 21 +++++++++++++++++++++ bin/prepend-timestamps | 11 ----------- bin/run-ci-tests | 1 + 6 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 Slither.md delete mode 100755 bin/prepend-timestamps diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2e1ab882..fdae57ce 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,17 +56,17 @@ jobs: key: cape-v5-${{ hashFiles('Cargo.lock') }} - name: Linting - run: nix-shell --run "prepend-timestamps lint-ci" + run: nix-shell --run "lint-ci" - name: Build Slow Tests # Make sure the slow tests build, but don't run them (we have another workflow for that). - run: nix-shell --run "prepend-timestamps cargo test --release --features=slow-tests --no-run" + run: nix-shell --run "cargo test --release --features=slow-tests --no-run" - name: Run Tests - run: nix-shell --run "prepend-timestamps cape-test-geth" + run: nix-shell --run "cape-test-geth" - name: Generate Docs - run: nix-shell --run "prepend-timestamps make-doc" + run: nix-shell --run "make-doc" - name: Build all executables run: nix-shell --run "cargo build --release" diff --git a/.github/workflows/slow-tests.yml b/.github/workflows/slow-tests.yml index ab0148d4..c80218c8 100644 --- a/.github/workflows/slow-tests.yml +++ b/.github/workflows/slow-tests.yml @@ -29,7 +29,7 @@ jobs: - uses: cachix/cachix-action@v10 with: name: espresso-systems-private - authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" - name: Potential broken submodules fix run: | @@ -53,4 +53,4 @@ jobs: key: cape-v5-${{ hashFiles('Cargo.lock') }} - name: Run Tests - run: nix-shell --run "prepend-timestamps cape-test-geth-slow" + run: nix-shell --run "cape-test-geth-slow" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1fbe9c9d..7849574f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,13 +16,13 @@ lint: tags: - docker script: - - nix-shell --run "prepend-timestamps lint-ci" + - nix-shell --run "lint-ci" test: tags: - docker script: - - nix-shell --run "prepend-timestamps cape-test-geth" + - nix-shell --run "cape-test-geth" cache: key: cape-test paths: @@ -33,7 +33,7 @@ doc: tags: - docker script: - - nix-shell --run "prepend-timestamps make-doc" + - nix-shell --run "make-doc" artifacts: paths: - doc diff --git a/Slither.md b/Slither.md new file mode 100644 index 00000000..2ad87de0 --- /dev/null +++ b/Slither.md @@ -0,0 +1,21 @@ + + +# Slither + +Run `run-slither` to analyze the contracts. + +To disable warnings add a code comment, for example + + // slither-disable-next-line variable-scope + +The configuration is [slither.config.json](./slither.config.json). + +The slither github workflow file is +[.github/workflows/slither.yml](./.github/workflows/slither.yml). diff --git a/bin/prepend-timestamps b/bin/prepend-timestamps deleted file mode 100755 index 33a9d771..00000000 --- a/bin/prepend-timestamps +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2022 Espresso Systems (espressosys.com) -# This file is part of the Configurable Asset Privacy for Ethereum (CAPE) library. -# -# This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# You should have received a copy of the GNU General Public License along with this program. If not, see . - -set -euo pipefail - -$@ | ts '[%Y-%m-%d %H:%M:%S]' diff --git a/bin/run-ci-tests b/bin/run-ci-tests index 8214966d..95908460 100755 --- a/bin/run-ci-tests +++ b/bin/run-ci-tests @@ -10,6 +10,7 @@ set -euo pipefail make-doc lint-ci +run-slither cape-test-geth echo Ok! From 80d863e7ab8c191589331f15929b8d926dc6cbff Mon Sep 17 00:00:00 2001 From: sveitser Date: Wed, 8 Jun 2022 16:02:46 +0200 Subject: [PATCH 24/24] fix typo --- Slither.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Slither.md b/Slither.md index 2ad87de0..e8dc7077 100644 --- a/Slither.md +++ b/Slither.md @@ -15,7 +15,7 @@ To disable warnings add a code comment, for example // slither-disable-next-line variable-scope -The configuration is [slither.config.json](./slither.config.json). +The configuration file is [slither.config.json](./slither.config.json). The slither github workflow file is [.github/workflows/slither.yml](./.github/workflows/slither.yml).