/
IRegistry.sol
243 lines (209 loc) · 12 KB
/
IRegistry.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title Registry
* @notice A contract which is essentially a glorified forwarder.
* It essentially brings together people who want things executed,
* and people who want to do that execution in return for a fee.
* Users register the details of what they want executed, which
* should always revert unless their execution condition is true,
* and executors execute the request when the condition is true.
* Only a specific executor is allowed to execute requests at any
* given time, as determined by the StakeManager, which requires
* staking AUTO tokens. This is infrastructure, and an integral
* piece of the future of web3. It also provides the spark of life
* for a new form of organism - cyber life. We are the gods now.
* @author Quantaf1re (James Key)
*/
interface IRegistry {
// The address vars are 20b, total 60, calldata is 4b + n*32b usually, which
// has a factor of 32. uint112 since the current ETH supply of ~115m can fit
// into that and it's the highest such that 2 * uint112 + 3 * bool is < 256b
struct Request {
address payable user;
address target;
address payable referer;
bytes callData;
uint112 initEthSent;
uint112 ethForCall;
bool verifyUser;
bool insertFeeAmount;
bool payWithAUTO;
bool isAlive;
}
//////////////////////////////////////////////////////////////
// //
// Hashed Requests //
// //
//////////////////////////////////////////////////////////////
/**
* @notice Creates a new request, logs the request info in an event, then saves
* a hash of it on-chain in `_hashedReqs`. Uses the default for whether
* to pay in ETH or AUTO
* @param target The contract address that needs to be called
* @param referer The referer to get rewarded for referring the sender
* to using Autonomy. Usally the address of a dapp owner
* @param callData The calldata of the call that the request is to make, i.e.
* the fcn identifier + inputs, encoded
* @param ethForCall The ETH to send with the call
* @param verifyUser Whether the 1st input of the calldata equals the sender.
* Needed for dapps to know who the sender is whilst
* ensuring that the sender intended
* that fcn and contract to be called - dapps will
* require that msg.sender is the Verified Forwarder,
* and only requests that have `verifyUser` = true will
* be forwarded via the Verified Forwarder, so any calls
* coming from it are guaranteed to have the 1st argument
* be the sender
* @param insertFeeAmount Whether the gas estimate of the executor should be inserted
* into the callData
* @param isAlive Whether or not the request should be deleted after it's executed
* for the first time. If `true`, the request will exist permanently
* (tho it can be cancelled any time), therefore executing the same
* request repeatedly aslong as the request is executable,
* and can be used to create fully autonomous contracts - the
* first single-celled cyber life. We are the gods now
* @return id The id of the request, equal to the index in `_hashedReqs`
*/
function newReq(
address target,
address payable referer,
bytes calldata callData,
uint112 ethForCall,
bool verifyUser,
bool insertFeeAmount,
bool isAlive
) external payable returns (uint id);
/**
* @notice Creates a new request, logs the request info in an event, then saves
* a hash of it on-chain in `_hashedReqs`
* @param target The contract address that needs to be called
* @param referer The referer to get rewarded for referring the sender
* to using Autonomy. Usally the address of a dapp owner
* @param callData The calldata of the call that the request is to make, i.e.
* the fcn identifier + inputs, encoded
* @param ethForCall The ETH to send with the call
* @param verifyUser Whether the 1st input of the calldata equals the sender.
* Needed for dapps to know who the sender is whilst
* ensuring that the sender intended
* that fcn and contract to be called - dapps will
* require that msg.sender is the Verified Forwarder,
* and only requests that have `verifyUser` = true will
* be forwarded via the Verified Forwarder, so any calls
* coming from it are guaranteed to have the 1st argument
* be the sender
* @param insertFeeAmount Whether the gas estimate of the executor should be inserted
* into the callData
* @param payWithAUTO Whether the sender wants to pay for the request in AUTO
* or ETH. Paying in AUTO reduces the fee
* @param isAlive Whether or not the request should be deleted after it's executed
* for the first time. If `true`, the request will exist permanently
* (tho it can be cancelled any time), therefore executing the same
* request repeatedly aslong as the request is executable,
* and can be used to create fully autonomous contracts - the
* first single-celled cyber life. We are the gods now
* @return id The id of the request, equal to the index in `_hashedReqs`
*/
function newReqPaySpecific(
address target,
address payable referer,
bytes calldata callData,
uint112 ethForCall,
bool verifyUser,
bool insertFeeAmount,
bool payWithAUTO,
bool isAlive
) external payable returns (uint id);
/**
* @notice Gets all keccak256 hashes of encoded requests. Completed requests will be 0x00
* @return [bytes32[]] An array of all hashes
*/
function getHashedReqs() external view returns (bytes32[] memory);
/**
* @notice Gets part of the keccak256 hashes of encoded requests. Completed requests will be 0x00.
* Needed since the array will quickly grow to cost more gas than the block limit to retrieve.
* so it can be viewed in chunks. E.g. for an array of x = [4, 5, 6, 7], x[1, 2] returns [5],
* the same as lists in Python
* @param startIdx [uint] The starting index from which to start getting the slice (inclusive)
* @param endIdx [uint] The ending index from which to start getting the slice (exclusive)
* @return [bytes32[]] An array of all hashes
*/
function getHashedReqsSlice(uint startIdx, uint endIdx) external view returns (bytes32[] memory);
/**
* @notice Gets the total number of requests that have been made, hashed, and stored
* @return [uint] The total number of hashed requests
*/
function getHashedReqsLen() external view returns (uint);
/**
* @notice Gets a single hashed request
* @param id [uint] The id of the request, which is its index in the array
* @return [bytes32] The sha3 hash of the request
*/
function getHashedReq(uint id) external view returns (bytes32);
//////////////////////////////////////////////////////////////
// //
// Bytes Helpers //
// //
//////////////////////////////////////////////////////////////
/**
* @notice Encode a request into bytes
* @param r [request] The request to be encoded
* @return [bytes] The bytes array of the encoded request
*/
function getReqBytes(Request memory r) external pure returns (bytes memory);
function insertToCallData(bytes calldata callData, uint expectedGas, uint startIdx) external pure returns (bytes memory);
//////////////////////////////////////////////////////////////
// //
// Executions //
// //
//////////////////////////////////////////////////////////////
/**
* @notice Execute a hashedReq. Calls the `target` with `callData`, then
* charges the user the fee, and gives it to the executor
* @param id [uint] The index of the request in `_hashedReqs`
* @param r [request] The full request struct that fully describes the request.
* Typically known by seeing the `HashedReqAdded` event emitted with `newReq`
* @param expectedGas [uint] The gas that the executor expects the execution to cost,
* known by simulating the the execution of this tx locally off-chain.
* This can be forwarded as part of the requested call such that the
* receiving contract knows how much gas the whole execution cost and
* can do something to compensate the exact amount (e.g. as part of a trade).
* Cannot be more than 10% above the measured gas cost by the end of execution
* @return gasUsed [uint] The gas that was used as part of the execution. Used to know `expectedGas`
*/
function executeHashedReq(
uint id,
Request calldata r,
uint expectedGas
) external returns (uint gasUsed);
//////////////////////////////////////////////////////////////
// //
// Cancellations //
// //
//////////////////////////////////////////////////////////////
/**
* @notice Execute a hashedReq. Calls the `target` with `callData`, then
* charges the user the fee, and gives it to the executor
* @param id [uint] The index of the request in `_hashedReqs`
* @param r [request] The full request struct that fully describes the request.
* Typically known by seeing the `HashedReqAdded` event emitted with `newReq`
*/
function cancelHashedReq(
uint id,
Request memory r
) external;
//////////////////////////////////////////////////////////////
// //
// Getters //
// //
//////////////////////////////////////////////////////////////
function getAUTOAddr() external view returns (address);
function getStakeManager() external view returns (address);
function getOracle() external view returns (address);
function getUserForwarder() external view returns (address);
function getGasForwarder() external view returns (address);
function getUserGasForwarder() external view returns (address);
function getReqCountOf(address addr) external view returns (uint);
function getExecCountOf(address addr) external view returns (uint);
function getReferalCountOf(address addr) external view returns (uint);
}