-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathEIP712Mod.sol
More file actions
87 lines (76 loc) · 2.47 KB
/
EIP712Mod.sol
File metadata and controls
87 lines (76 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.30;
bytes32 constant STORAGE_POSITION = keccak256("eip712.typed.structured.data.hashing.and.signing");
/**
* @custom:storage-location erc8042:eip712.typed.structured.data.hashing.and.signing
*/
struct EIP712Storage {
bytes32 domainSeparator;
string name;
string version;
bytes32 TYPE_HASH;
bytes32 NAME_HASH;
bytes32 VERSION_HASH;
uint256 chainId;
address verifyingContract;
}
/**
* @notice Returns a pointer to the ERC-712 storage struct.
* @dev Uses inline assembly to access the storage slot defined by STORAGE_POSITION.
* @return s The EIP712Storage struct in storage.
*/
function getStorage() pure returns (EIP712Storage storage s) {
bytes32 position = STORAGE_POSITION;
assembly {
s.slot := position
}
}
/**
* @notice Retures a domain separator from storage if calling contract and chain id is same as verifyingContract and chainId stored in storage.
* @notice otherwise it builds the deomain separator
* @return the domain separator
*/
function domainSeparator() view returns (bytes32) {
EIP712Storage memory s = getStorage();
address thisAddress;
uint256 chain;
assembly {
thisAddress := address()
chain := chainid()
}
if (thisAddress == s.verifyingContract && chain == s.chainId) {
return s.domainSeparator;
} else {
return buildDomainSeparator(s, thisAddress, chain);
}
}
/**
* @param s EIP712 storage in smart contract
* @param verifyingContract verifying smart contract address from storage or current calling contract
* @param chainid chainid of current using chain
* @return returns the domain separator
*/
function buildDomainSeparator(EIP712Storage memory s, address verifyingContract, uint256 chainid)
pure
returns (bytes32)
{
return keccak256(abi.encode(s.TYPE_HASH, s.NAME_HASH, s.VERSION_HASH, chainid, verifyingContract));
}
function hashTypedData(bytes32 structHash) view returns (bytes32) {
return typedDataHash(domainSeparator(), structHash);
}
function typedDataHash(bytes32 domainSeparator, bytes32 structHash) pure returns (bytes32) {
return keccak256(abi.encode("\x19\x01", domainSeparator, structHash));
}
/**
* @return name of the EIP712 contract
*/
function EIP712Name() view returns (string memory) {
return getStorage().name;
}
/**
* @return version of the EIP712 contract
*/
function EIP712Version() view returns (string memory) {
return getStorage().version;
}