diff --git a/src/Membership.sol b/src/Membership.sol index ea2769c..c94a6eb 100644 --- a/src/Membership.sol +++ b/src/Membership.sol @@ -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; diff --git a/src/WakuRlnV2.sol b/src/WakuRlnV2.sol index 70eace6..fc0ae47 100644 --- a/src/WakuRlnV2.sol +++ b/src/WakuRlnV2.sol @@ -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; } } diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index 71b205e..1c4e136 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -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);