Skip to content
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

Gas Optimized Semaphore.sol #113

Merged
merged 1 commit into from
Jul 25, 2022
Merged
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
48 changes: 40 additions & 8 deletions contracts/Semaphore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import "./interfaces/IVerifier.sol";
import "./base/SemaphoreCore.sol";
import "./base/SemaphoreGroups.sol";

error Semaphore__CallerIsNotTheGroupAdmin();
error Semaphore__TreeDepthIsNotSupported();
error Semaphore__GroupDoesNotExist();

/// @title Semaphore
contract Semaphore is ISemaphore, SemaphoreCore, SemaphoreGroups {
/// @dev Gets a tree depth and returns its verifier address.
Expand All @@ -17,22 +21,28 @@ contract Semaphore is ISemaphore, SemaphoreCore, SemaphoreGroups {
/// @dev Checks if the group admin is the transaction sender.
/// @param groupId: Id of the group.
modifier onlyGroupAdmin(uint256 groupId) {
require(groupAdmins[groupId] == _msgSender(), "Semaphore: caller is not the group admin");
if (groupAdmins[groupId] != _msgSender()) {
revert Semaphore__CallerIsNotTheGroupAdmin();
}
_;
}

/// @dev Checks if there is a verifier for the given tree depth.
/// @param depth: Depth of the tree.
modifier onlySupportedDepth(uint8 depth) {
require(address(verifiers[depth]) != address(0), "Semaphore: tree depth is not supported");
if (address(verifiers[depth]) == address(0)) {
revert Semaphore__TreeDepthIsNotSupported();
}
_;
}

/// @dev Initializes the Semaphore verifiers used to verify the user's ZK proofs.
/// @param _verifiers: List of Semaphore verifiers (address and related Merkle tree depth).
constructor(Verifier[] memory _verifiers) {
for (uint8 i = 0; i < _verifiers.length; i++) {
verifiers[_verifiers[i].merkleTreeDepth] = IVerifier(_verifiers[i].contractAddress);
verifiers[_verifiers[i].merkleTreeDepth] = IVerifier(
_verifiers[i].contractAddress
);
}
}

Expand All @@ -51,14 +61,22 @@ contract Semaphore is ISemaphore, SemaphoreCore, SemaphoreGroups {
}

/// @dev See {ISemaphore-updateGroupAdmin}.
function updateGroupAdmin(uint256 groupId, address newAdmin) external override onlyGroupAdmin(groupId) {
function updateGroupAdmin(uint256 groupId, address newAdmin)
external
override
onlyGroupAdmin(groupId)
{
groupAdmins[groupId] = newAdmin;

emit GroupAdminUpdated(groupId, _msgSender(), newAdmin);
}

/// @dev See {ISemaphore-addMember}.
function addMember(uint256 groupId, uint256 identityCommitment) external override onlyGroupAdmin(groupId) {
function addMember(uint256 groupId, uint256 identityCommitment)
external
override
onlyGroupAdmin(groupId)
{
_addMember(groupId, identityCommitment);
}

Expand All @@ -69,7 +87,12 @@ contract Semaphore is ISemaphore, SemaphoreCore, SemaphoreGroups {
uint256[] calldata proofSiblings,
uint8[] calldata proofPathIndices
) external override onlyGroupAdmin(groupId) {
_removeMember(groupId, identityCommitment, proofSiblings, proofPathIndices);
_removeMember(
groupId,
identityCommitment,
proofSiblings,
proofPathIndices
);
}

/// @dev See {ISemaphore-verifyProof}.
Expand All @@ -83,11 +106,20 @@ contract Semaphore is ISemaphore, SemaphoreCore, SemaphoreGroups {
uint256 root = getRoot(groupId);
uint8 depth = getDepth(groupId);

require(depth != 0, "Semaphore: group does not exist");
if (depth == 0) {
revert Semaphore__GroupDoesNotExist();
}

IVerifier verifier = verifiers[depth];

_verifyProof(signal, root, nullifierHash, externalNullifier, proof, verifier);
_verifyProof(
signal,
root,
nullifierHash,
externalNullifier,
proof,
verifier
);

_saveNullifierHash(nullifierHash);

Expand Down