Skip to content

FleetTreasuryPaymaster — whitelisted contract destinations#102

Open
Douglasacost wants to merge 1 commit intomainfrom
feat/fleet-paymastering
Open

FleetTreasuryPaymaster — whitelisted contract destinations#102
Douglasacost wants to merge 1 commit intomainfrom
feat/fleet-paymastering

Conversation

@Douglasacost
Copy link
Copy Markdown
Collaborator

Extends FleetTreasuryPaymaster so gas sponsorship is not limited to fleetIdentity only: allowed to addresses are tracked in isWhitelistedContract. fleetIdentity is seeded at deploy and cannot be removed. Documentation and tests are updated accordingly.

Sponsors need to pay gas for user transactions targeting other protocol contracts (for example SwarmRegistryUniversal) while keeping the same user whitelist and ETH balance checks, without deploying a separate WhitelistPaymaster.

  • Introduced isWhitelistedContract mapping to manage allowed destinations for gas sponsorship.
  • Added functions to add and remove whitelisted contracts, with checks to prevent removal of fleetIdentity.
  • Updated validation logic in _validateAndPayGeneralFlow to accommodate new contract whitelist.
  • Enhanced documentation in the swarm specification to reflect these changes.
  • Added tests for whitelisted contract functionality and validation scenarios.

…nd validation improvements

- Introduced `isWhitelistedContract` mapping to manage allowed destinations for gas sponsorship.
- Added functions to add and remove whitelisted contracts, with checks to prevent removal of `fleetIdentity`.
- Updated validation logic in `_validateAndPayGeneralFlow` to accommodate new contract whitelist.
- Enhanced documentation in the swarm specification to reflect these changes.
- Added tests for whitelisted contract functionality and validation scenarios.
@Douglasacost Douglasacost requested a review from aliXsed March 26, 2026 14:43
@github-actions
Copy link
Copy Markdown

LCOV of commit 37d2603 during checks #629

Summary coverage rate:
  lines......: 32.2% (769 of 2390 lines)
  functions..: 28.6% (108 of 378 functions)
  branches...: 37.3% (139 of 373 branches)

Files changed coverage rate:
                                                  |Lines       |Functions  |Branches    
  Filename                                        |Rate     Num|Rate    Num|Rate     Num
  ======================================================================================
  src/paymasters/FleetTreasuryPaymaster.sol       | 0.0%     52| 0.0%     9| 0.0%     11
  test/paymasters/FleetTreasuryPaymaster.t.sol    | 0.0%      6| 0.0%     3|    -      0

Comment on lines +133 to +140
if (to == address(this)) {
if (!hasRole(WHITELIST_ADMIN_ROLE, from)) {
revert DestinationNotAllowed();
}
} else if (isWhitelistedContract[to]) {
if (!isWhitelistedUser[from]) {
revert UserIsNotWhitelisted();
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggest a simplification as follows

Suggested change
if (to == address(this)) {
if (!hasRole(WHITELIST_ADMIN_ROLE, from)) {
revert DestinationNotAllowed();
}
} else if (isWhitelistedContract[to]) {
if (!isWhitelistedUser[from]) {
revert UserIsNotWhitelisted();
}
if (!isWhitelistedUser[from]) {
revert UserIsNotWhitelisted();
} else if (!isWhitelistedContract[to]) {
revert DestinationNotAllowed();
}

Then make sure that in the constructor you add address(this) to the whitelisted contracts and admin to the whitelisted users.

constructor(
address admin,
address withdrawer,
address fleetIdentity_,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since it's possible to add any contract to white listed contracts then you can remove fleetIdentity here

/// @dev Only callable by the FleetIdentity contract during claimUuidSponsored.
/// The actual NODL transfer is done separately by FleetIdentity via transferFrom.
function consumeSponsoredBond(address user, uint256 amount) external {
if (msg.sender != fleetIdentity) revert NotFleetIdentity();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

In the more general case you can here check if (isWhitelistedContract(msg.sender)

/// Gas sponsorship: `fleetIdentity` is seeded into `isWhitelistedContract` at
/// deploy; admins add more destinations the same way. Admin-only calls to this
/// contract use `WHITELIST_ADMIN_ROLE` instead of user whitelist.
contract FleetTreasuryPaymaster is BasePaymaster, QuotaControl {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If you take my other suggestions, then consider renaming FleetTreasuryPaymaster to TreasuryPaymaster or use your AI assistant to suggest a better name that matches the contract logic.

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.

2 participants