After a membership expires, it enters a grace period, during which the user can extend it.
Extending a membership requires no additional deposit.
After the grace period, an expired membership can be taken over by another user.
At any point, a user can withdraw their deposit and terminate the membership.
In more detail, the membership life-cycle is as follows:
1. A user registers a membership:
1. If there are expired unclaimed slots in the tree, use the slot with the earliest expiration date past its grace period, otherwise create a new slot;
1. Do nothing. The deposit remains in the contract, and the user retains the ability to send messages (respecting the per-epoch rate limit) until another user takes their slot;
2. Withdraw the deposit. The user receives the full deposit back, and loses the ability to send messages;
3. Extend the membership. The user sends a transaction to re-enable their membership for another expiration term. The user only covers gas costs and does not have to provide additional funds. The original deposit remains in the contract. The membership is prolonged for another expiration term under the same conditions.
The user can extend the membership both during and after its grace period.
Each nullifier plus metadata is `128` bytes (per message).
This means that one user with a `1` message per second rate limit (high-tier) generates up to `600 * 128 / 1024 = 75 KiB` of nullifier log data per 10-min epoch.
#### Maximum total message limit / concurrently active memberships
We may want to limit the total rate limit available to all users.
The rationale is that the total network bandwidth is a limited resource.
The total active rate limit should not exceed the network's real capabilities.
There may be two ways to implement a global cap:
- limit the total rate limits;
- limit the total number of active memberships (e.g., at 10K memberships).
#### Proportional pricing
We suggest proportional pricing for simplicity.
Proportional pricing means that if tier A offers N times the limit of tier B, then tier A is N times more expensive than tier B.
An alternative approach could be bulk discounts for high-tier memberships.
Discounts are more efficient but promote centralization.
Finding the right trade-off remains subject for future work.
#### Accepted tokens
When choosing a token to accept, we consider the following criteria:
- a stablecoin: USD-denominated pricing is simpler for users and for developers (avoiding an oracle);
- popular, high liquidity;
- preferably decentralized;
- with a reasonably good track record w.r.t. censorship.
Based on these criteria, we suggest accepting DAI for the initial deployment.
Other tokens may be added in the future.
#### Grace period and membership extension
On the one hand, memberships must expire,
otherwise a one-time payment would give a user the right to potentially infinite resource usage.
On the other hand, the “soft” expiration suggested above is likely sufficient
while balancing abuse prevention and ease of implementation:
- although extending a membership doesn’t require a new deposit, keeping the original deposit locked up plus paying gas fees imposes cost on membership extension;
- a legitimate user is unlikely to risk their membership being taken over at any moment by not renewing their membership.
## Implementation Suggestions
The current version of the contract (RLNv2) is deployed on Sepolia testnet ([source code](https://github.com/waku-org/waku-rlnv2-contract/blob/main/src/WakuRlnV2.sol)).
## Security / Privacy Considerations
Requesting a Merkle proof for one's own membership through a third-party RPC provider may endanger the requester's privacy.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).