Skip to content

fix(recurring): grant and revoke relayer as separate calls - #1761

Closed
LeoSlrRf wants to merge 1 commit into
feat/req-429-eventsfrom
feat/req-429-access-control
Closed

fix(recurring): grant and revoke relayer as separate calls#1761
LeoSlrRf wants to merge 1 commit into
feat/req-429-eventsfrom
feat/req-429-access-control

Conversation

@LeoSlrRf

@LeoSlrRf LeoSlrRf commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Remove Ownable dependency; unify access control under AccessControl

Ownable has been removed from ERC20RecurringPaymentProxy. All privileged functions (pause, unpause, setFeeProxy, rescueTokens) now require DEFAULT_ADMIN_ROLE instead of onlyOwner, and the transferOwnership call in the constructor has been dropped.

The single setRelayer function (which atomically swapped one relayer for another) has been replaced with two explicit functions:

  • grantRelayer(address) — grants RELAYER_ROLE to an address; reverts on the zero address.
  • revokeRelayer(address) — revokes RELAYER_ROLE; reverts with ERC20RecurringPaymentProxy__NotRelayer if the address does not currently hold the role.

Both functions are gated by DEFAULT_ADMIN_ROLE. This makes it possible to have multiple concurrent relayers competing for relayerFee, since _payRelayer pays msg.sender.

A new custom error ERC20RecurringPaymentProxy__NotRelayer is introduced to give a clear revert reason when attempting to revoke a role from an address that does not hold it.

Tests have been updated accordingly: the Ownership suite is replaced by an Admin role suite covering DEFAULT_ADMIN_ROLE grant/revoke via the standard AccessControl interface, and the setRelayer suite is expanded into grantRelayer and revokeRelayer with coverage for zero-address grants, invalid revokes, event emissions, and non-admin access attempts.

@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR replaces atomic relayer replacement with independent role grants and revocations and consolidates privileged operations under AccessControl.

  • Adds grantRelayer and checked revokeRelayer entry points.
  • Removes Ownable inheritance and applies DEFAULT_ADMIN_ROLE to fee-proxy updates, pausing, and token rescue.
  • Updates contract tests for the new role-management behavior.
  • Leaves the published versioned ABI out of sync with the changed contract interface.

Confidence Score: 4/5

The PR should not merge until the published ERC20RecurringPaymentProxy artifact is synchronized with the new administration and relayer API.

Package consumers currently receive an ABI that omits the newly added relayer methods and advertises methods removed from the contract bytecode, causing transaction encoding failures or reverts.

Files Needing Attention: packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol and packages/smart-contracts/src/lib/artifacts/ERC20RecurringPaymentProxy/0.1.0.json

Important Files Changed

Filename Overview
packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol Replaces Ownable and atomic relayer replacement with AccessControl-based administration, but the corresponding published ABI remains unsynchronized.
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts Updates deployment, authorization, relayer-management, and administrative tests consistently with the new AccessControl API.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Admin[DEFAULT_ADMIN_ROLE holder] -->|grantRelayer| New[New relayer]
  Admin -->|revokeRelayer| Old[Old relayer]
  New -->|trigger due cycle| Proxy[Recurring payment proxy]
  Old -->|while role remains| Proxy
  Proxy -->|relayer fee| Caller[msg.sender]
Loading

Reviews (1): Last reviewed commit: "fix(recurring): grant and revoke relayer..." | Re-trigger Greptile

Comment on lines +411 to 424
function grantRelayer(address relayer) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (relayer == address(0)) revert ERC20RecurringPaymentProxy__ZeroAddress();
_grantRole(RELAYER_ROLE, relayer);
}

/**
* @notice Revokes `RELAYER_ROLE`. Reverts if `relayer` does not hold the role.
*/
function revokeRelayer(address relayer) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (!hasRole(RELAYER_ROLE, relayer)) {
revert ERC20RecurringPaymentProxy__NotRelayer();
}
_revokeRole(RELAYER_ROLE, relayer);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Published ABI misses relayer methods

When clients connect through the published erc20RecurringPaymentProxyArtifact, its ABI lacks grantRelayer and revokeRelayer while retaining the removed setRelayer and Ownable methods, causing new operations to be unavailable and obsolete calls to revert against bytecode built from this source. Update the committed versioned artifact alongside this public API change.

Knowledge Base Used: Smart contracts and deployments

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

New ABI is published in a PR up the graphite stack

@LeoSlrRf LeoSlrRf closed this Aug 24, 2026
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.

1 participant