Skip to content

Conversation

@aimensahnoun
Copy link
Member

@aimensahnoun aimensahnoun commented Jun 16, 2025

🔄 Add ERC20 Recurring Payment Proxy Support

📝 Description

Introduces a new proxy contract and supporting infrastructure for handling recurring ERC20 payments in the Request Network ecosystem.

🔍 Key Changes

  • ✨ New ERC20RecurringPaymentProxy smart contract
  • 🛠️ Payment processor integration with comprehensive test coverage
  • 🔗 CREATE2 deployment configuration

🧪 Testing

  • ✅ Unit tests for all proxy functions
  • ✅ Allowance management
  • ✅ Payment execution flows
  • ✅ Error handling scenarios

🔒 Security Considerations

  • Role-based access control for executors
  • Signature verification for payment schedules
  • Safe ERC20 handling patterns
  • Pausable functionality for emergency scenarios

Summary by CodeRabbit

  • New Features

    • Introduced support for recurring ERC20 token payments with a new smart contract, enabling automated, scheduled transfers with fee and gas management.
    • Added utilities and APIs for interacting with recurring payment schedules, including allowance management, approval encoding, and payment execution, with special handling for USDT tokens.
    • Provided a new interface for defining recurring payment permits.
  • Tests

    • Added comprehensive test suites for the new recurring payment contract and its associated utilities to ensure correct behavior and robust error handling.
  • Chores

    • Updated deployment scripts, verification, and artifacts to support the new recurring payment proxy contract.

@aimensahnoun aimensahnoun self-assigned this Jun 16, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 16, 2025

## Walkthrough

The changes introduce a new recurring payments feature for ERC20 tokens on EVM-compatible blockchains. This includes a new Solidity smart contract (`ERC20RecurringPaymentProxy`), TypeScript contract artifacts, deployment scripts, and comprehensive tests. Corresponding utilities and encoding functions are added to the payment processor package, along with type definitions and unit tests to support and validate recurring payment flows.

## Changes

| File(s)                                                                                                   | Change Summary                                                                                                                                                                                                                                   |
|-----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol`<br>`.../ERC20RecurringPaymentProxy/0.1.0.json`<br>`.../ERC20RecurringPaymentProxy/index.ts`<br>`.../artifacts/index.ts` | New smart contract, ABI artifact, and artifact export for `ERC20RecurringPaymentProxy`, enabling recurring ERC20 payments with schedule permits, signature validation, and role-based access control.                                             |
| `packages/types/src/payment-types.ts`                                                                     | Added `SchedulePermit` interface for recurring payment schedule data.                                                                                                                                                                             |
| `packages/payment-processor/src/payment/erc20-recurring-payment-proxy.ts`                                 | New module with functions for interacting with the recurring payment proxy: allowance retrieval, encoding approvals (including USDT special case), encoding payment triggers, and executing recurring payments on-chain.                         |
| `packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts`                                | New test suite covering recurring payment proxy utility functions, encoding, and execution logic, including USDT allowance handling and error scenarios.                                                                                         |
| `packages/smart-contracts/scripts-create2/compute-one-address.ts`<br>`.../constructor-args.ts`<br>`.../utils.ts`<br>`.../verify.ts` | Added support for `ERC20RecurringPaymentProxy` in CREATE2 deployment scripts, constructor argument generation, artifact retrieval, and verification logic.                                                                                        |
| `packages/smart-contracts/scripts/test-deploy-erc20-recurring-payment-proxy.ts`                           | New deployment script for `ERC20RecurringPaymentProxy` contract.                                                                                                                                                                                  |
| `packages/smart-contracts/scripts/test-deploy-all.ts`                                                     | Added deployment of `ERC20RecurringPaymentProxy` to the main deployment sequence.                                                                                                                          |
| `packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts`                              | New comprehensive test suite for the `ERC20RecurringPaymentProxy` contract, covering deployment, access control, pausing, ownership, and recurring payment execution.                                      |
| `packages/payment-processor/src/index.ts`                                                                 | Exported the new `erc20-recurring-payment-proxy` module to extend the payment processor package API.                                                                                                                                                |
| `packages/smart-contracts/hardhat.config.ts`                                                              | Updated Hardhat verification plugin import and simplified etherscan API key configuration.                                                                                                                                                        |
| `packages/smart-contracts/package.json`                                                                    | Updated `@nomicfoundation/hardhat-verify` version and added `typescript` as a dev dependency.                                                                                                                                                      |
| `packages/smart-contracts/deploy/utils-zk.ts`                                                              | Adjusted type assertion for accessing `verifyURL` in Hardhat network config.                                                                                                                                                                       |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Subscriber
    participant Executor
    participant ERC20RecurringPaymentProxy
    participant ERC20Token
    participant ERC20FeeProxy
    participant Recipient
    participant FeeAddress

    Subscriber->>ERC20Token: Approve allowance to Proxy
    Executor->>ERC20RecurringPaymentProxy: execute(permit, signature, index, ref)
    ERC20RecurringPaymentProxy->>ERC20RecurringPaymentProxy: Validate signature, timing, and order
    ERC20RecurringPaymentProxy->>ERC20Token: transferFrom(subscriber, proxy, amount+fee+relayerFee)
    ERC20RecurringPaymentProxy->>ERC20Token: approve(ERC20FeeProxy, amount+fee)
    ERC20RecurringPaymentProxy->>ERC20FeeProxy: transferFromWithReferenceAndFee(token, recipient, amount, ref, fee, feeAddress)
    ERC20FeeProxy->>Recipient: Transfer amount
    ERC20FeeProxy->>FeeAddress: Transfer fee
    ERC20RecurringPaymentProxy->>Executor: Transfer relayerFee (if any)

Suggested reviewers

  • alexandre-abrioux
  • kevindavee
  • leoslr
  • MantisClone
  • sstefdev

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=RequestNetwork/requestNetwork&utm_content=1633):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

…port both object and string formats for compatibility
…data for ERC20 approval with multiple methods
…allowance and executing recurring payments with detailed error handling
…curring payment functions including allowance retrieval, approval encoding, and execution
@aimensahnoun aimensahnoun marked this pull request as ready for review June 20, 2025 12:52
@aimensahnoun aimensahnoun requested review from MantisClone and removed request for alexandre-abrioux and leoslr June 20, 2025 12:53
@aimensahnoun aimensahnoun linked an issue Jun 20, 2025 that may be closed by this pull request
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (1)

82-82: Consider adding deadline expiry test.

The permit includes a deadline field, but there's no test verifying that expired permits are rejected. Consider adding a test case where the deadline has passed to ensure the contract properly validates permit expiry.

Add a test case like:

it('should revert when permit deadline has expired', async () => {
  const permit = createSchedulePermit({
    deadline: Math.floor(Date.now() / 1000) - 3600, // 1 hour ago
  });
  const signature = await createSignature(permit, subscriber);

  await expect(
    erc20RecurringPaymentProxy
      .connect(relayer)
      .triggerRecurringPayment(permit, signature, 1, paymentReference),
  ).to.be.revertedWith('ERC20RecurringPaymentProxy__DeadlineExpired');
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 098c985 and 6b390ae.

📒 Files selected for processing (1)
  • packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (18)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts:14-32
Timestamp: 2024-10-28T20:00:25.780Z
Learning: In test files, such as `packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts`, extensive error handling and input validation are considered unnecessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts:19-27
Timestamp: 2024-11-04T12:18:13.888Z
Learning: In the file `packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts`, when using `payPrivateErc20FeeProxyRequest`, the returned `tx` is a `RelayerTransaction`, so calling `.wait()` on it is unnecessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts:4-7
Timestamp: 2024-10-28T20:00:33.707Z
Learning: In TypeScript test files (e.g., `test-deploy-single-request-proxy.ts`), it's acceptable to use `string` types for Ethereum addresses in interfaces (like `FeeProxyAddresses`), as stricter type safety is not necessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:138-139
Timestamp: 2024-10-29T08:02:02.600Z
Learning: When testing invalid requests in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to use `@ts-expect-error` to suppress TypeScript errors when the request intentionally lacks required properties.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/prepared-transaction.ts:15-16
Timestamp: 2024-11-04T14:31:29.664Z
Learning: In `packages/payment-processor/src/payment/prepared-transaction.ts`, for the `IPreparedPrivateTransaction` interface, use `string[]` for the `ops` field since Hinkal's relevant functions accept arrays of `string` as inputs.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:198-206
Timestamp: 2024-11-08T18:24:19.095Z
Learning: In tests for `SingleRequestProxyFactory`, the `feeProxyUsed` in events should be verified by retrieving the `ethereumFeeProxy` public variable from the `SingleRequestProxyFactory` contract, not `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts:23-32
Timestamp: 2024-11-04T20:55:51.395Z
Learning: In `packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts`, the team has decided not to implement a delay or graceful shutdown handling after `process.exit(0)`, as they consider it unnecessary.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test
🔇 Additional comments (10)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (10)

1-31: Test setup looks good!

The imports, variable declarations, and role constant definition are properly structured. Good practice defining the RELAYER_ROLE constant to match the contract's role identifier.


32-65: Comprehensive test setup!

The beforeEach block properly initializes all test accounts, deploys contracts in the correct order, and sets up the testing environment. Good practice deploying a test token with sufficient balance for various test scenarios.


67-86: Well-designed permit helper function!

The createSchedulePermit helper provides sensible defaults and flexible overrides. Good use of BigNumber for numeric fields and current timestamp calculations.


88-143: Robust EIP712 signature implementation!

Excellent handling of different provider behaviors with the try-catch fallback pattern. The type definitions correctly match the SchedulePermit structure, and the domain separator is properly configured.


145-185: Thorough deployment and access control verification!

Excellent coverage of initial state verification including contract addresses, role assignments, and default pausable state. Good practice verifying role constants match expected values.


187-232: Comprehensive admin function testing!

Good coverage of setRelayer and setFeeProxy functions including access control, event emissions, and input validation. The zero address check for fee proxy is an important security test.


234-275: Excellent pausable functionality tests!

Complete coverage of pause/unpause operations including access control and event verification. Good practice testing both the state changes and emitted events.


277-310: Complete ownership functionality coverage!

Thorough testing of ownership transfer and renouncement including access control and event emissions. Good practice verifying the zero address is set after renouncing ownership.


312-424: Excellent core payment functionality tests!

Comprehensive coverage including:

  • Access control verification with proper error message format
  • Signature validation
  • Correct balance calculations (subscriber pays 115 = 100 amount + 10 fee + 5 relayer fee)
  • Proper event verification
  • State checks (paused, timing, duplicates)

The test setup with token transfers and approvals is well structured.


426-525: Thorough edge case and error condition testing!

Excellent coverage of:

  • Sequential payment execution with proper time advancement between payments
  • Zero fee scenarios (both relayer and protocol fees)
  • Insufficient balance/allowance error conditions

The time manipulation using evm_increaseTime and evm_mine is the correct approach for testing time-based constraints.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

♻️ Duplicate comments (2)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (2)

63-82: Field name inconsistencies remain in helper function.

The createSchedulePermit helper function still uses inconsistent field names that don't match the EIP712 signature structure:

  1. Line 73: Uses executorFee but should be relayerFee (as seen in EIP712 types on line 101)
  2. Line 75: Uses firstExec but should be firstPayment (as seen in EIP712 types on line 103)
  3. Line 76: Uses totalExecutions but should be totalPayments (as seen in EIP712 types on line 104)

Apply this diff to fix the field name inconsistencies:

 const createSchedulePermit = (overrides: any = {}) => {
   const now = Math.floor(Date.now() / 1000);
   return {
     subscriber: subscriberAddress,
     token: testERC20.address,
     recipient: recipientAddress,
     feeAddress: feeAddressString,
     amount: 100,
     feeAmount: 10,
-    executorFee: 5,
+    relayerFee: 5,
     periodSeconds: 3600,
-    firstExec: now,
-    totalExecutions: 3,
+    firstPayment: now,
+    totalPayments: 3,
     nonce: 0,
     deadline: now + 86400, // 24 hours from now
     strictOrder: false,
     ...overrides,
   };
 };

515-515: Use consistent field name in test override.

The test uses totalExecutions but should use totalPayments to match the corrected helper function.

Apply this diff:

-const permit = createSchedulePermit({ totalExecutions: 3, periodSeconds: 1 });
+const permit = createSchedulePermit({ totalPayments: 3, periodSeconds: 1 });
🧹 Nitpick comments (1)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (1)

372-372: Update test description to match implementation.

The test description mentions "non-executor" but the contract uses relayer role terminology.

Apply this diff:

-it('should revert when called by non-executor', async () => {
+it('should revert when called by non-relayer', async () => {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef71174 and 7efe903.

📒 Files selected for processing (1)
  • packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (19)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts:14-32
Timestamp: 2024-10-28T20:00:25.780Z
Learning: In test files, such as `packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts`, extensive error handling and input validation are considered unnecessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts:19-27
Timestamp: 2024-11-04T12:18:13.888Z
Learning: In the file `packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts`, when using `payPrivateErc20FeeProxyRequest`, the returned `tx` is a `RelayerTransaction`, so calling `.wait()` on it is unnecessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts:4-7
Timestamp: 2024-10-28T20:00:33.707Z
Learning: In TypeScript test files (e.g., `test-deploy-single-request-proxy.ts`), it's acceptable to use `string` types for Ethereum addresses in interfaces (like `FeeProxyAddresses`), as stricter type safety is not necessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:138-139
Timestamp: 2024-10-29T08:02:02.600Z
Learning: When testing invalid requests in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to use `@ts-expect-error` to suppress TypeScript errors when the request intentionally lacks required properties.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/prepared-transaction.ts:15-16
Timestamp: 2024-11-04T14:31:29.664Z
Learning: In `packages/payment-processor/src/payment/prepared-transaction.ts`, for the `IPreparedPrivateTransaction` interface, use `string[]` for the `ops` field since Hinkal's relevant functions accept arrays of `string` as inputs.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:198-206
Timestamp: 2024-11-08T18:24:19.095Z
Learning: In tests for `SingleRequestProxyFactory`, the `feeProxyUsed` in events should be verified by retrieving the `ethereumFeeProxy` public variable from the `SingleRequestProxyFactory` contract, not `wallet.address`.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts:23-32
Timestamp: 2024-11-04T20:55:51.395Z
Learning: In `packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts`, the team has decided not to implement a delay or graceful shutdown handling after `process.exit(0)`, as they consider it unnecessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1478
File: packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts:45-58
Timestamp: 2024-11-05T05:04:01.710Z
Learning: When executing blockchain transactions in scripts (e.g., in `packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts`), ensure that transactions are executed serially rather than in parallel to maintain correct execution order and prevent potential issues.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test
🔇 Additional comments (2)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (2)

347-369: Excellent test coverage for balance verification.

The test correctly verifies all balance changes including subscriber deduction (amount + fee + relayer fee), recipient credit (amount), fee address credit (fee), and relayer credit (relayer fee). The balance calculations are accurate.


514-563: Comprehensive sequential execution test.

This test effectively validates the sequential execution of multiple payments with proper time advancement and duplicate execution prevention. The verification approach using failed re-execution attempts is a clever way to test the internal bitmap state.

…o relayer for consistency and clarity in tests
…t and update related test descriptions for clarity
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/smart-contracts/src/lib/artifacts/ERC20RecurringPaymentProxy/0.1.0.json (2)

213-218: setRelayer() API could be simplified – consider dropping the oldRelayer param

Having both oldRelayer and newRelayer in the setter forces callers to supply a value that the contract can already read from storage, adding gas and widening the surface for mistaken inputs (e.g., passing an outdated oldRelayer). Unless this redundancy is used for an extra safety check in the Solidity implementation, a single-argument setter (newRelayer) plus an emit RelayerChanged(old, new) event would be leaner and less error-prone.


20-25: InvalidShortString / StringTooLong errors increase byte-code, are they used?

The ABI exposes string-length helpers that come from OpenZeppelin’s ShortStrings library. If the contract never manipulates arbitrary-length strings (aside from the EIP-712 name/version constants), these custom errors occupy byte-code and ABI space needlessly. Double-check whether they are referenced in the Solidity code; if not, consider removing the library to slim deployment size.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 55f9e8b and cd19cae.

📒 Files selected for processing (2)
  • packages/payment-processor/src/index.ts (1 hunks)
  • packages/smart-contracts/src/lib/artifacts/ERC20RecurringPaymentProxy/0.1.0.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/payment-processor/src/index.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/smart-contracts/src/lib/artifacts/ERC20RecurringPaymentProxy/0.1.0.json (13)
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:11-15
Timestamp: 2024-10-05T14:43:14.816Z
Learning: In the `EthereumSingleRequestProxy` contract, the state variables `payee`, `paymentReference`, `feeAddress`, `feeAmount`, and `ethereumFeeProxy` should remain public, as they need to be accessed externally.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/smart-contracts/src/lib/artifacts/SingleRequestProxyFactory/index.ts:5-5
Timestamp: 2024-11-12T16:52:41.557Z
Learning: When the smart contracts are not being modified, types like `SingleRequestProxyFactory` in `packages/smart-contracts/src/lib/artifacts/SingleRequestProxyFactory/index.ts` should remain unchanged, even if terminology elsewhere in the code is updated.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:36-56
Timestamp: 2024-10-05T14:43:15.124Z
Learning: In the `ERC20SingleRequestProxy` contract (`packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`), the `receive()` function is intentionally used to trigger logic when the smart contract receives a 0 ETH transfer, as per the design. Replacing it with a named function is not appropriate in this context.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/SingleRequestProxyFactory.sol:22-27
Timestamp: 2024-10-15T07:50:58.094Z
Learning: In the `SingleRequestProxyFactory` contract, the `paymentReference` parameter in events should remain `indexed`, even if removing `indexed` could reduce gas costs.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:156-160
Timestamp: 2024-10-28T15:52:05.032Z
Learning: In the `payRequestWithSingleRequestProxy` function of `single-request-proxy.ts`, failing to retrieve `tokenAddress()` is expected for `EthereumSingleRequestProxy` contracts and is not an error.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test
🔇 Additional comments (1)
packages/smart-contracts/src/lib/artifacts/ERC20RecurringPaymentProxy/0.1.0.json (1)

151-156: lastPaymentIndex return type limits schedules to 255 payments

lastPaymentIndex(bytes32) → uint8 caps the trackable index to 255. Given that totalPayments in the SchedulePermit struct is also uint8, this is consistent, but it leaves zero head-room for future versions needing longer schedules. Confirm that this intentional hard limit is acceptable for all foreseeable use-cases.

…ngPayment from TransactionReceipt to TransactionResponse for accuracy
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd19cae and c5b0e1a.

📒 Files selected for processing (1)
  • packages/payment-processor/src/payment/erc20-recurring-payment-proxy.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/payment-processor/src/payment/erc20-recurring-payment-proxy.ts (23)
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:156-160
Timestamp: 2024-10-28T15:52:05.032Z
Learning: In the `payRequestWithSingleRequestProxy` function of `single-request-proxy.ts`, failing to retrieve `tokenAddress()` is expected for `EthereumSingleRequestProxy` contracts and is not an error.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:123-184
Timestamp: 2024-10-28T21:11:48.524Z
Learning: When suggesting error handling improvements in `packages/payment-processor/src/payment/single-request-proxy.ts`, avoid recommending try-catch blocks that re-throw errors without additional processing.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:138-139
Timestamp: 2024-10-29T08:02:02.600Z
Learning: When testing invalid requests in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to use `@ts-expect-error` to suppress TypeScript errors when the request intentionally lacks required properties.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc-20-private-payment-hinkal.ts:80-99
Timestamp: 2024-12-09T18:59:04.613Z
Learning: In the `RequestNetwork` codebase, payment processor functions such as `payErc20ProxyRequestFromHinkalShieldedAddress` in `packages/payment-processor/src/payment/erc-20-private-payment-hinkal.ts` should not include explicit request validation or try/catch blocks, and should rely on the underlying components (like `hinkalObject`) to handle error reporting.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/prepare-hinkal.ts:5-13
Timestamp: 2024-11-04T20:53:41.522Z
Learning: When reviewing the RequestNetwork codebase, avoid suggesting the addition of example usage in documentation if it would make the comments overly verbose, especially for functions like `prepareHinkal` in `packages/payment-processor/src/payment/prepare-hinkal.ts`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/src/payment/single-request-proxy.ts:0-0
Timestamp: 2024-11-08T20:01:10.313Z
Learning: In `packages/payment-processor/src/payment/single-request-proxy.ts`, when decoding event data, the team prefers not to include documentation of the event data structure if maintaining it would be difficult.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:156-160
Timestamp: 2024-10-28T15:52:05.032Z
Learning: When determining if a `SingleRequestProxy` is an `ERC20SingleRequestProxy` or an `EthereumSingleRequestProxy`, include a comment explaining that the presence of `tokenAddress` distinguishes between the two.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:225-228
Timestamp: 2024-10-29T08:03:10.463Z
Learning: In 'packages/payment-processor/test/payment/single-request-proxy.test.ts' (TypeScript), when testing with an invalid proxy address, we should not use the zero address.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/prepare-hinkal.ts:20-20
Timestamp: 2024-11-04T20:54:11.202Z
Learning: In `packages/payment-processor/src/payment/prepare-hinkal.ts`, when passing `undefined` parameters to functions like `initProviderAdapter`, it's acceptable not to add comments explaining the `undefined` parameter to avoid overly verbose code.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/src/payment/single-request-proxy.ts:0-0
Timestamp: 2024-11-08T20:01:10.313Z
Learning: In `packages/payment-processor/src/payment/single-request-proxy.ts`, the team prefers not to store or validate decoded values that are not needed.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1478
File: packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts:30-36
Timestamp: 2024-11-05T05:33:36.551Z
Learning: In the RequestNetwork project, admin scripts like `setupSingleRequestProxyFactory.ts` in `packages/smart-contracts/scripts-create2/contract-setup/` do not require extensive error checking.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1478
File: packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts:26-28
Timestamp: 2024-11-05T05:33:36.189Z
Learning: In the `requestNetwork` project's TypeScript setup scripts located in `packages/smart-contracts/scripts-create2/contract-setup`, `Promise.all` is used for asynchronous network setup tasks to maintain consistency across scripts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1478
File: packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts:38-43
Timestamp: 2024-11-05T05:33:32.481Z
Learning: In the RequestNetwork codebase, setup scripts such as `setupSingleRequestProxyFactory.ts` do not include contract existence checks before interacting with contracts, even though scripts like `check-deployer.ts` do include such checks.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test
🔇 Additional comments (5)
packages/payment-processor/src/payment/erc20-recurring-payment-proxy.ts (5)

1-5: LGTM!

The imports are well-organized and properly reference the required dependencies from the smart-contracts package and types.


22-47: LGTM!

The function correctly delegates to the existing getErc20Allowance utility, maintaining consistency with the codebase. The error handling and address validation are appropriate.


66-104: LGTM!

The function correctly implements the USDT special case by first calling approve(0) before approve(amount). This follows the established pattern for handling USDT's non-standard ERC20 behavior.


124-147: LGTM!

The function correctly encodes the transaction data for triggering recurring payments. The parameter handling and interface usage are appropriate.


219-227: LGTM!

The helper function correctly retrieves the proxy address with appropriate error handling. The implementation is clean and follows the established pattern.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (1)

200-212: Strengthen the test assertion for encoded trigger data validation.

The test only verifies that the encoded data starts with '0x', but should validate the actual method signature to ensure the correct function is being encoded.

Apply this diff to improve the test validation:

     const encodedData = encodeRecurringPaymentTrigger({
       permitTuple: schedulePermit,
       permitSignature,
       paymentIndex: 1,
       paymentReference,
       network,
       provider,
     });

     // Verify it's a valid hex string
     expect(encodedData.startsWith('0x')).toBe(true);
+    
+    // Verify it contains the triggerRecurringPayment method signature (first 4 bytes)
+    expect(encodedData.length).toBeGreaterThan(10);
+    expect(encodedData.slice(0, 10)).toMatch(/^0x[a-f0-9]{8}$/);
🧹 Nitpick comments (1)
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (1)

82-103: Improve error handling in signature creation helper.

The fallback mechanism catches all errors but doesn't provide meaningful error messages for debugging test failures.

Consider enhancing error handling to provide better debugging information:

   try {
     return await (signer.provider as any).send('eth_signTypedData', [
       await signer.getAddress(),
       {
         types: {
           EIP712Domain: [
             { name: 'name', type: 'string' },
             { name: 'version', type: 'string' },
             { name: 'chainId', type: 'uint256' },
             { name: 'verifyingContract', type: 'address' },
           ],
           ...types,
         },
         primaryType: 'SchedulePermit',
         domain,
         message,
       },
     ]);
-  } catch (_) {
+  } catch (error) {
     // Fallback to ethers helper (works in most in-process Hardhat environments)
+    console.warn('eth_signTypedData failed, falling back to _signTypedData:', error);
     return await (signer as any)._signTypedData(domain, types, message);
   }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fa1f5c and 69a41b0.

📒 Files selected for processing (1)
  • packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (17)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:138-139
Timestamp: 2024-10-29T08:02:02.600Z
Learning: When testing invalid requests in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to use `@ts-expect-error` to suppress TypeScript errors when the request intentionally lacks required properties.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:0-0
Timestamp: 2024-12-04T05:05:19.610Z
Learning: The function `createRequestForHinkal` in `erc-20-private-payment-hinkal.test.ts` is intended for testing purposes only and should remain in the test directory.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1484
File: packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts:0-0
Timestamp: 2024-11-06T14:48:18.698Z
Learning: In `packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts`, when the existing happy path tests are deemed sufficient, additional test cases may not be necessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: rodrigopavezi
PR: RequestNetwork/requestNetwork#1475
File: packages/transaction-manager/test/unit/utils/test-data.ts:87-119
Timestamp: 2024-11-21T09:06:12.938Z
Learning: In `packages/transaction-manager/test/unit/utils/test-data.ts`, mocks like `fakeEpkCipherProvider` do not require extensive test coverage for input validation and error handling.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: rodrigopavezi
PR: RequestNetwork/requestNetwork#1475
File: packages/transaction-manager/test/unit/utils/test-data.ts:0-0
Timestamp: 2024-11-22T13:13:26.166Z
Learning: In `packages/transaction-manager/test/unit/utils/test-data.ts`, the `FakeLitProtocolProvider` class uses `{}` as the return type for its methods `encrypt` and `decrypt`. Changing the return type to a more specific interface caused issues, so the current return type `{}` should remain as is.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:225-228
Timestamp: 2024-10-29T08:03:10.463Z
Learning: In 'packages/payment-processor/test/payment/single-request-proxy.test.ts' (TypeScript), when testing with an invalid proxy address, we should not use the zero address.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc-20-private-payment-hinkal.ts:80-99
Timestamp: 2024-12-09T18:59:04.613Z
Learning: In the `RequestNetwork` codebase, payment processor functions such as `payErc20ProxyRequestFromHinkalShieldedAddress` in `packages/payment-processor/src/payment/erc-20-private-payment-hinkal.ts` should not include explicit request validation or try/catch blocks, and should rely on the underlying components (like `hinkalObject`) to handle error reporting.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:123-184
Timestamp: 2024-10-28T21:11:48.524Z
Learning: When suggesting error handling improvements in `packages/payment-processor/src/payment/single-request-proxy.ts`, avoid recommending try-catch blocks that re-throw errors without additional processing.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:156-160
Timestamp: 2024-10-28T15:52:05.032Z
Learning: In the `payRequestWithSingleRequestProxy` function of `single-request-proxy.ts`, failing to retrieve `tokenAddress()` is expected for `EthereumSingleRequestProxy` contracts and is not an error.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test
🔇 Additional comments (2)
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (2)

1-15: LGTM! Test setup is well-configured.

The imports, provider setup, and test data configuration are appropriate for testing the ERC20 recurring payment proxy functionality.


111-190: LGTM! Comprehensive test coverage for allowance encoding.

The test suite properly covers:

  • Standard ERC20 token approval (single transaction)
  • USDT special case (two-step approval process)
  • Default behavior validation
  • Error handling when proxy contract is not found

The assertions correctly validate transaction data including method signatures and parameter encoding.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (2)

210-212: Strengthen test validation for encoded trigger data.

The current test only validates that the encoded data starts with '0x', but should verify the actual method signature and structure.

  // Verify it's a valid hex string
  expect(encodedData.startsWith('0x')).toBe(true);
+ // Verify it has reasonable length for encoded function call
+ expect(encodedData.length).toBeGreaterThan(200); // Should contain function selector + parameters
+ // Verify it contains a valid function selector (first 4 bytes)
+ expect(encodedData.slice(0, 10)).toMatch(/^0x[a-f0-9]{8}$/);

233-279: Remove duplicate test suite to improve maintainability.

This test suite duplicates functionality already covered in the main test suite, creating unnecessary maintenance overhead.

-describe('ERC20 Recurring Payment', () => {
-  const permit: PaymentTypes.SchedulePermit = {
-    // ... entire duplicate test suite
-  };
-
-  it('should encode recurring payment trigger', async () => {
-    // ... test implementation
-  });
-
-  it.skip('should trigger recurring payment', async () => {
-    // ... test implementation
-  });
-});
🧹 Nitpick comments (2)
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (2)

77-77: Simplify nonce handling in EIP-712 message preparation.

The conditional string conversion for nonce is unnecessary since the permit nonce is already consistently typed.

-    nonce: typeof permit.nonce === 'string' ? permit.nonce : permit.nonce.toString(),
+    nonce: permit.nonce.toString(),

82-103: Consider more specific error handling for signature creation.

The broad catch block may hide important errors during signature creation. Consider logging or handling specific signature failures.

  try {
    return await (signer.provider as any).send('eth_signTypedData', [
      await signer.getAddress(),
      // ... existing code
    ]);
-  } catch (_) {
+  } catch (error) {
    // Fallback to ethers helper (works in most in-process Hardhat environments)
+    console.warn('eth_signTypedData failed, falling back to _signTypedData:', error);
    return await (signer as any)._signTypedData(domain, types, message);
  }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc87fd2 and 9c3dfa6.

📒 Files selected for processing (1)
  • packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/payment-processor/test/payment/erc-20-recurring-payment.test.ts (16)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:138-139
Timestamp: 2024-10-29T08:02:02.600Z
Learning: When testing invalid requests in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to use `@ts-expect-error` to suppress TypeScript errors when the request intentionally lacks required properties.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:0-0
Timestamp: 2024-12-04T05:05:19.610Z
Learning: The function `createRequestForHinkal` in `erc-20-private-payment-hinkal.test.ts` is intended for testing purposes only and should remain in the test directory.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1484
File: packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts:0-0
Timestamp: 2024-11-06T14:48:18.698Z
Learning: In `packages/advanced-logic/test/extensions/payment-network/any-to-near.test.ts`, when the existing happy path tests are deemed sufficient, additional test cases may not be necessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: rodrigopavezi
PR: RequestNetwork/requestNetwork#1475
File: packages/transaction-manager/test/unit/utils/test-data.ts:0-0
Timestamp: 2024-11-22T13:13:26.166Z
Learning: In `packages/transaction-manager/test/unit/utils/test-data.ts`, the `FakeLitProtocolProvider` class uses `{}` as the return type for its methods `encrypt` and `decrypt`. Changing the return type to a more specific interface caused issues, so the current return type `{}` should remain as is.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:225-228
Timestamp: 2024-10-29T08:03:10.463Z
Learning: In 'packages/payment-processor/test/payment/single-request-proxy.test.ts' (TypeScript), when testing with an invalid proxy address, we should not use the zero address.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc-20-private-payment-hinkal.ts:80-99
Timestamp: 2024-12-09T18:59:04.613Z
Learning: In the `RequestNetwork` codebase, payment processor functions such as `payErc20ProxyRequestFromHinkalShieldedAddress` in `packages/payment-processor/src/payment/erc-20-private-payment-hinkal.ts` should not include explicit request validation or try/catch blocks, and should rely on the underlying components (like `hinkalObject`) to handle error reporting.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:123-184
Timestamp: 2024-10-28T21:11:48.524Z
Learning: When suggesting error handling improvements in `packages/payment-processor/src/payment/single-request-proxy.ts`, avoid recommending try-catch blocks that re-throw errors without additional processing.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:156-160
Timestamp: 2024-10-28T15:52:05.032Z
Learning: In the `payRequestWithSingleRequestProxy` function of `single-request-proxy.ts`, failing to retrieve `tokenAddress()` is expected for `EthereumSingleRequestProxy` contracts and is not an error.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test

…rringPayment to reflect immediate transaction response and clarify confirmation process
…st with updated triggerRecurringPayment call
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (1)

330-372: Update balance check comment for clarity.

The balance calculation is correct (115 = 100 + 10 + 5), but the comment incorrectly mentions "gas" fees. ERC20 transfers don't deduct gas from token balances.

-      expect(subscriberBalanceAfter).to.equal(subscriberBalanceBefore.sub(115)); // amount + fee + gas
+      expect(subscriberBalanceAfter).to.equal(subscriberBalanceBefore.sub(115)); // amount + feeAmount + relayerFee
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0a8eb3a and 0bea365.

📒 Files selected for processing (1)
  • packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:19-23
Timestamp: 2024-10-05T14:43:07.965Z
Learning: In the `EthereumSingleRequestProxy` contract, a custom reentrancy guard is used instead of OpenZeppelin's `ReentrancyGuard`, with minor edits to allow reentrancy by the `ethereumFeeProxy`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:77-78
Timestamp: 2024-10-15T07:50:54.734Z
Learning: In the `receive()` function of the `EthereumSingleRequestProxy` contract (`packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol`), the current error handling for the call to `ethereumFeeProxy` is considered sufficient, and no additional error handling is required.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (24)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts:150-152
Timestamp: 2024-10-17T18:30:55.410Z
Learning: In `packages/smart-contracts/test/contracts/ERC20SingleRequestProxy.test.ts`, the skipped test `'should process a partial payment correctly'` exists intentionally to show that partial payments are supported without duplicating previous happy-path tests.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1481
File: packages/integration-test/test/scheduled/erc20-proxy.test.ts:0-0
Timestamp: 2024-11-05T16:53:05.280Z
Learning: In `packages/integration-test/test/scheduled/erc20-proxy.test.ts`, when upgrading dependencies like `ethers`, additional error handling test cases for contract interactions and provider errors may not be necessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:251-270
Timestamp: 2024-10-28T16:03:33.215Z
Learning: When testing the payment-processor module, specifically in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to omit tests for partial payments if they have already been covered at the smart-contract level.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:237-246
Timestamp: 2024-11-08T18:24:06.144Z
Learning: In `packages/payment-processor/test/payment/single-request-proxy.test.ts`, when asserting the `feeProxyUsed` in emitted events from `SingleRequestProxyFactory`, retrieve the `erc20FeeProxy` (or `ethereumFeeProxy`) public variable from the `SingleRequestProxyFactory` contract instead of using `wallet.address`.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts:14-32
Timestamp: 2024-10-28T20:00:25.780Z
Learning: In test files, such as `packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts`, extensive error handling and input validation are considered unnecessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1633
File: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol:92-133
Timestamp: 2025-06-23T09:35:04.263Z
Learning: In the ERC20RecurringPaymentProxy contract, events were intentionally omitted to save gas costs since the underlying ERC20FeeProxy contract already emits events when payments are processed. This avoids duplicate event emissions while maintaining observability.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts:38-38
Timestamp: 2024-12-18T03:53:54.370Z
Learning: In `packages/payment-processor/test/payment/erc-20-private-payment-hinkal.test.ts`, mainnet RPC is intentionally used for real on-chain tests as confirmed by MantisClone.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts:19-27
Timestamp: 2024-11-04T12:18:13.888Z
Learning: In the file `packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts`, when using `payPrivateErc20FeeProxyRequest`, the returned `tx` is a `RelayerTransaction`, so calling `.wait()` on it is unnecessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:202-209
Timestamp: 2024-10-29T09:00:54.169Z
Learning: In the `packages/payment-processor/src/payment/single-request-proxy.ts` file, within the `payWithEthereumSingleRequestProxy` function, the current error handling is acceptable as per the project's expectations.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1474
File: packages/smart-contracts/scripts/test-deploy-single-request-proxy.ts:4-7
Timestamp: 2024-10-28T20:00:33.707Z
Learning: In TypeScript test files (e.g., `test-deploy-single-request-proxy.ts`), it's acceptable to use `string` types for Ethereum addresses in interfaces (like `FeeProxyAddresses`), as stricter type safety is not necessary.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:104-104
Timestamp: 2024-11-12T16:54:02.702Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, when the smart contract has not changed, event argument names such as `proxyAddress` remain the same, even if variable names in the code are updated to use new terminology like `forwarderAddress`.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/payment-processor/src/payment/erc20-fee-proxy.ts:186-186
Timestamp: 2024-11-04T14:32:57.040Z
Learning: In the `preparePrivateErc20FeeProxyPaymentTransaction` function in `packages/payment-processor/src/payment/erc20-fee-proxy.ts`, we should not make an allowance call on the token contract, as it is not relevant to our use case.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/payment-processor/src/payment/single-request-forwarder.ts:211-219
Timestamp: 2024-11-12T17:48:47.072Z
Learning: In `packages/payment-processor/src/payment/single-request-forwarder.ts`, the error handling logic in `payWithEthereumSingleRequestForwarder` is correct and does not require changes to differentiate between ERC20 and Ethereum SingleRequestForwarder contracts.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:138-139
Timestamp: 2024-10-29T08:02:02.600Z
Learning: When testing invalid requests in `packages/payment-processor/test/payment/single-request-proxy.test.ts`, it's acceptable to use `@ts-expect-error` to suppress TypeScript errors when the request intentionally lacks required properties.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1487
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:198-206
Timestamp: 2024-11-08T18:24:19.095Z
Learning: In tests for `SingleRequestProxyFactory`, the `feeProxyUsed` in events should be verified by retrieving the `ethereumFeeProxy` public variable from the `SingleRequestProxyFactory` contract, not `wallet.address`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1488
File: packages/smart-contracts/src/lib/artifacts/SingleRequestProxyFactory/index.ts:5-5
Timestamp: 2024-11-12T16:52:41.557Z
Learning: When the smart contracts are not being modified, types like `SingleRequestProxyFactory` in `packages/smart-contracts/src/lib/artifacts/SingleRequestProxyFactory/index.ts` should remain unchanged, even if terminology elsewhere in the code is updated.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1478
File: packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts:45-58
Timestamp: 2024-11-05T05:04:01.710Z
Learning: When executing blockchain transactions in scripts (e.g., in `packages/smart-contracts/scripts-create2/contract-setup/setupSingleRequestProxyFactory.ts`), ensure that transactions are executed serially rather than in parallel to maintain correct execution order and prevent potential issues.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/EthereumSingleRequestProxy.sol:11-15
Timestamp: 2024-10-05T14:43:14.816Z
Learning: In the `EthereumSingleRequestProxy` contract, the state variables `payee`, `paymentReference`, `feeAddress`, `feeAmount`, and `ethereumFeeProxy` should remain public, as they need to be accessed externally.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/SingleRequestProxyFactory.sol:0-0
Timestamp: 2024-09-27T11:42:01.062Z
Learning: In the `createEthereumSingleRequestProxy` function, it's acceptable for `_feeAddress` to be the zero address, as setting the fee address to zero is a common practice. Adding zero address checks is unnecessary and adds extra gas cost.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol:46-46
Timestamp: 2024-10-05T14:43:16.298Z
Learning: In `packages/smart-contracts/src/contracts/ERC20SingleRequestProxy.sol`, within the `receive()` function, it's acceptable to approve the entire `balance` to `erc20FeeProxy` because `balance == paymentAmount + feeAmount`.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/test/payment/single-request-proxy.test.ts:225-228
Timestamp: 2024-10-29T08:03:10.463Z
Learning: In 'packages/payment-processor/test/payment/single-request-proxy.test.ts' (TypeScript), when testing with an invalid proxy address, we should not use the zero address.
Learnt from: aimensahnoun
PR: RequestNetwork/requestNetwork#1474
File: packages/payment-processor/src/payment/single-request-proxy.ts:123-184
Timestamp: 2024-10-28T21:11:48.524Z
Learning: When suggesting error handling improvements in `packages/payment-processor/src/payment/single-request-proxy.ts`, avoid recommending try-catch blocks that re-throw errors without additional processing.
Learnt from: giorgi-kiknavelidze
PR: RequestNetwork/requestNetwork#1482
File: packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts:23-32
Timestamp: 2024-11-04T20:55:51.395Z
Learning: In `packages/usage-examples/src/hinkal/testPayErc20FeeProxyRequestHinkal.ts`, the team has decided not to implement a delay or graceful shutdown handling after `process.exit(0)`, as they consider it unnecessary.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1453
File: packages/smart-contracts/test/contracts/EthereumSingleRequestProxy.test.ts:0-0
Timestamp: 2024-10-17T18:33:41.124Z
Learning: In the `EthereumSingleRequestProxy` contract, the custom reentrancy guard is nearly identical to OpenZeppelin's ReentrancyGuard, except that it allows the first reentrancy call from the `ERC20FeeProxy`. We assume it works correctly without needing further tests.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-and-test
🔇 Additional comments (14)
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts (14)

1-61: LGTM: Well-structured test setup.

The test file setup follows best practices with comprehensive fixture setup, proper contract deployments, and clear variable naming conventions.


64-82: LGTM: Helper function properly structured.

The createSchedulePermit helper function correctly uses the updated field names (relayerFee, totalPayments, firstPayment) that align with the contract's expected structure.


85-139: LGTM: Robust signature creation with proper fallback handling.

The EIP712 signature helper handles different provider types (Hardhat in-process vs JSON-RPC/Ganache) correctly with appropriate fallback logic.


141-163: LGTM: Comprehensive deployment validation.

The deployment tests properly verify initial contract state including address assignment, role grants, and pause status.


165-193: LGTM: Thorough access control testing.

Role constant validation and role assignment checks are properly implemented using the correct RELAYER_ROLE naming.


195-226: LGTM: Complete relayer management testing.

Tests cover role transitions, access control, and proper event emissions for relayer updates.


228-250: LGTM: Proper fee proxy management validation.

Tests correctly validate owner-only access and zero address protection for fee proxy updates.


252-293: LGTM: Comprehensive pausable functionality testing.

All pausable contract aspects are properly tested including access control and event emissions.


295-328: LGTM: Complete ownership management testing.

Ownership transfer and renouncement functionality is thoroughly tested with proper access control validation.


374-436: LGTM: Comprehensive error scenario testing.

Tests properly validate access control, pause state, signature verification, expiration, and index bounds checking.


438-453: LGTM: Critical strict order validation test enabled.

This test correctly validates the strict order execution feature, which is an important security mechanism. Good to see this is now active rather than commented out.


455-565: LGTM: Thorough payment execution flow testing.

Tests cover out-of-order execution, bounds checking, timing validation, duplicate prevention, and sequential payment scenarios with proper state verification.


567-622: LGTM: Edge case handling well covered.

Tests properly validate zero fee scenarios and insufficient balance/allowance error handling.


625-654: LGTM: Integration test with appropriate dummy data.

The paused state integration test correctly uses a dummy signature since it's specifically testing the pause modifier, not signature validation.

@aimensahnoun aimensahnoun merged commit 0ebcb25 into master Jul 5, 2025
10 checks passed
@aimensahnoun aimensahnoun deleted the feat/ERC20-recurring-payment-proxy branch July 5, 2025 23:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Request Network - Develop ERC20RecurringPaymentFeeProxy

3 participants