Skip to content

fix: handle calldata tags in custom approvals#23527

Merged
adonesky1 merged 9 commits intoMetaMask:developfrom
horsefacts:horsefacts/approval-calldata-tags
Apr 26, 2024
Merged

fix: handle calldata tags in custom approvals#23527
adonesky1 merged 9 commits intoMetaMask:developfrom
horsefacts:horsefacts/approval-calldata-tags

Conversation

@horsefacts
Copy link
Copy Markdown
Contributor

@horsefacts horsefacts commented Mar 15, 2024

Description

The custom token approval utility function in ui/pages/confirmations/confirm-approve/confirm-approve.util.js parses ERC20 approve calldata and reconstructs it with an optional custom value.

This utility validates that the length of the parsed value amount is exactly 64 hex digits, assuming all calldata bytes after the spender are the value and the value is a uint256. However, this validation is too strict: it's possible for the calldata to include extra bytes following the value, which the contract will ignore in the call to approve. These are valid transactions.

Including a "calldata tag" for onchain attribution or analytics is an increasingly popular pattern. For example, Seaport uses calldata tags for order attribution, Viem provides a dataSuffix option, and Farcaster clients append an attribution suffix to transactions from Farcaster frames.

This utility should instead parse the first 64 bytes of the value and preserve any extra calldata.

Open in GitHub Codespaces

Screenshots

Error screenshot:

error image

Related issues

Previous issue in seaport-js: ProjectOpenSea/seaport-js#215

Manual testing steps

  1. Create an ERC20 approve with a calldata suffix. For example, using Viem:
await walletClient.writeContract({
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  abi: erc20Abi,
  functionName: 'approve',
  args: ['0x0000000000000000000000000000000000000001', 69420],
  dataSuffix: '0xdeadbeef'
});
  1. Execute the transaction in Metamask.

Pre-merge author checklist

  • I’ve followed MetaMask Coding Standards.
  • I've clearly explained what problem this PR is solving and how it is solved.
  • I've linked related issues
  • I've included manual testing steps
  • I've included screenshots/recordings if applicable
  • I’ve included tests if applicable
  • I’ve documented my code using JSDoc format if applicable
  • I’ve applied the right labels on the PR (see labeling guidelines). Not required for external contributors.
  • I’ve properly set the pull request status:
    • In case it's not yet "ready for review", I've set it to "draft".
    • In case it's "ready for review", I've changed it from "draft" to "non-draft".

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.

@horsefacts horsefacts requested a review from a team as a code owner March 15, 2024 16:19
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 15, 2024

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added external-contributor INVALID-PR-TEMPLATE PR's body doesn't match template labels Mar 15, 2024
@horsefacts
Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@horsefacts horsefacts force-pushed the horsefacts/approval-calldata-tags branch from efec747 to b2597bf Compare March 15, 2024 16:36
@horsefacts horsefacts force-pushed the horsefacts/approval-calldata-tags branch from b2597bf to 824e078 Compare March 15, 2024 21:32
const [signature, rest] = data.split(spender);
if (!signature || !rest) {
throw new Error('Invalid data');
} else if (tokenValue.length !== 64) {
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.

Perhaps we ought to continue to throw if rest value is less than 64 characters?

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.

Good call. I added a test for this case here, and added back this check, but it turns out we will throw here before hitting it. If the calldata length is shorter than expected, parseStandardTokenTransactionData will return undefined.

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.

Could we perhaps add the logic here just in case that upstream code changes?

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.

Sure, just added this check back!

@horsefacts horsefacts requested review from a team as code owners April 19, 2024 17:52
adonesky1
adonesky1 previously approved these changes Apr 22, 2024
jpuri
jpuri previously approved these changes Apr 24, 2024
Copy link
Copy Markdown
Contributor

@jpuri jpuri left a comment

Choose a reason for hiding this comment

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

lgtm

@Montoya Montoya dismissed stale reviews from adonesky1 and jpuri via 72539a7 April 25, 2024 14:49
@Montoya Montoya requested a review from jpuri April 25, 2024 14:58
@adonesky1 adonesky1 merged commit eeff513 into MetaMask:develop Apr 26, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Apr 26, 2024
@metamaskbot
Copy link
Copy Markdown
Collaborator

No release label on PR. Adding release label release-11.17.0 on PR, as PR was added to branch 11.17.0 when release was cut.

@gauthierpetetin gauthierpetetin added the release-12.0.0 Issue or pull request that will be included in release 12.0.0 label Jun 6, 2024
@benjisclowder benjisclowder added the team-confirmations Push issues to confirmations team label Jun 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

external-contributor INVALID-PR-TEMPLATE PR's body doesn't match template release-12.0.0 Issue or pull request that will be included in release 12.0.0 team-confirmations Push issues to confirmations team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants