Skip to content

Conversation

@V00D00-child
Copy link
Member

@V00D00-child V00D00-child commented Nov 12, 2025

Description

Currently, during permission revocation submission, we store a boolean revoked flag to track the permission revocation status in profile sync. This PR extends the permission revocation submission process to allow storing additional metadata on the revocation transaction.

References

Required by(Core): Attach metadata when submitting a revocation to the permission provider snap

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Introduces on-chain validation and metadata storage for revocations.

  • New BlockchainClient: Adds checkDelegationDisabledOnChain and checkTransactionReceipt with retry logic and ensureChain usage
  • Refactor: Moves delegation-disabled check out of BlockchainTokenMetadataClient into BlockchainClient
  • Profile Sync: Extends StoredGrantedPermission with optional revocationMetadata (currently txHash); updates updatePermissionRevocationStatus(permissionContext, isRevoked, revocationMetadata) to persist/clear metadata
  • RPC submitRevocation: Validates revocationMetadata, ensures delegation is disabled on-chain, optionally verifies txHash success via receipt, then updates profile sync; handler now depends on blockchainClient
  • Validation/Types: Adds zTransactionReceipt and validateTransactionReceipt; updates revocation params schema; exposes TransactionReceipt type
  • Utils: Adds getTransactionReceipt with retries in utils/blockchain.ts
  • Wiring/Tests: Wires BlockchainClient in index.ts; adds/updates comprehensive tests for client, RPC, and profile sync

Written by Cursor Bugbot for commit 5dbb6e6. This will update automatically on new commits. Configure here.

@V00D00-child V00D00-child marked this pull request as ready for review December 17, 2025 22:28
@V00D00-child V00D00-child requested a review from a team as a code owner December 17, 2025 22:28
Copy link
Contributor

@jeffsmale90 jeffsmale90 left a comment

Choose a reason for hiding this comment

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

A couple of general comments, and, I think a more architectural concern:

I think we should remove isRevoked from the stored permission, and use the existence of revocationMetadata to determine whether the permission is revoked to help improve data integrity.

… make txHash property optional on RevocationMetadata type
…ationMetadata to handle legacy data that was created before revocationMetadata was introduced
…egation disable and transaction receipt functions checks to BlockchainMetadataClient class
.object({
txHash: zHexStr.optional(),
})
.default({}),
Copy link
Contributor

Choose a reason for hiding this comment

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

As per my previous comment - I think we should remove isRevoked and make the revocationMetadata optional - and remove it's default value.

Copy link
Contributor

Choose a reason for hiding this comment

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

One other thought - we should ensure that a permission without revocationMetadata, but with isRevoked: true is parsed appropriately with a revocationMetadata (a legacy revoked permission)

Copy link
Member Author

@V00D00-child V00D00-child Jan 9, 2026

Choose a reason for hiding this comment

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

We can make revocationMetadata optional, but per the previous comment that you already acknowledged, we cannot remove isRevoked due to an edge case. Let us not continue revisiting the discussion about removing isRevoked, as it has been resolved.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated revocationMetadata to optional on the StoredGrantedPermission type

Comment on lines +184 to +186
_: Hex,
__: boolean,
___: RevocationMetadata,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can we use _ prefixed named properties here? I know this is an unconfigured instance, but it would be nice to see from this signature what the properties are

Comment on lines 383 to +384
isRevoked: boolean,
revocationMetadata: RevocationMetadata,
Copy link
Contributor

Choose a reason for hiding this comment

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

as per other comments - we should drop isRevoked, and just make revocationMetadata optional - actually, is there ever a scenario where we want to unrevoke the stored permission?

Maybe this should just be a function markPermissionRevoked that requires the revocationMetadata

Copy link
Member Author

@V00D00-child V00D00-child Jan 9, 2026

Choose a reason for hiding this comment

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

We are making revocationMetadata required on the interface on the corresponding GatorPermissionsController PR, so that it seems odd to make the update function take an optional revocationMetadata.

The DelegationManager contract allows enabling delegation after it is disabled, so the permission can be unrevoked.

…etadata optional. Infer TransactionReceipt type from zTransactionReceipt
permissionContext: zHexStr,
revocationMetadata: z.object({
txHash: zHexStr.optional(),
}),
Copy link

Choose a reason for hiding this comment

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

Optional txHash allows skipping transaction verification

Medium Severity

The txHash field in zRevocationParams is marked as optional, which means callers can submit revocations with revocationMetadata: {} (empty object). When txHash is missing, the transaction receipt verification in submitRevocation is entirely skipped due to the if (txHash) guard. While the on-chain delegation disabled check still runs, this bypasses verification that the specific revocation transaction was successful. Based on reviewer feedback indicating "metadata should be required," this appears to be an unintended security gap in the revocation verification flow.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link
Member Author

Choose a reason for hiding this comment

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

This bypassing verification is expected behavior, as some submit revocations do not have an associated txHash when the RPC method is called from the MM client. In this edge case, revocations are submitted as revocationMetadata: {} (empty object).

This is highlighted in previous comments: #228 (comment)

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.

4 participants