## Scope - RLN.sol at commit [2dd6719387620e4693c0ce6daf6c203512b8cfb1](https://github.com/Rate-Limiting-Nullifier/rln-contract/blob/2dd6719387620e4693c0ce6daf6c203512b8cfb1/src/RLN.sol). ## Overview Rate limiting nullifier uses Fiat-Shamir secret sharing and token staking to prevent spamming on a network. A participant should lock a stake with RLN contract which can only be withdrawn or slashed if a secret is known. That secret is split using Fiat-Shamir secret sharing scheme and if a user sends more messages than a limit, any observer can extract the secret and slash the participant. For more details, head to the [documentation](https://rate-limiting-nullifier.github.io/rln-docs/rln.html). ## Issues ### 1. Low - Careful when setting `FEE_RECEIVER` `FEE_RECEIVER` is transferred some tokens during [slashing](https://github.com/Rate-Limiting-Nullifier/rln-contract/blob/2dd6719387620e4693c0ce6daf6c203512b8cfb1/src/RLN.sol#L179C9-L179C53): ```solidity token.safeTransfer(FEE_RECEIVER, feeAmount); ``` If this statement reverts, it becomes impossible to slash. Hence, care should be taken to ensure `FEE_RECEIVER` can always receiver tokens. #### Recommendation Add a `require` statement in constructor to ensure it's not set to `0x0` as some popular ERC20 tokens revert on transfer to `0x0`. Also prepare an advisory for RLN deployers to perform a check that their `FEE_RECEIVER` address can receive tokens (for example, it's not blocked by the token contract). ### 2. Gas - Cache `identityCommitmentIndex` `register()` reads the storage variable 4 times. Since storage reads are expensive, its value can be stored on the stack. #### Recommendation Load `identityCommitmentIndex` in a new `index` variable at the beginning of the function, and replace all further uses with `index`. ### 3. Gas - `DEPTH` not used [`DEPTH`](https://github.com/Rate-Limiting-Nullifier/rln-contract/blob/2dd6719387620e4693c0ce6daf6c203512b8cfb1/src/RLN.sol#L36) variable is not used in the contract. Since it's a public variable, a getter function is created increasing the deploy time gas. #### Recommendation Remove the variable if not required. ### 4. Informational - Document why self-slashing is prohibited [Self-slashing](https://github.com/Rate-Limiting-Nullifier/rln-contract/blob/2dd6719387620e4693c0ce6daf6c203512b8cfb1/src/RLN.sol#L168) is prohibited: ```solidity require(member.userAddress != receiver, "RLN, slash: self-slashing is prohibited"); ``` As clarified by the RLN team, `withdraw()` transaction can be frontrun by an attacker by calling `slash()` and providing `member.userAddress` as `receiver`. To prevent, this attack, it's important to revert when `member.userAddress == receiver`. #### Recommendation Document this attack as the reason to prevent self-slashing.