From 134009e3501da711565eeacad99aee8e09174c67 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sat, 10 Jan 2026 14:23:00 -0500 Subject: [PATCH 1/4] fix(permit2): Update example witnessTypeString contents --- docs/contracts/permit2/reference/signature-transfer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contracts/permit2/reference/signature-transfer.md b/docs/contracts/permit2/reference/signature-transfer.md index 8403071ac..19b22796d 100644 --- a/docs/contracts/permit2/reference/signature-transfer.md +++ b/docs/contracts/permit2/reference/signature-transfer.md @@ -197,7 +197,7 @@ The `witness` that should be passed along with the permit message should be: And the `witnessTypeString` to be passed in should be: ```solidity -string constant witnessTypeString = "ExampleTrade witness)ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)TokenPermissions(address token,uint256 amount)" +string constant witnessTypeString = "ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)TokenPermissions(address token,uint256 amount)" ``` It’s important to note that when hashing multiple typed structs, the ordering of the structs in the type string matters. Referencing EIP-721: From 083d946a473263d6c38ddbe83649fb42c5392049 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sat, 10 Jan 2026 14:28:06 -0500 Subject: [PATCH 2/4] fix(permit2): Add links for EIP-712 references --- docs/contracts/permit2/reference/signature-transfer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contracts/permit2/reference/signature-transfer.md b/docs/contracts/permit2/reference/signature-transfer.md index 19b22796d..7d69f420e 100644 --- a/docs/contracts/permit2/reference/signature-transfer.md +++ b/docs/contracts/permit2/reference/signature-transfer.md @@ -181,7 +181,7 @@ struct ExampleTrade { } ``` -Following EIP-712, the typehash for the data would be defined by: +Following [EIP-712](https://eips.ethereum.org/EIPS/eip-712), the typehash for the data would be defined by: ```solidity bytes32 _EXAMPLE_TRADE_TYPEHASH = keccak256('ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)'); @@ -200,7 +200,7 @@ And the `witnessTypeString` to be passed in should be: string constant witnessTypeString = "ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)TokenPermissions(address token,uint256 amount)" ``` -It’s important to note that when hashing multiple typed structs, the ordering of the structs in the type string matters. Referencing EIP-721: +It’s important to note that when hashing multiple typed structs, the ordering of the structs in the type string matters. Referencing [EIP-712](https://eips.ethereum.org/EIPS/eip-712): > If the struct type references other struct types (and these in turn reference even more struct types), then the set of referenced struct types is collected, sorted by name and appended to the encoding. An example encoding is `Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)` > From 17572c10b2cf8cec77a96e1d2d5dee47f70d51fd Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Mon, 16 Feb 2026 00:25:53 -0500 Subject: [PATCH 3/4] fixup! fix(permit2): Update example witnessTypeString contents --- .../permit2/reference/signature-transfer.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/contracts/permit2/reference/signature-transfer.md b/docs/contracts/permit2/reference/signature-transfer.md index 7d69f420e..85dae2339 100644 --- a/docs/contracts/permit2/reference/signature-transfer.md +++ b/docs/contracts/permit2/reference/signature-transfer.md @@ -143,7 +143,7 @@ function permitWitnessTransferFrom( - transferDetails constructed with same type as defined above in the single permitTransferFrom case - owner - the signer of the permit message and owner of the tokens - witness - arbitrary data passed through that was signed by the user. Is used to reconstruct the signature. Pass through this data if you want the permit signature recovery also to validate other data. -- witnessTypeString - a string that defines the typed data that the witness was hashed from. It must also include the `TokenPermissions` struct and comply with [EIP-712](https://eips.ethereum.org/EIPS/eip-712) struct ordering. See an example below. +- witnessTypeString - a string derived from the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) encoding of a struct type that extends the above `PermitTransferFrom` by adding a final member field for the data whose hash is in the `witness` parameter, starting from the representation of that final member and including `TokenPermissions` in correctly sorted position. See an example below. - signature - the signature over the permit data. Supports EOA signatures, compact signatures defined by [EIP-2098](https://eips.ethereum.org/EIPS/eip-2098), and contract signatures defined by [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) ### Batch `permitWitnessTransferFrom` @@ -167,7 +167,7 @@ function permitWitnessTransferFrom( - transferDetails - constructed with the same type in the batched case of `permitTransferFrom` - owner - the signer of the permit message and owner of the tokens - witness - arbitrary data passed through that was signed by the user. Is used to reconstruct the signature. Pass through this data if you want the permit signature recovery to also validate other data. -- witnessTypeString - a string that defines the typed data that the witness was hashed from. It must also include the `TokenPermissions` struct and comply with [EIP-712](https://eips.ethereum.org/EIPS/eip-712) struct ordering. See an example below. +- witnessTypeString - a string derived from the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) encoding of a struct type that extends the above `PermitBatchTransferFrom` by adding a final member field for the data whose hash is in the `witness` parameter, starting from the representation of that final member and including `TokenPermissions` in correctly sorted position. See an example below. - signature - the signature over the permit data. Supports EOA signatures, compact signatures defined by [EIP-2098](https://eips.ethereum.org/EIPS/eip-2098), and contract signatures defined by [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) **Example `permitWitnessTransferFrom` parameters** @@ -181,7 +181,7 @@ struct ExampleTrade { } ``` -Following [EIP-712](https://eips.ethereum.org/EIPS/eip-712), the typehash for the data would be defined by: +Following [EIP-712](https://eips.ethereum.org/EIPS/eip-712), the typehash for ExampleTrade data would be defined by: ```solidity bytes32 _EXAMPLE_TRADE_TYPEHASH = keccak256('ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)'); @@ -194,10 +194,15 @@ The `witness` that should be passed along with the permit message should be: abi.encode(_EXAMPLE_TRADE_TYPEHASH, exampleTrade.exampleTokenAddress, exampleTrade.exampleMinimumAmountOut)); ``` -And the `witnessTypeString` to be passed in should be: +The encoding of the struct type containing that witness would be something like +```solidity +string constant fullTypeString = "PermitWitnessTransferFrom(TokenPermissions permitted,uint256 nonce,uint256 deadline,ExampleTrade witness)ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)TokenPermissions(address token,uint256 amount)" +``` + +And the `witnessTypeString` to be passed in should be the suffix of that encoding starting with the final top-level member: ```solidity -string constant witnessTypeString = "ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)TokenPermissions(address token,uint256 amount)" +string constant witnessTypeString = "ExampleTrade witness)ExampleTrade(address exampleTokenAddress,uint256 exampleMinimumAmountOut)TokenPermissions(address token,uint256 amount)" ``` It’s important to note that when hashing multiple typed structs, the ordering of the structs in the type string matters. Referencing [EIP-712](https://eips.ethereum.org/EIPS/eip-712): From 4484566747c54d13cdafd86c4a2acd2d73fcf410 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Mon, 16 Feb 2026 00:29:39 -0500 Subject: [PATCH 4/4] Promote "Example `permitWitnessTransferFrom` parameters" to a proper heading --- docs/contracts/permit2/reference/signature-transfer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contracts/permit2/reference/signature-transfer.md b/docs/contracts/permit2/reference/signature-transfer.md index 85dae2339..9a6d4d653 100644 --- a/docs/contracts/permit2/reference/signature-transfer.md +++ b/docs/contracts/permit2/reference/signature-transfer.md @@ -170,9 +170,9 @@ function permitWitnessTransferFrom( - witnessTypeString - a string derived from the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) encoding of a struct type that extends the above `PermitBatchTransferFrom` by adding a final member field for the data whose hash is in the `witness` parameter, starting from the representation of that final member and including `TokenPermissions` in correctly sorted position. See an example below. - signature - the signature over the permit data. Supports EOA signatures, compact signatures defined by [EIP-2098](https://eips.ethereum.org/EIPS/eip-2098), and contract signatures defined by [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) -**Example `permitWitnessTransferFrom` parameters** +## Example `permitWitnessTransferFrom` parameters -If an integrating contract would also like the signer to verify information about a trade, an integrating contract may ask the signer to also sign an `ExampleTrade` object that we define below: +If an integrating contract would also like the signer to verify information about a trade, it may ask the signer to also sign an `ExampleTrade` object that we define below: ```solidity struct ExampleTrade {