Skip to content

Commit 47c7923

Browse files
authored
Merge pull request #133 from semaphore-protocol/feat/member-index
feat: add member index parameter to events Former-commit-id: 2bbacbe
2 parents e6fe600 + a35a505 commit 47c7923

File tree

6 files changed

+49
-13
lines changed

6 files changed

+49
-13
lines changed

contracts/base/SemaphoreGroups.sol

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ abstract contract SemaphoreGroups is Context, ISemaphoreGroups {
4848
groups[groupId].insert(identityCommitment);
4949

5050
uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
51+
uint256 index = getNumberOfMerkleTreeLeaves(groupId) - 1;
5152

52-
emit MemberAdded(groupId, identityCommitment, merkleTreeRoot);
53+
emit MemberAdded(groupId, index, identityCommitment, merkleTreeRoot);
5354
}
5455

5556
/// @dev Updates an identity commitment of an existing group. A proof of membership is
@@ -73,8 +74,9 @@ abstract contract SemaphoreGroups is Context, ISemaphoreGroups {
7374
groups[groupId].update(identityCommitment, newIdentityCommitment, proofSiblings, proofPathIndices);
7475

7576
uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
77+
uint256 index = proofPathIndicesToMemberIndex(proofPathIndices);
7678

77-
emit MemberUpdated(groupId, identityCommitment, newIdentityCommitment, merkleTreeRoot);
79+
emit MemberUpdated(groupId, index, identityCommitment, newIdentityCommitment, merkleTreeRoot);
7880
}
7981

8082
/// @dev Removes an identity commitment from an existing group. A proof of membership is
@@ -96,8 +98,9 @@ abstract contract SemaphoreGroups is Context, ISemaphoreGroups {
9698
groups[groupId].remove(identityCommitment, proofSiblings, proofPathIndices);
9799

98100
uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
101+
uint256 index = proofPathIndicesToMemberIndex(proofPathIndices);
99102

100-
emit MemberRemoved(groupId, identityCommitment, merkleTreeRoot);
103+
emit MemberRemoved(groupId, index, identityCommitment, merkleTreeRoot);
101104
}
102105

103106
/// @dev See {ISemaphoreGroups-getMerkleTreeRoot}.
@@ -114,4 +117,27 @@ abstract contract SemaphoreGroups is Context, ISemaphoreGroups {
114117
function getNumberOfMerkleTreeLeaves(uint256 groupId) public view virtual override returns (uint256) {
115118
return groups[groupId].numberOfLeaves;
116119
}
120+
121+
/// @dev Converts the path indices of a Merkle proof to the identity commitment index in the tree.
122+
/// @param proofPathIndices: Path of the proof of membership.
123+
/// @return Index of a group member.
124+
function proofPathIndicesToMemberIndex(uint8[] calldata proofPathIndices) private pure returns (uint256) {
125+
uint256 memberIndex = 0;
126+
127+
for (uint8 i = uint8(proofPathIndices.length); i > 0; ) {
128+
if (memberIndex > 0 || proofPathIndices[i - 1] != 0) {
129+
memberIndex *= 2;
130+
131+
if (proofPathIndices[i - 1] == 1) {
132+
memberIndex += 1;
133+
}
134+
}
135+
136+
unchecked {
137+
--i;
138+
}
139+
}
140+
141+
return memberIndex;
142+
}
117143
}

contracts/interfaces/ISemaphoreGroups.sol

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,31 @@ interface ISemaphoreGroups {
1616

1717
/// @dev Emitted when a new identity commitment is added.
1818
/// @param groupId: Group id of the group.
19+
/// @param index: Identity commitment index.
1920
/// @param identityCommitment: New identity commitment.
2021
/// @param merkleTreeRoot: New root hash of the tree.
21-
event MemberAdded(uint256 indexed groupId, uint256 identityCommitment, uint256 merkleTreeRoot);
22+
event MemberAdded(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);
2223

2324
/// @dev Emitted when an identity commitment is updated.
2425
/// @param groupId: Group id of the group.
25-
/// @param identityCommitment: New identity commitment.
26+
/// @param index: Identity commitment index.
27+
/// @param identityCommitment: Existing identity commitment to be updated.
2628
/// @param newIdentityCommitment: New identity commitment.
2729
/// @param merkleTreeRoot: New root hash of the tree.
2830
event MemberUpdated(
2931
uint256 indexed groupId,
32+
uint256 index,
3033
uint256 identityCommitment,
3134
uint256 newIdentityCommitment,
3235
uint256 merkleTreeRoot
3336
);
3437

3538
/// @dev Emitted when a new identity commitment is removed.
3639
/// @param groupId: Group id of the group.
40+
/// @param index: Identity commitment index.
3741
/// @param identityCommitment: Existing identity commitment to be removed.
3842
/// @param merkleTreeRoot: New root hash of the tree.
39-
event MemberRemoved(uint256 indexed groupId, uint256 identityCommitment, uint256 merkleTreeRoot);
43+
event MemberRemoved(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);
4044

4145
/// @dev Returns the last root hash of a group.
4246
/// @param groupId: Id of the group.

test/Semaphore.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ describe("Semaphore", () => {
101101
.to.emit(contract, "MemberAdded")
102102
.withArgs(
103103
groupId,
104+
0,
104105
members[0],
105106
"18951329906296061785889394467312334959162736293275411745101070722914184798221"
106107
)
@@ -125,7 +126,7 @@ describe("Semaphore", () => {
125126

126127
const transaction = contract.addMembers(groupId, members)
127128

128-
await expect(transaction).to.emit(contract, "MemberAdded").withArgs(groupId, BigInt(3), group.root)
129+
await expect(transaction).to.emit(contract, "MemberAdded").withArgs(groupId, 2, BigInt(3), group.root)
129130
})
130131
})
131132

@@ -152,7 +153,9 @@ describe("Semaphore", () => {
152153

153154
const transaction = contract.updateMember(groupId, BigInt(1), BigInt(4), siblings, pathIndices)
154155

155-
await expect(transaction).to.emit(contract, "MemberUpdated").withArgs(groupId, BigInt(1), BigInt(4), root)
156+
await expect(transaction)
157+
.to.emit(contract, "MemberUpdated")
158+
.withArgs(groupId, 0, BigInt(1), BigInt(4), root)
156159
})
157160
})
158161

@@ -170,16 +173,16 @@ describe("Semaphore", () => {
170173

171174
group.addMembers(members)
172175

173-
group.removeMember(0)
176+
group.removeMember(2)
174177

175178
await contract["createGroup(uint256,uint256,uint256,address)"](groupId, treeDepth, 0, accounts[0])
176179
await contract.addMembers(groupId, members)
177180

178-
const { siblings, pathIndices, root } = group.generateProofOfMembership(0)
181+
const { siblings, pathIndices, root } = group.generateProofOfMembership(2)
179182

180-
const transaction = contract.removeMember(groupId, BigInt(1), siblings, pathIndices)
183+
const transaction = contract.removeMember(groupId, BigInt(3), siblings, pathIndices)
181184

182-
await expect(transaction).to.emit(contract, "MemberRemoved").withArgs(groupId, BigInt(1), root)
185+
await expect(transaction).to.emit(contract, "MemberRemoved").withArgs(groupId, 2, BigInt(3), root)
183186
})
184187
})
185188

test/SemaphoreVoting.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ describe("SemaphoreVoting", () => {
120120
.to.emit(contract, "MemberAdded")
121121
.withArgs(
122122
pollIds[1],
123+
0,
123124
identityCommitment,
124125
"14787813191318312920980352979830075893203307366494541177071234930769373297362"
125126
)

test/SemaphoreWhistleblowing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ describe("SemaphoreWhistleblowing", () => {
8585
.to.emit(contract, "MemberAdded")
8686
.withArgs(
8787
entityIds[0],
88+
0,
8889
identityCommitment,
8990
"14787813191318312920980352979830075893203307366494541177071234930769373297362"
9091
)
@@ -129,6 +130,7 @@ describe("SemaphoreWhistleblowing", () => {
129130
.to.emit(contract, "MemberRemoved")
130131
.withArgs(
131132
entityIds[0],
133+
0,
132134
identityCommitment,
133135
"15019797232609675441998260052101280400536945603062888308240081994073687793470"
134136
)

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6483,7 +6483,7 @@ __metadata:
64836483
dependencies:
64846484
bn.js: ^4.11.8
64856485
ethereumjs-util: ^6.0.0
6486-
checksum: ae074be0bb012857ab5d3ae644d1163b908a48dd724b7d2567cfde309dc72222d460438f2411936a70dc949dc604ce1ef7118f7273bd525815579143c907e336
6486+
checksum: 03127d09960e5f8a44167463faf25b2894db2f746376dbb8195b789ed11762f93db9c574eaa7c498c400063508e9dfc1c80de2edf5f0e1406b25c87d860ff2f1
64876487
languageName: node
64886488
linkType: hard
64896489

0 commit comments

Comments
 (0)