mirror of
https://github.com/logos-messaging/logos-messaging-rlnv2-contract.git
synced 2026-01-30 11:33:23 +00:00
refactor, group functions by funcitonality
This commit is contained in:
parent
6ffac526ba
commit
79f694c79f
@ -26,7 +26,7 @@ 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 depositAmountCalculator;
|
||||
IPriceCalculator public priceCalculator;
|
||||
|
||||
/// @notice Maximum total rate limit of all memberships in the membership set (messages per epoch)
|
||||
uint32 public maxTotalRateLimit;
|
||||
@ -38,17 +38,17 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
uint32 public minMembershipRateLimit;
|
||||
|
||||
/// @notice Membership active period duration (A in the spec)
|
||||
uint32 public activeDuration;
|
||||
uint32 public activeDurationForNewMemberships;
|
||||
|
||||
/// @notice Membership grace period duration (G in the spec)
|
||||
uint32 public gracePeriodDurationForNewMemberships;
|
||||
|
||||
/// @notice deposits available for withdrawal
|
||||
/// Deposits unavailable for withdrawal are stored in MembershipInfo.
|
||||
/// Note: deposits unavailable for withdrawal are stored in MembershipInfo.
|
||||
mapping(address holder => mapping(address token => uint256 balance)) public depositsToWithdraw;
|
||||
|
||||
/// @notice Current total rate limit of all memberships in the membership set (messages per epoch)
|
||||
uint256 public totalRateLimit;
|
||||
uint256 public currentTotalRateLimit;
|
||||
|
||||
/// @notice List of memberships in the membership set
|
||||
mapping(uint256 idCommitment => MembershipInfo membership) public memberships;
|
||||
@ -56,8 +56,8 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
/// @notice The index in the membership set for the next membership to be registered
|
||||
uint32 public nextFreeIndex;
|
||||
|
||||
/// @notice indices of memberships (expired or grace-period marked for erasure) that can be reused
|
||||
uint32[] public reusableIndicesOfErasedMemberships;
|
||||
/// @notice Indices of memberships marked as erased but not yet actually erased from the membership set
|
||||
uint32[] public indicesOfLazilyErasedMemberships;
|
||||
|
||||
struct MembershipInfo {
|
||||
/// @notice deposit amount (in tokens) to register this membership
|
||||
@ -76,6 +76,11 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
address token;
|
||||
}
|
||||
|
||||
/// Emitted when a new membership is added to the membership set // FIXME: rateCommitment or membershipRateLimit?
|
||||
/// @param rateCommitment The rateCommitment of the membership
|
||||
/// @param index The index of the membership in the membership set
|
||||
event MembershipRegistered(uint256 idCommitment, uint256 rateCommitment, uint32 index);
|
||||
|
||||
/// @notice Emitted when a membership is expired (exceeded its grace period and not extended)
|
||||
/// @param idCommitment the idCommitment of the membership
|
||||
/// @param membershipRateLimit the rate limit of this membership
|
||||
@ -142,21 +147,14 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
require(_activeDuration > 0);
|
||||
// Note: grace period duration may be equal to zero
|
||||
|
||||
depositAmountCalculator = IPriceCalculator(_priceCalculator);
|
||||
priceCalculator = IPriceCalculator(_priceCalculator);
|
||||
maxTotalRateLimit = _maxTotalRateLimit;
|
||||
minMembershipRateLimit = _minMembershipRateLimit;
|
||||
maxMembershipRateLimit = _maxMembershipRateLimit;
|
||||
activeDuration = _activeDuration;
|
||||
activeDurationForNewMemberships = _activeDuration;
|
||||
gracePeriodDurationForNewMemberships = _gracePeriodDuration;
|
||||
}
|
||||
|
||||
/// @notice Checks if a rate limit is within the allowed bounds
|
||||
/// @param rateLimit The rate limit
|
||||
/// @return true if the rate limit is within the allowed bounds, false otherwise
|
||||
function isValidMembershipRateLimit(uint32 rateLimit) public view returns (bool) {
|
||||
return minMembershipRateLimit <= rateLimit && rateLimit <= maxMembershipRateLimit;
|
||||
}
|
||||
|
||||
/// @dev acquire a membership and trasnfer the deposit to the contract
|
||||
/// @param _sender address of the holder of the new membership
|
||||
/// @param _idCommitment the idCommitment of the new membership
|
||||
@ -176,20 +174,21 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
revert InvalidMembershipRateLimit();
|
||||
}
|
||||
|
||||
currentTotalRateLimit += _rateLimit;
|
||||
|
||||
// Determine if we exceed the total rate limit
|
||||
totalRateLimit += _rateLimit;
|
||||
if (totalRateLimit > maxTotalRateLimit) {
|
||||
if (currentTotalRateLimit > maxTotalRateLimit) {
|
||||
revert ExceededMaxTotalRateLimit();
|
||||
}
|
||||
|
||||
(address token, uint256 depositAmount) = depositAmountCalculator.calculate(_rateLimit);
|
||||
(address token, uint256 depositAmount) = priceCalculator.calculate(_rateLimit);
|
||||
|
||||
// Possibly reuse an index of an available erased membership
|
||||
(index, indexReused) = _getFreeIndex();
|
||||
|
||||
memberships[_idCommitment] = MembershipInfo({
|
||||
holder: _sender,
|
||||
gracePeriodStartTimestamp: block.timestamp + uint256(activeDuration),
|
||||
gracePeriodStartTimestamp: block.timestamp + uint256(activeDurationForNewMemberships),
|
||||
gracePeriodDuration: gracePeriodDurationForNewMemberships,
|
||||
token: token,
|
||||
depositAmount: depositAmount,
|
||||
@ -200,15 +199,22 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
IERC20(token).safeTransferFrom(_sender, address(this), depositAmount);
|
||||
}
|
||||
|
||||
/// @notice Checks if a rate limit is within the allowed bounds
|
||||
/// @param rateLimit The rate limit
|
||||
/// @return true if the rate limit is within the allowed bounds, false otherwise
|
||||
function isValidMembershipRateLimit(uint32 rateLimit) public view returns (bool) {
|
||||
return minMembershipRateLimit <= rateLimit && rateLimit <= maxMembershipRateLimit;
|
||||
}
|
||||
|
||||
/// @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 was reused from an erased membership
|
||||
function _getFreeIndex() internal returns (uint32 index, bool indexReused) {
|
||||
// Reuse the last erased membership
|
||||
uint256 numIndices = reusableIndicesOfErasedMemberships.length;
|
||||
uint256 numIndices = indicesOfLazilyErasedMemberships.length;
|
||||
if (numIndices != 0) {
|
||||
index = reusableIndicesOfErasedMemberships[numIndices - 1];
|
||||
reusableIndicesOfErasedMemberships.pop();
|
||||
index = indicesOfLazilyErasedMemberships[numIndices - 1];
|
||||
indicesOfLazilyErasedMemberships.pop();
|
||||
indexReused = true;
|
||||
} else {
|
||||
index = nextFreeIndex;
|
||||
@ -231,7 +237,7 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
uint256 newGracePeriodStartTimestamp = (
|
||||
membership.gracePeriodStartTimestamp + membership.gracePeriodDuration
|
||||
// FIXME: we must use this membership's activeDuration, not global default
|
||||
+ uint256(activeDuration)
|
||||
+ uint256(activeDurationForNewMemberships)
|
||||
);
|
||||
|
||||
membership.gracePeriodStartTimestamp = newGracePeriodStartTimestamp;
|
||||
@ -241,52 +247,6 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
);
|
||||
}
|
||||
|
||||
/// @dev Determine whether a grace period has passed (the membership is expired)
|
||||
/// @param _gracePeriodStartTimestamp timestamp in which the grace period starts
|
||||
/// @param _gracePeriodDuration duration of the grace period
|
||||
function _isExpired(uint256 _gracePeriodStartTimestamp, uint32 _gracePeriodDuration) internal view returns (bool) {
|
||||
return block.timestamp > _gracePeriodStartTimestamp + uint256(_gracePeriodDuration);
|
||||
}
|
||||
|
||||
/// @notice Determine if a membership is expired
|
||||
/// @param _idCommitment the idCommitment of the membership
|
||||
function isExpired(uint256 _idCommitment) public view returns (bool) {
|
||||
MembershipInfo memory membership = memberships[_idCommitment];
|
||||
return _isExpired(membership.gracePeriodStartTimestamp, membership.gracePeriodDuration);
|
||||
}
|
||||
|
||||
/// @notice Returns the timestamp on which a membership can be considered expired
|
||||
/// @param _idCommitment the idCommitment of the membership
|
||||
function membershipExpirationTimestamp(uint256 _idCommitment) public view returns (uint256) {
|
||||
MembershipInfo memory membership = memberships[_idCommitment];
|
||||
return membership.gracePeriodStartTimestamp + uint256(membership.gracePeriodDuration) + 1;
|
||||
}
|
||||
|
||||
/// @dev Determine whether the current timestamp is in a given grace period
|
||||
/// @param _gracePeriodStartTimestamp timestamp in which the grace period starts
|
||||
/// @param _gracePeriodDuration duration of the grace period
|
||||
function _isInGracePeriod(
|
||||
uint256 _gracePeriodStartTimestamp,
|
||||
uint32 _gracePeriodDuration
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
uint256 timeNow = block.timestamp;
|
||||
return (
|
||||
_gracePeriodStartTimestamp <= timeNow
|
||||
&& timeNow <= _gracePeriodStartTimestamp + uint256(_gracePeriodDuration)
|
||||
);
|
||||
}
|
||||
|
||||
/// @notice Determine if a membership is in grace period now
|
||||
/// @param _idCommitment the idCommitment of the membership
|
||||
function isInGracePeriod(uint256 _idCommitment) public view returns (bool) {
|
||||
MembershipInfo memory membership = memberships[_idCommitment];
|
||||
return _isInGracePeriod(membership.gracePeriodStartTimestamp, membership.gracePeriodDuration);
|
||||
}
|
||||
|
||||
/// @dev Erase expired memberships or owned grace-period memberships.
|
||||
/// @param _sender address of the sender of transaction (will be used to check memberships in grace period)
|
||||
/// @param _idCommitment idCommitment of the membership to erase
|
||||
@ -310,10 +270,10 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
depositsToWithdraw[_membership.holder][_membership.token] += _membership.depositAmount;
|
||||
|
||||
// Deduct the rate limit of this membership from the total rate limit
|
||||
totalRateLimit -= _membership.rateLimit;
|
||||
currentTotalRateLimit -= _membership.rateLimit;
|
||||
|
||||
// Mark this membership as reusable
|
||||
reusableIndicesOfErasedMemberships.push(_membership.index);
|
||||
indicesOfLazilyErasedMemberships.push(_membership.index);
|
||||
|
||||
// Erase this membership from the memberships mapping
|
||||
// Note: the Merkle tree data will be erased when the index is reused
|
||||
@ -325,6 +285,52 @@ abstract contract MembershipUpgradeable is Initializable {
|
||||
emit MembershipErased(_idCommitment, _membership.rateLimit, _membership.index);
|
||||
}
|
||||
|
||||
/// @notice Determine if a membership is in grace period now
|
||||
/// @param _idCommitment the idCommitment of the membership
|
||||
function isInGracePeriod(uint256 _idCommitment) public view returns (bool) {
|
||||
MembershipInfo memory membership = memberships[_idCommitment];
|
||||
return _isInGracePeriod(membership.gracePeriodStartTimestamp, membership.gracePeriodDuration);
|
||||
}
|
||||
|
||||
/// @dev Determine whether the current timestamp is in a given grace period
|
||||
/// @param _gracePeriodStartTimestamp timestamp in which the grace period starts
|
||||
/// @param _gracePeriodDuration duration of the grace period
|
||||
function _isInGracePeriod(
|
||||
uint256 _gracePeriodStartTimestamp,
|
||||
uint32 _gracePeriodDuration
|
||||
)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
uint256 timeNow = block.timestamp;
|
||||
return (
|
||||
_gracePeriodStartTimestamp <= timeNow
|
||||
&& timeNow <= _gracePeriodStartTimestamp + uint256(_gracePeriodDuration)
|
||||
);
|
||||
}
|
||||
|
||||
/// @notice Determine if a membership is expired
|
||||
/// @param _idCommitment the idCommitment of the membership
|
||||
function isExpired(uint256 _idCommitment) public view returns (bool) {
|
||||
MembershipInfo memory membership = memberships[_idCommitment];
|
||||
return _isExpired(membership.gracePeriodStartTimestamp, membership.gracePeriodDuration);
|
||||
}
|
||||
|
||||
/// @dev Determine whether a grace period ends(the membership is expired)
|
||||
/// @param _gracePeriodStartTimestamp timestamp in which the grace period starts
|
||||
/// @param _gracePeriodDuration duration of the grace period
|
||||
function _isExpired(uint256 _gracePeriodStartTimestamp, uint32 _gracePeriodDuration) internal view returns (bool) {
|
||||
return block.timestamp > _gracePeriodStartTimestamp + uint256(_gracePeriodDuration);
|
||||
}
|
||||
|
||||
/// @notice Returns the timestamp on which a membership can be considered expired (i.e. when its grace period ends)
|
||||
/// @param _idCommitment the idCommitment of the membership
|
||||
function membershipExpirationTimestamp(uint256 _idCommitment) public view returns (uint256) {
|
||||
MembershipInfo memory membership = memberships[_idCommitment];
|
||||
return membership.gracePeriodStartTimestamp + uint256(membership.gracePeriodDuration) + 1;
|
||||
}
|
||||
|
||||
/// @dev Withdraw any available deposit balance in tokens after a membership is erased.
|
||||
/// @param _sender the address of the owner of the tokens
|
||||
/// @param _token the address of the token to withdraw
|
||||
|
||||
@ -37,11 +37,6 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
/// @notice The Merkle tree that stores rate commitments of memberships
|
||||
LazyIMTData public merkleTree;
|
||||
|
||||
/// Emitted when a new membership is added to the membership set
|
||||
/// @param rateCommitment The rateCommitment of the membership
|
||||
/// @param index The index of the membership in the membership set
|
||||
event MembershipRegistered(uint256 rateCommitment, uint32 index);
|
||||
|
||||
/// @notice the modifier to check if the idCommitment is valid
|
||||
/// @param idCommitment The idCommitment of the membership
|
||||
modifier onlyValidIdCommitment(uint256 idCommitment) {
|
||||
@ -110,11 +105,12 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
return idCommitment != 0 && idCommitment < Q;
|
||||
}
|
||||
|
||||
/// @notice Returns the rateCommitment of a membership at a given index
|
||||
/// @param index The index of the membership in the membership set
|
||||
/// @return The rateCommitment of the membership
|
||||
function getRateCommmitment(uint32 index) internal view returns (uint256) {
|
||||
return merkleTree.elements[LazyIMT.indexForElement(0, index)];
|
||||
/// @notice Checks if a membership exists
|
||||
/// @param idCommitment The idCommitment of the membership
|
||||
/// @return true if the membership exists, false otherwise
|
||||
function membershipExists(uint256 idCommitment) public view returns (bool) {
|
||||
(,, uint256 rateCommitment) = getMembershipInfo(idCommitment);
|
||||
return rateCommitment != 0;
|
||||
}
|
||||
|
||||
/// @notice Returns the membership info (rate limit, index, rateCommitment) by its idCommitment
|
||||
@ -126,15 +122,29 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
if (membership.rateLimit == 0) {
|
||||
return (0, 0, 0);
|
||||
}
|
||||
return (membership.rateLimit, membership.index, getRateCommmitment(membership.index));
|
||||
return (membership.rateLimit, membership.index, _getRateCommmitment(membership.index));
|
||||
}
|
||||
|
||||
/// @notice Checks if a membership exists
|
||||
/// @param idCommitment The idCommitment of the membership
|
||||
/// @return true if the membership exists, false otherwise
|
||||
function membershipExists(uint256 idCommitment) public view returns (bool) {
|
||||
(,, uint256 rateCommitment) = getMembershipInfo(idCommitment);
|
||||
return rateCommitment != 0;
|
||||
/// @notice Returns the rateCommitments of memberships within an index range
|
||||
/// @param startIndex The start index of the range (inclusive)
|
||||
/// @param endIndex The end index of the range (inclusive)
|
||||
/// @return The rateCommitments of the memberships
|
||||
function getRateCommitmentsInRange(uint32 startIndex, uint32 endIndex) public view returns (uint256[] memory) {
|
||||
if (startIndex > endIndex) revert InvalidPaginationQuery(startIndex, endIndex);
|
||||
if (endIndex > nextFreeIndex) revert InvalidPaginationQuery(startIndex, endIndex); //FIXME: should it be >=?
|
||||
|
||||
uint256[] memory rateCommitments = new uint256[](endIndex - startIndex + 1);
|
||||
for (uint32 i = startIndex; i <= endIndex; i++) {
|
||||
rateCommitments[i - startIndex] = _getRateCommmitment(i);
|
||||
}
|
||||
return rateCommitments;
|
||||
}
|
||||
|
||||
/// @notice Returns the rateCommitment of a membership at a given index
|
||||
/// @param index The index of the membership in the membership set
|
||||
/// @return The rateCommitment of the membership
|
||||
function _getRateCommmitment(uint32 index) internal view returns (uint256) {
|
||||
return merkleTree.elements[LazyIMT.indexForElement(0, index)];
|
||||
}
|
||||
|
||||
/// @notice Register a membership
|
||||
@ -170,18 +180,6 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
_register(idCommitment, rateLimit);
|
||||
}
|
||||
|
||||
/// @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];
|
||||
if (membershipToErase.rateLimit == 0) revert InvalidIdCommitment(idCommitmentToErase);
|
||||
_eraseMembershipAndSaveSlotToReuse(_msgSender(), idCommitmentToErase, membershipToErase);
|
||||
LazyIMT.update(merkleTree, 0, membershipToErase.index);
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Registers a membership
|
||||
/// @param idCommitment The idCommitment of the membership
|
||||
/// @param rateLimit The rate limit of the membership
|
||||
@ -198,22 +196,7 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
nextFreeIndex += 1;
|
||||
}
|
||||
|
||||
emit MembershipRegistered(rateCommitment, index);
|
||||
}
|
||||
|
||||
/// @notice Returns the rateCommitments of memberships within an index range
|
||||
/// @param startIndex The start index of the range (inclusive)
|
||||
/// @param endIndex The end index of the range (inclusive)
|
||||
/// @return The rateCommitments of the memberships
|
||||
function getRateCommitmentsInRange(uint32 startIndex, uint32 endIndex) public view returns (uint256[] memory) {
|
||||
if (startIndex > endIndex) revert InvalidPaginationQuery(startIndex, endIndex);
|
||||
if (endIndex > nextFreeIndex) revert InvalidPaginationQuery(startIndex, endIndex); //FIXME: should it be >=?
|
||||
|
||||
uint256[] memory rateCommitments = new uint256[](endIndex - startIndex + 1);
|
||||
for (uint32 i = startIndex; i <= endIndex; i++) {
|
||||
rateCommitments[i - startIndex] = getRateCommmitment(i);
|
||||
}
|
||||
return rateCommitments;
|
||||
emit MembershipRegistered(idCommitment, rateCommitment, index);
|
||||
}
|
||||
|
||||
/// @notice Returns the root of the Merkle tree that stores rate commitments of memberships
|
||||
@ -253,6 +236,18 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
_eraseMemberships(idCommitments);
|
||||
}
|
||||
|
||||
/// @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];
|
||||
if (membershipToErase.rateLimit == 0) revert InvalidIdCommitment(idCommitmentToErase);
|
||||
_eraseMembershipAndSaveSlotToReuse(_msgSender(), idCommitmentToErase, membershipToErase);
|
||||
LazyIMT.update(merkleTree, 0, membershipToErase.index);
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Withdraw any available deposit balance in tokens after a membership is erased.
|
||||
/// @param token The address of the token to withdraw
|
||||
function withdraw(address token) external {
|
||||
@ -261,8 +256,8 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
|
||||
/// @notice Set the address of the price calculator
|
||||
/// @param _priceCalculator new price calculator address
|
||||
function setDepositAmountCalculator(address _priceCalculator) external onlyOwner {
|
||||
depositAmountCalculator = IPriceCalculator(_priceCalculator);
|
||||
function setPriceCalculator(address _priceCalculator) external onlyOwner {
|
||||
priceCalculator = IPriceCalculator(_priceCalculator);
|
||||
}
|
||||
|
||||
/// @notice Set the maximum total rate limit of all memberships in the membership set
|
||||
@ -291,7 +286,7 @@ contract WakuRlnV2 is Initializable, Ownable2StepUpgradeable, UUPSUpgradeable, M
|
||||
/// @param _activeDuration new active duration
|
||||
function setActiveDuration(uint32 _activeDuration) external onlyOwner {
|
||||
require(_activeDuration > 0);
|
||||
activeDuration = _activeDuration;
|
||||
activeDurationForNewMemberships = _activeDuration;
|
||||
}
|
||||
|
||||
/// @notice Set the grace period for new memberships (grace periods of existing memberships don't change)
|
||||
|
||||
@ -41,7 +41,7 @@ contract WakuRlnV2Test is Test {
|
||||
|
||||
uint256 idCommitment = 2;
|
||||
uint32 membershipRateLimit = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
token.approve(address(w), price);
|
||||
w.register(idCommitment, membershipRateLimit);
|
||||
@ -95,7 +95,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistration(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
uint256 minMembershipRateLimit = w.minMembershipRateLimit();
|
||||
uint256 maxMembershipRateLimit = w.maxMembershipRateLimit();
|
||||
vm.assume(membershipRateLimit >= minMembershipRateLimit && membershipRateLimit <= maxMembershipRateLimit);
|
||||
@ -114,16 +114,15 @@ contract WakuRlnV2Test is Test {
|
||||
assertEq(fetchedRateCommitment, rateCommitment);
|
||||
|
||||
assertEq(token.balanceOf(address(w)), price);
|
||||
assertEq(w.totalRateLimit(), membershipRateLimit);
|
||||
assertEq(w.currentTotalRateLimit(), membershipRateLimit);
|
||||
}
|
||||
|
||||
function test__LinearPriceCalculation(uint32 membershipRateLimit) external view {
|
||||
IPriceCalculator depositAmountCalculator = w.depositAmountCalculator();
|
||||
uint256 pricePerMessagePerPeriod =
|
||||
LinearPriceCalculator(address(depositAmountCalculator)).pricePerMessagePerEpoch();
|
||||
IPriceCalculator priceCalculator = w.priceCalculator();
|
||||
uint256 pricePerMessagePerPeriod = LinearPriceCalculator(address(priceCalculator)).pricePerMessagePerEpoch();
|
||||
assertNotEq(pricePerMessagePerPeriod, 0);
|
||||
uint256 expectedPrice = uint256(membershipRateLimit) * pricePerMessagePerPeriod;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
assertEq(price, expectedPrice);
|
||||
}
|
||||
|
||||
@ -133,7 +132,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.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price - 1);
|
||||
@ -153,7 +152,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 0;
|
||||
uint32 membershipRateLimit = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price);
|
||||
@ -164,7 +163,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__InvalidRegistration__InvalidIdCommitment__LargerThanField() external {
|
||||
vm.pauseGasMetering();
|
||||
uint32 membershipRateLimit = 20;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
uint256 idCommitment = w.Q() + 1;
|
||||
@ -189,7 +188,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistrationExtend(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -227,7 +226,7 @@ contract WakuRlnV2Test is Test {
|
||||
|
||||
assertEq(oldGracePeriodDuration, newGracePeriodDuration);
|
||||
assertEq(
|
||||
oldGracePeriodStartTimestamp + oldGracePeriodDuration + uint256(w.activeDuration()),
|
||||
oldGracePeriodStartTimestamp + oldGracePeriodDuration + uint256(w.activeDurationForNewMemberships()),
|
||||
newGracePeriodStartTimestamp
|
||||
);
|
||||
assertFalse(w.isInGracePeriod(idCommitment));
|
||||
@ -244,7 +243,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistrationExtendSingleMembership(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -276,7 +275,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__ValidRegistrationExpiry(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -308,7 +307,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.stopPrank();
|
||||
vm.resumeGasMetering();
|
||||
|
||||
(, uint256 priceA) = w.depositAmountCalculator().calculate(20);
|
||||
(, uint256 priceA) = w.priceCalculator().calculate(20);
|
||||
|
||||
for (uint256 i = 1; i <= 5; i++) {
|
||||
token.approve(address(w), priceA);
|
||||
@ -326,7 +325,7 @@ contract WakuRlnV2Test is Test {
|
||||
assertFalse(w.isExpired(5));
|
||||
assertFalse(w.isInGracePeriod(5));
|
||||
|
||||
(, uint256 priceB) = w.depositAmountCalculator().calculate(60);
|
||||
(, uint256 priceB) = w.priceCalculator().calculate(60);
|
||||
token.approve(address(w), priceB);
|
||||
|
||||
// Should fail. There's not enough free rate limit
|
||||
@ -386,33 +385,33 @@ contract WakuRlnV2Test is Test {
|
||||
|
||||
// Exceeds the max rate limit per user
|
||||
uint32 membershipRateLimit = 10;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(abi.encodeWithSelector(InvalidMembershipRateLimit.selector));
|
||||
w.register(1, membershipRateLimit);
|
||||
|
||||
// Should register succesfully
|
||||
membershipRateLimit = 4;
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
w.register(2, membershipRateLimit);
|
||||
|
||||
// Exceeds the rate limit
|
||||
membershipRateLimit = 2;
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(abi.encodeWithSelector(ExceededMaxTotalRateLimit.selector));
|
||||
w.register(3, membershipRateLimit);
|
||||
|
||||
// Should register succesfully
|
||||
membershipRateLimit = 1;
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
w.register(3, membershipRateLimit);
|
||||
|
||||
// We ran out of rate limit again
|
||||
membershipRateLimit = 1;
|
||||
(, price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
token.approve(address(w), price);
|
||||
vm.expectRevert(abi.encodeWithSelector(ExceededMaxTotalRateLimit.selector));
|
||||
w.register(4, membershipRateLimit);
|
||||
@ -421,7 +420,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__indexReuse_eraseMemberships(uint32 idCommitmentsLength) external {
|
||||
vm.assume(idCommitmentsLength > 0 && idCommitmentsLength < 50);
|
||||
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(20);
|
||||
(, uint256 price) = w.priceCalculator().calculate(20);
|
||||
uint32 index;
|
||||
uint256[] memory commitmentsToErase = new uint256[](idCommitmentsLength);
|
||||
for (uint256 i = 1; i <= idCommitmentsLength; i++) {
|
||||
@ -439,28 +438,28 @@ contract WakuRlnV2Test is Test {
|
||||
|
||||
// Verify that expired indices match what we expect
|
||||
for (uint32 i = 0; i < idCommitmentsLength; i++) {
|
||||
assertEq(i, w.reusableIndicesOfErasedMemberships(i));
|
||||
assertEq(i, w.indicesOfLazilyErasedMemberships(i));
|
||||
}
|
||||
|
||||
uint32 currnextCommitmentIndex = w.nextFreeIndex();
|
||||
for (uint256 i = 1; i <= idCommitmentsLength; i++) {
|
||||
uint256 idCommitment = i + 10;
|
||||
uint256 expectedindexReusedPos = idCommitmentsLength - i;
|
||||
uint32 expectedIndex = w.reusableIndicesOfErasedMemberships(expectedindexReusedPos);
|
||||
uint32 expectedIndex = w.indicesOfLazilyErasedMemberships(expectedindexReusedPos);
|
||||
token.approve(address(w), price);
|
||||
w.register(idCommitment, 20);
|
||||
(,,,, index,,) = w.memberships(idCommitment);
|
||||
assertEq(expectedIndex, index);
|
||||
// Should have been removed from the list
|
||||
vm.expectRevert();
|
||||
w.reusableIndicesOfErasedMemberships(expectedindexReusedPos);
|
||||
w.indicesOfLazilyErasedMemberships(expectedindexReusedPos);
|
||||
// Should not have been affected
|
||||
assertEq(currnextCommitmentIndex, w.nextFreeIndex());
|
||||
}
|
||||
|
||||
// No indexes should be available for reuse
|
||||
vm.expectRevert();
|
||||
w.reusableIndicesOfErasedMemberships(0);
|
||||
w.indicesOfLazilyErasedMemberships(0);
|
||||
|
||||
// Should use a new index since we got rid of all available indexes
|
||||
token.approve(address(w), price);
|
||||
@ -473,7 +472,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__RemoveExpiredMemberships(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
);
|
||||
@ -531,7 +530,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
vm.assume(idCommitmentsLength > 1 && idCommitmentsLength <= 100);
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
uint256 time = block.timestamp;
|
||||
@ -567,10 +566,10 @@ contract WakuRlnV2Test is Test {
|
||||
function test__WithdrawToken(uint32 membershipRateLimit) external {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
LinearPriceCalculator depositAmountCalculator = LinearPriceCalculator(address(w.depositAmountCalculator()));
|
||||
vm.prank(depositAmountCalculator.owner());
|
||||
depositAmountCalculator.setTokenAndPrice(address(token), 5 wei);
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
LinearPriceCalculator priceCalculator = LinearPriceCalculator(address(w.priceCalculator()));
|
||||
vm.prank(priceCalculator.owner());
|
||||
priceCalculator.setTokenAndPrice(address(token), 5 wei);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
token.mint(address(this), price);
|
||||
vm.assume(
|
||||
membershipRateLimit >= w.minMembershipRateLimit() && membershipRateLimit <= w.maxMembershipRateLimit()
|
||||
@ -610,7 +609,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 2;
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price);
|
||||
@ -624,7 +623,7 @@ contract WakuRlnV2Test is Test {
|
||||
function test__InvalidRegistration__FullTree() external {
|
||||
vm.pauseGasMetering();
|
||||
uint32 membershipRateLimit = 20;
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
// we progress the tree to the last leaf
|
||||
@ -670,7 +669,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
uint256 idCommitment = 1;
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
vm.resumeGasMetering();
|
||||
|
||||
token.approve(address(w), price);
|
||||
@ -685,7 +684,7 @@ contract WakuRlnV2Test is Test {
|
||||
vm.pauseGasMetering();
|
||||
vm.assume(idCommitmentsLength > 0 && idCommitmentsLength <= 100);
|
||||
uint32 membershipRateLimit = w.minMembershipRateLimit();
|
||||
(, uint256 price) = w.depositAmountCalculator().calculate(membershipRateLimit);
|
||||
(, uint256 price) = w.priceCalculator().calculate(membershipRateLimit);
|
||||
|
||||
for (uint256 i = 0; i < idCommitmentsLength; i++) {
|
||||
token.approve(address(w), price);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user