Skip to content

Add code comments to contracts #669

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/contracts/contracts/Semaphore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,24 @@ contract Semaphore is ISemaphore, SemaphoreGroups {
groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
}

/// @dev See {ISemaphore-validateProof}.
function validateProof(
uint256 groupId,
SemaphoreProof calldata proof
) external override onlyExistingGroup(groupId) {
// The function will revert if the nullifier that is part of the proof,
// was already used inside the group with id groupId.
if (groups[groupId].nullifiers[proof.nullifier]) {
revert Semaphore__YouAreUsingTheSameNullifierTwice();
}

// The function will revert if the proof is not verified successfully.
if (!verifyProof(groupId, proof)) {
revert Semaphore__InvalidProof();
}

// Saves the nullifier so that it cannot be used again to successfully verify a proof
// that is part of the group with id groupId.
groups[groupId].nullifiers[proof.nullifier] = true;

emit ProofValidated(
Expand All @@ -125,20 +131,26 @@ contract Semaphore is ISemaphore, SemaphoreGroups {
);
}

/// @dev See {ISemaphore-verifyProof}.
function verifyProof(
uint256 groupId,
SemaphoreProof calldata proof
) public view override onlyExistingGroup(groupId) returns (bool) {
// The function will revert if the Merkle tree depth is not supported.
if (proof.merkleTreeDepth < 1 || proof.merkleTreeDepth > 12) {
revert Semaphore__MerkleTreeDepthIsNotSupported();
}

// Gets the number of leaves in the Incremental Merkle Tree that represents the group
// with id groupId which is the same as the number of members in the group groupId.
uint256 merkleTreeSize = getMerkleTreeSize(groupId);

// The function will revert if there are no members in the group.
if (merkleTreeSize == 0) {
revert Semaphore__GroupHasNoMembers();
}

// Gets the Merkle root of the Incremental Merkle Tree that represents the group with id groupId.
uint256 currentMerkleTreeRoot = getMerkleTreeRoot(groupId);

// A proof could have used an old Merkle tree root.
Expand Down
3 changes: 3 additions & 0 deletions packages/contracts/contracts/base/SemaphoreGroups.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ abstract contract SemaphoreGroups is ISemaphoreGroups {
using InternalLeanIMT for LeanIMTData;

/// @dev Gets a group id and returns its tree data.
/// The tree is an Incremental Merkle Tree
/// which is called Lean Incremental Merkle Tree.
mapping(uint256 => LeanIMTData) internal merkleTrees;

/// @dev Gets a group id and returns its admin.
/// The admin can be an Ethereum account or a smart contract.
mapping(uint256 => address) internal admins;

/// @dev Checks if the group admin is the transaction sender.
Expand Down
6 changes: 6 additions & 0 deletions packages/contracts/contracts/base/SemaphoreVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ contract SemaphoreVerifier {
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;

// TODO: Add more variables when Semaphore supports tree depth > 12.
// Right now Semaphore supports tree depth 1-12.

// Verification Key points.
// These values are taken from the verification key json file generated with snarkjs.
// It allows to use the same verifier to verify proofs for all the tree depths supported by Semaphore.
uint256[14][12] VK_POINTS = [
[
563562783592406106461234396505774794044312891062077216951605541624542949349,
Expand Down
14 changes: 7 additions & 7 deletions packages/contracts/contracts/interfaces/ISemaphore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface ISemaphore {
mapping(uint256 => bool) nullifiers;
}

/// It defines all the group parameters used by Semaphore.sol.
/// It defines all the Semaphore proof parameters used by Semaphore.sol.
struct SemaphoreProof {
uint256 merkleTreeDepth;
uint256 merkleTreeRoot;
Expand All @@ -27,7 +27,7 @@ interface ISemaphore {
uint256[8] points;
}

/// @dev Emitted when the Merkle tree duration of a group is updated.
/// @dev Event emitted when the Merkle tree duration of a group is updated.
/// @param groupId: Id of the group.
/// @param oldMerkleTreeDuration: Old Merkle tree duration of the group.
/// @param newMerkleTreeDuration: New Merkle tree duration of the group.
Expand All @@ -37,7 +37,7 @@ interface ISemaphore {
uint256 newMerkleTreeDuration
);

/// @dev Emitted when a Semaphore proof is validated.
/// @dev Event emitted when a Semaphore proof is validated.
/// @param groupId: Id of the group.
/// @param merkleTreeDepth: Depth of the Merkle tree.
/// @param merkleTreeRoot: Root of the Merkle tree.
Expand All @@ -60,7 +60,7 @@ interface ISemaphore {

/// @dev It creates a group with a custom Merkle tree duration.
/// @param groupId: Id of the group.
/// @param admin: Admin of the group.
/// @param admin: Admin of the group. It can be an Ethereum account or a smart contract.
/// @param merkleTreeDuration: Merkle tree duration.
function createGroup(uint256 groupId, address admin, uint256 merkleTreeDuration) external;

Expand Down Expand Up @@ -89,14 +89,14 @@ interface ISemaphore {
/// @dev See {SemaphoreGroups-_removeMember}.
function removeMember(uint256 groupId, uint256 identityCommitment, uint256[] calldata merkleProofSiblings) external;

/// @dev Saves the nullifier hash to avoid double signaling and emits an event
/// @dev Saves the nullifier hash to prevent double signaling and emits an event
/// if the zero-knowledge proof is valid.
/// @param groupId: Id of the group.
/// @param proof: Zero-knowledge proof.
/// @param proof: Semaphore zero-knowledge proof.
function validateProof(uint256 groupId, SemaphoreProof calldata proof) external;

/// @dev Verifies a zero-knowledge proof by returning true or false.
/// @param groupId: Id of the group.
/// @param proof: Zero-knowledge proof.
/// @param proof: Semaphore zero-knowledge proof.
function verifyProof(uint256 groupId, SemaphoreProof calldata proof) external view returns (bool);
}
14 changes: 7 additions & 7 deletions packages/contracts/contracts/interfaces/ISemaphoreGroups.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ interface ISemaphoreGroups {
error Semaphore__GroupAlreadyExists();
error Semaphore__CallerIsNotTheGroupAdmin();

/// @dev Emitted when a new group is created.
/// @dev Event emitted when a new group is created.
/// @param groupId: Id of the group.
event GroupCreated(uint256 indexed groupId);

/// @dev Emitted when an admin is assigned to a group.
/// @dev Event emitted when an admin is assigned to a group.
/// @param groupId: Id of the group.
/// @param oldAdmin: Old admin of the group.
/// @param newAdmin: New admin of the group.
event GroupAdminUpdated(uint256 indexed groupId, address indexed oldAdmin, address indexed newAdmin);

/// @dev Emitted when a new identity commitment is added.
/// @dev Event emitted when a new identity commitment is added.
/// @param groupId: Group id of the group.
/// @param index: Merkle tree leaf index.
/// @param identityCommitment: New identity commitment.
/// @param merkleTreeRoot: New root hash of the tree.
event MemberAdded(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);

/// @dev Emitted when many identity commitments are added at the same time.
/// @dev Event emitted when many identity commitments are added at the same time.
/// @param groupId: Group id of the group.
/// @param startIndex: Index of the first element of the new identity commitments in the merkle tree.
/// @param identityCommitments: The new identity commitments.
Expand All @@ -36,7 +36,7 @@ interface ISemaphoreGroups {
uint256 merkleTreeRoot
);

/// @dev Emitted when an identity commitment is updated.
/// @dev Event emitted when an identity commitment is updated.
/// @param groupId: Group id of the group.
/// @param index: Identity commitment index.
/// @param identityCommitment: Existing identity commitment to be updated.
Expand All @@ -50,14 +50,14 @@ interface ISemaphoreGroups {
uint256 merkleTreeRoot
);

/// @dev Emitted when a new identity commitment is removed.
/// @dev Event emitted when a new identity commitment is removed.
/// @param groupId: Group id of the group.
/// @param index: Identity commitment index.
/// @param identityCommitment: Existing identity commitment to be removed.
/// @param merkleTreeRoot: New root hash of the tree.
event MemberRemoved(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);

/// @dev Returns the address of the group admin.
/// @dev Returns the address of the group admin. The group admin can be an Ethereum account or a smart contract.
/// @param groupId: Id of the group.
/// @return Address of the group admin.
function getGroupAdmin(uint256 groupId) external view returns (address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ pragma solidity 0.8.23;

/// @title SemaphoreVerifier contract interface.
interface ISemaphoreVerifier {
/// @dev Returns true if the proof was successfully verified.
/// @param _pA: Point A.
/// @param _pB: Point B.
/// @param _pC: Point C.
/// @param _pubSignals: Public signals.
/// @param merkleTreeDepth: Merkle tree depth.
/// @return True if the proof was successfully verified, false otherwise.
function verifyProof(
uint[2] calldata _pA,
uint[2][2] calldata _pB,
Expand Down