mirror of
https://github.com/logos-messaging/logos-messaging-rlnv2-contract.git
synced 2026-01-25 17:23:06 +00:00
refactor, minor fixes
This commit is contained in:
parent
ce52272102
commit
eedd9288f2
@ -7,27 +7,26 @@ import { SafeERC20 } from "openzeppelin-contracts/contracts/token/ERC20/utils/Sa
|
||||
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
|
||||
// The specified rate limit was not correct or within the expected limits
|
||||
error InvalidRateLimit();
|
||||
error InvalidMembershipRateLimit();
|
||||
|
||||
// It's not possible to acquire the rate limit due to exceeding the expected limits
|
||||
// even after attempting to erase expired memberships
|
||||
error ExceededMaxTotalRateLimit();
|
||||
|
||||
// This membership is not in grace period yet // FIXME: yet or also already?
|
||||
// This membership is not in grace period
|
||||
error NotInGracePeriod(uint256 idCommitment);
|
||||
|
||||
// The sender is not the holder of the membership
|
||||
error AttemptedExtensionByNonHolder(uint256 idCommitment);
|
||||
|
||||
// This membership cannot be erased (either it is not expired or not in grace period and/or not the owner) // FIXME:
|
||||
// separate into two errors?
|
||||
error CantEraseMembership(uint256 idCommitment);
|
||||
// This membership cannot be erased
|
||||
error CannotEraseMembership(uint256 idCommitment);
|
||||
|
||||
abstract contract MembershipUpgradeable is Initializable {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/// @notice Address of the Price Calculator used to calculate the price of a new membership
|
||||
IPriceCalculator public priceCalculator; // FIXME: naming: price vs deposit?
|
||||
IPriceCalculator public depositAmountCalculator;
|
||||
|
||||
/// @notice Maximum total rate limit of all memberships in the membership set (messages per epoch)
|
||||
uint32 public maxTotalRateLimit;
|
||||
@ -42,7 +41,7 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
uint32 public activeStateDuration;
|
||||
|
||||
/// @notice Membership grace period duration (G in the spec)
|
||||
uint32 public gracePeriodDuration;
|
||||
uint32 public gracePeriodDurationForNewMemberships;
|
||||
|
||||
/// @notice deposits available for withdrawal
|
||||
/// Deposits unavailable for withdrawal are stored in MembershipInfo.
|
||||
@ -65,8 +64,8 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
uint256 depositAmount;
|
||||
/// @notice timestamp of when the grace period starts for this membership
|
||||
uint256 gracePeriodStartTimestamp;
|
||||
/// @notice duration of the grace period
|
||||
uint32 gracePeriodDuration; // FIXME: does each membership need to store it if it's a global constant?
|
||||
/// @notice duration of the grace period for this membership
|
||||
uint32 gracePeriodDuration;
|
||||
/// @notice the membership rate limit
|
||||
uint32 rateLimit;
|
||||
/// @notice the index of the membership in the membership set
|
||||
@ -138,16 +137,17 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
onlyInitializing
|
||||
{
|
||||
require(0 < _minMembershipRateLimit);
|
||||
require(_minMembershipRateLimit <= _maxMembershipRateLimit); // FIXME: < or <=?
|
||||
require(_minMembershipRateLimit <= _maxMembershipRateLimit);
|
||||
require(_maxMembershipRateLimit <= _maxTotalRateLimit);
|
||||
require(_activeStateDuration > 0); // FIXME: also _gracePeriodDuration > 0?
|
||||
require(_activeStateDuration > 0);
|
||||
// Note: grace period duration may be equal to zero
|
||||
|
||||
priceCalculator = IPriceCalculator(_priceCalculator);
|
||||
depositAmountCalculator = IPriceCalculator(_priceCalculator);
|
||||
maxTotalRateLimit = _maxTotalRateLimit;
|
||||
minMembershipRateLimit = _minMembershipRateLimit;
|
||||
maxMembershipRateLimit = _maxMembershipRateLimit;
|
||||
activeStateDuration = _activeStateDuration;
|
||||
gracePeriodDuration = _gracePeriodDuration;
|
||||
gracePeriodDurationForNewMemberships = _gracePeriodDuration;
|
||||
}
|
||||
|
||||
/// @notice Checks if a rate limit is within the allowed bounds
|
||||
@ -171,69 +171,40 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
internal
|
||||
returns (uint32 index, bool indexReused)
|
||||
{
|
||||
// Check if the rate limit is valid
|
||||
if (!isValidMembershipRateLimit(_rateLimit)) {
|
||||
revert InvalidRateLimit();
|
||||
revert InvalidMembershipRateLimit();
|
||||
}
|
||||
(address token, uint256 amount) = priceCalculator.calculate(_rateLimit);
|
||||
(index, indexReused) = _setupMembershipDetails(_sender, _idCommitment, _rateLimit, token, amount);
|
||||
_transferDepositToContract(_sender, token, amount);
|
||||
}
|
||||
|
||||
// FIXME: do we need this as a separate function? (it's not called anywhere else)
|
||||
function _transferDepositToContract(address _from, address _token, uint256 _amount) internal {
|
||||
IERC20(_token).safeTransferFrom(_from, address(this), _amount);
|
||||
}
|
||||
|
||||
/// @dev Setup a new membership. If there are not enough remaining rate limit to acquire
|
||||
/// a new membership, it will attempt to erase existing expired memberships
|
||||
/// and reuse one of their slots
|
||||
/// @param _sender holder of the membership. Generally `msg.sender` // FIXME: keeper?
|
||||
/// @param _idCommitment idCommitment
|
||||
/// @param _rateLimit membership rate limit
|
||||
/// @param _token Address of the token used to acquire the membership
|
||||
/// @param _depositAmount Amount of the tokens used to acquire the membership
|
||||
/// @return index membership index in the membership set
|
||||
/// @return indexReused indicates whether the index returned was a reused slot on the tree or not
|
||||
function _setupMembershipDetails(
|
||||
address _sender,
|
||||
uint256 _idCommitment,
|
||||
uint32 _rateLimit,
|
||||
address _token,
|
||||
uint256 _depositAmount
|
||||
)
|
||||
internal
|
||||
returns (uint32 index, bool indexReused)
|
||||
{
|
||||
// Determine if we exceed the total rate limit
|
||||
totalRateLimit += _rateLimit;
|
||||
if (totalRateLimit > maxTotalRateLimit) {
|
||||
revert ExceededMaxTotalRateLimit();
|
||||
}
|
||||
|
||||
// FIXME: check if we even need to reuse an expired membership?
|
||||
(address token, uint256 depositAmount) = depositAmountCalculator.calculate(_rateLimit);
|
||||
|
||||
// Reuse available expired memberships
|
||||
// Possibly reuse an index of an available erased membership
|
||||
(index, indexReused) = _getFreeIndex();
|
||||
|
||||
// FIXME: we must check that the rate limit of the reused membership is sufficient
|
||||
// otherwise, the total rate limit may become too high
|
||||
|
||||
memberships[_idCommitment] = MembershipInfo({
|
||||
holder: _sender, // FIXME: keeper?
|
||||
gracePeriodStartTimestamp: block.timestamp + uint256(activeStateDuration),
|
||||
gracePeriodDuration: gracePeriodDuration,
|
||||
token: _token,
|
||||
depositAmount: _depositAmount,
|
||||
gracePeriodDuration: gracePeriodDurationForNewMemberships,
|
||||
token: token,
|
||||
depositAmount: depositAmount,
|
||||
rateLimit: _rateLimit,
|
||||
index: index
|
||||
});
|
||||
|
||||
IERC20(token).safeTransferFrom(_sender, address(this), depositAmount);
|
||||
}
|
||||
|
||||
/// @dev Get a free index (possibly from reusing an index of an erased membership)
|
||||
/// @return index index to be used for another membership registration
|
||||
/// @return indexReused indicates whether index comes form reusing a slot of an erased membership
|
||||
/// @return indexReused indicates whether index was reused from an erased membership
|
||||
function _getFreeIndex() internal returns (uint32 index, bool indexReused) {
|
||||
// Reuse the last membership marked as reusable
|
||||
// Reuse the last erased membership
|
||||
uint256 numIndices = reusableIndicesOfErasedMemberships.length;
|
||||
if (numIndices != 0) {
|
||||
index = reusableIndicesOfErasedMemberships[numIndices - 1];
|
||||
@ -253,13 +224,13 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
if (!_isInGracePeriod(membership.gracePeriodStartTimestamp, membership.gracePeriodDuration)) {
|
||||
revert NotInGracePeriod(_idCommitment);
|
||||
}
|
||||
// FIXME: turn into a modifier?
|
||||
|
||||
if (_sender != membership.holder) revert AttemptedExtensionByNonHolder(_idCommitment);
|
||||
|
||||
// FIXME: see spec: should extension depend on the current block.timestamp?
|
||||
uint256 newGracePeriodStartTimestamp = block.timestamp + uint256(activeStateDuration);
|
||||
|
||||
membership.gracePeriodStartTimestamp = newGracePeriodStartTimestamp;
|
||||
membership.gracePeriodDuration = gracePeriodDuration; // FIXME: redundant: just assigns old value
|
||||
|
||||
emit MembershipExtended(
|
||||
_idCommitment, membership.rateLimit, membership.index, membership.gracePeriodStartTimestamp
|
||||
@ -323,11 +294,13 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
internal
|
||||
{
|
||||
bool membershipExpired = _isExpired(_membership.gracePeriodStartTimestamp, _membership.gracePeriodDuration);
|
||||
bool membershipIsInGracePeriodAndHeld = _isInGracePeriod(
|
||||
_membership.gracePeriodStartTimestamp, _membership.gracePeriodDuration
|
||||
) && _membership.holder == _sender;
|
||||
// FIXME: we already had a non-holder check: reuse it here as a modifier?
|
||||
if (!membershipExpired && !membershipIsInGracePeriodAndHeld) revert CantEraseMembership(_idCommitment);
|
||||
bool membershipIsInGracePeriod =
|
||||
_isInGracePeriod(_membership.gracePeriodStartTimestamp, _membership.gracePeriodDuration);
|
||||
bool isHolder = (_membership.holder == _sender);
|
||||
|
||||
if (!membershipExpired && !(membershipIsInGracePeriod && isHolder)) {
|
||||
revert CannotEraseMembership(_idCommitment);
|
||||
}
|
||||
|
||||
// Move deposit balance from the membership to be erased to holder deposit balance
|
||||
depositsToWithdraw[_membership.holder][_membership.token] += _membership.depositAmount;
|
||||
|
||||
@ -11,18 +11,12 @@ import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils
|
||||
import { MembershipUpgradeable } from "./Membership.sol";
|
||||
import { IPriceCalculator } from "./IPriceCalculator.sol";
|
||||
|
||||
/// The membership set is full
|
||||
error FullMembershipSet();
|
||||
|
||||
/// A membership with this idCommitment is already registered
|
||||
error DuplicateIdCommitment();
|
||||
|
||||
/// Invalid idCommitment
|
||||
error InvalidIdCommitment(uint256 idCommitment);
|
||||
|
||||
/// Invalid membership rate limit // FIXME: this is not used - remove?
|
||||
error InvalidMembershipRateLimit(uint32 rateLimit);
|
||||
|
||||
/// Invalid pagination query
|
||||
error InvalidPaginationQuery(uint256 startIndex, uint256 endIndex);
|
||||
|
||||
@ -55,13 +49,26 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
_;
|
||||
}
|
||||
|
||||
/// @notice the modifier to check that the membership with this idCommitment doesn't already exist
|
||||
/// @param idCommitment The idCommitment of the membership
|
||||
modifier noDuplicateMembership(uint256 idCommitment) {
|
||||
require(!membershipExists(idCommitment), "Duplicate idCommitment: membership already exists");
|
||||
_;
|
||||
}
|
||||
|
||||
/// @notice the modifier to check that the membership set is not full
|
||||
modifier membershipSetNotFull() {
|
||||
require(nextFreeIndex < MAX_MEMBERSHIP_SET_SIZE, "Membership set is full");
|
||||
_;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
_disableInitializers();
|
||||
}
|
||||
|
||||
/// @dev contract initializer
|
||||
/// @param _priceCalculator Address of an instance of IPriceCalculator
|
||||
/// @param _maxTotalRateLimit Maximum total rate limit of all memberships FIXME: clarify: excl expired?
|
||||
/// @param _maxTotalRateLimit Maximum total rate limit of all memberships in the membership set
|
||||
/// @param _minMembershipRateLimit Minimum rate limit of one membership
|
||||
/// @param _maxMembershipRateLimit Maximum rate limit of one membership
|
||||
/// @param _activeStateDuration Membership expiration term
|
||||
@ -133,15 +140,16 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
/// @notice Register a membership
|
||||
/// @param idCommitment The idCommitment of the new membership
|
||||
/// @param rateLimit The rate limit of the new membership
|
||||
function register(uint256 idCommitment, uint32 rateLimit) external onlyValidIdCommitment(idCommitment) {
|
||||
// FIXME: turn into modifier?
|
||||
if (membershipExists(idCommitment)) revert DuplicateIdCommitment();
|
||||
|
||||
uint32 index;
|
||||
bool indexReused;
|
||||
(index, indexReused) = _acquireMembership(_msgSender(), idCommitment, rateLimit);
|
||||
|
||||
_register(idCommitment, rateLimit, index, indexReused);
|
||||
function register(
|
||||
uint256 idCommitment,
|
||||
uint32 rateLimit
|
||||
)
|
||||
external
|
||||
onlyValidIdCommitment(idCommitment)
|
||||
noDuplicateMembership(idCommitment)
|
||||
membershipSetNotFull
|
||||
{
|
||||
_register(idCommitment, rateLimit);
|
||||
}
|
||||
|
||||
/// @notice Register a membership
|
||||
@ -155,11 +163,16 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
)
|
||||
external
|
||||
onlyValidIdCommitment(idCommitment)
|
||||
noDuplicateMembership(idCommitment)
|
||||
membershipSetNotFull
|
||||
{
|
||||
// FIXME: turn into modifier?
|
||||
if (membershipExists(idCommitment)) revert DuplicateIdCommitment();
|
||||
_eraseMemberships(idCommitmentsToErase);
|
||||
_register(idCommitment, rateLimit);
|
||||
}
|
||||
|
||||
// FIXME: extract in a separate function?
|
||||
/// @dev Erase memberships from the list of idCommitments
|
||||
/// @param idCommitmentsToErase The idCommitments to erase
|
||||
function _eraseMemberships(uint256[] calldata idCommitmentsToErase) internal {
|
||||
for (uint256 i = 0; i < idCommitmentsToErase.length; i++) {
|
||||
uint256 idCommitmentToErase = idCommitmentsToErase[i];
|
||||
MembershipInfo memory membershipToErase = memberships[idCommitmentToErase];
|
||||
@ -167,24 +180,15 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
_eraseMembershipAndSaveSlotToReuse(_msgSender(), idCommitmentToErase, membershipToErase);
|
||||
LazyIMT.update(merkleTree, 0, membershipToErase.index);
|
||||
}
|
||||
|
||||
// FIXME: code repeats cf. register()
|
||||
uint32 index;
|
||||
bool indexReused;
|
||||
(index, indexReused) = _acquireMembership(_msgSender(), idCommitment, rateLimit);
|
||||
|
||||
_register(idCommitment, rateLimit, index, indexReused);
|
||||
}
|
||||
|
||||
/// @dev Registers a membership
|
||||
/// @param idCommitment The idCommitment of the membership
|
||||
/// @param rateLimit The rate limit of the membership
|
||||
/// @param index The index of the membership in the membership set
|
||||
/// @param indexReused Indicates whether we're inserting a new element in the Merkle tree or updating a existing
|
||||
/// element
|
||||
function _register(uint256 idCommitment, uint32 rateLimit, uint32 index, bool indexReused) internal {
|
||||
// FIXME: check this earlier, e.g. as a modifier to register() functions?
|
||||
if (nextFreeIndex >= MAX_MEMBERSHIP_SET_SIZE) revert FullMembershipSet();
|
||||
function _register(uint256 idCommitment, uint32 rateLimit) internal {
|
||||
uint32 index;
|
||||
bool indexReused;
|
||||
(index, indexReused) = _acquireMembership(_msgSender(), idCommitment, rateLimit);
|
||||
|
||||
uint256 rateCommitment = PoseidonT3.hash([idCommitment, rateLimit]);
|
||||
if (indexReused) {
|
||||
@ -246,14 +250,7 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
/// The user (i.e. the transaction sender) can then withdraw the deposited tokens.
|
||||
/// @param idCommitments list of idCommitments of the memberships to erase
|
||||
function eraseMemberships(uint256[] calldata idCommitments) external {
|
||||
for (uint256 i = 0; i < idCommitments.length; i++) {
|
||||
// FIXME: not DRY: see register()
|
||||
uint256 idCommitmentToErase = idCommitments[i];
|
||||
MembershipInfo memory membershipToErase = memberships[idCommitmentToErase];
|
||||
if (membershipToErase.rateLimit == 0) revert InvalidIdCommitment(idCommitmentToErase);
|
||||
_eraseMembershipAndSaveSlotToReuse(_msgSender(), idCommitmentToErase, membershipToErase);
|
||||
LazyIMT.update(merkleTree, 0, membershipToErase.index);
|
||||
}
|
||||
_eraseMemberships(idCommitments);
|
||||
}
|
||||
|
||||
/// @notice Withdraw any available deposit balance in tokens after a membership is erased.
|
||||
@ -264,11 +261,11 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
|
||||
/// @notice Set the address of the price calculator
|
||||
/// @param _priceCalculator new price calculator address
|
||||
function setPriceCalculator(address _priceCalculator) external onlyOwner {
|
||||
priceCalculator = IPriceCalculator(_priceCalculator);
|
||||
function setDepositAmountCalculator(address _priceCalculator) external onlyOwner {
|
||||
depositAmountCalculator = IPriceCalculator(_priceCalculator);
|
||||
}
|
||||
|
||||
/// @notice Set the maximum total rate limit of all (FIXME: excl expired?) memberships in the membership set
|
||||
/// @notice Set the maximum total rate limit of all memberships in the membership set
|
||||
/// @param _maxTotalRateLimit new maximum total rate limit (messages per epoch)
|
||||
function setMaxTotalRateLimit(uint32 _maxTotalRateLimit) external onlyOwner {
|
||||
require(_maxTotalRateLimit >= maxMembershipRateLimit);
|
||||
@ -285,7 +282,8 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
/// @notice Set the minimum rate limit of one membership
|
||||
/// @param _minMembershipRateLimit new minimum rate limit per membership (messages per epoch)
|
||||
function setMinMembershipRateLimit(uint32 _minMembershipRateLimit) external onlyOwner {
|
||||
require(_minMembershipRateLimit > 0); // FIXME: we must also check here that min rate <= max rate
|
||||
require(_minMembershipRateLimit > 0);
|
||||
require(_minMembershipRateLimit <= maxMembershipRateLimit);
|
||||
minMembershipRateLimit = _minMembershipRateLimit;
|
||||
}
|
||||
|
||||
@ -299,7 +297,7 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
/// @notice Set the grace period for new memberships (grace periods of existing memberships don't change)
|
||||
/// @param _gracePeriod new grace period term
|
||||
function setGracePeriod(uint32 _gracePeriod) external onlyOwner {
|
||||
// FIXME: shall we check that _gracePeriod > 0?
|
||||
gracePeriodDuration = _gracePeriod;
|
||||
// Note: grace period duration may be equal to zero
|
||||
gracePeriodDurationForNewMemberships = _gracePeriod;
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ contract WakuRlnV2Test is Test {
|
||||
|
||||
uint256 idCommitment = 2;
|
||||
uint32 membershipRateLimit = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
token.approve(address(w), price);
|
||||
w.register(idCommitment, membershipRateLimit);
|
||||
@ -59,8 +59,7 @@ contract WakuRlnV2Test is Test {
|
||||
w.root(),
|
||||
13_801_897_483_540_040_307_162_267_952_866_411_686_127_372_014_953_358_983_481_592_640_000_001_877_295
|
||||
);
|
||||
(uint32 fetchedMembershipRateLimit2, uint32 index2, uint256 rateCommitment2) =
|
||||
w.getMembershipInfo(idCommitment);
|
||||
(uint32 fetchedMembershipRateLimit2, uint32 index2, uint256 rateCommitment2) = w.getMembershipInfo(idCommitment);
|
||||
assertEq(fetchedMembershipRateLimit2, membershipRateLimit);
|
||||
assertEq(index2, 0);
|
||||
assertEq(rateCommitment2, rateCommitment);
|
||||
@ -96,7 +95,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistration(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
uint256 minMembershipRateLimit = w.minMembershipRateLimit();
|
||||
uint256 maxMembershipRateLimit = w.maxMembershipRateLimit();
|
||||
vm.assume(membershipRateLimit >= minMembershipRateLimit && membershipRateLimit <= maxMembershipRateLimit);
|
||||
@ -119,11 +118,12 @@ contract WakuRlnV2Test is Test {
|
||||
}
|
||||
|
||||
function test__LinearPriceCalculation(uint32 membershipRateLimit) external view {
|
||||
IPriceCalculator priceCalculator = w.priceCalculator();
|
||||
uint256 pricePerMessagePerPeriod = LinearPriceCalculator(address(priceCalculator)).pricePerMessagePerEpoch();
|
||||
IPriceCalculator depositAmountCalculator = w.depositAmountCalculator();
|
||||
uint256 pricePerMessagePerPeriod =
|
||||
LinearPriceCalculator(address(depositAmountCalculator)).pricePerMessagePerEpoch();
|
||||
assertNotEq(pricePerMessagePerPeriod, 0);
|
||||
uint256 expectedPrice = uint256(membershipRateLimit) * pricePerMessagePerPeriod;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
assertEq(price, expectedPrice);
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ contract WakuRlnV2Test is Test {
|
||||
uint256 maxMembershipRateLimit = w.maxMembershipRateLimit();
|
||||
vm.assume(membershipRateLimit >= minMembershipRateLimit && membershipRateLimit <= maxMembershipRateLimit);
|
||||
vm.assume(w.isValidIdCommitment(idCommitment) && w.isValidMembershipRateLimit(membershipRateLimit));
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price - 1);
|
||||
@ -153,7 +153,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 0;
|
||||
uint32 membershipRateLimit = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price);
|
||||
@ -164,7 +164,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__InvalidRegistration__InvalidIdCommitment__LargerThanField() external {
|
||||
vm.pauseGasMetering();
|
||||
uint32 membershipRateLimit = 20;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
uint256 idCommitment = w.Q() + 1;
|
||||
@ -179,17 +179,17 @@ contract WakuRlnV2Test is Test {
|
||||
uint32 invalidMin = w.minMembershipRateLimit() - 1;
|
||||
uint32 invalidMax = w.maxMembershipRateLimit() + 1;
|
||||
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidRateLimit.selector));
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidMembershipRateLimit.selector));
|
||||
w.register(idCommitment, invalidMin);
|
||||
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidRateLimit.selector));
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidMembershipRateLimit.selector));
|
||||
w.register(idCommitment, invalidMax);
|
||||
}
|
||||
|
||||
function test__ValidRegistrationExtend(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -239,7 +239,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistrationExtendSingleMembership(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -271,7 +271,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistrationExpiry(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -303,7 +303,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.stopPrank();
|
||||
vm.resumeGasMetering();
|
||||
|
||||
(, uint256 priceA) = w.priceCalculator().calculate(20);
|
||||
(, uint256 priceA) = w.depositAmountCalculator().calculate(20);
|
||||
|
||||
for (uint256 i = 1; i <= 5; i++) {
|
||||
token.approve(address(w), priceA);
|
||||
@ -321,7 +321,7 @@ contract WakuRlnV2Test is Test {
|
||||
assertFalse(w.isExpired(5));
|
||||
assertFalse(w.isInGracePeriod(5));
|
||||
|
||||
(, uint256 priceB) = w.priceCalculator().calculate(60);
|
||||
(, uint256 priceB) = w.depositAmountCalculator().calculate(60);
|
||||
token.approve(address(w), priceB);
|
||||
|
||||
// Should fail. There's not enough free rate limit
|
||||
@ -334,7 +334,7 @@ contract WakuRlnV2Test is Test {
|
||||
commitmentsToErase[1] = 2;
|
||||
commitmentsToErase[2] = 5; // This one is still active
|
||||
token.approve(address(w), priceB);
|
||||
vm.expectRevert(abi.encodeWithSelector(CantEraseMembership.selector, 5));
|
||||
vm.expectRevert(abi.encodeWithSelector(CannotEraseMembership.selector, 5));
|
||||
w.register(6, 60, commitmentsToErase);
|
||||
|
||||
// Attempt to expire 3 commitments that can be erased
|
||||
@ -381,33 +381,33 @@ contract WakuRlnV2Test is Test {
|
||||
|
||||
// Exceeds the max rate limit per user
|
||||
uint32 membershipRateLimit = 10;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidRateLimit.selector));
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidMembershipRateLimit.selector));
|
||||
w.register(1, membershipRateLimit);
|
||||
|
||||
// Should register succesfully
|
||||
membershipRateLimit = 4;
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
w.register(2, membershipRateLimit);
|
||||
|
||||
// Exceeds the rate limit
|
||||
membershipRateLimit = 2;
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(abi.encodeWithSelector(ExceededMaxTotalRateLimit.selector));
|
||||
w.register(3, membershipRateLimit);
|
||||
|
||||
// Should register succesfully
|
||||
membershipRateLimit = 1;
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
w.register(3, membershipRateLimit);
|
||||
|
||||
// We ran out of rate limit again
|
||||
membershipRateLimit = 1;
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(abi.encodeWithSelector(ExceededMaxTotalRateLimit.selector));
|
||||
w.register(4, membershipRateLimit);
|
||||
@ -416,7 +416,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__indexReuse_eraseMemberships(uint32 idCommitmentsLength) external {
|
||||
vm.assume(idCommitmentsLength > 0 && idCommitmentsLength < 50);
|
||||
|
||||
(, uint256 price) = w.priceCalculator().calculate(20);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(20);
|
||||
uint32 index;
|
||||
uint256[] memory commitmentsToErase = new uint256[](idCommitmentsLength);
|
||||
for (uint256 i = 1; i <= idCommitmentsLength; i++) {
|
||||
@ -468,7 +468,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__RemoveExpiredMemberships(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -518,7 +518,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.warp(gracePeriodStartTimestamp - 1);
|
||||
commitmentsToErase[0] = idCommitment;
|
||||
commitmentsToErase[1] = idCommitment + 4;
|
||||
vm.expectRevert(abi.encodeWithSelector(CantEraseMembership.selector, idCommitment + 4));
|
||||
vm.expectRevert(abi.encodeWithSelector(CannotEraseMembership.selector, idCommitment + 4));
|
||||
w.eraseMemberships(commitmentsToErase);
|
||||
}
|
||||
|
||||
@ -526,7 +526,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
vm.assume(idCommitmentsLength > 1 && idCommitmentsLength <= 100);
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
uint256 time = block.timestamp;
|
||||
@ -562,10 +562,10 @@ contract WakuRlnV2Test is Test {
|
||||
function test__WithdrawToken(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
LinearPriceCalculator priceCalculator = LinearPriceCalculator(address(w.priceCalculator()));
|
||||
vm.prank(priceCalculator.owner());
|
||||
priceCalculator.setTokenAndPrice(address(token), 5 wei);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
LinearPriceCalculator depositAmountCalculator = LinearPriceCalculator(address(w.depositAmountCalculator()));
|
||||
vm.prank(depositAmountCalculator.owner());
|
||||
depositAmountCalculator.setTokenAndPrice(address(token), 5 wei);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
token.mint(address(this), price);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
@ -605,21 +605,21 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price);
|
||||
w.register(idCommitment, membershipRateLimit);
|
||||
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(DuplicateIdCommitment.selector);
|
||||
vm.expectRevert(bytes("Duplicate idCommitment: membership already exists"));
|
||||
w.register(idCommitment, membershipRateLimit);
|
||||
}
|
||||
|
||||
function test__InvalidRegistration__FullTree() external {
|
||||
vm.pauseGasMetering();
|
||||
uint32 membershipRateLimit = 20;
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
// we progress the tree to the last leaf
|
||||
@ -647,7 +647,7 @@ contract WakuRlnV2Test is Test {
|
||||
// we set nextFreeIndex to 4294967295 (1 << 20) = 0x00100000
|
||||
vm.store(address(w), bytes32(uint256(256)), 0x0000000000000000000000000000000000000000000000000000000000100000);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(FullMembershipSet.selector);
|
||||
vm.expectRevert(bytes("Membership set is full"));
|
||||
w.register(1, membershipRateLimit);
|
||||
}
|
||||
|
||||
@ -665,7 +665,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 1;
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price);
|
||||
@ -680,7 +680,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
vm.assume(idCommitmentsLength > 0 && idCommitmentsLength <= 100);
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
|
||||
for (uint256 i = 0; i < idCommitmentsLength; i++) {
|
||||
token.approve(address(w), price);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user