forked from delegatable/delegatable-sol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDelegatable.sol
146 lines (133 loc) · 4.61 KB
/
Delegatable.sol
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
// import "hardhat/console.sol";
import {EIP712DOMAIN_TYPEHASH} from "./TypesAndDecoders.sol";
import {Delegation, Invocation, Invocations, SignedInvocation, SignedDelegation} from "./CaveatEnforcer.sol";
import {DelegatableCore} from "./DelegatableCore.sol";
import {IDelegatable} from "./interfaces/IDelegatable.sol";
abstract contract Delegatable is IDelegatable, DelegatableCore {
/// @notice The hash of the domain separator used in the EIP712 domain hash.
bytes32 public immutable domainHash;
/**
* @notice Delegatable Constructor
* @param contractName string - The name of the contract
* @param version string - The version of the contract
*/
constructor(string memory contractName, string memory version) {
domainHash = getEIP712DomainHash(
contractName,
version,
block.chainid,
address(this)
);
}
/* ===================================================================================== */
/* External Functions */
/* ===================================================================================== */
/// @inheritdoc IDelegatable
function getDelegationTypedDataHash(Delegation memory delegation)
public
view
returns (bytes32)
{
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
domainHash,
GET_DELEGATION_PACKETHASH(delegation)
)
);
return digest;
}
/// @inheritdoc IDelegatable
function getInvocationsTypedDataHash(Invocations memory invocations)
public
view
returns (bytes32)
{
bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
domainHash,
GET_INVOCATIONS_PACKETHASH(invocations)
)
);
return digest;
}
function getEIP712DomainHash(
string memory contractName,
string memory version,
uint256 chainId,
address verifyingContract
) public pure returns (bytes32) {
bytes memory encoded = abi.encode(
EIP712DOMAIN_TYPEHASH,
keccak256(bytes(contractName)),
keccak256(bytes(version)),
chainId,
verifyingContract
);
return keccak256(encoded);
}
function verifyDelegationSignature(SignedDelegation memory signedDelegation)
public
view
virtual
override(IDelegatable, DelegatableCore)
returns (address)
{
Delegation memory delegation = signedDelegation.delegation;
bytes32 sigHash = getDelegationTypedDataHash(delegation);
address recoveredSignatureSigner = recover(
sigHash,
signedDelegation.signature
);
return recoveredSignatureSigner;
}
function verifyInvocationSignature(SignedInvocation memory signedInvocation)
public
view
returns (address)
{
bytes32 sigHash = getInvocationsTypedDataHash(
signedInvocation.invocations
);
address recoveredSignatureSigner = recover(
sigHash,
signedInvocation.signature
);
return recoveredSignatureSigner;
}
// --------------------------------------
// WRITES
// --------------------------------------
/// @inheritdoc IDelegatable
function contractInvoke(Invocation[] calldata batch)
external
override
returns (bool)
{
return _invoke(batch, msg.sender);
}
/// @inheritdoc IDelegatable
function invoke(SignedInvocation[] calldata signedInvocations)
external
override
returns (bool success)
{
for (uint256 i = 0; i < signedInvocations.length; i++) {
SignedInvocation calldata signedInvocation = signedInvocations[i];
address invocationSigner = verifyInvocationSignature(
signedInvocation
);
_enforceReplayProtection(
invocationSigner,
signedInvocations[i].invocations.replayProtection
);
_invoke(signedInvocation.invocations.batch, invocationSigner);
}
}
/* ===================================================================================== */
/* Internal Functions */
/* ===================================================================================== */
}