fix: full tree revert
This commit is contained in:
parent
19cd647e13
commit
ae01148ffc
|
@ -2,7 +2,7 @@
|
||||||
pragma solidity 0.8.15;
|
pragma solidity 0.8.15;
|
||||||
|
|
||||||
import {IPoseidonHasher} from "rln-contract/PoseidonHasher.sol";
|
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";
|
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
|
||||||
|
|
||||||
error NotImplemented();
|
error NotImplemented();
|
||||||
|
@ -25,7 +25,7 @@ contract WakuRln is Ownable, RlnBase {
|
||||||
idCommitmentIndex += 1;
|
idCommitmentIndex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function register(uint256[] memory idCommitments) external onlyOwner {
|
function register(uint256[] calldata idCommitments) external onlyOwner {
|
||||||
uint256 len = idCommitments.length;
|
uint256 len = idCommitments.length;
|
||||||
for (uint256 i = 0; i < len;) {
|
for (uint256 i = 0; i < len;) {
|
||||||
_register(idCommitments[i]);
|
_register(idCommitments[i]);
|
||||||
|
@ -45,6 +45,7 @@ contract WakuRln is Ownable, RlnBase {
|
||||||
|
|
||||||
function _validateRegistration(uint256 idCommitment) internal view override {
|
function _validateRegistration(uint256 idCommitment) internal view override {
|
||||||
if (members[idCommitment] != 0) revert DuplicateIdCommitment();
|
if (members[idCommitment] != 0) revert DuplicateIdCommitment();
|
||||||
|
if (idCommitmentIndex >= SET_SIZE) revert FullTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
|
function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
|
||||||
|
|
|
@ -4,7 +4,6 @@ pragma solidity 0.8.15;
|
||||||
import {WakuRln} from "./WakuRln.sol";
|
import {WakuRln} from "./WakuRln.sol";
|
||||||
import {IPoseidonHasher} from "rln-contract/PoseidonHasher.sol";
|
import {IPoseidonHasher} from "rln-contract/PoseidonHasher.sol";
|
||||||
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
|
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
|
||||||
import "forge-std/console.sol";
|
|
||||||
|
|
||||||
error StorageAlreadyExists(address storageAddress);
|
error StorageAlreadyExists(address storageAddress);
|
||||||
error NoStorageContractAvailable();
|
error NoStorageContractAvailable();
|
||||||
|
@ -56,12 +55,28 @@ contract WakuRlnRegistry is Ownable {
|
||||||
assembly {
|
assembly {
|
||||||
revert(add(32, err), mload(err))
|
revert(add(32, err), mload(err))
|
||||||
}
|
}
|
||||||
|
// when there are no further storage contracts available, revert
|
||||||
|
} else if (usingStorageIndex + 1 >= nextStorageIndex) {
|
||||||
|
revert NoStorageContractAvailable();
|
||||||
}
|
}
|
||||||
usingStorageIndex += 1;
|
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 {
|
function forceProgress() external onlyOwner {
|
||||||
if (usingStorageIndex >= nextStorageIndex) revert NoStorageContractAvailable();
|
if (usingStorageIndex >= nextStorageIndex) revert NoStorageContractAvailable();
|
||||||
usingStorageIndex += 1;
|
usingStorageIndex += 1;
|
||||||
|
|
|
@ -178,6 +178,18 @@ function newStorage() external
|
||||||
function register(uint256[] commitments) external payable
|
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
|
### forceProgress
|
||||||
|
|
||||||
```solidity
|
```solidity
|
||||||
|
|
|
@ -8,3 +8,5 @@ cache_path = 'cache_forge'
|
||||||
# 5667: Unused function parameter. Remove or comment out the variable name to silence this warning.
|
# 5667: Unused function parameter. Remove or comment out the variable name to silence this warning.
|
||||||
# 5740: Unreachable code.
|
# 5740: Unreachable code.
|
||||||
ignored_error_codes = [5667, 5740]
|
ignored_error_codes = [5667, 5740]
|
||||||
|
# setting this to allow expensive larger inserts during tests
|
||||||
|
memory_limit = 100_000_000
|
||||||
|
|
|
@ -3,12 +3,14 @@ pragma solidity ^0.8.15;
|
||||||
|
|
||||||
import "../contracts/WakuRlnRegistry.sol";
|
import "../contracts/WakuRlnRegistry.sol";
|
||||||
import {PoseidonHasher} from "rln-contract/PoseidonHasher.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 {noDuplicate} from "./utils.sol";
|
||||||
import "forge-std/Test.sol";
|
import "forge-std/Test.sol";
|
||||||
import "forge-std/StdCheats.sol";
|
import "forge-std/StdCheats.sol";
|
||||||
|
|
||||||
contract WakuRlnRegistryTest is Test {
|
contract WakuRlnRegistryTest is Test {
|
||||||
|
using stdStorage for StdStorage;
|
||||||
|
|
||||||
WakuRlnRegistry public wakuRlnRegistry;
|
WakuRlnRegistry public wakuRlnRegistry;
|
||||||
PoseidonHasher public poseidonHasher;
|
PoseidonHasher public poseidonHasher;
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ contract WakuRlnRegistryTest is Test {
|
||||||
wakuRlnRegistry.register(commitments);
|
wakuRlnRegistry.register(commitments);
|
||||||
}
|
}
|
||||||
|
|
||||||
function test__BadRegister(uint256[] calldata commitments) public {
|
function test__InvalidRegistration_Duplicate(uint256[] calldata commitments) public {
|
||||||
vm.assume(!noDuplicate(commitments));
|
vm.assume(!noDuplicate(commitments));
|
||||||
wakuRlnRegistry.newStorage();
|
wakuRlnRegistry.newStorage();
|
||||||
vm.expectRevert(DuplicateIdCommitment.selector);
|
vm.expectRevert(DuplicateIdCommitment.selector);
|
||||||
|
@ -52,4 +54,50 @@ contract WakuRlnRegistryTest is Test {
|
||||||
wakuRlnRegistry.forceProgress();
|
wakuRlnRegistry.forceProgress();
|
||||||
require(wakuRlnRegistry.usingStorageIndex() == 1);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue