fix: full tree revert

This commit is contained in:
rymnc 2023-08-08 13:32:07 +05:30
parent 19cd647e13
commit ae01148ffc
No known key found for this signature in database
GPG Key ID: AAA088D5C68ECD34
5 changed files with 84 additions and 6 deletions

View File

@ -2,7 +2,7 @@
pragma solidity 0.8.15;
import {IPoseidonHasher} from "rln-contract/PoseidonHasher.sol";
import {RlnBase, DuplicateIdCommitment} from "rln-contract/RlnBase.sol";
import {RlnBase, DuplicateIdCommitment, FullTree} from "rln-contract/RlnBase.sol";
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
error NotImplemented();
@ -25,7 +25,7 @@ contract WakuRln is Ownable, RlnBase {
idCommitmentIndex += 1;
}
function register(uint256[] memory idCommitments) external onlyOwner {
function register(uint256[] calldata idCommitments) external onlyOwner {
uint256 len = idCommitments.length;
for (uint256 i = 0; i < len;) {
_register(idCommitments[i]);
@ -45,6 +45,7 @@ contract WakuRln is Ownable, RlnBase {
function _validateRegistration(uint256 idCommitment) internal view override {
if (members[idCommitment] != 0) revert DuplicateIdCommitment();
if (idCommitmentIndex >= SET_SIZE) revert FullTree();
}
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)

View File

@ -4,7 +4,6 @@ pragma solidity 0.8.15;
import {WakuRln} from "./WakuRln.sol";
import {IPoseidonHasher} from "rln-contract/PoseidonHasher.sol";
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
import "forge-std/console.sol";
error StorageAlreadyExists(address storageAddress);
error NoStorageContractAvailable();
@ -56,12 +55,28 @@ contract WakuRlnRegistry is Ownable {
assembly {
revert(add(32, err), mload(err))
}
// when there are no further storage contracts available, revert
} else if (usingStorageIndex + 1 >= nextStorageIndex) {
revert NoStorageContractAvailable();
}
usingStorageIndex += 1;
}
}
}
function register(uint16 storageIndex, uint256[] calldata commitments) external payable {
if (storageIndex >= nextStorageIndex) revert NoStorageContractAvailable();
WakuRln(storages[storageIndex]).register(commitments);
}
function register(uint16 storageIndex, uint256 commitment) external payable {
if (storageIndex >= nextStorageIndex) revert NoStorageContractAvailable();
// optimize the gas used below
uint256[] memory commitments = new uint256[](1);
commitments[0] = commitment;
WakuRln(storages[storageIndex]).register(commitments);
}
function forceProgress() external onlyOwner {
if (usingStorageIndex >= nextStorageIndex) revert NoStorageContractAvailable();
usingStorageIndex += 1;

View File

@ -178,6 +178,18 @@ function newStorage() external
function register(uint256[] commitments) external payable
```
### register
```solidity
function register(uint16 storageIndex, uint256[] commitments) external payable
```
### register
```solidity
function register(uint16 storageIndex, uint256 commitment) external payable
```
### forceProgress
```solidity

View File

@ -8,3 +8,5 @@ cache_path = 'cache_forge'
# 5667: Unused function parameter. Remove or comment out the variable name to silence this warning.
# 5740: Unreachable code.
ignored_error_codes = [5667, 5740]
# setting this to allow expensive larger inserts during tests
memory_limit = 100_000_000

View File

@ -3,12 +3,14 @@ pragma solidity ^0.8.15;
import "../contracts/WakuRlnRegistry.sol";
import {PoseidonHasher} from "rln-contract/PoseidonHasher.sol";
import {DuplicateIdCommitment} from "rln-contract/RlnBase.sol";
import {DuplicateIdCommitment, FullTree} from "rln-contract/RlnBase.sol";
import {noDuplicate} from "./utils.sol";
import "forge-std/Test.sol";
import "forge-std/StdCheats.sol";
contract WakuRlnRegistryTest is Test {
using stdStorage for StdStorage;
WakuRlnRegistry public wakuRlnRegistry;
PoseidonHasher public poseidonHasher;
@ -40,7 +42,7 @@ contract WakuRlnRegistryTest is Test {
wakuRlnRegistry.register(commitments);
}
function test__BadRegister(uint256[] calldata commitments) public {
function test__InvalidRegistration_Duplicate(uint256[] calldata commitments) public {
vm.assume(!noDuplicate(commitments));
wakuRlnRegistry.newStorage();
vm.expectRevert(DuplicateIdCommitment.selector);
@ -52,4 +54,50 @@ contract WakuRlnRegistryTest is Test {
wakuRlnRegistry.forceProgress();
require(wakuRlnRegistry.usingStorageIndex() == 1);
}
function test__SingleRegistration(uint256 commitment) public {
wakuRlnRegistry.newStorage();
wakuRlnRegistry.register(0, commitment);
}
function test__InvalidSingleRegistration__NoStorageContract(uint256 commitment) public {
wakuRlnRegistry.newStorage();
vm.expectRevert(NoStorageContractAvailable.selector);
wakuRlnRegistry.register(1, commitment);
}
function test__InvalidSingleRegistration__Duplicate(uint256 commitment) public {
wakuRlnRegistry.newStorage();
wakuRlnRegistry.register(0, commitment);
vm.expectRevert(DuplicateIdCommitment.selector);
wakuRlnRegistry.register(0, commitment);
}
function test__InvalidSingleRegistration__FullTree() public {
vm.pauseGasMetering();
wakuRlnRegistry.newStorage();
WakuRln wakuRln = WakuRln(wakuRlnRegistry.storages(0));
uint256 setSize = wakuRln.SET_SIZE();
// setSize - 1 because RlnBase uses 1-indexing
for (uint256 i = 0; i < setSize - 1; i++) {
wakuRlnRegistry.register(0, i);
}
vm.resumeGasMetering();
vm.expectRevert(FullTree.selector);
wakuRlnRegistry.register(0, setSize);
}
function test__InvalidRegistration__NoStorageContract() public {
vm.pauseGasMetering();
wakuRlnRegistry.newStorage();
address storageContract = wakuRlnRegistry.storages(0);
uint256 setSize = WakuRln(storageContract).SET_SIZE();
uint256[] memory commitments = new uint256[](setSize);
for (uint256 i = 1; i < setSize; i++) {
commitments[i] = i;
}
vm.expectRevert(NoStorageContractAvailable.selector);
wakuRlnRegistry.register(commitments);
}
}