2024-01-11 09:29:18 +00:00
|
|
|
// SPDX-License-Identifier: UNLICENSED
|
2023-03-29 09:49:32 +00:00
|
|
|
pragma solidity ^0.8.15;
|
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
import { Test, console } from "forge-std/Test.sol";
|
2023-03-29 11:48:00 +00:00
|
|
|
import "forge-std/StdCheats.sol";
|
2024-01-11 09:29:18 +00:00
|
|
|
|
|
|
|
import { TrueVerifier, FalseVerifier } from "./mocks/VerifierMock.sol";
|
|
|
|
|
|
|
|
import { Deploy } from "../script/Deploy.s.sol";
|
|
|
|
import { DeploymentConfig } from "../script/DeploymentConfig.s.sol";
|
|
|
|
import "../src/Rln.sol";
|
2023-03-29 09:49:32 +00:00
|
|
|
|
2023-07-26 10:42:37 +00:00
|
|
|
contract RlnTest is Test {
|
2023-03-29 11:48:00 +00:00
|
|
|
using stdStorage for StdStorage;
|
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
Rln internal rln;
|
|
|
|
TrueVerifier internal trueVerifier;
|
|
|
|
FalseVerifier internal falseVerifier;
|
2023-05-26 08:01:05 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
function setUp() public virtual {
|
2023-05-26 08:01:05 +00:00
|
|
|
trueVerifier = new TrueVerifier();
|
|
|
|
falseVerifier = new FalseVerifier();
|
2024-01-11 09:29:18 +00:00
|
|
|
|
|
|
|
rln = new Rln(MEMBERSHIP_DEPOSIT, DEPTH, address(trueVerifier));
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
uint256 public constant MEMBERSHIP_DEPOSIT = 1_000_000_000_000_000;
|
|
|
|
uint256 public constant DEPTH = 20;
|
|
|
|
uint256 public constant SET_SIZE = 1_048_576;
|
|
|
|
uint256[8] public zeroedProof = [0, 0, 0, 0, 0, 0, 0, 0];
|
|
|
|
|
2023-03-29 09:49:32 +00:00
|
|
|
/// @dev Ensure that you can hash a value.
|
|
|
|
function test__Constants() public {
|
|
|
|
assertEq(rln.MEMBERSHIP_DEPOSIT(), MEMBERSHIP_DEPOSIT);
|
|
|
|
assertEq(rln.DEPTH(), DEPTH);
|
|
|
|
assertEq(rln.SET_SIZE(), SET_SIZE);
|
2023-08-21 07:07:15 +00:00
|
|
|
assertEq(rln.deployedBlockNumber(), 1);
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function test__ValidRegistration(uint256 idCommitment) public {
|
2023-08-16 13:20:49 +00:00
|
|
|
vm.assume(rln.isValidCommitment(idCommitment));
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 09:49:32 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
2023-08-30 16:47:07 +00:00
|
|
|
assertEq(rln.memberExists(idCommitment), true);
|
|
|
|
assertEq(rln.members(idCommitment), 0);
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 10:42:37 +00:00
|
|
|
function test__InvalidRegistration__DuplicateCommitment(uint256 idCommitment) public {
|
2023-08-16 13:20:49 +00:00
|
|
|
vm.assume(rln.isValidCommitment(idCommitment));
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 09:49:32 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
2023-08-30 16:47:07 +00:00
|
|
|
assertEq(rln.memberExists(idCommitment), true);
|
|
|
|
assertEq(rln.members(idCommitment), 0);
|
2023-03-30 12:00:54 +00:00
|
|
|
vm.expectRevert(DuplicateIdCommitment.selector);
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
|
|
|
|
2023-08-16 13:20:49 +00:00
|
|
|
function test__InvalidRegistration__InvalidIdCommitment(uint256 idCommitment) public {
|
|
|
|
vm.assume(!rln.isValidCommitment(idCommitment));
|
|
|
|
vm.expectRevert(abi.encodeWithSelector(InvalidIdCommitment.selector, idCommitment));
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-08-16 13:20:49 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 10:42:37 +00:00
|
|
|
function test__InvalidRegistration__InsufficientDeposit(uint256 idCommitment) public {
|
2023-08-16 13:20:49 +00:00
|
|
|
vm.assume(rln.isValidCommitment(idCommitment));
|
2023-03-30 12:00:54 +00:00
|
|
|
uint256 badDepositAmount = MEMBERSHIP_DEPOSIT - 1;
|
2023-07-26 10:42:37 +00:00
|
|
|
vm.expectRevert(abi.encodeWithSelector(InsufficientDeposit.selector, MEMBERSHIP_DEPOSIT, badDepositAmount));
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: badDepositAmount }(idCommitment);
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
|
|
|
|
2023-08-16 13:20:49 +00:00
|
|
|
function test__InvalidRegistration__FullSet() public {
|
2024-01-11 09:29:18 +00:00
|
|
|
Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, address(rln.verifier()));
|
2023-08-30 16:47:07 +00:00
|
|
|
uint256 setSize = tempRln.SET_SIZE();
|
2023-08-16 13:20:49 +00:00
|
|
|
for (uint256 i = 1; i <= setSize; i++) {
|
2024-01-11 09:29:18 +00:00
|
|
|
tempRln.register{ value: MEMBERSHIP_DEPOSIT }(i);
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
|
|
|
assertEq(tempRln.idCommitmentIndex(), 4);
|
2023-05-23 06:54:58 +00:00
|
|
|
vm.expectRevert(FullTree.selector);
|
2024-01-11 09:29:18 +00:00
|
|
|
tempRln.register{ value: MEMBERSHIP_DEPOSIT }(setSize + 1);
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|
2023-03-29 11:48:00 +00:00
|
|
|
|
2023-05-26 08:01:05 +00:00
|
|
|
function test__ValidSlash(uint256 idCommitment, address payable to) public {
|
2023-03-29 11:48:00 +00:00
|
|
|
// avoid precompiles, etc
|
2023-03-29 12:21:48 +00:00
|
|
|
// TODO: wrap both of these in a single function
|
2023-03-29 11:48:00 +00:00
|
|
|
assumePayable(to);
|
2023-08-08 17:13:19 +00:00
|
|
|
assumeNotPrecompile(to);
|
2023-03-29 11:59:33 +00:00
|
|
|
vm.assume(to != address(0));
|
2023-08-16 13:20:49 +00:00
|
|
|
vm.assume(rln.isValidCommitment(idCommitment));
|
2023-03-29 11:48:00 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
|
|
|
|
|
|
|
uint256 balanceBefore = to.balance;
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, to, zeroedProof);
|
2024-01-11 09:29:18 +00:00
|
|
|
assertEq(rln.withdrawalBalance(to), MEMBERSHIP_DEPOSIT);
|
2023-03-30 14:53:08 +00:00
|
|
|
vm.prank(to);
|
|
|
|
rln.withdraw();
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), 0);
|
2023-05-23 06:54:58 +00:00
|
|
|
assertEq(rln.members(idCommitment), 0);
|
2024-01-11 09:29:18 +00:00
|
|
|
assertEq(rln.withdrawalBalance(to), 0);
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(to.balance, balanceBefore + MEMBERSHIP_DEPOSIT);
|
|
|
|
}
|
|
|
|
|
2023-03-30 14:53:08 +00:00
|
|
|
function test__InvalidSlash__ToZeroAddress() public {
|
2024-01-11 09:29:18 +00:00
|
|
|
uint256 idCommitment =
|
|
|
|
9_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
2023-05-26 08:01:05 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
2023-07-26 10:42:37 +00:00
|
|
|
vm.expectRevert(abi.encodeWithSelector(InvalidReceiverAddress.selector, address(0)));
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, payable(address(0)), zeroedProof);
|
2023-03-29 11:48:00 +00:00
|
|
|
}
|
|
|
|
|
2023-03-30 14:53:08 +00:00
|
|
|
function test__InvalidSlash__ToRlnAddress() public {
|
2024-01-11 09:29:18 +00:00
|
|
|
uint256 idCommitment =
|
|
|
|
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
2023-07-26 10:42:37 +00:00
|
|
|
vm.expectRevert(abi.encodeWithSelector(InvalidReceiverAddress.selector, address(rln)));
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, payable(address(rln)), zeroedProof);
|
2023-03-29 11:48:00 +00:00
|
|
|
}
|
|
|
|
|
2023-08-16 13:20:49 +00:00
|
|
|
function test__InvalidSlash__MemberNotRegistered(uint256 idCommitment) public {
|
|
|
|
vm.assume(rln.isValidCommitment(idCommitment));
|
2023-07-26 10:42:37 +00:00
|
|
|
vm.expectRevert(abi.encodeWithSelector(MemberNotRegistered.selector, idCommitment));
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, payable(address(this)), zeroedProof);
|
2023-03-29 11:48:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// this shouldn't be possible, but just in case
|
2023-07-26 10:42:37 +00:00
|
|
|
function test__InvalidSlash__NoStake(uint256 idCommitment, address payable to) public {
|
2023-03-29 11:48:00 +00:00
|
|
|
// avoid precompiles, etc
|
|
|
|
assumePayable(to);
|
2023-08-08 17:13:19 +00:00
|
|
|
assumeNotPrecompile(to);
|
2023-03-29 11:59:33 +00:00
|
|
|
vm.assume(to != address(0));
|
2023-08-16 13:20:49 +00:00
|
|
|
vm.assume(rln.isValidCommitment(idCommitment));
|
2023-03-29 11:48:00 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
|
|
|
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, to, zeroedProof);
|
2023-03-29 11:48:00 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), 0);
|
2023-05-23 06:54:58 +00:00
|
|
|
assertEq(rln.members(idCommitment), 0);
|
2023-03-29 11:48:00 +00:00
|
|
|
|
|
|
|
// manually set members[idCommitment] to true using vm
|
2023-08-30 16:47:07 +00:00
|
|
|
stdstore.target(address(rln)).sig("memberExists(uint256)").with_key(idCommitment).depth(0).checked_write(true);
|
2023-07-26 10:42:37 +00:00
|
|
|
|
|
|
|
vm.expectRevert(abi.encodeWithSelector(MemberHasNoStake.selector, idCommitment));
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, to, zeroedProof);
|
|
|
|
}
|
|
|
|
|
|
|
|
function test__InvalidSlash__InvalidProof() public {
|
2024-01-11 09:29:18 +00:00
|
|
|
uint256 idCommitment =
|
|
|
|
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
2023-05-26 08:01:05 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
Rln tempRln = new Rln(MEMBERSHIP_DEPOSIT, 2, address(falseVerifier));
|
2023-05-26 08:01:05 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
tempRln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-05-26 08:01:05 +00:00
|
|
|
|
|
|
|
vm.expectRevert(InvalidProof.selector);
|
|
|
|
tempRln.slash(idCommitment, payable(address(this)), zeroedProof);
|
2023-03-29 11:48:00 +00:00
|
|
|
}
|
|
|
|
|
2023-03-30 14:53:08 +00:00
|
|
|
function test__InvalidWithdraw__InsufficientWithdrawalBalance() public {
|
|
|
|
vm.expectRevert(InsufficientWithdrawalBalance.selector);
|
|
|
|
rln.withdraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
function test__InvalidWithdraw__InsufficientContractBalance() public {
|
2024-01-11 09:29:18 +00:00
|
|
|
uint256 idCommitment =
|
|
|
|
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-30 14:53:08 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, payable(address(this)), zeroedProof);
|
2023-03-30 14:53:08 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), 0);
|
2023-05-23 06:54:58 +00:00
|
|
|
assertEq(rln.members(idCommitment), 0);
|
2023-03-30 14:53:08 +00:00
|
|
|
|
|
|
|
vm.deal(address(rln), 0);
|
|
|
|
vm.expectRevert(InsufficientContractBalance.selector);
|
|
|
|
rln.withdraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
function test__ValidWithdraw(address payable to) public {
|
|
|
|
assumePayable(to);
|
2023-08-08 17:13:19 +00:00
|
|
|
assumeNotPrecompile(to);
|
2024-01-11 09:29:18 +00:00
|
|
|
vm.assume(to != address(0));
|
2023-03-30 14:53:08 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
uint256 idCommitment =
|
|
|
|
19_014_214_495_641_488_759_237_505_126_948_346_942_972_912_379_615_652_741_039_992_445_865_937_985_820;
|
2023-03-30 14:53:08 +00:00
|
|
|
|
2024-01-11 09:29:18 +00:00
|
|
|
rln.register{ value: MEMBERSHIP_DEPOSIT }(idCommitment);
|
2023-03-30 14:53:08 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), MEMBERSHIP_DEPOSIT);
|
2023-05-26 08:01:05 +00:00
|
|
|
rln.slash(idCommitment, to, zeroedProof);
|
2023-03-30 14:53:08 +00:00
|
|
|
assertEq(rln.stakedAmounts(idCommitment), 0);
|
2023-05-23 06:54:58 +00:00
|
|
|
assertEq(rln.members(idCommitment), 0);
|
2024-01-11 09:29:18 +00:00
|
|
|
assertEq(rln.memberExists(idCommitment), false);
|
2023-03-30 14:53:08 +00:00
|
|
|
|
|
|
|
vm.prank(to);
|
|
|
|
rln.withdraw();
|
|
|
|
assertEq(rln.withdrawalBalance(to), 0);
|
|
|
|
}
|
2023-03-29 09:49:32 +00:00
|
|
|
}
|