Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
ee284df3
Commit
ee284df3
authored
Aug 10, 2023
by
lbeder
Committed by
Mark Tyneway
Aug 11, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: Add EIP1271 support to EAS
parent
2261ab3b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
48 additions
and
33 deletions
+48
-33
Common.sol
packages/contracts-bedrock/src/EAS/Common.sol
+2
-2
EAS.sol
packages/contracts-bedrock/src/EAS/EAS.sol
+6
-8
IEAS.sol
packages/contracts-bedrock/src/EAS/IEAS.sol
+5
-7
EIP1271Verifier.sol
...ges/contracts-bedrock/src/EAS/eip1271/EIP1271Verifier.sol
+35
-16
No files found.
packages/contracts-bedrock/src/EAS/Common.sol
View file @
ee284df3
...
...
@@ -13,8 +13,8 @@ error InvalidLength();
error InvalidSignature();
error NotFound();
/// @dev A struct representing E
IP712
signature data.
struct
EIP712
Signature {
/// @dev A struct representing E
CDSA
signature data.
struct Signature {
uint8 v; // The recovery ID.
bytes32 r; // The x-coordinate of the nonce R.
bytes32 s; // The signature data.
...
...
packages/contracts-bedrock/src/EAS/EAS.sol
View file @
ee284df3
...
...
@@ -4,13 +4,13 @@ pragma solidity 0.8.19;
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { Semver } from "../universal/Semver.sol";
import { Predeploys } from "../libraries/Predeploys.sol";
import { EIP
712Verifier } from "./eip712/EIP712
Verifier.sol";
import { EIP
1271Verifier } from "./eip1271/EIP1271
Verifier.sol";
import { ISchemaResolver } from "./resolver/ISchemaResolver.sol";
import {
AccessDenied,
EMPTY_UID,
EIP712
Signature,
Signature,
InvalidLength,
MAX_GAP,
NotFound,
...
...
@@ -44,7 +44,7 @@ struct AttestationsResult {
/// @custom:predeploy 0x4200000000000000000000000000000000000021
/// @title EAS
/// @notice The Ethereum Attestation Service protocol.
contract EAS is IEAS, Semver, EIP
712
Verifier {
contract EAS is IEAS, Semver, EIP
1271
Verifier {
using Address for address payable;
error AlreadyRevoked();
...
...
@@ -80,7 +80,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
uint256[MAX_GAP - 3] private __gap;
/// @dev Creates a new EAS instance.
constructor() Semver(1, 0, 2) EIP
712
Verifier("EAS", "1.0.1") { }
constructor() Semver(1, 0, 2) EIP
1271
Verifier("EAS", "1.0.1") { }
/// @inheritdoc IEAS
function getSchemaRegistry() external pure returns (ISchemaRegistry) {
...
...
@@ -186,8 +186,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
revert InvalidLength();
}
// Verify EIP712 signatures. Please note that the signatures are assumed to be signed with increasing
// nonces.
// Verify signatures. Please note that the signatures are assumed to be signed with increasing nonces.
for (uint256 j = 0; j < data.length; j = uncheckedInc(j)) {
_verifyAttest(
DelegatedAttestationRequest({
...
...
@@ -287,8 +286,7 @@ contract EAS is IEAS, Semver, EIP712Verifier {
revert InvalidLength();
}
// Verify EIP712 signatures. Please note that the signatures are assumed to be signed with increasing
// nonces.
// Verify signatures. Please note that the signatures are assumed to be signed with increasing nonces.
for (uint256 j = 0; j < data.length; j = uncheckedInc(j)) {
_verifyRevoke(
DelegatedRevocationRequest({
...
...
packages/contracts-bedrock/src/EAS/IEAS.sol
View file @
ee284df3
...
...
@@ -2,7 +2,7 @@
pragma solidity ^0.8.0;
import { ISchemaRegistry } from "./ISchemaRegistry.sol";
import { Attestation,
EIP712
Signature } from "./Common.sol";
import { Attestation, Signature } from "./Common.sol";
/// @dev A struct representing the arguments of the attestation request.
struct AttestationRequestData {
...
...
@@ -25,7 +25,7 @@ struct AttestationRequest {
struct DelegatedAttestationRequest {
bytes32 schema; // The unique identifier of the schema.
AttestationRequestData data; // The arguments of the attestation request.
EIP712Signature signature; // The EIP712
signature data.
Signature signature; // The ECDSA
signature data.
address attester; // The attesting account.
}
...
...
@@ -39,8 +39,7 @@ struct MultiAttestationRequest {
struct MultiDelegatedAttestationRequest {
bytes32 schema; // The unique identifier of the schema.
AttestationRequestData[] data; // The arguments of the attestation requests.
EIP712Signature[] signatures; // The EIP712 signatures data. Please note that the signatures are assumed to be
// signed with increasing nonces.
Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.
address attester; // The attesting account.
}
...
...
@@ -61,7 +60,7 @@ struct RevocationRequest {
struct DelegatedRevocationRequest {
bytes32 schema; // The unique identifier of the schema.
RevocationRequestData data; // The arguments of the revocation request.
EIP712Signature signature; // The EIP712
signature data.
Signature signature; // The ECDSA
signature data.
address revoker; // The revoking account.
}
...
...
@@ -75,8 +74,7 @@ struct MultiRevocationRequest {
struct MultiDelegatedRevocationRequest {
bytes32 schema; // The unique identifier of the schema.
RevocationRequestData[] data; // The arguments of the revocation requests.
EIP712Signature[] signatures; // The EIP712 signatures data. Please note that the signatures are assumed to be
// signed with increasing nonces.
Signature[] signatures; // The ECDSA signatures data. Please note that the signatures are assumed to be signed with increasing nonces.
address revoker; // The revoking account.
}
...
...
packages/contracts-bedrock/src/EAS/eip
712/EIP712
Verifier.sol
→
packages/contracts-bedrock/src/EAS/eip
1271/EIP1271
Verifier.sol
View file @
ee284df3
...
...
@@ -3,21 +3,23 @@ pragma solidity 0.8.19;
import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import {
AttestationRequest,
AttestationRequestData,
DelegatedAttestationRequest,
DelegatedRevocationRequest,
RevocationRequest,
RevocationRequestData
} from "../IEAS.sol";
import { EIP712Signature, InvalidSignature, MAX_GAP, stringToBytes32, bytes32ToString } from "../Common.sol";
import { Signature, InvalidSignature, MAX_GAP, stringToBytes32, bytes32ToString } from "../Common.sol";
/// @title EIP1271Verifier
/// @notice EIP1271Verifier typed signatures verifier for EAS delegated attestations.
abstract contract EIP1271Verifier is EIP712 {
using Address for address;
/// @title EIP712
/// @notice The EIP712 typed signatures verifier for EAS delegated attestations.
abstract contract EIP712Verifier is EIP712 {
// The hash of the data type used to relay calls to the attest function. It's the value of
// keccak256("Attest(bytes32 schema,address recipient,uint64 expirationTime,bool revocable,bytes32 refUID,bytes
// data,uint256 nonce)").
...
...
@@ -36,13 +38,14 @@ abstract contract EIP712Verifier is EIP712 {
// Upgrade forward-compatibility storage gap
uint256[MAX_GAP - 1] private __gap;
/// @dev Creates a new EIP
712
Verifier instance.
/// @dev Creates a new EIP
1271
Verifier instance.
/// @param version The current major version of the signing domain
constructor(string memory name, string memory version) EIP712(name, version) {
_name = stringToBytes32(name);
}
/// @notice Returns the domain separator used in the encoding of the signatures for attest, and revoke.
/// @return The domain separator used in the encoding of the signatures for attest, and revoke.
function getDomainSeparator() external view returns (bytes32) {
return _domainSeparatorV4();
}
...
...
@@ -55,13 +58,13 @@ abstract contract EIP712Verifier is EIP712 {
}
/// @notice Returns the EIP712 type hash for the attest function.
/// @return The EIP712
attest function type hash
.
/// @return The EIP712
type hash for the attest function
.
function getAttestTypeHash() external pure returns (bytes32) {
return ATTEST_TYPEHASH;
}
/// @notice Returns the EIP712 type hash for the revoke function.
/// @return
hash_ The EIP712 revoke function type hash
.
/// @return
The EIP712 type hash for the revoke function
.
function getRevokeTypeHash() external pure returns (bytes32) {
return REVOKE_TYPEHASH;
}
...
...
@@ -76,7 +79,7 @@ abstract contract EIP712Verifier is EIP712 {
/// @param request The arguments of the delegated attestation request.
function _verifyAttest(DelegatedAttestationRequest memory request) internal {
AttestationRequestData memory data = request.data;
EIP712
Signature memory signature = request.signature;
Signature memory signature = request.signature;
uint256 nonce;
unchecked {
...
...
@@ -97,17 +100,14 @@ abstract contract EIP712Verifier is EIP712 {
)
)
);
if (ECDSA.recover(digest, signature.v, signature.r, signature.s) != request.attester) {
revert InvalidSignature();
}
_verifySignature(digest, signature, request.attester);
}
/// @notice Verifies delegated revocation request.
/// @param request The arguments of the delegated revocation request.
function _verifyRevoke(DelegatedRevocationRequest memory request) internal {
RevocationRequestData memory data = request.data;
EIP712
Signature memory signature = request.signature;
Signature memory signature = request.signature;
uint256 nonce;
unchecked {
...
...
@@ -115,8 +115,27 @@ abstract contract EIP712Verifier is EIP712 {
}
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(REVOKE_TYPEHASH, request.schema, data.uid, nonce)));
_verifySignature(digest, signature, request.revoker);
}
/// @notice Verifies EIP712 signatures (with EIP1271 support).
/// @param digest The typed-data digest to verify.
/// @param signature The signature to verify (either a "real" ECDSA signature or an EIP1271-aware signature).
/// @param signer The signer to verify the signature against.
function _verifySignature(bytes32 digest, Signature memory signature, address signer) private view {
// If the signer is a contract, check if it's EIP1271 compliant.
if (signer.isContract()) {
bytes4 magicValue = IERC1271(signer).isValidSignature(digest, abi.encode(signature));
if (magicValue != IERC1271.isValidSignature.selector) {
revert InvalidSignature();
}
return;
}
if (ECDSA.recover(digest, signature.v, signature.r, signature.s) != request.revoker) {
// If the signer is an EOA, verify the signature using the standard (non-malleable) ECDSA signature
// verification.
if (ECDSA.recover(digest, signature.v, signature.r, signature.s) != signer) {
revert InvalidSignature();
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment