Skip to content

Commit

Permalink
Merge branch 'privacy-scaling-explorations:dev' into blogcards
Browse files Browse the repository at this point in the history
  • Loading branch information
mabsattar authored Jun 10, 2024
2 parents dd52e58 + ba2fcc7 commit ca00f1e
Show file tree
Hide file tree
Showing 38 changed files with 5,256 additions and 1,966 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ build
typechain-types
.eslintrc.js
commitlint.config.js
subgraph/generated
38 changes: 38 additions & 0 deletions .github/workflows/subgraph-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Subgraph

on:
push:
branches: [dev]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 8

- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"

- name: Install
run: |
pnpm install --frozen-lockfile --prefer-offline
- name: Build
run: |
pnpm run build
- name: Test
run: pnpm run test
working-directory: subgraph
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ website/.docusaurus/
website/src/pages/solidity-docs/index.md
**/deployed-contracts.json
**/deploy-config.json
subgraph/generated
subgraph/templates/*.yaml
subgraph/subgraph.yaml

2 changes: 1 addition & 1 deletion circuits/ts/__tests__/IncrementalQuinaryTree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ describe("Incremental Quinary Tree (IQT)", function test() {
};

for (let level = 0; level < maxLevel; level += 1) {
it.only(`should check the computation of correct merkle root (level ${level + 1}) [fuzz]`, async () => {
it(`should check the computation of correct merkle root (level ${level + 1}) [fuzz]`, async () => {
await fc.assert(
fc.asyncProperty(generateLeaves(level + 1), async (leaves: bigint[]) => quinCheckRootTest(leaves)),
);
Expand Down
87 changes: 87 additions & 0 deletions contracts/contracts/gatekeepers/zupass/ZupassGatekeeper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

import { SignUpGatekeeper } from "../SignUpGatekeeper.sol";

import { ZupassGroth16Verifier } from "./ZupassGroth16Verifier.sol";

/// @title ZupassGatekeeper
/// @notice This contract allows to gatekeep MACI signups
/// by requiring new voters to own a certain Zupass event ticket
contract ZupassGatekeeper is SignUpGatekeeper, Ownable(msg.sender) {
/// @notice the Zupass event UUID converted to bigint
uint256 public immutable validEventId;

/// @notice the Zupass event signer converted to bigint
uint256 public immutable validSigner1;
uint256 public immutable validSigner2;

/// @notice the ZupassGroth16Verifier contract address
ZupassGroth16Verifier public immutable verifier;

/// @notice the reference to the MACI contract
address public maci;

/// @notice a mapping of ticket IDs to whether they have been used
mapping(uint256 => bool) public registeredTickets;

/// @notice custom errors
error AlreadyRegistered();
error InvalidProof();
error InvalidEventId();
error InvalidSigners();
error InvalidWatermark();
error OnlyMACI();
error ZeroAddress();

/// @notice Creates a new ZupassGatekeeper
/// @param _validEventId Zupass event UUID converted to bigint
/// @param _validSigner1 Zupass event signer[0] converted to bigint
/// @param _validSigner2 Zupass event signer[1] converted to bigint
/// @param _verifier The ZupassGroth16Verifier contract address
constructor(uint256 _validEventId, uint256 _validSigner1, uint256 _validSigner2, address _verifier) payable {
validEventId = _validEventId;
validSigner1 = _validSigner1;
validSigner2 = _validSigner2;
verifier = ZupassGroth16Verifier(_verifier);
}

/// @notice Adds an uninitialised MACI instance to allow for token signups
/// @param _maci The MACI contract interface to be stored
function setMaciInstance(address _maci) public override onlyOwner {
if (_maci == address(0)) revert ZeroAddress();
maci = _maci;
}

/// @notice Registers the user only if they have the Zupass event ticket
/// @param _user The user's Ethereum address.
/// @param _data The ABI-encoded proof and public signals.
function register(address _user, bytes memory _data) public override {
if (maci != msg.sender) revert OnlyMACI();

// Decode the given _data bytes
(uint256[2] memory _pA, uint256[2][2] memory _pB, uint256[2] memory _pC, uint256[38] memory _pubSignals) = abi
.decode(_data, (uint256[2], uint256[2][2], uint256[2], uint256[38]));

// Ticket ID is stored at index 0
uint256 ticketId = _pubSignals[0];
if (registeredTickets[ticketId]) revert AlreadyRegistered();

registeredTickets[ticketId] = true;

// Verify proof
if (!verifier.verifyProof(_pA, _pB, _pC, _pubSignals)) revert InvalidProof();

// Event id is stored at index 15
if (_pubSignals[15] != validEventId) revert InvalidEventId();

// Signers are stored at index 13 and 14
if (_pubSignals[13] != validSigner1 || _pubSignals[14] != validSigner2) revert InvalidSigners();

// Watermark is stored at index 37
// user address converted to bigint is used as the watermark
if (_pubSignals[37] != uint256(uint160(_user))) revert InvalidWatermark();
}
}
Loading

0 comments on commit ca00f1e

Please sign in to comment.