From ad0dc9a81d892864ac2576d74e628ce93da592ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?rich=CE=9Brd?= Date: Sat, 21 Jun 2025 19:11:08 -0400 Subject: [PATCH] chore: remove permit (#27) --- src/Membership.sol | 58 -------------------------------------------- src/WakuRlnV2.sol | 37 ---------------------------- test/WakuRlnV2.t.sol | 42 -------------------------------- 3 files changed, 137 deletions(-) diff --git a/src/Membership.sol b/src/Membership.sol index 0ef6939..7470f93 100644 --- a/src/Membership.sol +++ b/src/Membership.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.24; import { IPriceCalculator } from "./IPriceCalculator.sol"; import { IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; -import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; // The rate limit is outside the expected limits @@ -209,63 +208,6 @@ abstract contract MembershipUpgradeable is Initializable { IERC20(token).safeTransferFrom(_sender, address(this), depositAmount); } - /// @dev acquire a membership and transfer the deposit to the contract - /// Uses the RC20 Permit extension allowing approvals to be made via signatures, as defined in - /// [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612). - /// @param _owner The address of the token owner who is giving permission and will own the membership. - /// @param _deadline The timestamp until when the permit is valid. - /// @param _v The recovery byte of the signature. - /// @param _r Half of the ECDSA signature pair. - /// @param _s Half of the ECDSA signature pair. - /// @param _idCommitment the idCommitment of the new membership - /// @param _rateLimit the membership rate limit - /// @return index the index of the new membership in the membership set - /// @return indexReused true if the index was reused, false otherwise - function _acquireMembershipWithPermit( - address _owner, - uint256 _deadline, - uint8 _v, - bytes32 _r, - bytes32 _s, - uint256 _idCommitment, - uint32 _rateLimit - ) - internal - returns (uint32 index, bool indexReused) - { - // Check if the rate limit is valid - if (!isValidMembershipRateLimit(_rateLimit)) { - revert InvalidMembershipRateLimit(); - } - - currentTotalRateLimit += _rateLimit; - - // Determine if we exceed the total rate limit - if (currentTotalRateLimit > maxTotalRateLimit) { - revert CannotExceedMaxTotalRateLimit(); - } - - (address token, uint256 depositAmount) = priceCalculator.calculate(_rateLimit); - - ERC20Permit(token).permit(_owner, address(this), depositAmount, _deadline, _v, _r, _s); - - // Possibly reuse an index of an erased membership - (index, indexReused) = _getFreeIndex(); - - memberships[_idCommitment] = MembershipInfo({ - holder: _owner, - activeDuration: activeDurationForNewMemberships, - gracePeriodStartTimestamp: block.timestamp + uint256(activeDurationForNewMemberships), - gracePeriodDuration: gracePeriodDurationForNewMemberships, - token: token, - depositAmount: depositAmount, - rateLimit: _rateLimit, - index: index - }); - - IERC20(token).safeTransferFrom(_owner, 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 diff --git a/src/WakuRlnV2.sol b/src/WakuRlnV2.sol index e984de1..802bd67 100644 --- a/src/WakuRlnV2.sol +++ b/src/WakuRlnV2.sol @@ -178,43 +178,6 @@ contract WakuRlnV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable, Member emit MembershipRegistered(idCommitment, rateLimit, index); } - /// @notice Register a membership while erasing some expired memberships to reuse their rate limit. - /// Uses the RC20 Permit extension allowing approvals to be made via signatures, as defined in - /// [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612). - /// @param owner The address of the token owner who is giving permission and will own the membership. - /// @param deadline The timestamp until when the permit is valid. - /// @param v The recovery byte of the signature. - /// @param r Half of the ECDSA signature pair. - /// @param s Half of the ECDSA signature pair. - /// @param idCommitment The idCommitment of the new membership - /// @param rateLimit The rate limit of the new membership - /// @param idCommitmentsToErase The list of idCommitments of expired memberships to erase - function registerWithPermit( - address owner, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s, - uint256 idCommitment, - uint32 rateLimit, - uint256[] calldata idCommitmentsToErase - ) - external - onlyValidIdCommitment(idCommitment) - noDuplicateMembership(idCommitment) - membershipSetNotFull - { - // erase memberships without overwriting membership set data to zero (save gas) - _eraseMemberships(idCommitmentsToErase, false); - - (uint32 index, bool indexReused) = - _acquireMembershipWithPermit(owner, deadline, v, r, s, idCommitment, rateLimit); - - _upsertInTree(idCommitment, rateLimit, index, indexReused); - - emit MembershipRegistered(idCommitment, rateLimit, index); - } - /// @dev Register a membership (internal function) /// @param idCommitment The idCommitment of the membership /// @param rateLimit The rate limit of the membership diff --git a/test/WakuRlnV2.t.sol b/test/WakuRlnV2.t.sol index e372d96..70f6927 100644 --- a/test/WakuRlnV2.t.sol +++ b/test/WakuRlnV2.t.sol @@ -122,48 +122,6 @@ contract WakuRlnV2Test is Test { assertEq(w.currentTotalRateLimit(), membershipRateLimit); } - function test__ValidRegistrationWithPermit() external { - vm.pauseGasMetering(); - uint256 idCommitment = 2; - uint32 membershipRateLimit = w.minMembershipRateLimit(); - (, uint256 price) = w.priceCalculator().calculate(membershipRateLimit); - - // Creating an owner for a membership (Alice) - uint256 alicePrivK = 0xA11CE; - address aliceAddr = vm.addr(alicePrivK); - - // Minting some tokens so Alice can register a membership - token.mint(aliceAddr, price); - - // Prepare the permit parameters - bytes32 permitHash = keccak256( - abi.encode( - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"), - aliceAddr, // Owner of the membership - address(w), // Spender (The rln proxy contract) - price, - token.nonces(aliceAddr), - block.timestamp + 1 hours // Deadline - ) - ); - - // Sign the permit hash using the owner's private key - (uint8 v, bytes32 r, bytes32 s) = - vm.sign(alicePrivK, ECDSA.toTypedDataHash(token.DOMAIN_SEPARATOR(), permitHash)); - - vm.resumeGasMetering(); - - // Call the function on-chain using the generated signature - w.registerWithPermit( - aliceAddr, block.timestamp + 1 hours, v, r, s, idCommitment, membershipRateLimit, noIdCommitmentsToErase - ); - - (,,,, uint32 fetchedMembershipRateLimit,, address holder,) = w.memberships(idCommitment); - assertEq(fetchedMembershipRateLimit, membershipRateLimit); - assertEq(holder, aliceAddr); - assertEq(token.balanceOf(address(w)), price); - } - function test__LinearPriceCalculation(uint32 membershipRateLimit) external view { IPriceCalculator priceCalculator = w.priceCalculator(); uint256 pricePerMessagePerPeriod = LinearPriceCalculator(address(priceCalculator)).pricePerMessagePerEpoch();