fix(rln): use zero based indexing for commitments (#28)

This commit is contained in:
Aaryamann Challani 2023-08-30 22:17:07 +05:30 committed by GitHub
parent bd8403a74e
commit 35f2182669
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 7 deletions

View File

@ -51,7 +51,7 @@ abstract contract RlnBase {
uint256 public immutable SET_SIZE; uint256 public immutable SET_SIZE;
/// @notice The index of the next member to be registered /// @notice The index of the next member to be registered
uint256 public idCommitmentIndex = 1; uint256 public idCommitmentIndex = 0;
/// @notice The amount of eth staked by each member /// @notice The amount of eth staked by each member
/// maps from idCommitment to the amount staked /// maps from idCommitment to the amount staked
@ -61,6 +61,8 @@ abstract contract RlnBase {
/// maps from idCommitment to their index in the set /// maps from idCommitment to their index in the set
mapping(uint256 => uint256) public members; mapping(uint256 => uint256) public members;
mapping(uint256 => bool) public memberExists;
/// @notice The balance of each user that can be withdrawn /// @notice The balance of each user that can be withdrawn
mapping(address => uint256) public withdrawalBalance; mapping(address => uint256) public withdrawalBalance;
@ -111,10 +113,11 @@ abstract contract RlnBase {
/// @param idCommitment The idCommitment of the member /// @param idCommitment The idCommitment of the member
/// @param stake The amount of eth staked by the member /// @param stake The amount of eth staked by the member
function _register(uint256 idCommitment, uint256 stake) internal virtual { function _register(uint256 idCommitment, uint256 stake) internal virtual {
if (members[idCommitment] != 0) revert DuplicateIdCommitment(); if (memberExists[idCommitment]) revert DuplicateIdCommitment();
if (idCommitmentIndex >= SET_SIZE) revert FullTree(); if (idCommitmentIndex >= SET_SIZE) revert FullTree();
members[idCommitment] = idCommitmentIndex; members[idCommitment] = idCommitmentIndex;
memberExists[idCommitment] = true;
stakedAmounts[idCommitment] = stake; stakedAmounts[idCommitment] = stake;
emit MemberRegistered(idCommitment, idCommitmentIndex); emit MemberRegistered(idCommitment, idCommitmentIndex);
@ -144,7 +147,7 @@ abstract contract RlnBase {
revert InvalidReceiverAddress(receiver); revert InvalidReceiverAddress(receiver);
} }
if (members[idCommitment] == 0) revert MemberNotRegistered(idCommitment); if (memberExists[idCommitment] == false) revert MemberNotRegistered(idCommitment);
// check if member is registered // check if member is registered
if (stakedAmounts[idCommitment] == 0) { if (stakedAmounts[idCommitment] == 0) {
revert MemberHasNoStake(idCommitment); revert MemberHasNoStake(idCommitment);
@ -159,6 +162,7 @@ abstract contract RlnBase {
// delete member // delete member
uint256 index = members[idCommitment]; uint256 index = members[idCommitment];
members[idCommitment] = 0; members[idCommitment] = 0;
memberExists[idCommitment] = false;
stakedAmounts[idCommitment] = 0; stakedAmounts[idCommitment] = 0;
// refund deposit // refund deposit

View File

@ -41,14 +41,16 @@ contract RlnTest is Test {
vm.assume(rln.isValidCommitment(idCommitment)); vm.assume(rln.isValidCommitment(idCommitment));
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment); rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
assertEq(rln.members(idCommitment), 1); assertEq(rln.memberExists(idCommitment), true);
assertEq(rln.members(idCommitment), 0);
} }
function test__InvalidRegistration__DuplicateCommitment(uint256 idCommitment) public { function test__InvalidRegistration__DuplicateCommitment(uint256 idCommitment) public {
vm.assume(rln.isValidCommitment(idCommitment)); vm.assume(rln.isValidCommitment(idCommitment));
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment); rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT); assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
assertEq(rln.members(idCommitment), 1); assertEq(rln.memberExists(idCommitment), true);
assertEq(rln.members(idCommitment), 0);
vm.expectRevert(DuplicateIdCommitment.selector); vm.expectRevert(DuplicateIdCommitment.selector);
rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment); rln.register{value: MEMBERSHIP_DEPOSIT}(idCommitment);
} }
@ -73,7 +75,7 @@ contract RlnTest is Test {
address(rln.poseidonHasher()), address(rln.poseidonHasher()),
address(rln.verifier()) address(rln.verifier())
); );
uint256 setSize = tempRln.SET_SIZE() - 1; uint256 setSize = tempRln.SET_SIZE();
for (uint256 i = 1; i <= setSize; i++) { for (uint256 i = 1; i <= setSize; i++) {
tempRln.register{value: MEMBERSHIP_DEPOSIT}(i); tempRln.register{value: MEMBERSHIP_DEPOSIT}(i);
} }
@ -141,7 +143,7 @@ contract RlnTest is Test {
assertEq(rln.members(idCommitment), 0); assertEq(rln.members(idCommitment), 0);
// manually set members[idCommitment] to true using vm // manually set members[idCommitment] to true using vm
stdstore.target(address(rln)).sig("members(uint256)").with_key(idCommitment).depth(0).checked_write(true); stdstore.target(address(rln)).sig("memberExists(uint256)").with_key(idCommitment).depth(0).checked_write(true);
vm.expectRevert(abi.encodeWithSelector(MemberHasNoStake.selector, idCommitment)); vm.expectRevert(abi.encodeWithSelector(MemberHasNoStake.selector, idCommitment));
rln.slash(idCommitment, to, zeroedProof); rln.slash(idCommitment, to, zeroedProof);