Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for typehash and beneficiary specific nonces #4420

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Amxx
Copy link
Collaborator

@Amxx Amxx commented Jul 4, 2023

Fixes #3927

Proposal for typehash nonces / operation ids. This enables "per application" parallel nonces, meaning that the parallelism is explicitly controlled by the verifier unlike what I proposed here.

Still, I believe it would still be possible to build by-design out-of-order nonce mechanism on top of this PR.

    function _verifyAndConsumeNonce(address owner, uint256 nonce) internal virtual {
        _useCheckedNonce(DEFAULT_TYPEHASH, owner, nonce >> 128, nonce % (1 << 128));
    }
  • The default nonce is an alias to DEFAULT_TYPEHASH = bytes32(0) (this value is open to discussion). ERC20Permit and ERC20Votes will hook into that, preserving the current behavior.
  • I made the opinionated choice that the operation nonces are operation ids with beneficiary = 0

PR Checklist

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

@changeset-bot
Copy link

changeset-bot bot commented Jul 4, 2023

🦋 Changeset detected

Latest commit: 31fc95f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Amxx Amxx marked this pull request as draft July 4, 2023 15:46
@Amxx Amxx added this to the 5.0 milestone Jul 4, 2023
@@ -32,7 +33,7 @@ import {IERC5267} from "../../interfaces/IERC5267.sol";
*
* @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
*/
abstract contract EIP712 is IERC5267 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is required for contract linearization.

/**
* @dev Returns the next unused nonce for an address and a typehash.
*/
function operationNonces(bytes32 typehash, address signer) public view virtual returns (uint256) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nonces(owner) comes from EIP-2616 but is a really bad name.

This one should be something like getUnusedOperationNonce?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

operationNonces (and other) are names defined in the 6077 proposal. We should probably take some time to discuss all the naming.

* - last must be at least the current nonce.
* - last must not invalidate more than 5000 nonces at once.
*/
function useOperationNonce(bytes32 typehash, uint256 last) public virtual {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I would remove this one, useOperationIds should be enough. Having many aliases/variations pollutes the interface.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, we have to consider that this will add a lot of new functions to the token interfaces. Do we want to do that for ERC20Permit when it's not necessary? Starting to think that this should just be a separate feature.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

IMO the storage should be defined in Nonce.sol for all these usecase. Having storage split in 2 (when using the separate feature) is not something I would be happy with)

I also agree with not including all the public functions by default.

Where do we set the limit between the two parts ? Would Nonce contain the internal getters and setters, and the "extension" the public ones ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Would Nonce contain the internal getters and setters, and the "extension" the public ones ?

Yes this makes sense.

/**
* @dev Returns the next unused nonce for an address, a typehash and a beneficiary.
*/
function operationIds(bytes32 typehash, address signer, bytes32 beneficiary) public view virtual returns (uint256) {
Copy link
Contributor

Choose a reason for hiding this comment

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

"Beneficiary" is not the right term, we should probably use "track"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Again, name comes from 6077. I like "track"

@frangio
Copy link
Contributor

frangio commented Jul 5, 2023

Related new issue: #4425

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.

New abstractions for better nonce system
2 participants