@d20dao/vrf-sdk 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +11 -11
- package/API.md +411 -193
- package/BUILD-MANIFEST.json +36 -24
- package/CHANGELOG.md +53 -0
- package/PROTOCOL-PROVENANCE.json +15 -9
- package/README.md +66 -26
- package/THIRD_PARTY_NOTICES.md +3 -1
- package/abi/D20BeaconVerifier.json +165 -0
- package/abi/EpochEntropy.json +233 -0
- package/dist/abi.d.ts +303 -0
- package/dist/abi.js +2 -1
- package/dist/beacon.d.ts +28 -0
- package/dist/beacon.js +133 -0
- package/dist/epoch.d.ts +11 -3
- package/dist/epoch.js +70 -9
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -2
- package/dist/sources.d.ts +11 -0
- package/dist/sources.js +72 -0
- package/notices/BLS-BN254-LICENSE +21 -0
- package/notices/PROVENANCE.md +12 -0
- package/package.json +30 -4
package/API.md
CHANGED
|
@@ -2,23 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- Generated by scripts/api-reference.mjs from abi/*.json and scripts/api-descriptions.mjs. Do not edit by hand. -->
|
|
4
4
|
|
|
5
|
-
Every function, event and error of `D20VRFCoordinator` and `
|
|
5
|
+
Every function, event and error of `D20VRFCoordinator`, `EpochEntropy` and `D20BeaconVerifier`, generated from the ABIs of `@d20dao/vrf-sdk` 0.5.0. Regenerate with `npm run build && npm run api-reference`; `npm test` fails when this file is out of date.
|
|
6
6
|
|
|
7
|
-
- Package: `@d20dao/vrf-sdk` 0.
|
|
8
|
-
- Protocol source: commit `
|
|
7
|
+
- Package: `@d20dao/vrf-sdk` 0.5.0
|
|
8
|
+
- Protocol source: commit `98e537fb249dd0d3365b8d78e6040a9323a65a88`, copied to [`protocol/contracts/`](protocol/contracts/) (hashes in `PROTOCOL-PROVENANCE.json`)
|
|
9
9
|
- Compiler: solc 0.8.28+commit.7893614a.Emscripten.clang, EVM version `cancun`
|
|
10
10
|
- `abi/D20VRFCoordinator.json` SHA-256: `4764ba62745e109f3b968b21ed23e88da739a4a26906fc2ed3192fa23b8d79c1`
|
|
11
|
-
- `abi/EpochEntropy.json` SHA-256: `
|
|
11
|
+
- `abi/EpochEntropy.json` SHA-256: `74eff72ea9f7f434b628dd98ac921867e68e55cfac609f33d088f2e06c9cbc6c`
|
|
12
|
+
- `abi/D20BeaconVerifier.json` SHA-256: `06a0d6a046a5b790c49ed21cf545f3dfca36c7bac1ef262e927598c01292d6e5`
|
|
12
13
|
|
|
13
14
|
This reference describes that source. A deployment runs it only while the implementation behind each proxy is the one the deployment manifest records for that commit: check when you integrate and whenever a proxy emits `Upgraded` (README [Security and trust](README.md#security-and-trust)).
|
|
14
15
|
|
|
15
16
|
## Conventions
|
|
16
17
|
|
|
17
|
-
- **Addresses.** Call the proxies listed in README [Deployments](README.md#deployments). The ABIs are those of the implementations; `D20Proxy` adds no functions of its own.
|
|
18
|
+
- **Addresses.** Call the proxies listed in README [Deployments](README.md#deployments). The ABIs are those of the implementations; `D20Proxy` adds no functions of its own. `D20BeaconVerifier` is not behind a proxy: its address is in each beacon registration (`beaconOf`) and in README [Deployments](README.md#deployments).
|
|
18
19
|
- **Units.** Fees and credits are wei of native USDC, which has 18 decimals (`1e18` is 1 USDC). Deadlines and timestamps are Unix seconds. Ratios are basis points (10000 is 100%).
|
|
19
20
|
- **Callers.** "Anyone" means any account or contract; "Any contract" means `msg.sender` must have code. Owner-only functions revert `OwnableUnauthorizedAccount` for other callers.
|
|
20
21
|
- **Selectors.** Functions and errors show their 4-byte selector, events their topic 0, so revert data and logs can be matched by hand.
|
|
21
|
-
- **Decoding errors.** `coordinatorAbi` and `
|
|
22
|
+
- **Decoding errors.** `coordinatorAbi`, `epochEntropyAbi` and `beaconVerifierAbi` (`@d20dao/vrf-sdk/abi`) contain every custom error below. When your consumer calls the coordinator with an ordinary Solidity call, a coordinator revert is passed through unchanged, so a wallet sending a transaction to your consumer sees the coordinator's selector. Decode with `coordinator.interface.parseError(data)` in ethers or `decodeErrorResult({ abi: coordinatorAbi, data })` in viem, or build your consumer's contract object from its ABI plus the coordinator's error entries. Your consumer's own errors, such as `OnlyCoordinator` and `InvalidCoordinator` from `D20VRFConsumer`, are only in your consumer's ABI. Arithmetic overflow reverts with `Panic(uint256)`.
|
|
22
23
|
- **ethers v6 results.** Structs and multiple return values arrive as `Result` objects, which are arrays. A named value is also a property unless its name collides with an `Array` or `Result` member, such as `length`, `values`, `keys`, `map` or `filter`; read such a value with `result.getValue(name)`, by position, or from `result.toObject()`. Unnamed outputs, such as those of `pricing()`, are positional only.
|
|
23
24
|
- **Consumer contracts.** `D20VRFConsumer` implements `rawFulfillRandomness(requestId, randomness)` and `onRefund(requestId)`; both revert `OnlyCoordinator` unless called by the coordinator proxy given to its constructor, which reverts `InvalidCoordinator` for an address without code.
|
|
24
25
|
|
|
@@ -47,6 +48,10 @@ This reference describes that source. A deployment runs it only while the implem
|
|
|
47
48
|
- [Constants](#registry-constants)
|
|
48
49
|
- [Events](#registry-events)
|
|
49
50
|
- [Errors](#registry-errors)
|
|
51
|
+
- [D20BeaconVerifier](#verifier)
|
|
52
|
+
- [Verification](#verifier-verification)
|
|
53
|
+
- [Constants](#verifier-constants)
|
|
54
|
+
- [Errors](#verifier-errors)
|
|
50
55
|
|
|
51
56
|
## <a id="coordinator"></a>D20VRFCoordinator
|
|
52
57
|
|
|
@@ -60,7 +65,7 @@ Requests, fulfillment, `storeBlockHash`, retries, `refundRequest` and withdrawal
|
|
|
60
65
|
|
|
61
66
|
Returned by `getRequest`. It does not contain the escrowed fee or the refund ratio; read `requestFeePaid` and `requestRefundBps`.
|
|
62
67
|
|
|
63
|
-
Source: `D20VRFCoordinator.sol` lines
|
|
68
|
+
Source: `D20VRFCoordinator.sol` lines 61–79
|
|
64
69
|
|
|
65
70
|
| Field | Type | Meaning |
|
|
66
71
|
| --- | --- | --- |
|
|
@@ -124,7 +129,7 @@ Requests must come from a contract and pay at least the fee computed in their ow
|
|
|
124
129
|
function quoteFee(uint32 callbackGasLimit) external view returns (uint256)
|
|
125
130
|
```
|
|
126
131
|
|
|
127
|
-
Selector `0xc9caa0c3` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
132
|
+
Selector `0xc9caa0c3` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 232–237
|
|
128
133
|
|
|
129
134
|
Fee for a request with this `callbackGasLimit` priced at `block.basefee`, that is `quoteFeeAt(callbackGasLimit, block.basefee)`. Exact inside the requesting transaction, which is how `D20VRFRequests` helpers pay. Through `eth_call` the base fee is commonly reported as 0 (observed on Arc), so the answer collapses to `minFee` and a transaction sent with it reverts `IncorrectFee`. Off-chain, quote with `quoteFeeAt` and the latest header base fee plus a buffer, as `quoteRequestFee` does. It does not check the gas limit range.
|
|
130
135
|
|
|
@@ -136,7 +141,7 @@ Fee for a request with this `callbackGasLimit` priced at `block.basefee`, that i
|
|
|
136
141
|
function quoteFeeAt(uint32 callbackGasLimit, uint256 baseFee) external view returns (uint256)
|
|
137
142
|
```
|
|
138
143
|
|
|
139
|
-
Selector `0x26fa8481` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
144
|
+
Selector `0x26fa8481` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 224–231
|
|
140
145
|
|
|
141
146
|
`max(minFee, feeMultiplier × baseFee × (fulfillGasOverhead + callbackGasLimit))` over the live pricing for a base fee in wei that you supply; with `feeMultiplier` 0 it returns `minFee`. A quote, not a reservation: pricing can change before your transaction. A `baseFee` large enough to overflow uint256 reverts with `Panic(0x11)` instead of `FeeOverflow`.
|
|
142
147
|
|
|
@@ -148,7 +153,7 @@ Selector `0x26fa8481` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol
|
|
|
148
153
|
function requestRandomness(bytes32 clientSeed, uint32 callbackGasLimit, address _refundAddress) external payable returns (uint256 requestId)
|
|
149
154
|
```
|
|
150
155
|
|
|
151
|
-
Selector `0x9849d1e5` · Caller: Any contract · Source: `D20VRFCoordinator.sol` lines
|
|
156
|
+
Selector `0x9849d1e5` · Caller: Any contract · Source: `D20VRFCoordinator.sol` lines 239–244, 252–291
|
|
152
157
|
|
|
153
158
|
Creates a raw request (spec all zero) with `msg.sender` as consumer and returns its ID. Needs `msg.value` at least the fee computed in this transaction; escrows exactly that fee and credits any excess to `_refundAddress` as refund credit. Fixes the request block, epoch, client seed, refund address, fee, refund ratio (`refundBps`) and a deadline of `block.timestamp + RESPONSE_TIMEOUT`. After acceptance the consumer receives `rawFulfillRandomness(requestId, randomness)` with exactly `callbackGasLimit` gas. Checks run in this order: caller has code, refund address non-zero, gas limit in range, fee, mapping, epoch started.
|
|
154
159
|
|
|
@@ -162,7 +167,7 @@ Creates a raw request (spec all zero) with `msg.sender` as consumer and returns
|
|
|
162
167
|
function requestMappedRandomness(bytes32 clientSeed, uint32 callbackGasLimit, address _refundAddress, RandomnessMapping.Spec spec) external payable returns (uint256 requestId)
|
|
163
168
|
```
|
|
164
169
|
|
|
165
|
-
Selector `0xe6b41a8c` · Caller: Any contract · Source: `D20VRFCoordinator.sol` lines
|
|
170
|
+
Selector `0xe6b41a8c` · Caller: Any contract · Source: `D20VRFCoordinator.sol` lines 246–250, 252–291
|
|
166
171
|
|
|
167
172
|
Same as `requestRandomness`, storing `spec` with the request (`getMapping`, `mappingHash`). The callback still carries the raw word; read the mapped values with `getMappedResult`. `D20VRFRequests` helpers call this function and pay `quoteFee` from the calling contract balance.
|
|
168
173
|
|
|
@@ -176,11 +181,11 @@ Views, callable by anyone. They describe requests created from now on; an existi
|
|
|
176
181
|
|
|
177
182
|
| Function | Selector | Meaning | Source |
|
|
178
183
|
| --- | --- | --- | --- |
|
|
179
|
-
| <a id="coordinator-fn-pricing"></a>`pricing() returns (uint256, uint16, uint32)` | `0x7ce91411` | Live `(minFee, feeMultiplier, fulfillGasOverhead)`. The outputs are unnamed, so read them by position. | lines
|
|
180
|
-
| <a id="coordinator-fn-minfee"></a>`minFee() returns (uint256)` | `0x24ec7590` | Minimum fee in wei, at most `MAX_MIN_FEE` (10 USDC). | line
|
|
181
|
-
| <a id="coordinator-fn-feemultiplier"></a>`feeMultiplier() returns (uint16)` | `0xe5a70ef7` | Base-fee multiplier, 0 to `MAX_FEE_MULTIPLIER` (20); 0 makes every fee `minFee`. | lines
|
|
182
|
-
| <a id="coordinator-fn-fulfillgasoverhead"></a>`fulfillGasOverhead() returns (uint32)` | `0x19d40839` | Gas added to `callbackGasLimit` in the fee formula, `MIN_FULFILL_GAS_OVERHEAD` to `MAX_FULFILL_GAS_OVERHEAD`. | line
|
|
183
|
-
| <a id="coordinator-fn-refundbps"></a>`refundBps() returns (uint16)` | `0xec8c9a0b` | Current refund ratio in basis points (5000 to 10000), copied into each new request. Not the ratio of an existing request: use `requestRefundBps(requestId)`. | lines
|
|
184
|
+
| <a id="coordinator-fn-pricing"></a>`pricing() returns (uint256, uint16, uint32)` | `0x7ce91411` | Live `(minFee, feeMultiplier, fulfillGasOverhead)`. The outputs are unnamed, so read them by position. | lines 215–217 |
|
|
185
|
+
| <a id="coordinator-fn-minfee"></a>`minFee() returns (uint256)` | `0x24ec7590` | Minimum fee in wei, at most `MAX_MIN_FEE` (10 USDC). | line 46 |
|
|
186
|
+
| <a id="coordinator-fn-feemultiplier"></a>`feeMultiplier() returns (uint16)` | `0xe5a70ef7` | Base-fee multiplier, 0 to `MAX_FEE_MULTIPLIER` (20); 0 makes every fee `minFee`. | lines 48–49 |
|
|
187
|
+
| <a id="coordinator-fn-fulfillgasoverhead"></a>`fulfillGasOverhead() returns (uint32)` | `0x19d40839` | Gas added to `callbackGasLimit` in the fee formula, `MIN_FULFILL_GAS_OVERHEAD` to `MAX_FULFILL_GAS_OVERHEAD`. | line 50 |
|
|
188
|
+
| <a id="coordinator-fn-refundbps"></a>`refundBps() returns (uint16)` | `0xec8c9a0b` | Current refund ratio in basis points (5000 to 10000), copied into each new request. Not the ratio of an existing request: use `requestRefundBps(requestId)`. | lines 51–52 |
|
|
184
189
|
|
|
185
190
|
### <a id="coordinator-reading-request-state-and-results"></a>Reading request state and results
|
|
186
191
|
|
|
@@ -192,7 +197,7 @@ Views, callable by anyone, including from a callback. Request IDs start at 1 and
|
|
|
192
197
|
function getRequest(uint256 requestId) external view returns (D20VRFCoordinator.Request result)
|
|
193
198
|
```
|
|
194
199
|
|
|
195
|
-
Selector `0xc58343ef` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
200
|
+
Selector `0xc58343ef` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 293–312, 575–580
|
|
196
201
|
|
|
197
202
|
Full state of a request, see [`D20VRFCoordinator.Request`](#coordinator-type-d20vrfcoordinator-request). `targetBlock` and `epochHash` are resolved from the registry, so they become non-zero as soon as the epoch packet is published. `fulfilled` means the word is final; `delivered` only reports that a callback succeeded. A request that is not `fulfilled` in a block whose timestamp is after `deadline` has expired and can only be refunded. When polling, read the latest block before `getRequest`, so that a proof included up to that block is visible.
|
|
198
203
|
|
|
@@ -204,7 +209,7 @@ Full state of a request, see [`D20VRFCoordinator.Request`](#coordinator-type-d20
|
|
|
204
209
|
function getMapping(uint256 requestId) external view returns (RandomnessMapping.Spec)
|
|
205
210
|
```
|
|
206
211
|
|
|
207
|
-
Selector `0xede9ba8b` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
212
|
+
Selector `0xede9ba8b` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 344–347
|
|
208
213
|
|
|
209
214
|
The stored [`RandomnessMapping.Spec`](#coordinator-type-randomnessmapping-spec); all fields zero (Raw) for `requestRandomness`.
|
|
210
215
|
|
|
@@ -216,7 +221,7 @@ The stored [`RandomnessMapping.Spec`](#coordinator-type-randomnessmapping-spec);
|
|
|
216
221
|
function getMappedResult(uint256 requestId) external view returns (uint256[])
|
|
217
222
|
```
|
|
218
223
|
|
|
219
|
-
Selector `0x8f09a3e6` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
224
|
+
Selector `0x8f09a3e6` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 349–353
|
|
220
225
|
|
|
221
226
|
The accepted word mapped with the stored spec: `[uint256(word)]` for a raw request, otherwise the values in README [Randomness options](README.md#randomness-options). Part of `ID20VRF`. Reverts `NotFulfilled` until a proof is accepted, so an expired or refunded request never has a result. Gas grows with the mapping; a 256-item shuffle is expensive onchain.
|
|
222
227
|
|
|
@@ -228,7 +233,7 @@ The accepted word mapped with the stored spec: `[uint256(word)]` for a raw reque
|
|
|
228
233
|
function mapRandomness(bytes32 randomness, RandomnessMapping.Spec spec) external pure returns (uint256[])
|
|
229
234
|
```
|
|
230
235
|
|
|
231
|
-
Selector `0x41c2a199` · Caller: Anyone (pure) · Source: `D20VRFCoordinator.sol` lines
|
|
236
|
+
Selector `0x41c2a199` · Caller: Anyone (pure) · Source: `D20VRFCoordinator.sol` lines 355–360
|
|
232
237
|
|
|
233
238
|
Maps any word with any valid spec, like the SDK `mapRandomness(word, spec)` off-chain. It does not show that a request was fulfilled.
|
|
234
239
|
|
|
@@ -240,7 +245,7 @@ Maps any word with any valid spec, like the SDK `mapRandomness(word, spec)` off-
|
|
|
240
245
|
function requestFeePaid(uint256 requestId) external view returns (uint256)
|
|
241
246
|
```
|
|
242
247
|
|
|
243
|
-
Selector `0xef7cc992` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
248
|
+
Selector `0xef7cc992` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 335–338
|
|
244
249
|
|
|
245
250
|
Fee escrowed by the request (`feePaid` in `RandomnessRequested`), excluding any overpayment. The keeper share, the protocol share and the refund are computed from it.
|
|
246
251
|
|
|
@@ -252,7 +257,7 @@ Fee escrowed by the request (`feePaid` in `RandomnessRequested`), excluding any
|
|
|
252
257
|
function requestRefundBps(uint256 requestId) external view returns (uint16)
|
|
253
258
|
```
|
|
254
259
|
|
|
255
|
-
Selector `0x5d170fd7` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
260
|
+
Selector `0x5d170fd7` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 339–342
|
|
256
261
|
|
|
257
262
|
Refund ratio the request copied from `refundBps` at creation. An expiry refund pays `requestFeePaid × requestRefundBps / 10000`; a later `setRefundBps` does not change it.
|
|
258
263
|
|
|
@@ -264,7 +269,7 @@ Refund ratio the request copied from `refundBps` at creation. An expiry refund p
|
|
|
264
269
|
function refundCallbackDelivered(uint256) external view returns (bool)
|
|
265
270
|
```
|
|
266
271
|
|
|
267
|
-
Selector `0x281d3157` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
272
|
+
Selector `0x281d3157` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 105, 528
|
|
268
273
|
|
|
269
274
|
True once an `onRefund` notification for the request succeeded, at `refundRequest` or `retryRefundCallback`. Returns false for unknown IDs instead of reverting.
|
|
270
275
|
|
|
@@ -274,7 +279,7 @@ True once an `onRefund` notification for the request succeeded, at `refundReques
|
|
|
274
279
|
function nextRequestId() external view returns (uint256)
|
|
275
280
|
```
|
|
276
281
|
|
|
277
|
-
Selector `0x6a84a985` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
282
|
+
Selector `0x6a84a985` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 53, 175, 265
|
|
278
283
|
|
|
279
284
|
ID the next request will receive. Issued IDs are 1 to `nextRequestId() - 1`.
|
|
280
285
|
|
|
@@ -288,7 +293,7 @@ Recovery calls need no value or role. They forward gas to the consumer and rever
|
|
|
288
293
|
function refundRequest(uint256 requestId) external
|
|
289
294
|
```
|
|
290
295
|
|
|
291
|
-
Selector `0x7411484e` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines
|
|
296
|
+
Selector `0x7411484e` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines 483–507, 519–530
|
|
292
297
|
|
|
293
298
|
Refunds an unfulfilled request once a block timestamp is after its deadline. Marks it refunded, sends `feePaid × requestRefundBps / 10000` to the fixed refund address with a 30,000-gas transfer, or adds it to that address's refund credit if the transfer fails, and adds the rest of the fee to `earnedFees`. Then calls `onRefund(requestId)` on the consumer with 100,000 gas; a failed notification does not undo the refund. The caller receives nothing. Measured minimum transaction gas limit 302,558 to 357,517; use 400,000.
|
|
294
299
|
|
|
@@ -302,7 +307,7 @@ Refunds an unfulfilled request once a block timestamp is after its deadline. Mar
|
|
|
302
307
|
function retryCallback(uint256 requestId, uint32 gasLimit) external
|
|
303
308
|
```
|
|
304
309
|
|
|
305
|
-
Selector `0xdd11c275` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines
|
|
310
|
+
Selector `0xdd11c275` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines 473–481, 630–647
|
|
306
311
|
|
|
307
312
|
Calls `rawFulfillRandomness` again with the same accepted word after a failed callback, forwarding `gasLimit` (30,000 to 1,000,000 and not below the request's `callbackGasLimit`). Sets `delivered` on success. Pays nobody and never changes the word. Transaction gas limit: about `gasLimit + 250,000`.
|
|
308
313
|
|
|
@@ -316,7 +321,7 @@ Calls `rawFulfillRandomness` again with the same accepted word after a failed ca
|
|
|
316
321
|
function retryRefundCallback(uint256 requestId, uint32 gasLimit) external
|
|
317
322
|
```
|
|
318
323
|
|
|
319
|
-
Selector `0x054f6962` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines
|
|
324
|
+
Selector `0x054f6962` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines 509–517, 519–530
|
|
320
325
|
|
|
321
326
|
Repeats a failed `onRefund` notification for a refunded request with `gasLimit` (100,000 to 1,000,000). Never transfers funds again. Transaction gas limit: about `gasLimit + 150,000`.
|
|
322
327
|
|
|
@@ -330,7 +335,7 @@ Repeats a failed `onRefund` notification for a refunded request with `gasLimit`
|
|
|
330
335
|
function withdrawRefundCredit(address recipient) external
|
|
331
336
|
```
|
|
332
337
|
|
|
333
|
-
Selector `0x445071f2` · Caller: Refund-credit holder · Source: `D20VRFCoordinator.sol` lines
|
|
338
|
+
Selector `0x445071f2` · Caller: Refund-credit holder · Source: `D20VRFCoordinator.sol` lines 532–542
|
|
334
339
|
|
|
335
340
|
Sends all of the caller's refund credit, `refundCredits(msg.sender)`, to `recipient` with all remaining gas. Credit comes from overpayment and from refund transfers that failed, and belongs to the request's refund address, so that address must make the call. If `recipient` rejects the transfer the call reverts and the credit stays.
|
|
336
341
|
|
|
@@ -344,7 +349,7 @@ Sends all of the caller's refund credit, `refundCredits(msg.sender)`, to `recipi
|
|
|
344
349
|
function withdrawFees(address recipient) external
|
|
345
350
|
```
|
|
346
351
|
|
|
347
|
-
Selector `0x164e68de` · Caller: Fee recipient · Source: `D20VRFCoordinator.sol` lines
|
|
352
|
+
Selector `0x164e68de` · Caller: Fee recipient · Source: `D20VRFCoordinator.sol` lines 544–553
|
|
348
353
|
|
|
349
354
|
Sends all `earnedFees` to `recipient`. Fees accrue at acceptance (fee minus keeper share) and from the part of a refunded fee that is not returned; open escrow is never included. With nothing earned it sends zero without reverting.
|
|
350
355
|
|
|
@@ -358,7 +363,7 @@ Sends all `earnedFees` to `recipient`. Fees accrue at acceptance (fee minus keep
|
|
|
358
363
|
function withdrawKeeperCredit(address recipient) external
|
|
359
364
|
```
|
|
360
365
|
|
|
361
|
-
Selector `0xf62c546b` · Caller: Keeper-credit holder · Source: `D20VRFCoordinator.sol` lines
|
|
366
|
+
Selector `0xf62c546b` · Caller: Keeper-credit holder · Source: `D20VRFCoordinator.sol` lines 555–564
|
|
362
367
|
|
|
363
368
|
Sends all of the caller's keeper credit (keeper-share transfers that failed) to `recipient`.
|
|
364
369
|
|
|
@@ -372,13 +377,13 @@ Views, callable by anyone. Amounts are in wei of native USDC.
|
|
|
372
377
|
|
|
373
378
|
| Function | Selector | Meaning | Source |
|
|
374
379
|
| --- | --- | --- | --- |
|
|
375
|
-
| <a id="coordinator-fn-refundcredits"></a>`refundCredits(address) returns (uint256)` | `0x61137e40` | Refund credit that an address can withdraw with `withdrawRefundCredit`. | line
|
|
376
|
-
| <a id="coordinator-fn-totalrefundcredits"></a>`totalRefundCredits() returns (uint256)` | `0x6e0842e1` | Sum of all refund credit held by the coordinator. | line
|
|
377
|
-
| <a id="coordinator-fn-earnedfees"></a>`earnedFees() returns (uint256)` | `0xb1b3ffd9` | Protocol fees that the fee recipient can withdraw. | line
|
|
378
|
-
| <a id="coordinator-fn-feerecipient"></a>`feeRecipient() returns (address)` | `0x46904840` | Address allowed to call `withdrawFees`; changed with `setFeeRecipient`. | line
|
|
379
|
-
| <a id="coordinator-fn-keeperfeebps"></a>`keeperFeeBps() returns (uint16)` | `0x0eab7d63` | Keeper share of each accepted fee in basis points (0 to 10000). Read at acceptance, not snapshotted: a change applies to open requests accepted afterwards. It only splits the escrowed fee; what the consumer paid and can be refunded does not change. | lines
|
|
380
|
-
| <a id="coordinator-fn-keepercredits"></a>`keeperCredits(address) returns (uint256)` | `0xf5c764f6` | Keeper credit that an address can withdraw with `withdrawKeeperCredit`. | line
|
|
381
|
-
| <a id="coordinator-fn-totalkeepercredits"></a>`totalKeeperCredits() returns (uint256)` | `0xc7281b7a` | Sum of all keeper credit held by the coordinator. | line
|
|
380
|
+
| <a id="coordinator-fn-refundcredits"></a>`refundCredits(address) returns (uint256)` | `0x61137e40` | Refund credit that an address can withdraw with `withdrawRefundCredit`. | line 59 |
|
|
381
|
+
| <a id="coordinator-fn-totalrefundcredits"></a>`totalRefundCredits() returns (uint256)` | `0x6e0842e1` | Sum of all refund credit held by the coordinator. | line 58 |
|
|
382
|
+
| <a id="coordinator-fn-earnedfees"></a>`earnedFees() returns (uint256)` | `0xb1b3ffd9` | Protocol fees that the fee recipient can withdraw. | line 54 |
|
|
383
|
+
| <a id="coordinator-fn-feerecipient"></a>`feeRecipient() returns (address)` | `0x46904840` | Address allowed to call `withdrawFees`; changed with `setFeeRecipient`. | line 42 |
|
|
384
|
+
| <a id="coordinator-fn-keeperfeebps"></a>`keeperFeeBps() returns (uint16)` | `0x0eab7d63` | Keeper share of each accepted fee in basis points (0 to 10000). Read at acceptance, not snapshotted: a change applies to open requests accepted afterwards. It only splits the escrowed fee; what the consumer paid and can be refunded does not change. | lines 43, 450 |
|
|
385
|
+
| <a id="coordinator-fn-keepercredits"></a>`keeperCredits(address) returns (uint256)` | `0xf5c764f6` | Keeper credit that an address can withdraw with `withdrawKeeperCredit`. | line 44 |
|
|
386
|
+
| <a id="coordinator-fn-totalkeepercredits"></a>`totalKeeperCredits() returns (uint256)` | `0xc7281b7a` | Sum of all keeper credit held by the coordinator. | line 45 |
|
|
382
387
|
|
|
383
388
|
### <a id="coordinator-keeper-and-proof-functions"></a>Keeper and proof functions
|
|
384
389
|
|
|
@@ -390,7 +395,7 @@ Proof submission is permissionless: anyone holding a valid proof may submit it,
|
|
|
390
395
|
function fulfillRandomness(uint256 requestId, VRF.Proof proof) external
|
|
391
396
|
```
|
|
392
397
|
|
|
393
|
-
Selector `0xef7c2b19` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines
|
|
398
|
+
Selector `0xef7c2b19` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines 393–401, 430–465
|
|
394
399
|
|
|
395
400
|
Accepts a proof for a request that is not fulfilled, not refunded and not past its deadline; acceptance in a block with timestamp equal to `deadline` is timely. Stores the target block hash if needed, verifies the proof against `requestSeed(requestId)`, stores the word, proof hash and transcript hash, sets `fulfilled`, adds `feePaid` minus the keeper share to `earnedFees` and calls the consumer with `callbackGasLimit` gas. It then sends the keeper share (`keeperFeeBps` of `feePaid`) with 30,000 gas to the submitting wallet when the registry answers `isAuthorizedCommitter` true for it (the committer or an allowed backup committer) and to `committer()` otherwise, or records it as that wallet's keeper credit; a registry call that reverts also pays `committer()`. A failing callback does not revert the fulfillment.
|
|
396
401
|
|
|
@@ -404,9 +409,9 @@ Accepts a proof for a request that is not fulfilled, not refunded and not past i
|
|
|
404
409
|
function fulfillRandomnessBatch(uint256[] ids, VRF.Proof[] proofs) external
|
|
405
410
|
```
|
|
406
411
|
|
|
407
|
-
Selector `0x9497b180` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines
|
|
412
|
+
Selector `0x9497b180` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines 403–428
|
|
408
413
|
|
|
409
|
-
Fulfills up to `MAX_FULFILL_BATCH` (16) requests, one proof each. Members already fulfilled, refunded or past their deadline, including an ID repeated in the batch, are skipped with `FulfillmentSkipped`; every other member runs exactly like `fulfillRandomness` and emits the same events, so an unknown ID, an unready member or an invalid proof reverts the whole batch.
|
|
414
|
+
Fulfills up to `MAX_FULFILL_BATCH` (16) requests, one proof each. Members already fulfilled, refunded or past their deadline, including an ID repeated in the batch, are skipped with `FulfillmentSkipped`; every other member runs exactly like `fulfillRandomness` and emits the same events, so an unknown ID, an unready member or an invalid proof reverts the whole batch. Before any result is revealed it checks that the gas left covers every member that will be served, `140,000 + Σ(callbackGasLimit + callbackGasLimit / 63 + 400,000)`, and reverts `InsufficientCallbackGas` otherwise, so no callback can starve a later member and revert results already revealed.
|
|
410
415
|
|
|
411
416
|
**Emits:** [`FulfillmentSkipped`](#coordinator-event-fulfillmentskipped), [`BlockHashStored`](#coordinator-event-blockhashstored), [`RequestServed`](#coordinator-event-requestserved), [`ProofVerified`](#coordinator-event-proofverified), [`RandomnessFulfilled`](#coordinator-event-randomnessfulfilled), [`FulfillmentEvidence`](#coordinator-event-fulfillmentevidence), [`CallbackAttempted`](#coordinator-event-callbackattempted), [`KeeperFeePaid`](#coordinator-event-keeperfeepaid).
|
|
412
417
|
|
|
@@ -418,7 +423,7 @@ Fulfills up to `MAX_FULFILL_BATCH` (16) requests, one proof each. Members alread
|
|
|
418
423
|
function storeBlockHash(uint256 requestId) external returns (bytes32)
|
|
419
424
|
```
|
|
420
425
|
|
|
421
|
-
Selector `0x262fd733` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines
|
|
426
|
+
Selector `0x262fd733` · Caller: Anyone · Source: `D20VRFCoordinator.sol` lines 372–376, 581–596
|
|
422
427
|
|
|
423
428
|
Resolves the target block from the published epoch, stores its hash if not stored yet and returns it. Fulfillment does this automatically; calling it earlier keeps a request provable after its target leaves the 256-block `BLOCKHASH` window. Needs `block.number` at least `targetBlock + confirmationBlocks`. Works on any request, whatever its status.
|
|
424
429
|
|
|
@@ -432,7 +437,7 @@ Resolves the target block from the published epoch, stores its hash if not store
|
|
|
432
437
|
function verifyRequestProof(uint256 requestId, VRF.Proof proof) external view returns (bytes32)
|
|
433
438
|
```
|
|
434
439
|
|
|
435
|
-
Selector `0x0846de99` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
440
|
+
Selector `0x0846de99` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 362–370
|
|
436
441
|
|
|
437
442
|
Returns the word a proof yields for the request's seed, without changing state. A valid proof is not acceptance: check `getRequest(requestId).fulfilled`.
|
|
438
443
|
|
|
@@ -444,7 +449,7 @@ Returns the word a proof yields for the request's seed, without changing state.
|
|
|
444
449
|
function requestSeed(uint256 requestId) external view returns (uint256)
|
|
445
450
|
```
|
|
446
451
|
|
|
447
|
-
Selector `0xa9df851a` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
452
|
+
Selector `0xa9df851a` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 378–383, 598–606
|
|
448
453
|
|
|
449
454
|
Seed the proof must use: `keccak256(abi.encode(SEED_DOMAIN, chainId, coordinator, keyHash, requestId, consumer, clientSeed, mappingHash, requestBlock, targetBlock, blockHash, epochId, epochHash))` as uint256. Available only after publication and `confirmationBlocks` confirmations of the target block.
|
|
450
455
|
|
|
@@ -456,7 +461,7 @@ Seed the proof must use: `keccak256(abi.encode(SEED_DOMAIN, chainId, coordinator
|
|
|
456
461
|
function getProofContext(uint256 requestId) external view returns (uint256 seed, uint64 deadline, bool fulfilled, bool refunded)
|
|
457
462
|
```
|
|
458
463
|
|
|
459
|
-
Selector `0xcf14de9d` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
464
|
+
Selector `0xcf14de9d` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 385–391
|
|
460
465
|
|
|
461
466
|
`requestSeed` together with `deadline`, `fulfilled` and `refunded`. It reverts `NotReady` like `requestSeed`, so it is not a status read for waiting requests; use `getRequest`.
|
|
462
467
|
|
|
@@ -468,7 +473,7 @@ Selector `0xcf14de9d` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol
|
|
|
468
473
|
function getPendingRequestIds(uint256 fromId, uint256 limit) external view returns (uint256[] ids, uint256 nextCursor)
|
|
469
474
|
```
|
|
470
475
|
|
|
471
|
-
Selector `0xfdfe72e6` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines
|
|
476
|
+
Selector `0xfdfe72e6` · Caller: Anyone (view) · Source: `D20VRFCoordinator.sol` lines 314–333
|
|
472
477
|
|
|
473
478
|
Scans `limit` (1 to 256) request IDs from `fromId` (at least 1) and returns those not fulfilled, not refunded and not past their deadline, with the ID to continue from. Continue with `nextCursor` until it equals `nextRequestId()`. The answer can be stale by the time a transaction lands.
|
|
474
479
|
|
|
@@ -480,17 +485,17 @@ Views, callable by anyone. Nothing here has a setter except through an upgrade.
|
|
|
480
485
|
|
|
481
486
|
| Function | Selector | Meaning | Source |
|
|
482
487
|
| --- | --- | --- | --- |
|
|
483
|
-
| <a id="coordinator-fn-lastservedrequestid"></a>`lastServedRequestId() returns (uint256)` | `0xef54e226` | ID of the most recently accepted request; 0 before the first. | lines
|
|
484
|
-
| <a id="coordinator-fn-lastservedindex"></a>`lastServedIndex() returns (uint256)` | `0x7e176eed` | Number of accepted requests so far: the `serveIndex` of the latest `RequestServed`. | lines
|
|
485
|
-
| <a id="coordinator-fn-servedrequestat"></a>`servedRequestAt(uint256) returns (uint256)` | `0xf9a4acc6` | Request ID accepted at a serve index (from 1); 0 for an index not used yet. | lines
|
|
486
|
-
| <a id="coordinator-fn-keyhash"></a>`keyHash() returns (bytes32)` | `0x61728f39` | `keccak256(abi.encode(publicKey))` of the VRF key; indexed in `RandomnessRequested` and `ProofVerified`. | lines
|
|
487
|
-
| <a id="coordinator-fn-publickeyx"></a>`publicKeyX() returns (uint256)` | `0xfa6df55d` | x coordinate of the VRF public key. | line
|
|
488
|
-
| <a id="coordinator-fn-publickeyy"></a>`publicKeyY() returns (uint256)` | `0xd7a6f6e8` | y coordinate of the VRF public key. | line
|
|
489
|
-
| <a id="coordinator-fn-confirmationblocks"></a>`confirmationBlocks() returns (uint16)` | `0x460a58aa` | Blocks after the target block before the seed and proofs become available (1 to 64, set at initialization). | lines
|
|
490
|
-
| <a id="coordinator-fn-epochregistry"></a>`epochRegistry() returns (address)` | `0x2b12cb69` | The `EpochEntropy` proxy that supplies epochs and the keeper-share recipient. | line
|
|
491
|
-
| <a id="coordinator-fn-protocolconfigurationhash"></a>`protocolConfigurationHash() returns (bytes32)` | `0x155cf49b` | Hash of the initialized configuration (public key, initial fee recipient, initial minimum fee, confirmations, registry, initial catalog hash, first epoch start, epoch length 200) under `CONFIG_DOMAIN`. Bound into every transcript hash. | lines
|
|
492
|
-
| <a id="coordinator-fn-initialfeerecipient"></a>`initialFeeRecipient() returns (address)` | `0x308c2d6b` | Fee recipient given to `initialize`, used by replay. The live payout address is `feeRecipient()`. | lines
|
|
493
|
-
| <a id="coordinator-fn-initialminfee"></a>`initialMinFee() returns (uint256)` | `0xb3839295` | Minimum fee given to `initialize`, used by replay. The live minimum is `minFee()`. | lines
|
|
488
|
+
| <a id="coordinator-fn-lastservedrequestid"></a>`lastServedRequestId() returns (uint256)` | `0xef54e226` | ID of the most recently accepted request; 0 before the first. | lines 55, 452 |
|
|
489
|
+
| <a id="coordinator-fn-lastservedindex"></a>`lastServedIndex() returns (uint256)` | `0x7e176eed` | Number of accepted requests so far: the `serveIndex` of the latest `RequestServed`. | lines 56, 453 |
|
|
490
|
+
| <a id="coordinator-fn-servedrequestat"></a>`servedRequestAt(uint256) returns (uint256)` | `0xf9a4acc6` | Request ID accepted at a serve index (from 1); 0 for an index not used yet. | lines 57, 453 |
|
|
491
|
+
| <a id="coordinator-fn-keyhash"></a>`keyHash() returns (bytes32)` | `0x61728f39` | `keccak256(abi.encode(publicKey))` of the VRF key; indexed in `RandomnessRequested` and `ProofVerified`. | lines 39, 182 |
|
|
492
|
+
| <a id="coordinator-fn-publickeyx"></a>`publicKeyX() returns (uint256)` | `0xfa6df55d` | x coordinate of the VRF public key. | line 37 |
|
|
493
|
+
| <a id="coordinator-fn-publickeyy"></a>`publicKeyY() returns (uint256)` | `0xd7a6f6e8` | y coordinate of the VRF public key. | line 38 |
|
|
494
|
+
| <a id="coordinator-fn-confirmationblocks"></a>`confirmationBlocks() returns (uint16)` | `0x460a58aa` | Blocks after the target block before the seed and proofs become available (1 to 64, set at initialization). | lines 47, 583 |
|
|
495
|
+
| <a id="coordinator-fn-epochregistry"></a>`epochRegistry() returns (address)` | `0x2b12cb69` | The `EpochEntropy` proxy that supplies epochs and the keeper-share recipient. | line 35 |
|
|
496
|
+
| <a id="coordinator-fn-protocolconfigurationhash"></a>`protocolConfigurationHash() returns (bytes32)` | `0x155cf49b` | Hash of the initialized configuration (public key, initial fee recipient, initial minimum fee, confirmations, registry, initial catalog hash, first epoch start, epoch length 200) under `CONFIG_DOMAIN`. Bound into every transcript hash. | lines 34, 192 |
|
|
497
|
+
| <a id="coordinator-fn-initialfeerecipient"></a>`initialFeeRecipient() returns (address)` | `0x308c2d6b` | Fee recipient given to `initialize`, used by replay. The live payout address is `feeRecipient()`. | lines 41, 184 |
|
|
498
|
+
| <a id="coordinator-fn-initialminfee"></a>`initialMinFee() returns (uint256)` | `0xb3839295` | Minimum fee given to `initialize`, used by replay. The live minimum is `minFee()`. | lines 107, 187 |
|
|
494
499
|
|
|
495
500
|
### <a id="coordinator-owner-administration"></a>Owner administration
|
|
496
501
|
|
|
@@ -502,9 +507,9 @@ Owner-only functions revert `OwnableUnauthorizedAccount` for anyone else. No set
|
|
|
502
507
|
function setPricing(uint256 nextMinFee, uint16 multiplier, uint32 overhead) external
|
|
503
508
|
```
|
|
504
509
|
|
|
505
|
-
Selector `0x4c729ce6` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines
|
|
510
|
+
Selector `0x4c729ce6` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines 207–214
|
|
506
511
|
|
|
507
|
-
Sets `minFee` (at most `MAX_MIN_FEE`, 10 USDC), `feeMultiplier` (at most `MAX_FEE_MULTIPLIER`, 20) and `fulfillGasOverhead` (`MIN_FULFILL_GAS_OVERHEAD` to `MAX_FULFILL_GAS_OVERHEAD`, 100,000 to 2,000,000 gas). Affects requests created afterwards; open requests keep their escrowed fee.
|
|
512
|
+
Sets `minFee` (at most `MAX_MIN_FEE`, 10 USDC), `feeMultiplier` (at most `MAX_FEE_MULTIPLIER`, 20) and `fulfillGasOverhead` (`MIN_FULFILL_GAS_OVERHEAD` to `MAX_FULFILL_GAS_OVERHEAD`, 100,000 to 2,000,000 gas). `minFee` and `feeMultiplier` cannot both be zero, so a request is never free. Affects requests created afterwards; open requests keep their escrowed fee.
|
|
508
513
|
|
|
509
514
|
**Emits:** [`PricingChanged`](#coordinator-event-pricingchanged).
|
|
510
515
|
|
|
@@ -516,7 +521,7 @@ Sets `minFee` (at most `MAX_MIN_FEE`, 10 USDC), `feeMultiplier` (at most `MAX_FE
|
|
|
516
521
|
function setRefundBps(uint16 next) external
|
|
517
522
|
```
|
|
518
523
|
|
|
519
|
-
Selector `0x55a94d1b` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines
|
|
524
|
+
Selector `0x55a94d1b` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines 218–222
|
|
520
525
|
|
|
521
526
|
Sets the refund ratio for requests created afterwards, `MIN_REFUND_BPS` (5000) to 10000.
|
|
522
527
|
|
|
@@ -530,7 +535,7 @@ Sets the refund ratio for requests created afterwards, `MIN_REFUND_BPS` (5000) t
|
|
|
530
535
|
function setKeeperFeeBps(uint16 next) external
|
|
531
536
|
```
|
|
532
537
|
|
|
533
|
-
Selector `0xe140f0ca` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines
|
|
538
|
+
Selector `0xe140f0ca` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines 203–206
|
|
534
539
|
|
|
535
540
|
Sets the keeper share, 0 to 10000 basis points. Read at each acceptance, so it also applies to open requests accepted later.
|
|
536
541
|
|
|
@@ -544,7 +549,7 @@ Sets the keeper share, 0 to 10000 basis points. Read at each acceptance, so it a
|
|
|
544
549
|
function setFeeRecipient(address next) external
|
|
545
550
|
```
|
|
546
551
|
|
|
547
|
-
Selector `0xe74b981b` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines
|
|
552
|
+
Selector `0xe74b981b` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines 199–202
|
|
548
553
|
|
|
549
554
|
Sets the address allowed to withdraw `earnedFees`, including fees earned before the change. The zero address is rejected.
|
|
550
555
|
|
|
@@ -606,7 +611,7 @@ Completes the transfer to the caller and clears the nomination.
|
|
|
606
611
|
function renounceOwnership() external view
|
|
607
612
|
```
|
|
608
613
|
|
|
609
|
-
Selector `0x715018a6` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines
|
|
614
|
+
Selector `0x715018a6` · Caller: Owner · Source: `D20VRFCoordinator.sol` lines 196–197
|
|
610
615
|
|
|
611
616
|
Disabled and declared `view`: the owner gets `RenounceDisabled` and anyone else `OwnableUnauthorizedAccount`, so the contract always has an owner and upgrade authority can only move through an accepted transfer.
|
|
612
617
|
|
|
@@ -644,7 +649,7 @@ ERC-1822 check used by `upgradeToAndCall`. Returns the ERC-1967 implementation s
|
|
|
644
649
|
function initialize(uint256[2] publicKey, address initialOwner, address recipient, uint256 fee, uint16 confirmations, address registry, uint16 keeperBps) external
|
|
645
650
|
```
|
|
646
651
|
|
|
647
|
-
Selector `0x56b95b47` · Caller: Once, by `D20Proxy` at deployment · Source: `D20VRFCoordinator.sol` lines
|
|
652
|
+
Selector `0x56b95b47` · Caller: Once, by `D20Proxy` at deployment · Source: `D20VRFCoordinator.sol` lines 172–193
|
|
648
653
|
|
|
649
654
|
Sets owner, VRF public key, fee recipient, minimum fee, confirmations, registry and keeper share, with `feeMultiplier` 5, `fulfillGasOverhead` 300,000 and `refundBps` 10000. A public key that is not on the curve can also revert with an `Error(string)` from the verifier.
|
|
650
655
|
|
|
@@ -684,7 +689,7 @@ Views returning values fixed in the implementation code.
|
|
|
684
689
|
event RandomnessRequested(uint256 indexed requestId, address indexed consumer, bytes32 indexed keyHash, bytes32 clientSeed, uint64 requestBlock, uint32 callbackGasLimit, uint256 feePaid, address refundAddress, uint64 deadline)
|
|
685
690
|
```
|
|
686
691
|
|
|
687
|
-
Topic 0 `0xaf91b17376114a36689aa115062983bda7b43263a891fb8de0cc69d30d4240ad` · Emitted by: [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness) · Source: `D20VRFCoordinator.sol` lines
|
|
692
|
+
Topic 0 `0xaf91b17376114a36689aa115062983bda7b43263a891fb8de0cc69d30d4240ad` · Emitted by: [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness) · Source: `D20VRFCoordinator.sol` lines 141–145, 288–289
|
|
688
693
|
|
|
689
694
|
A request was created. `feePaid` is the escrowed fee, not `msg.value`; `deadline` is the block timestamp plus 60 seconds. Read `requestId` from this log in the request receipt, filtering by the coordinator address and event name: with an overpayment, `FeeOverpaymentCredited` comes first.
|
|
690
695
|
|
|
@@ -694,7 +699,7 @@ A request was created. `feePaid` is the escrowed fee, not `msg.value`; `deadline
|
|
|
694
699
|
event MappingRequested(uint256 indexed requestId, bytes32 indexed mappingHash, RandomnessMapping.Spec spec)
|
|
695
700
|
```
|
|
696
701
|
|
|
697
|
-
Topic 0 `0xbe1c93f40bd74ff9acd22dc40818e36d04e0b8a49b8238d0537c63219c2336dd` · Emitted by: [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness) · Source: `D20VRFCoordinator.sol` lines
|
|
702
|
+
Topic 0 `0xbe1c93f40bd74ff9acd22dc40818e36d04e0b8a49b8238d0537c63219c2336dd` · Emitted by: [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness) · Source: `D20VRFCoordinator.sol` lines 160, 290
|
|
698
703
|
|
|
699
704
|
Emitted right after `RandomnessRequested` with the stored spec (all zero for a raw request) and its hash.
|
|
700
705
|
|
|
@@ -704,7 +709,7 @@ Emitted right after `RandomnessRequested` with the stored spec (all zero for a r
|
|
|
704
709
|
event FeeOverpaymentCredited(uint256 indexed requestId, address indexed refundAddress, uint256 amount)
|
|
705
710
|
```
|
|
706
711
|
|
|
707
|
-
Topic 0 `0x8ae693db98f043f48e8f427375449ed5576aba97575e4f7f93ff2c1f6c75dcb5` · Emitted by: [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness) · Source: `D20VRFCoordinator.sol` lines
|
|
712
|
+
Topic 0 `0x8ae693db98f043f48e8f427375449ed5576aba97575e4f7f93ff2c1f6c75dcb5` · Emitted by: [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness) · Source: `D20VRFCoordinator.sol` lines 154, 282–287
|
|
708
713
|
|
|
709
714
|
`msg.value` exceeded the fee and `amount` was added to `refundCredits(refundAddress)`, independently of what happens to the request. Emitted before `RandomnessRequested`.
|
|
710
715
|
|
|
@@ -714,7 +719,7 @@ Topic 0 `0x8ae693db98f043f48e8f427375449ed5576aba97575e4f7f93ff2c1f6c75dcb5` ·
|
|
|
714
719
|
event BlockHashStored(uint256 indexed requestId, uint64 targetBlock, bytes32 blockHash)
|
|
715
720
|
```
|
|
716
721
|
|
|
717
|
-
Topic 0 `0x81bc3b4ec75af0fb9ed3521d7c766d8f995d04b0735c17d61ff9d468b0f04911` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`storeBlockHash`](#coordinator-fn-storeblockhash) · Source: `D20VRFCoordinator.sol` lines
|
|
722
|
+
Topic 0 `0x81bc3b4ec75af0fb9ed3521d7c766d8f995d04b0735c17d61ff9d468b0f04911` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`storeBlockHash`](#coordinator-fn-storeblockhash) · Source: `D20VRFCoordinator.sol` lines 146, 589–596
|
|
718
723
|
|
|
719
724
|
The target block hash of the request was stored. Emitted once per request: by `storeBlockHash`, or by fulfillment if the hash was not stored before.
|
|
720
725
|
|
|
@@ -724,7 +729,7 @@ The target block hash of the request was stored. Emitted once per request: by `s
|
|
|
724
729
|
event RequestServed(uint256 indexed requestId, uint256 indexed serveIndex)
|
|
725
730
|
```
|
|
726
731
|
|
|
727
|
-
Topic 0 `0x2012511e6cebd578bcabff1ef3346edb032cbab8622e9f23d9f15d7d1037267f` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
732
|
+
Topic 0 `0x2012511e6cebd578bcabff1ef3346edb032cbab8622e9f23d9f15d7d1037267f` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 162, 452–454
|
|
728
733
|
|
|
729
734
|
A proof was accepted. `serveIndex` counts accepted requests from 1 (`lastServedIndex`, `servedRequestAt`).
|
|
730
735
|
|
|
@@ -734,7 +739,7 @@ A proof was accepted. `serveIndex` counts accepted requests from 1 (`lastServedI
|
|
|
734
739
|
event ProofVerified(uint256 indexed requestId, bytes32 indexed keyHash, uint256 seed, bytes32 proofHash)
|
|
735
740
|
```
|
|
736
741
|
|
|
737
|
-
Topic 0 `0x55bb25be3ecd9f68ceae7cdabf4eabe2e0940bd8fc1c26c0d68ad5f7c5d08d22` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
742
|
+
Topic 0 `0x55bb25be3ecd9f68ceae7cdabf4eabe2e0940bd8fc1c26c0d68ad5f7c5d08d22` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 161, 455
|
|
738
743
|
|
|
739
744
|
Seed and hash of the accepted proof.
|
|
740
745
|
|
|
@@ -744,7 +749,7 @@ Seed and hash of the accepted proof.
|
|
|
744
749
|
event RandomnessFulfilled(uint256 indexed requestId, bytes32 randomness, address indexed submitter)
|
|
745
750
|
```
|
|
746
751
|
|
|
747
|
-
Topic 0 `0x9c82683ee7932041c254d206bcce4241d66a811d53ee7191799cc120777b2b87` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
752
|
+
Topic 0 `0x9c82683ee7932041c254d206bcce4241d66a811d53ee7191799cc120777b2b87` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 147, 456
|
|
748
753
|
|
|
749
754
|
A proof was accepted and `randomness` is final. `submitter` sent the transaction; `KeeperFeePaid` names the wallet that received the keeper share, which is `submitter` only when the registry authorizes it.
|
|
750
755
|
|
|
@@ -754,7 +759,7 @@ A proof was accepted and `randomness` is final. `submitter` sent the transaction
|
|
|
754
759
|
event FulfillmentEvidence(uint256 indexed requestId, bytes32 indexed transcriptHash, bytes packet)
|
|
755
760
|
```
|
|
756
761
|
|
|
757
|
-
Topic 0 `0xa121bbea897439460dfb08c3e6d6af064bc1f31e9477471828a87c5596b92e77` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
762
|
+
Topic 0 `0xa121bbea897439460dfb08c3e6d6af064bc1f31e9477471828a87c5596b92e77` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 165–166, 467–471
|
|
758
763
|
|
|
759
764
|
The accepted proof as a 416-byte ABI-encoded packet, indexed by `transcriptHash`. Decode it with `decodeEvidencePacket`; take evidence from this log, not from calldata, since a batch carries several proofs.
|
|
760
765
|
|
|
@@ -764,7 +769,7 @@ The accepted proof as a 416-byte ABI-encoded packet, indexed by `transcriptHash`
|
|
|
764
769
|
event CallbackAttempted(uint256 indexed requestId, bool success, uint32 gasLimit)
|
|
765
770
|
```
|
|
766
771
|
|
|
767
|
-
Topic 0 `0x70f64c0739e827900ae6f2e1317601653f4080bc857f423671fc58d5822f1f4a` · Emitted by: [`retryCallback`](#coordinator-fn-retrycallback), [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
772
|
+
Topic 0 `0x70f64c0739e827900ae6f2e1317601653f4080bc857f423671fc58d5822f1f4a` · Emitted by: [`retryCallback`](#coordinator-fn-retrycallback), [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 148, 630–647
|
|
768
773
|
|
|
769
774
|
Result of calling `rawFulfillRandomness` with `gasLimit` gas, at fulfillment and at each `retryCallback`. `success` false means the consumer reverted, ran out of gas or has no code; the word is accepted either way.
|
|
770
775
|
|
|
@@ -774,7 +779,7 @@ Result of calling `rawFulfillRandomness` with `gasLimit` gas, at fulfillment and
|
|
|
774
779
|
event KeeperFeePaid(uint256 indexed requestId, address indexed keeper, uint256 amount, bool paid)
|
|
775
780
|
```
|
|
776
781
|
|
|
777
|
-
Topic 0 `0x7605929b04963e0365f647d9ab12e7ac4aeba5474bb80f1e1554fccad0584683` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
782
|
+
Topic 0 `0x7605929b04963e0365f647d9ab12e7ac4aeba5474bb80f1e1554fccad0584683` · Emitted by: [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 155, 459–464
|
|
778
783
|
|
|
779
784
|
At acceptance, when the keeper share is non-zero: `amount` went to `keeper`, the submitter when the registry authorizes it and `committer()` otherwise, by a 30,000-gas transfer (`paid` true) or was added to `keeperCredits(keeper)` (`paid` false). Emitted after `CallbackAttempted`.
|
|
780
785
|
|
|
@@ -784,7 +789,7 @@ At acceptance, when the keeper share is non-zero: `amount` went to `keeper`, the
|
|
|
784
789
|
event FulfillmentSkipped(uint256 indexed requestId, uint8 reason)
|
|
785
790
|
```
|
|
786
791
|
|
|
787
|
-
Topic 0 `0x45d96bda73a91db41bdeab56114e5d7b9f42c9f38add9e2d2c6d6f5761203ca3` · Emitted by: [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines
|
|
792
|
+
Topic 0 `0x45d96bda73a91db41bdeab56114e5d7b9f42c9f38add9e2d2c6d6f5761203ca3` · Emitted by: [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch) · Source: `D20VRFCoordinator.sol` lines 163–164, 424–425
|
|
788
793
|
|
|
789
794
|
A batch member was left untouched: `reason` 1 already fulfilled, 2 refunded, 3 past its deadline.
|
|
790
795
|
|
|
@@ -794,7 +799,7 @@ A batch member was left untouched: `reason` 1 already fulfilled, 2 refunded, 3 p
|
|
|
794
799
|
event RequestRefundedTo(uint256 indexed requestId, address indexed refundAddress, uint256 amount, bool paid)
|
|
795
800
|
```
|
|
796
801
|
|
|
797
|
-
Topic 0 `0x0f6107d218fea62a20553f3700dba7c94dcf653bd2027c0bf1ebe0832f42a506` · Emitted by: [`refundRequest`](#coordinator-fn-refundrequest) · Source: `D20VRFCoordinator.sol` lines
|
|
802
|
+
Topic 0 `0x0f6107d218fea62a20553f3700dba7c94dcf653bd2027c0bf1ebe0832f42a506` · Emitted by: [`refundRequest`](#coordinator-fn-refundrequest) · Source: `D20VRFCoordinator.sol` lines 157, 505
|
|
798
803
|
|
|
799
804
|
An expired request was refunded: `amount` (`feePaid × requestRefundBps / 10000`) was sent to `refundAddress` (`paid` true) or added to its refund credit (`paid` false).
|
|
800
805
|
|
|
@@ -804,7 +809,7 @@ An expired request was refunded: `amount` (`feePaid × requestRefundBps / 10000`
|
|
|
804
809
|
event RefundCallbackAttempted(uint256 indexed requestId, address indexed consumer, bool success, uint32 gasLimit)
|
|
805
810
|
```
|
|
806
811
|
|
|
807
|
-
Topic 0 `0x88448c9fbcfc67f28f0266e82766e402ccd28115fbb84edb6e5b2597effe83d8` · Emitted by: [`refundRequest`](#coordinator-fn-refundrequest), [`retryRefundCallback`](#coordinator-fn-retryrefundcallback) · Source: `D20VRFCoordinator.sol` lines
|
|
812
|
+
Topic 0 `0x88448c9fbcfc67f28f0266e82766e402ccd28115fbb84edb6e5b2597effe83d8` · Emitted by: [`refundRequest`](#coordinator-fn-refundrequest), [`retryRefundCallback`](#coordinator-fn-retryrefundcallback) · Source: `D20VRFCoordinator.sol` lines 159, 519–530
|
|
808
813
|
|
|
809
814
|
Result of calling `onRefund(requestId)` on `consumer` with `gasLimit` gas: 100,000 at `refundRequest`, the caller's limit at `retryRefundCallback`.
|
|
810
815
|
|
|
@@ -816,7 +821,7 @@ Result of calling `onRefund(requestId)` on `consumer` with `gasLimit` gas: 100,0
|
|
|
816
821
|
event RefundCreditWithdrawn(address indexed owner, address indexed recipient, uint256 amount)
|
|
817
822
|
```
|
|
818
823
|
|
|
819
|
-
Topic 0 `0x9d520065b24fda0469128acd3f3078de7e43d70ab762aeea8c741bde25070192` · Emitted by: [`withdrawRefundCredit`](#coordinator-fn-withdrawrefundcredit) · Source: `D20VRFCoordinator.sol` lines
|
|
824
|
+
Topic 0 `0x9d520065b24fda0469128acd3f3078de7e43d70ab762aeea8c741bde25070192` · Emitted by: [`withdrawRefundCredit`](#coordinator-fn-withdrawrefundcredit) · Source: `D20VRFCoordinator.sol` lines 158, 541
|
|
820
825
|
|
|
821
826
|
`owner`, the credit holder (not the contract owner), withdrew `amount` of refund credit to `recipient`.
|
|
822
827
|
|
|
@@ -826,7 +831,7 @@ Topic 0 `0x9d520065b24fda0469128acd3f3078de7e43d70ab762aeea8c741bde25070192` ·
|
|
|
826
831
|
event KeeperCreditWithdrawn(address indexed keeper, address indexed recipient, uint256 amount)
|
|
827
832
|
```
|
|
828
833
|
|
|
829
|
-
Topic 0 `0x22f05c41968705c032a86a65f8fda7e64483ea5e6b6b27a920d1fbfab94267ba` · Emitted by: [`withdrawKeeperCredit`](#coordinator-fn-withdrawkeepercredit) · Source: `D20VRFCoordinator.sol` lines
|
|
834
|
+
Topic 0 `0x22f05c41968705c032a86a65f8fda7e64483ea5e6b6b27a920d1fbfab94267ba` · Emitted by: [`withdrawKeeperCredit`](#coordinator-fn-withdrawkeepercredit) · Source: `D20VRFCoordinator.sol` lines 156, 563
|
|
830
835
|
|
|
831
836
|
`keeper` withdrew `amount` of keeper credit to `recipient`.
|
|
832
837
|
|
|
@@ -836,7 +841,7 @@ Topic 0 `0x22f05c41968705c032a86a65f8fda7e64483ea5e6b6b27a920d1fbfab94267ba` ·
|
|
|
836
841
|
event FeesWithdrawn(address indexed recipient, uint256 amount)
|
|
837
842
|
```
|
|
838
843
|
|
|
839
|
-
Topic 0 `0xc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a` · Emitted by: [`withdrawFees`](#coordinator-fn-withdrawfees) · Source: `D20VRFCoordinator.sol` lines
|
|
844
|
+
Topic 0 `0xc0819c13be868895eb93e40eaceb96de976442fa1d404e5c55f14bb65a8c489a` · Emitted by: [`withdrawFees`](#coordinator-fn-withdrawfees) · Source: `D20VRFCoordinator.sol` lines 149, 552
|
|
840
845
|
|
|
841
846
|
The fee recipient withdrew `amount` of earned fees to `recipient`.
|
|
842
847
|
|
|
@@ -848,7 +853,7 @@ The fee recipient withdrew `amount` of earned fees to `recipient`.
|
|
|
848
853
|
event PricingChanged(uint256 minFee, uint16 feeMultiplier, uint32 fulfillGasOverhead)
|
|
849
854
|
```
|
|
850
855
|
|
|
851
|
-
Topic 0 `0x32806eb5e21ac2f5fb7d11f898c2995e19fdf203c8a5aeed8b824506cd0d44ff` · Emitted by: [`setPricing`](#coordinator-fn-setpricing) · Source: `D20VRFCoordinator.sol` lines
|
|
856
|
+
Topic 0 `0x32806eb5e21ac2f5fb7d11f898c2995e19fdf203c8a5aeed8b824506cd0d44ff` · Emitted by: [`setPricing`](#coordinator-fn-setpricing) · Source: `D20VRFCoordinator.sol` lines 152, 213
|
|
852
857
|
|
|
853
858
|
New `minFee`, `feeMultiplier` and `fulfillGasOverhead` for requests created afterwards.
|
|
854
859
|
|
|
@@ -858,7 +863,7 @@ New `minFee`, `feeMultiplier` and `fulfillGasOverhead` for requests created afte
|
|
|
858
863
|
event RefundBpsChanged(uint16 previousBps, uint16 newBps)
|
|
859
864
|
```
|
|
860
865
|
|
|
861
|
-
Topic 0 `0x21e3c4cf3007c4ee385a3936593ff4cfa23fc17bca1175b6350c546f9810e0d8` · Emitted by: [`setRefundBps`](#coordinator-fn-setrefundbps) · Source: `D20VRFCoordinator.sol` lines
|
|
866
|
+
Topic 0 `0x21e3c4cf3007c4ee385a3936593ff4cfa23fc17bca1175b6350c546f9810e0d8` · Emitted by: [`setRefundBps`](#coordinator-fn-setrefundbps) · Source: `D20VRFCoordinator.sol` lines 153, 221
|
|
862
867
|
|
|
863
868
|
New refund ratio for requests created afterwards.
|
|
864
869
|
|
|
@@ -868,7 +873,7 @@ New refund ratio for requests created afterwards.
|
|
|
868
873
|
event KeeperFeeBpsChanged(uint16 previousBps, uint16 newBps)
|
|
869
874
|
```
|
|
870
875
|
|
|
871
|
-
Topic 0 `0xa648a60f1d22511c1cc898ca69b633d1a1114079e83734b9ab9a13e0e28c68b7` · Emitted by: [`setKeeperFeeBps`](#coordinator-fn-setkeeperfeebps) · Source: `D20VRFCoordinator.sol` lines
|
|
876
|
+
Topic 0 `0xa648a60f1d22511c1cc898ca69b633d1a1114079e83734b9ab9a13e0e28c68b7` · Emitted by: [`setKeeperFeeBps`](#coordinator-fn-setkeeperfeebps) · Source: `D20VRFCoordinator.sol` lines 151, 205
|
|
872
877
|
|
|
873
878
|
New keeper share, applied at later acceptances, including of requests already open.
|
|
874
879
|
|
|
@@ -878,7 +883,7 @@ New keeper share, applied at later acceptances, including of requests already op
|
|
|
878
883
|
event FeeRecipientChanged(address indexed previousRecipient, address indexed newRecipient)
|
|
879
884
|
```
|
|
880
885
|
|
|
881
|
-
Topic 0 `0x0bc21fe5c3ab742ff1d15b5c4477ffbacf1167e618228078fa625edebe7f331d` · Emitted by: [`setFeeRecipient`](#coordinator-fn-setfeerecipient) · Source: `D20VRFCoordinator.sol` lines
|
|
886
|
+
Topic 0 `0x0bc21fe5c3ab742ff1d15b5c4477ffbacf1167e618228078fa625edebe7f331d` · Emitted by: [`setFeeRecipient`](#coordinator-fn-setfeerecipient) · Source: `D20VRFCoordinator.sol` lines 150, 201
|
|
882
887
|
|
|
883
888
|
New address allowed to withdraw earned fees.
|
|
884
889
|
|
|
@@ -928,7 +933,7 @@ Topic 0 `0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2` ·
|
|
|
928
933
|
|
|
929
934
|
#### <a id="coordinator-error-contractconsumerrequired"></a>`ContractConsumerRequired`
|
|
930
935
|
|
|
931
|
-
`error ContractConsumerRequired()` · Selector `0x2b99db1e` · Source: `D20VRFCoordinator.sol` lines
|
|
936
|
+
`error ContractConsumerRequired()` · Selector `0x2b99db1e` · Source: `D20VRFCoordinator.sol` lines 113, 255
|
|
932
937
|
|
|
933
938
|
**Raised by:** [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness).
|
|
934
939
|
|
|
@@ -938,7 +943,7 @@ The caller of a request function has no code: an externally owned account, or a
|
|
|
938
943
|
|
|
939
944
|
#### <a id="coordinator-error-invalidrefundaddress"></a>`InvalidRefundAddress`
|
|
940
945
|
|
|
941
|
-
`error InvalidRefundAddress()` · Selector `0xe2fe2726` · Source: `D20VRFCoordinator.sol` lines
|
|
946
|
+
`error InvalidRefundAddress()` · Selector `0xe2fe2726` · Source: `D20VRFCoordinator.sol` lines 127, 256, 534
|
|
942
947
|
|
|
943
948
|
**Raised by:** [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness), [`withdrawRefundCredit`](#coordinator-fn-withdrawrefundcredit).
|
|
944
949
|
|
|
@@ -948,7 +953,7 @@ A request named the zero address as refund address, or `withdrawRefundCredit` na
|
|
|
948
953
|
|
|
949
954
|
#### <a id="coordinator-error-invalidcallbackgas"></a>`InvalidCallbackGas`
|
|
950
955
|
|
|
951
|
-
`error InvalidCallbackGas()` · Selector `0x35883c54` · Source: `D20VRFCoordinator.sol` lines
|
|
956
|
+
`error InvalidCallbackGas()` · Selector `0x35883c54` · Source: `D20VRFCoordinator.sol` lines 115, 479, 515, 626–628
|
|
952
957
|
|
|
953
958
|
**Raised by:** [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness), [`retryCallback`](#coordinator-fn-retrycallback), [`retryRefundCallback`](#coordinator-fn-retryrefundcallback).
|
|
954
959
|
|
|
@@ -958,7 +963,7 @@ A gas limit is out of range: a request `callbackGasLimit` outside 30,000 to 1,00
|
|
|
958
963
|
|
|
959
964
|
#### <a id="coordinator-error-incorrectfee"></a>`IncorrectFee`
|
|
960
965
|
|
|
961
|
-
`error IncorrectFee(uint256 expected, uint256 actual)` · Selector `0xdcf6afcb` · Source: `D20VRFCoordinator.sol` lines
|
|
966
|
+
`error IncorrectFee(uint256 expected, uint256 actual)` · Selector `0xdcf6afcb` · Source: `D20VRFCoordinator.sol` lines 114, 259
|
|
962
967
|
|
|
963
968
|
**Raised by:** [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness).
|
|
964
969
|
|
|
@@ -968,7 +973,7 @@ A gas limit is out of range: a request `callbackGasLimit` outside 30,000 to 1,00
|
|
|
968
973
|
|
|
969
974
|
#### <a id="coordinator-error-feeoverflow"></a>`FeeOverflow`
|
|
970
975
|
|
|
971
|
-
`error FeeOverflow()` · Selector `0x8181adca` · Source: `D20VRFCoordinator.sol` lines
|
|
976
|
+
`error FeeOverflow()` · Selector `0x8181adca` · Source: `D20VRFCoordinator.sol` lines 138, 229
|
|
972
977
|
|
|
973
978
|
**Raised by:** [`quoteFee`](#coordinator-fn-quotefee), [`quoteFeeAt`](#coordinator-fn-quotefeeat), [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness).
|
|
974
979
|
|
|
@@ -988,7 +993,7 @@ The spec breaks the rules for its operation (README [Randomness options](README.
|
|
|
988
993
|
|
|
989
994
|
#### <a id="coordinator-error-epochunavailable"></a>`EpochUnavailable`
|
|
990
995
|
|
|
991
|
-
`error EpochUnavailable()` · Selector `0x0b3487b8` · Source: `D20VRFCoordinator.sol` lines
|
|
996
|
+
`error EpochUnavailable()` · Selector `0x0b3487b8` · Source: `D20VRFCoordinator.sol` lines 111, 263
|
|
992
997
|
|
|
993
998
|
**Raised by:** [`requestRandomness`](#coordinator-fn-requestrandomness), [`requestMappedRandomness`](#coordinator-fn-requestmappedrandomness).
|
|
994
999
|
|
|
@@ -1000,7 +1005,7 @@ The request block is before the registry's first epoch: `epochForBlock(block.num
|
|
|
1000
1005
|
|
|
1001
1006
|
#### <a id="coordinator-error-unknownrequest"></a>`UnknownRequest`
|
|
1002
1007
|
|
|
1003
|
-
`error UnknownRequest()` · Selector `0x6d080297` · Source: `D20VRFCoordinator.sol` lines
|
|
1008
|
+
`error UnknownRequest()` · Selector `0x6d080297` · Source: `D20VRFCoordinator.sol` lines 116, 566–569
|
|
1004
1009
|
|
|
1005
1010
|
**Raised by:** [`getRequest`](#coordinator-fn-getrequest), [`getMapping`](#coordinator-fn-getmapping), [`getMappedResult`](#coordinator-fn-getmappedresult), [`requestFeePaid`](#coordinator-fn-requestfeepaid), [`requestRefundBps`](#coordinator-fn-requestrefundbps), [`refundRequest`](#coordinator-fn-refundrequest), [`retryCallback`](#coordinator-fn-retrycallback), [`retryRefundCallback`](#coordinator-fn-retryrefundcallback), [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`storeBlockHash`](#coordinator-fn-storeblockhash), [`verifyRequestProof`](#coordinator-fn-verifyrequestproof), [`requestSeed`](#coordinator-fn-requestseed), [`getProofContext`](#coordinator-fn-getproofcontext).
|
|
1006
1011
|
|
|
@@ -1010,7 +1015,7 @@ No request has this ID: 0, or not below `nextRequestId()`. An unknown ID also re
|
|
|
1010
1015
|
|
|
1011
1016
|
#### <a id="coordinator-error-notfulfilled"></a>`NotFulfilled`
|
|
1012
1017
|
|
|
1013
|
-
`error NotFulfilled()` · Selector `0x07bc6c3e` · Source: `D20VRFCoordinator.sol` lines
|
|
1018
|
+
`error NotFulfilled()` · Selector `0x07bc6c3e` · Source: `D20VRFCoordinator.sol` lines 120, 351, 476
|
|
1014
1019
|
|
|
1015
1020
|
**Raised by:** [`getMappedResult`](#coordinator-fn-getmappedresult), [`retryCallback`](#coordinator-fn-retrycallback).
|
|
1016
1021
|
|
|
@@ -1020,7 +1025,7 @@ No request has this ID: 0, or not below `nextRequestId()`. An unknown ID also re
|
|
|
1020
1025
|
|
|
1021
1026
|
#### <a id="coordinator-error-alreadydelivered"></a>`AlreadyDelivered`
|
|
1022
1027
|
|
|
1023
|
-
`error AlreadyDelivered()` · Selector `0xb9f79653` · Source: `D20VRFCoordinator.sol` lines
|
|
1028
|
+
`error AlreadyDelivered()` · Selector `0xb9f79653` · Source: `D20VRFCoordinator.sol` lines 121, 477
|
|
1024
1029
|
|
|
1025
1030
|
**Raised by:** [`retryCallback`](#coordinator-fn-retrycallback).
|
|
1026
1031
|
|
|
@@ -1030,7 +1035,7 @@ No request has this ID: 0, or not below `nextRequestId()`. An unknown ID also re
|
|
|
1030
1035
|
|
|
1031
1036
|
#### <a id="coordinator-error-refundnotavailable"></a>`RefundNotAvailable`
|
|
1032
1037
|
|
|
1033
|
-
`error RefundNotAvailable()` · Selector `0x0b4d6981` · Source: `D20VRFCoordinator.sol` lines
|
|
1038
|
+
`error RefundNotAvailable()` · Selector `0x0b4d6981` · Source: `D20VRFCoordinator.sol` lines 130, 488
|
|
1034
1039
|
|
|
1035
1040
|
**Raised by:** [`refundRequest`](#coordinator-fn-refundrequest).
|
|
1036
1041
|
|
|
@@ -1040,7 +1045,7 @@ No request has this ID: 0, or not below `nextRequestId()`. An unknown ID also re
|
|
|
1040
1045
|
|
|
1041
1046
|
#### <a id="coordinator-error-notrefunded"></a>`NotRefunded`
|
|
1042
1047
|
|
|
1043
|
-
`error NotRefunded()` · Selector `0xfae7079c` · Source: `D20VRFCoordinator.sol` lines
|
|
1048
|
+
`error NotRefunded()` · Selector `0xfae7079c` · Source: `D20VRFCoordinator.sol` lines 133, 512
|
|
1044
1049
|
|
|
1045
1050
|
**Raised by:** [`retryRefundCallback`](#coordinator-fn-retryrefundcallback).
|
|
1046
1051
|
|
|
@@ -1050,7 +1055,7 @@ No request has this ID: 0, or not below `nextRequestId()`. An unknown ID also re
|
|
|
1050
1055
|
|
|
1051
1056
|
#### <a id="coordinator-error-refundcallbackalreadydelivered"></a>`RefundCallbackAlreadyDelivered`
|
|
1052
1057
|
|
|
1053
|
-
`error RefundCallbackAlreadyDelivered()` · Selector `0x6502f8ae` · Source: `D20VRFCoordinator.sol` lines
|
|
1058
|
+
`error RefundCallbackAlreadyDelivered()` · Selector `0x6502f8ae` · Source: `D20VRFCoordinator.sol` lines 134, 513
|
|
1054
1059
|
|
|
1055
1060
|
**Raised by:** [`retryRefundCallback`](#coordinator-fn-retryrefundcallback).
|
|
1056
1061
|
|
|
@@ -1060,19 +1065,19 @@ No request has this ID: 0, or not below `nextRequestId()`. An unknown ID also re
|
|
|
1060
1065
|
|
|
1061
1066
|
#### <a id="coordinator-error-insufficientcallbackgas"></a>`InsufficientCallbackGas`
|
|
1062
1067
|
|
|
1063
|
-
`error InsufficientCallbackGas()` · Selector `0xa2c23f0d` · Source: `D20VRFCoordinator.sol` lines
|
|
1068
|
+
`error InsufficientCallbackGas()` · Selector `0xa2c23f0d` · Source: `D20VRFCoordinator.sol` lines 124, 421, 497, 522, 638–639
|
|
1064
1069
|
|
|
1065
1070
|
**Raised by:** [`refundRequest`](#coordinator-fn-refundrequest), [`retryCallback`](#coordinator-fn-retrycallback), [`retryRefundCallback`](#coordinator-fn-retryrefundcallback), [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch).
|
|
1066
1071
|
|
|
1067
|
-
Too little gas remained to forward the full callback budget and keep the coordinator's reserve: `gasLimit + gasLimit/63 + 140,000` before a fulfillment callback, `100,000 + 100,000/63 + 140,000` after refund settlement, `gasLimit + gasLimit/63 + 50,000` before a refund notification. The coordinator reverts instead of forwarding less.
|
|
1072
|
+
Too little gas remained to forward the full callback budget and keep the coordinator's reserve: `gasLimit + gasLimit/63 + 140,000` before a fulfillment callback, `100,000 + 100,000/63 + 140,000` after refund settlement, `gasLimit + gasLimit/63 + 50,000` before a refund notification, and `140,000 + Σ(callbackGasLimit + callbackGasLimit / 63 + 400,000)` over the served members before `fulfillRandomnessBatch` reveals any result. The coordinator reverts instead of forwarding less.
|
|
1068
1073
|
|
|
1069
|
-
**What to do:** Raise the transaction gas limit: 400,000 for `refundRequest`, `gasLimit + 250,000` for `retryCallback`, `gasLimit + 150,000` for `retryRefundCallback` (README [Gas for refund and retry calls](README.md#gas-for-refund-and-retry-calls)). `eth_estimateGas` finds the minimum.
|
|
1074
|
+
**What to do:** Raise the transaction gas limit: 400,000 for `refundRequest`, `gasLimit + 250,000` for `retryCallback`, `gasLimit + 150,000` for `retryRefundCallback` (README [Gas for refund and retry calls](README.md#gas-for-refund-and-retry-calls)); a keeper sizes a batch to the sum above. `eth_estimateGas` finds the minimum.
|
|
1070
1075
|
|
|
1071
1076
|
**Credits and withdrawals**
|
|
1072
1077
|
|
|
1073
1078
|
#### <a id="coordinator-error-norefundcredit"></a>`NoRefundCredit`
|
|
1074
1079
|
|
|
1075
|
-
`error NoRefundCredit()` · Selector `0x1d59da8e` · Source: `D20VRFCoordinator.sol` lines
|
|
1080
|
+
`error NoRefundCredit()` · Selector `0x1d59da8e` · Source: `D20VRFCoordinator.sol` lines 131, 536
|
|
1076
1081
|
|
|
1077
1082
|
**Raised by:** [`withdrawRefundCredit`](#coordinator-fn-withdrawrefundcredit).
|
|
1078
1083
|
|
|
@@ -1082,7 +1087,7 @@ Too little gas remained to forward the full callback budget and keep the coordin
|
|
|
1082
1087
|
|
|
1083
1088
|
#### <a id="coordinator-error-transferfailed"></a>`TransferFailed`
|
|
1084
1089
|
|
|
1085
|
-
`error TransferFailed()` · Selector `0x90b8ec18` · Source: `D20VRFCoordinator.sol` lines
|
|
1090
|
+
`error TransferFailed()` · Selector `0x90b8ec18` · Source: `D20VRFCoordinator.sol` lines 126, 540, 551, 562
|
|
1086
1091
|
|
|
1087
1092
|
**Raised by:** [`withdrawRefundCredit`](#coordinator-fn-withdrawrefundcredit), [`withdrawFees`](#coordinator-fn-withdrawfees), [`withdrawKeeperCredit`](#coordinator-fn-withdrawkeepercredit).
|
|
1088
1093
|
|
|
@@ -1092,7 +1097,7 @@ The `recipient` of `withdrawRefundCredit`, `withdrawFees` or `withdrawKeeperCred
|
|
|
1092
1097
|
|
|
1093
1098
|
#### <a id="coordinator-error-onlyfeerecipient"></a>`OnlyFeeRecipient`
|
|
1094
1099
|
|
|
1095
|
-
`error OnlyFeeRecipient()` · Selector `0x07d8ed3d` · Source: `D20VRFCoordinator.sol` lines
|
|
1100
|
+
`error OnlyFeeRecipient()` · Selector `0x07d8ed3d` · Source: `D20VRFCoordinator.sol` lines 125, 546
|
|
1096
1101
|
|
|
1097
1102
|
**Raised by:** [`withdrawFees`](#coordinator-fn-withdrawfees).
|
|
1098
1103
|
|
|
@@ -1102,7 +1107,7 @@ The `recipient` of `withdrawRefundCredit`, `withdrawFees` or `withdrawKeeperCred
|
|
|
1102
1107
|
|
|
1103
1108
|
#### <a id="coordinator-error-nokeepercredit"></a>`NoKeeperCredit`
|
|
1104
1109
|
|
|
1105
|
-
`error NoKeeperCredit()` · Selector `0x0d106640` · Source: `D20VRFCoordinator.sol` lines
|
|
1110
|
+
`error NoKeeperCredit()` · Selector `0x0d106640` · Source: `D20VRFCoordinator.sol` lines 132, 558
|
|
1106
1111
|
|
|
1107
1112
|
**Raised by:** [`withdrawKeeperCredit`](#coordinator-fn-withdrawkeepercredit).
|
|
1108
1113
|
|
|
@@ -1114,7 +1119,7 @@ The `recipient` of `withdrawRefundCredit`, `withdrawFees` or `withdrawKeeperCred
|
|
|
1114
1119
|
|
|
1115
1120
|
#### <a id="coordinator-error-notready"></a>`NotReady`
|
|
1116
1121
|
|
|
1117
|
-
`error NotReady()` · Selector `0x9488aaa6` · Source: `D20VRFCoordinator.sol` lines
|
|
1122
|
+
`error NotReady()` · Selector `0x9488aaa6` · Source: `D20VRFCoordinator.sol` lines 117, 583
|
|
1118
1123
|
|
|
1119
1124
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`storeBlockHash`](#coordinator-fn-storeblockhash), [`verifyRequestProof`](#coordinator-fn-verifyrequestproof), [`requestSeed`](#coordinator-fn-requestseed), [`getProofContext`](#coordinator-fn-getproofcontext).
|
|
1120
1125
|
|
|
@@ -1124,7 +1129,7 @@ The request cannot be proven yet: its epoch packet is not published, or `block.n
|
|
|
1124
1129
|
|
|
1125
1130
|
#### <a id="coordinator-error-blockhashunavailable"></a>`BlockHashUnavailable`
|
|
1126
1131
|
|
|
1127
|
-
`error BlockHashUnavailable()` · Selector `0xbfc9f0d3` · Source: `D20VRFCoordinator.sol` lines
|
|
1132
|
+
`error BlockHashUnavailable()` · Selector `0xbfc9f0d3` · Source: `D20VRFCoordinator.sol` lines 118, 586
|
|
1128
1133
|
|
|
1129
1134
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`storeBlockHash`](#coordinator-fn-storeblockhash), [`verifyRequestProof`](#coordinator-fn-verifyrequestproof), [`requestSeed`](#coordinator-fn-requestseed), [`getProofContext`](#coordinator-fn-getproofcontext).
|
|
1130
1135
|
|
|
@@ -1134,7 +1139,7 @@ The target block hash was never stored and is outside the 256-block `BLOCKHASH`
|
|
|
1134
1139
|
|
|
1135
1140
|
#### <a id="coordinator-error-alreadyfulfilled"></a>`AlreadyFulfilled`
|
|
1136
1141
|
|
|
1137
|
-
`error AlreadyFulfilled()` · Selector `0x4a4117f9` · Source: `D20VRFCoordinator.sol` lines
|
|
1142
|
+
`error AlreadyFulfilled()` · Selector `0x4a4117f9` · Source: `D20VRFCoordinator.sol` lines 119, 397
|
|
1138
1143
|
|
|
1139
1144
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness).
|
|
1140
1145
|
|
|
@@ -1144,7 +1149,7 @@ The target block hash was never stored and is outside the 256-block `BLOCKHASH`
|
|
|
1144
1149
|
|
|
1145
1150
|
#### <a id="coordinator-error-requestrefunded"></a>`RequestRefunded`
|
|
1146
1151
|
|
|
1147
|
-
`error RequestRefunded()` · Selector `0xe0dec416` · Source: `D20VRFCoordinator.sol` lines
|
|
1152
|
+
`error RequestRefunded()` · Selector `0xe0dec416` · Source: `D20VRFCoordinator.sol` lines 129, 398
|
|
1148
1153
|
|
|
1149
1154
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness).
|
|
1150
1155
|
|
|
@@ -1154,7 +1159,7 @@ The target block hash was never stored and is outside the 256-block `BLOCKHASH`
|
|
|
1154
1159
|
|
|
1155
1160
|
#### <a id="coordinator-error-requestexpired"></a>`RequestExpired`
|
|
1156
1161
|
|
|
1157
|
-
`error RequestExpired()` · Selector `0xfef01cd2` · Source: `D20VRFCoordinator.sol` lines
|
|
1162
|
+
`error RequestExpired()` · Selector `0xfef01cd2` · Source: `D20VRFCoordinator.sol` lines 128, 399
|
|
1158
1163
|
|
|
1159
1164
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness).
|
|
1160
1165
|
|
|
@@ -1164,7 +1169,7 @@ The target block hash was never stored and is outside the 256-block `BLOCKHASH`
|
|
|
1164
1169
|
|
|
1165
1170
|
#### <a id="coordinator-error-wrongpublickey"></a>`WrongPublicKey`
|
|
1166
1171
|
|
|
1167
|
-
`error WrongPublicKey()` · Selector `0x2b0bb68e` · Source: `D20VRFCoordinator.sol` lines
|
|
1172
|
+
`error WrongPublicKey()` · Selector `0x2b0bb68e` · Source: `D20VRFCoordinator.sol` lines 122, 611
|
|
1168
1173
|
|
|
1169
1174
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`verifyRequestProof`](#coordinator-fn-verifyrequestproof).
|
|
1170
1175
|
|
|
@@ -1174,7 +1179,7 @@ The proof's `pk` is not the coordinator's VRF key.
|
|
|
1174
1179
|
|
|
1175
1180
|
#### <a id="coordinator-error-wrongseed"></a>`WrongSeed`
|
|
1176
1181
|
|
|
1177
|
-
`error WrongSeed()` · Selector `0xf36cbea4` · Source: `D20VRFCoordinator.sol` lines
|
|
1182
|
+
`error WrongSeed()` · Selector `0xf36cbea4` · Source: `D20VRFCoordinator.sol` lines 123, 613
|
|
1178
1183
|
|
|
1179
1184
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch), [`verifyRequestProof`](#coordinator-fn-verifyrequestproof).
|
|
1180
1185
|
|
|
@@ -1184,7 +1189,7 @@ The proof's `seed` differs from `requestSeed(requestId)`.
|
|
|
1184
1189
|
|
|
1185
1190
|
#### <a id="coordinator-error-evidencepackettoolarge"></a>`EvidencePacketTooLarge`
|
|
1186
1191
|
|
|
1187
|
-
`error EvidencePacketTooLarge()` · Selector `0xcfbc3ebf` · Source: `D20VRFCoordinator.sol` lines
|
|
1192
|
+
`error EvidencePacketTooLarge()` · Selector `0xcfbc3ebf` · Source: `D20VRFCoordinator.sol` lines 136, 469
|
|
1188
1193
|
|
|
1189
1194
|
**Raised by:** [`fulfillRandomness`](#coordinator-fn-fulfillrandomness), [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch).
|
|
1190
1195
|
|
|
@@ -1194,7 +1199,7 @@ The encoded proof exceeds `MAX_EVIDENCE_PACKET_BYTES`. A proof always encodes to
|
|
|
1194
1199
|
|
|
1195
1200
|
#### <a id="coordinator-error-invalidbatch"></a>`InvalidBatch`
|
|
1196
1201
|
|
|
1197
|
-
`error InvalidBatch()` · Selector `0x33b094a1` · Source: `D20VRFCoordinator.sol` lines
|
|
1202
|
+
`error InvalidBatch()` · Selector `0x33b094a1` · Source: `D20VRFCoordinator.sol` lines 139, 410
|
|
1198
1203
|
|
|
1199
1204
|
**Raised by:** [`fulfillRandomnessBatch`](#coordinator-fn-fulfillrandomnessbatch).
|
|
1200
1205
|
|
|
@@ -1204,7 +1209,7 @@ The encoded proof exceeds `MAX_EVIDENCE_PACKET_BYTES`. A proof always encodes to
|
|
|
1204
1209
|
|
|
1205
1210
|
#### <a id="coordinator-error-invalidscan"></a>`InvalidScan`
|
|
1206
1211
|
|
|
1207
|
-
`error InvalidScan()` · Selector `0x3e6249a2` · Source: `D20VRFCoordinator.sol` lines
|
|
1212
|
+
`error InvalidScan()` · Selector `0x3e6249a2` · Source: `D20VRFCoordinator.sol` lines 135, 320
|
|
1208
1213
|
|
|
1209
1214
|
**Raised by:** [`getPendingRequestIds`](#coordinator-fn-getpendingrequestids).
|
|
1210
1215
|
|
|
@@ -1216,17 +1221,17 @@ The encoded proof exceeds `MAX_EVIDENCE_PACKET_BYTES`. A proof always encodes to
|
|
|
1216
1221
|
|
|
1217
1222
|
#### <a id="coordinator-error-invalidconfig"></a>`InvalidConfig`
|
|
1218
1223
|
|
|
1219
|
-
`error InvalidConfig()` · Selector `0x35be3ac8` · Source: `D20VRFCoordinator.sol` lines
|
|
1224
|
+
`error InvalidConfig()` · Selector `0x35be3ac8` · Source: `D20VRFCoordinator.sol` lines 110, 176–177, 200, 204, 209, 211, 220, 547, 556
|
|
1220
1225
|
|
|
1221
1226
|
**Raised by:** [`withdrawFees`](#coordinator-fn-withdrawfees), [`withdrawKeeperCredit`](#coordinator-fn-withdrawkeepercredit), [`setPricing`](#coordinator-fn-setpricing), [`setRefundBps`](#coordinator-fn-setrefundbps), [`setKeeperFeeBps`](#coordinator-fn-setkeeperfeebps), [`setFeeRecipient`](#coordinator-fn-setfeerecipient), [`initialize`](#coordinator-fn-initialize).
|
|
1222
1227
|
|
|
1223
|
-
A value is out of bounds: in `initialize` (zero fee recipient, confirmations 0 or above 64, keeper share above 10000, minimum fee above 10 USDC, registry without code), `setFeeRecipient` with zero, `setKeeperFeeBps` above 10000, `setPricing` outside its bounds, `setRefundBps` outside 5000 to 10000, or a zero `recipient` for `withdrawFees` or `withdrawKeeperCredit`.
|
|
1228
|
+
A value is out of bounds: in `initialize` (zero fee recipient, confirmations 0 or above 64, keeper share above 10000, minimum fee above 10 USDC, registry without code), `setFeeRecipient` with zero, `setKeeperFeeBps` above 10000, `setPricing` outside its bounds or with `minFee` and `feeMultiplier` both zero, `setRefundBps` outside 5000 to 10000, or a zero `recipient` for `withdrawFees` or `withdrawKeeperCredit`.
|
|
1224
1229
|
|
|
1225
1230
|
**What to do:** Use values within the bounds given for each function.
|
|
1226
1231
|
|
|
1227
1232
|
#### <a id="coordinator-error-invalidpublickey"></a>`InvalidPublicKey`
|
|
1228
1233
|
|
|
1229
|
-
`error InvalidPublicKey()` · Selector `0xa2d0fee8` · Source: `D20VRFCoordinator.sol` lines
|
|
1234
|
+
`error InvalidPublicKey()` · Selector `0xa2d0fee8` · Source: `D20VRFCoordinator.sol` lines 112, 179
|
|
1230
1235
|
|
|
1231
1236
|
**Raised by:** [`initialize`](#coordinator-fn-initialize).
|
|
1232
1237
|
|
|
@@ -1266,7 +1271,7 @@ A `nonReentrant` coordinator function (a request, `storeBlockHash`, a fulfillmen
|
|
|
1266
1271
|
|
|
1267
1272
|
#### <a id="coordinator-error-renouncedisabled"></a>`RenounceDisabled`
|
|
1268
1273
|
|
|
1269
|
-
`error RenounceDisabled()` · Selector `0x89051165` · Source: `D20VRFCoordinator.sol` lines
|
|
1274
|
+
`error RenounceDisabled()` · Selector `0x89051165` · Source: `D20VRFCoordinator.sol` lines 137, 197
|
|
1270
1275
|
|
|
1271
1276
|
**Raised by:** [`renounceOwnership`](#coordinator-fn-renounceownership).
|
|
1272
1277
|
|
|
@@ -1358,7 +1363,9 @@ The initialization call made by `upgradeToAndCall` reverted without revert data.
|
|
|
1358
1363
|
|
|
1359
1364
|
The epoch registry. A consumer never needs to call it: a request fixes its epoch automatically, and the coordinator reads the registry for targets and for the keeper-share recipient. The first group and the events matter to consumers and verifiers (README [Replay and verification](README.md#replay-and-verification)); publication and administration are listed for completeness.
|
|
1360
1365
|
|
|
1361
|
-
Epoch sources are recipes in an owner-managed, append-only registry: each has an id, a canonical request whose `keccak256` is the query hash its signer signs, a data template that fixes the exact signed bytes the registry accepts (README [Data templates](README.md#data-templates)) and the
|
|
1366
|
+
Epoch sources are recipes in an owner-managed, append-only registry: each has an id, a canonical request whose `keccak256` is the query hash its signer signs, a data template that fixes the exact signed bytes the registry accepts (README [Data templates](README.md#data-templates)) and the body keepers send: the JSON they post to the provider gateway, or a beacon's canonical request. A catalog lists 1 to `MAX_SOURCES` registered recipes with one signer each; each epoch selects from the catalog in force for it (`catalogAt`).
|
|
1367
|
+
|
|
1368
|
+
A recipe is one of two kinds. A signed API recipe (`registerRecipe`) commits a provider's signed record: the signature is an EIP-191 signature of the recipe's signer over the query hash, timestamp and data. A beacon recipe (`registerBeacon`) commits one round of a public randomness beacon such as drand: the data is the round number, the timestamp the round's scheduled time and the signature the beacon's, which the verifier recorded in its registration (`beaconOf`) checks. Its catalog signer is `slotSigner(recipe)`, an identity derived from the registration. Replay needs the registration of every beacon recipe an epoch used (README [Beacon epochs](README.md#beacon-epochs)).
|
|
1362
1369
|
|
|
1363
1370
|
### <a id="registry-types"></a>Types
|
|
1364
1371
|
|
|
@@ -1366,7 +1373,7 @@ Epoch sources are recipes in an owner-managed, append-only registry: each has an
|
|
|
1366
1373
|
|
|
1367
1374
|
Returned by `getEpoch`; all zero until the epoch is published.
|
|
1368
1375
|
|
|
1369
|
-
Source: `EpochEntropy.sol` lines
|
|
1376
|
+
Source: `EpochEntropy.sol` lines 57–60
|
|
1370
1377
|
|
|
1371
1378
|
| Field | Type | Meaning |
|
|
1372
1379
|
| --- | --- | --- |
|
|
@@ -1384,28 +1391,42 @@ Source: `EpochEntropy.sol` lines 45–48
|
|
|
1384
1391
|
|
|
1385
1392
|
Returned by `getEpochSelection` and `getEpochFallbackSelection`.
|
|
1386
1393
|
|
|
1387
|
-
Source: `EpochEntropy.sol` lines
|
|
1394
|
+
Source: `EpochEntropy.sol` lines 55–56, 345–356
|
|
1388
1395
|
|
|
1389
1396
|
| Field | Type | Meaning |
|
|
1390
1397
|
| --- | --- | --- |
|
|
1391
1398
|
| `source` | `uint8` | Slot in the epoch's catalog. |
|
|
1392
1399
|
| `recipe` | `uint8` | Registered recipe id at that slot. |
|
|
1393
|
-
| `airnode` | `address` | Signer of that slot in the catalog in force for the epoch
|
|
1400
|
+
| `airnode` | `address` | Signer of that slot in the catalog in force for the epoch; for a beacon recipe its `slotSigner`. |
|
|
1394
1401
|
| `selector` | `bytes32` | `keccak256(abi.encode(SELECT_DOMAIN, catalogHash, epochId, anchor))`; the slot is `(selector mod count + attempt) mod count` with `count = sourceCountAt(epochId)`. |
|
|
1395
1402
|
| `queryHash` | `bytes32` | `keccak256` of `canonicalRequest`. |
|
|
1396
1403
|
| `canonicalRequest` | `string` | Canonical request of the recipe, as `getRecipe` returns it. |
|
|
1397
1404
|
|
|
1398
1405
|
#### <a id="registry-type-epochentropy-attestation"></a>`EpochEntropy.Attestation`
|
|
1399
1406
|
|
|
1400
|
-
|
|
1407
|
+
Source response passed to `commitEpoch` and `commitEpochFallback`: a signed API record or a beacon round.
|
|
1408
|
+
|
|
1409
|
+
Source: `EpochEntropy.sol` lines 54, 363–391
|
|
1410
|
+
|
|
1411
|
+
| Field | Type | Meaning |
|
|
1412
|
+
| --- | --- | --- |
|
|
1413
|
+
| `timestamp` | `uint256` | Signing time in Unix seconds, or for a beacon round its scheduled time `genesis + (round - 1) × period`; not in the future and at most `MAX_ATTESTATION_AGE` old at publication. |
|
|
1414
|
+
| `data` | `bytes` | Signed response bytes, or for a beacon the round number in decimal, at most `MAX_DATA_BYTES` (128), matching the data template of the slot's recipe exactly. |
|
|
1415
|
+
| `signature` | `bytes` | For a signed API recipe, the 65-byte signature over `toEthSignedMessageHash(keccak256(abi.encodePacked(queryHash, timestamp, data)))`. For a beacon recipe, the beacon's 64-byte signature of the round, which the registered verifier checks. |
|
|
1416
|
+
|
|
1417
|
+
#### <a id="registry-type-epochentropy-beacon"></a>`EpochEntropy.Beacon`
|
|
1401
1418
|
|
|
1402
|
-
|
|
1419
|
+
Returned by `beaconOf`: the registration of a beacon recipe. Fixed when `registerBeacon` appends the recipe. All zero for a signed API recipe.
|
|
1420
|
+
|
|
1421
|
+
Source: `EpochEntropy.sol` lines 64–66
|
|
1403
1422
|
|
|
1404
1423
|
| Field | Type | Meaning |
|
|
1405
1424
|
| --- | --- | --- |
|
|
1406
|
-
| `
|
|
1407
|
-
| `
|
|
1408
|
-
| `
|
|
1425
|
+
| `verifier` | `address` | Contract that checks a round's signature under `publicKey` (`IBeaconVerifier`, for drand's evmnet `D20BeaconVerifier`). Zero marks a signed API recipe. |
|
|
1426
|
+
| `genesis` | `uint64` | Scheduled time of round 1, Unix seconds. Round `r` is scheduled at `genesis + (r - 1) × period`. |
|
|
1427
|
+
| `period` | `uint64` | Seconds between rounds. |
|
|
1428
|
+
| `chainHash` | `bytes32` | Identifier of the beacon network (for drand, the chain hash), 32 bytes. The recipe's canonical request is `["drand","<chainHash>"]`. |
|
|
1429
|
+
| `publicKey` | `bytes` | The beacon's group public key as the verifier reads it; for `D20BeaconVerifier` 128 bytes, `x_im ‖ x_re ‖ y_im ‖ y_re` of a BN254 G2 point. |
|
|
1409
1430
|
|
|
1410
1431
|
### <a id="registry-epoch-state-for-consumers-and-verifiers"></a>Epoch state for consumers and verifiers
|
|
1411
1432
|
|
|
@@ -1417,7 +1438,7 @@ Views, callable by anyone. Epoch IDs start at 1; each epoch lasts `EPOCH_LENGTH`
|
|
|
1417
1438
|
function epochForBlock(uint256 number) external view returns (uint64)
|
|
1418
1439
|
```
|
|
1419
1440
|
|
|
1420
|
-
Selector `0x7018ebb1` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1441
|
+
Selector `0x7018ebb1` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 318–320
|
|
1421
1442
|
|
|
1422
1443
|
Epoch containing a block: 0 before `firstEpochStart`, otherwise `1 + (number - firstEpochStart) / 200`. A request belongs to `epochForBlock(requestBlock)`.
|
|
1423
1444
|
|
|
@@ -1427,7 +1448,7 @@ Epoch containing a block: 0 before `firstEpochStart`, otherwise `1 + (number - f
|
|
|
1427
1448
|
function epochStart(uint64 epochId) external view returns (uint64)
|
|
1428
1449
|
```
|
|
1429
1450
|
|
|
1430
|
-
Selector `0xa1587509` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1451
|
+
Selector `0xa1587509` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 314–317
|
|
1431
1452
|
|
|
1432
1453
|
First block of an epoch: `firstEpochStart + (epochId - 1) × 200`.
|
|
1433
1454
|
|
|
@@ -1439,7 +1460,7 @@ First block of an epoch: `firstEpochStart + (epochId - 1) × 200`.
|
|
|
1439
1460
|
function getEpoch(uint64 epochId) external view returns (EpochEntropy.Epoch)
|
|
1440
1461
|
```
|
|
1441
1462
|
|
|
1442
|
-
Selector `0x12a02c82` · Caller: Anyone (view) · Source: `EpochEntropy.sol` line
|
|
1463
|
+
Selector `0x12a02c82` · Caller: Anyone (view) · Source: `EpochEntropy.sol` line 335
|
|
1443
1464
|
|
|
1444
1465
|
The published [`EpochEntropy.Epoch`](#registry-type-epochentropy-epoch) record, or all zero while unpublished; it never reverts. A non-zero `epochHash` means published.
|
|
1445
1466
|
|
|
@@ -1449,7 +1470,7 @@ The published [`EpochEntropy.Epoch`](#registry-type-epochentropy-epoch) record,
|
|
|
1449
1470
|
function catalogAt(uint64 epochId) external view returns (bytes32 hash, uint8[] recipes, address[] signers)
|
|
1450
1471
|
```
|
|
1451
1472
|
|
|
1452
|
-
Selector `0xec993599` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1473
|
+
Selector `0xec993599` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 295–303, 309–313
|
|
1453
1474
|
|
|
1454
1475
|
The catalog in force for an epoch: its hash and the recipe id and signer of each slot, in slot order. That is the latest scheduled version whose `fromEpoch` is at or below `epochId`, otherwise the initial catalog: recipes 0 to 3 with the initial signers and hash `catalogHash()`. Replay needs this catalog, not the initial signer getters.
|
|
1455
1476
|
|
|
@@ -1459,7 +1480,7 @@ The catalog in force for an epoch: its hash and the recipe id and signer of each
|
|
|
1459
1480
|
function sourceCountAt(uint64 epochId) external view returns (uint256)
|
|
1460
1481
|
```
|
|
1461
1482
|
|
|
1462
|
-
Selector `0x3edc6b12` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1483
|
+
Selector `0x3edc6b12` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 304–308, 309–313
|
|
1463
1484
|
|
|
1464
1485
|
Number of slots in the catalog in force for an epoch, and so the number of selection attempts, 0 to count - 1.
|
|
1465
1486
|
|
|
@@ -1469,19 +1490,53 @@ Number of slots in the catalog in force for an epoch, and so the number of selec
|
|
|
1469
1490
|
function getRecipe(uint8 recipe) external view returns (bytes32 queryHash, string canonicalRequest, bytes template, string body)
|
|
1470
1491
|
```
|
|
1471
1492
|
|
|
1472
|
-
Selector `0xba01b103` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1493
|
+
Selector `0xba01b103` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 150–154, 157–160
|
|
1494
|
+
|
|
1495
|
+
A registered recipe: `queryHash` (`keccak256` of `canonicalRequest`), the canonical request its signer signs, the data template its signed data must match and the body keepers send: the JSON they post to the provider gateway, or for a beacon recipe its canonical request. Registered recipes never change. `readEpochRecipes` in `@d20dao/vrf-sdk/epoch` reads recipes with this view, checks each query hash and adds the registration of a beacon recipe from `beaconOf`.
|
|
1496
|
+
|
|
1497
|
+
**Errors:** [`InvalidConfig`](#registry-error-invalidconfig).
|
|
1498
|
+
|
|
1499
|
+
#### <a id="registry-fn-beaconof"></a>`beaconOf`
|
|
1500
|
+
|
|
1501
|
+
```solidity
|
|
1502
|
+
function beaconOf(uint8 recipe) external view returns (EpochEntropy.Beacon)
|
|
1503
|
+
```
|
|
1504
|
+
|
|
1505
|
+
Selector `0x87533a48` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 188–192
|
|
1473
1506
|
|
|
1474
|
-
|
|
1507
|
+
The registration of a recipe as an [`EpochEntropy.Beacon`](#registry-type-epochentropy-beacon): verifier, genesis, period, chain hash and public key. A signed API recipe returns all zero. Replay of a beacon epoch needs this registration, and `readEpochRecipes` reads it for every recipe whose canonical request names drand.
|
|
1475
1508
|
|
|
1476
1509
|
**Errors:** [`InvalidConfig`](#registry-error-invalidconfig).
|
|
1477
1510
|
|
|
1511
|
+
#### <a id="registry-fn-slotsigner"></a>`slotSigner`
|
|
1512
|
+
|
|
1513
|
+
```solidity
|
|
1514
|
+
function slotSigner(uint8 recipe) external view returns (address)
|
|
1515
|
+
```
|
|
1516
|
+
|
|
1517
|
+
Selector `0xb42be3c1` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 193–199
|
|
1518
|
+
|
|
1519
|
+
The signer a catalog lists for a beacon recipe: the low 160 bits of `keccak256(abi.encode(BEACON_DOMAIN, verifier, chainHash, keccak256(publicKey), genesis, period))`, an identity derived from the registration and not a key. Zero for a signed API recipe and for an id that is not registered. `scheduleCatalog` requires it as the signer of a beacon slot; `beaconSlotSigner` in `@d20dao/vrf-sdk` computes it off-chain.
|
|
1520
|
+
|
|
1521
|
+
#### <a id="registry-fn-verifybeacon"></a>`verifyBeacon`
|
|
1522
|
+
|
|
1523
|
+
```solidity
|
|
1524
|
+
function verifyBeacon(uint8 recipe, uint64 round, bytes signature) external view returns (bool)
|
|
1525
|
+
```
|
|
1526
|
+
|
|
1527
|
+
Selector `0x0ccd9ab2` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 200–209
|
|
1528
|
+
|
|
1529
|
+
Whether `signature` is the valid signature of `round` for a beacon recipe, checked the way a publication checks it: the recipe's verifier is called with a fixed allowance of `BEACON_VERIFY_GAS` and only an exact `true` counts. False for a signed API recipe and for an id that is not registered. For a beacon recipe it reverts `BeaconGasTooLow`, and never answers false, when the gas of the call cannot give the verifier its whole allowance; an `eth_call` needs about 461,000 gas.
|
|
1530
|
+
|
|
1531
|
+
**Errors:** [`BeaconGasTooLow`](#registry-error-beacongastoolow).
|
|
1532
|
+
|
|
1478
1533
|
#### <a id="registry-fn-reciperequest"></a>`recipeRequest`
|
|
1479
1534
|
|
|
1480
1535
|
```solidity
|
|
1481
1536
|
function recipeRequest(uint8 recipe) external view returns (string)
|
|
1482
1537
|
```
|
|
1483
1538
|
|
|
1484
|
-
Selector `0x7ce4b6e0` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1539
|
+
Selector `0x7ce4b6e0` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 155–160
|
|
1485
1540
|
|
|
1486
1541
|
Canonical request of a registered recipe, the same string `getRecipe` returns.
|
|
1487
1542
|
|
|
@@ -1493,7 +1548,7 @@ Canonical request of a registered recipe, the same string `getRecipe` returns.
|
|
|
1493
1548
|
function recipeCount() external view returns (uint256)
|
|
1494
1549
|
```
|
|
1495
1550
|
|
|
1496
|
-
Selector `0x69cfdf74` · Caller: Anyone (view) · Source: `EpochEntropy.sol` line
|
|
1551
|
+
Selector `0x69cfdf74` · Caller: Anyone (view) · Source: `EpochEntropy.sol` line 149
|
|
1497
1552
|
|
|
1498
1553
|
Number of registered recipes; ids run from 0 to `recipeCount() - 1`.
|
|
1499
1554
|
|
|
@@ -1503,17 +1558,17 @@ Views, callable by anyone.
|
|
|
1503
1558
|
|
|
1504
1559
|
| Function | Selector | Meaning | Source |
|
|
1505
1560
|
| --- | --- | --- | --- |
|
|
1506
|
-
| <a id="registry-fn-firstepochstart"></a>`firstEpochStart() returns (uint64)` | `0x219f2428` | First block of epoch 1: the initialization block plus 200. | lines
|
|
1507
|
-
| <a id="registry-fn-committer"></a>`committer() returns (address)` | `0x5bc8e8f9` | Primary publishing address. The coordinator pays it the keeper share of the requests it serves itself and of every request whose proof came from a wallet this registry does not authorize. | lines
|
|
1508
|
-
| <a id="registry-fn-isbackupcommitter"></a>`isBackupCommitter(address account) returns (bool)` | `0x1d97e417` | Whether an address may publish epochs besides `committer()`. | line
|
|
1509
|
-
| <a id="registry-fn-isauthorizedcommitter"></a>`isAuthorizedCommitter(address account) returns (bool)` | `0x1579ab83` | Whether an address may publish epochs at all: `committer()` or an allowed backup committer. The coordinator reads it to decide whether a proof submitter earns the keeper share. | lines
|
|
1510
|
-
| <a id="registry-fn-backupcommittercount"></a>`backupCommitterCount() returns (uint256)` | `0xa815c5bf` | Number of allowed backup committers, at most `MAX_BACKUP_COMMITTERS`. | lines
|
|
1511
|
-
| <a id="registry-fn-cataloghash"></a>`catalogHash() returns (bytes32)` | `0x830c083a` | Initial catalog hash, bound into `protocolConfigurationHash`. Never changes; `catalogAt` gives the catalog of an epoch. | lines
|
|
1512
|
-
| <a id="registry-fn-epochanchors"></a>`epochAnchors(uint64) returns (bytes32)` | `0x48a030fb` | Checkpointed anchor of an epoch (hash of block `epochStart - 1`); zero until a request, `checkpointEpoch` or publication stores it. | lines
|
|
1513
|
-
| <a id="registry-fn-hyperliquidsigner"></a>`hyperliquidSigner() returns (address)` | `0xf2a12563` | Initial-catalog signer of slot 0 (recipe 0, Hyperliquid BTC volume). Never changes; see `catalogAt`. | line
|
|
1514
|
-
| <a id="registry-fn-ethereumblocksigner"></a>`ethereumBlockSigner() returns (address)` | `0xd25eacfc` | Initial-catalog signer of slot 1 (recipe 1, Ethereum block hash). Never changes; see `catalogAt`. | lines
|
|
1515
|
-
| <a id="registry-fn-btctradesigner"></a>`btcTradeSigner() returns (address)` | `0xb3b9cbb0` | Initial-catalog signer of slot 2 (recipe 2, TickerLayer BTCUSD). Never changes; see `catalogAt`. | line
|
|
1516
|
-
| <a id="registry-fn-ethtradesigner"></a>`ethTradeSigner() returns (address)` | `0x3a700168` | Initial-catalog signer of slot 3 (recipe 3, TickerLayer ETHUSD). Never changes; see `catalogAt`. | line
|
|
1561
|
+
| <a id="registry-fn-firstepochstart"></a>`firstEpochStart() returns (uint64)` | `0x219f2428` | First block of epoch 1: the initialization block plus 200. | lines 52, 101 |
|
|
1562
|
+
| <a id="registry-fn-committer"></a>`committer() returns (address)` | `0x5bc8e8f9` | Primary publishing address. The coordinator pays it the keeper share of the requests it serves itself and of every request whose proof came from a wallet this registry does not authorize. | lines 51, 364 |
|
|
1563
|
+
| <a id="registry-fn-isbackupcommitter"></a>`isBackupCommitter(address account) returns (bool)` | `0x1d97e417` | Whether an address may publish epochs besides `committer()`. | line 136 |
|
|
1564
|
+
| <a id="registry-fn-isauthorizedcommitter"></a>`isAuthorizedCommitter(address account) returns (bool)` | `0x1579ab83` | Whether an address may publish epochs at all: `committer()` or an allowed backup committer. The coordinator reads it to decide whether a proof submitter earns the keeper share. | lines 137–139 |
|
|
1565
|
+
| <a id="registry-fn-backupcommittercount"></a>`backupCommitterCount() returns (uint256)` | `0xa815c5bf` | Number of allowed backup committers, at most `MAX_BACKUP_COMMITTERS`. | lines 78, 125–135 |
|
|
1566
|
+
| <a id="registry-fn-cataloghash"></a>`catalogHash() returns (bytes32)` | `0x830c083a` | Initial catalog hash, bound into `protocolConfigurationHash`. Never changes; `catalogAt` gives the catalog of an epoch. | lines 53, 102 |
|
|
1567
|
+
| <a id="registry-fn-epochanchors"></a>`epochAnchors(uint64) returns (bytes32)` | `0x48a030fb` | Checkpointed anchor of an epoch (hash of block `epochStart - 1`); zero until a request, `checkpointEpoch` or publication stores it. | lines 68, 324–327 |
|
|
1568
|
+
| <a id="registry-fn-hyperliquidsigner"></a>`hyperliquidSigner() returns (address)` | `0xf2a12563` | Initial-catalog signer of slot 0 (recipe 0, Hyperliquid BTC volume). Never changes; see `catalogAt`. | line 46 |
|
|
1569
|
+
| <a id="registry-fn-ethereumblocksigner"></a>`ethereumBlockSigner() returns (address)` | `0xd25eacfc` | Initial-catalog signer of slot 1 (recipe 1, Ethereum block hash). Never changes; see `catalogAt`. | lines 47–48 |
|
|
1570
|
+
| <a id="registry-fn-btctradesigner"></a>`btcTradeSigner() returns (address)` | `0xb3b9cbb0` | Initial-catalog signer of slot 2 (recipe 2, TickerLayer BTCUSD). Never changes; see `catalogAt`. | line 49 |
|
|
1571
|
+
| <a id="registry-fn-ethtradesigner"></a>`ethTradeSigner() returns (address)` | `0x3a700168` | Initial-catalog signer of slot 3 (recipe 3, TickerLayer ETHUSD). Never changes; see `catalogAt`. | line 50 |
|
|
1517
1572
|
|
|
1518
1573
|
### <a id="registry-source-selection-and-publication"></a>Source selection and publication
|
|
1519
1574
|
|
|
@@ -1525,7 +1580,7 @@ Used by keepers. Publication is restricted to the committer and backup committer
|
|
|
1525
1580
|
function getEpochSelection(uint64 epochId) external view returns (EpochEntropy.Selection s)
|
|
1526
1581
|
```
|
|
1527
1582
|
|
|
1528
|
-
Selector `0xec4960ad` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1583
|
+
Selector `0xec4960ad` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 336, 345–356
|
|
1529
1584
|
|
|
1530
1585
|
The selected source of an epoch, attempt 0, as an [`EpochEntropy.Selection`](#registry-type-epochentropy-selection).
|
|
1531
1586
|
|
|
@@ -1537,7 +1592,7 @@ The selected source of an epoch, attempt 0, as an [`EpochEntropy.Selection`](#re
|
|
|
1537
1592
|
function getEpochFallbackSelection(uint64 epochId, uint8 attempt) external view returns (EpochEntropy.Selection s)
|
|
1538
1593
|
```
|
|
1539
1594
|
|
|
1540
|
-
Selector `0x0e5a0e02` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1595
|
+
Selector `0x0e5a0e02` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 337–338, 345–356
|
|
1541
1596
|
|
|
1542
1597
|
The source for attempt 0 to `sourceCountAt(epochId) - 1`; attempt n uses the slot n positions after the selected one.
|
|
1543
1598
|
|
|
@@ -1549,7 +1604,7 @@ The source for attempt 0 to `sourceCountAt(epochId) - 1`; attempt n uses the slo
|
|
|
1549
1604
|
function fallbackOpensAt(uint64 epochId, uint8 attempt) external view returns (uint64)
|
|
1550
1605
|
```
|
|
1551
1606
|
|
|
1552
|
-
Selector `0x98208050` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines
|
|
1607
|
+
Selector `0x98208050` · Caller: Anyone (view) · Source: `EpochEntropy.sol` lines 339–343
|
|
1553
1608
|
|
|
1554
1609
|
First block at which an attempt may be published: `epochStart + attempt × FALLBACK_DELAY_BLOCKS` (20). With at most `MAX_SOURCES` (10) slots the last window opens 180 blocks into the epoch.
|
|
1555
1610
|
|
|
@@ -1561,7 +1616,7 @@ First block at which an attempt may be published: `epochStart + attempt × FALLB
|
|
|
1561
1616
|
function nextEpochToPrepare(uint256 number) external view returns (uint64)
|
|
1562
1617
|
```
|
|
1563
1618
|
|
|
1564
|
-
Selector `0xc78fafe2` · Caller: Anyone (view) · Source: `EpochEntropy.sol` line
|
|
1619
|
+
Selector `0xc78fafe2` · Caller: Anyone (view) · Source: `EpochEntropy.sol` line 321
|
|
1565
1620
|
|
|
1566
1621
|
Same value as `epochForBlock(number)`.
|
|
1567
1622
|
|
|
@@ -1571,7 +1626,7 @@ Same value as `epochForBlock(number)`.
|
|
|
1571
1626
|
function checkpointEpoch(uint64 epochId) external returns (bytes32 anchor)
|
|
1572
1627
|
```
|
|
1573
1628
|
|
|
1574
|
-
Selector `0x16de78cb` · Caller: Anyone · Source: `EpochEntropy.sol` lines
|
|
1629
|
+
Selector `0x16de78cb` · Caller: Anyone · Source: `EpochEntropy.sol` lines 322–327, 328–334
|
|
1575
1630
|
|
|
1576
1631
|
Stores the anchor of a started epoch (hash of block `epochStart - 1`) if not stored yet, and returns it. The coordinator calls it on every request, so the anchor of an epoch with requests survives the 256-block `BLOCKHASH` window.
|
|
1577
1632
|
|
|
@@ -1583,13 +1638,13 @@ Stores the anchor of a started epoch (hash of block `epochStart - 1`) if not sto
|
|
|
1583
1638
|
function commitEpoch(uint64 epochId, EpochEntropy.Attestation a) external
|
|
1584
1639
|
```
|
|
1585
1640
|
|
|
1586
|
-
Selector `0xb1580277` · Caller: Committer or backup committer · Source: `EpochEntropy.sol` lines
|
|
1641
|
+
Selector `0xb1580277` · Caller: Committer or backup committer · Source: `EpochEntropy.sol` lines 357, 363–391
|
|
1587
1642
|
|
|
1588
|
-
Publishes the packet of the selected source once per epoch, from the epoch start: checks that the attestation is not future-dated and at most 240 seconds old
|
|
1643
|
+
Publishes the packet of the selected source once per epoch, from the epoch start: checks that the attestation is not future-dated and at most 240 seconds old and that its data matches the data template of the slot's recipe exactly, then checks its signature. For a signed API recipe the slot's signer in the epoch's catalog must have signed it. For a beacon recipe the timestamp must be the scheduled time of the round in the data, and the verifier of its registration must accept the signature of that round within `BEACON_VERIFY_GAS`; the call reverts `BeaconGasTooLow` when the gas left cannot give the verifier that allowance. Stores the record and emits the packet. Publishing earns nothing by itself: the keeper share of each request goes to the authorized wallet that submits its accepted proof, or to `committer()` when the submitter is not authorized.
|
|
1589
1644
|
|
|
1590
1645
|
**Emits:** [`EpochCommitted`](#registry-event-epochcommitted).
|
|
1591
1646
|
|
|
1592
|
-
**Errors:** [`OnlyCommitter`](#registry-error-onlycommitter), [`AlreadyCommitted`](#registry-error-alreadycommitted), [`InvalidEpoch`](#registry-error-invalidepoch), [`FallbackNotOpen`](#registry-error-fallbacknotopen), [`AnchorUnavailable`](#registry-error-anchorunavailable), [`InvalidConfig`](#registry-error-invalidconfig), [`InvalidTime`](#registry-error-invalidtime), [`InvalidData`](#registry-error-invaliddata), [`ECDSAInvalidSignatureLength`](#registry-error-ecdsainvalidsignaturelength), [`ECDSAInvalidSignatureS`](#registry-error-ecdsainvalidsignatures), [`ECDSAInvalidSignature`](#registry-error-ecdsainvalidsignature), [`InvalidSigner`](#registry-error-invalidsigner), [`PacketTooLarge`](#registry-error-packettoolarge).
|
|
1647
|
+
**Errors:** [`OnlyCommitter`](#registry-error-onlycommitter), [`AlreadyCommitted`](#registry-error-alreadycommitted), [`InvalidEpoch`](#registry-error-invalidepoch), [`FallbackNotOpen`](#registry-error-fallbacknotopen), [`AnchorUnavailable`](#registry-error-anchorunavailable), [`InvalidConfig`](#registry-error-invalidconfig), [`InvalidTime`](#registry-error-invalidtime), [`InvalidData`](#registry-error-invaliddata), [`ECDSAInvalidSignatureLength`](#registry-error-ecdsainvalidsignaturelength), [`ECDSAInvalidSignatureS`](#registry-error-ecdsainvalidsignatures), [`ECDSAInvalidSignature`](#registry-error-ecdsainvalidsignature), [`InvalidSigner`](#registry-error-invalidsigner), [`BeaconGasTooLow`](#registry-error-beacongastoolow), [`PacketTooLarge`](#registry-error-packettoolarge).
|
|
1593
1648
|
|
|
1594
1649
|
#### <a id="registry-fn-commitepochfallback"></a>`commitEpochFallback`
|
|
1595
1650
|
|
|
@@ -1597,13 +1652,13 @@ Publishes the packet of the selected source once per epoch, from the epoch start
|
|
|
1597
1652
|
function commitEpochFallback(uint64 epochId, uint8 attempt, EpochEntropy.Attestation a) external
|
|
1598
1653
|
```
|
|
1599
1654
|
|
|
1600
|
-
Selector `0x5768d9a1` · Caller: Committer or backup committer · Source: `EpochEntropy.sol` lines
|
|
1655
|
+
Selector `0x5768d9a1` · Caller: Committer or backup committer · Source: `EpochEntropy.sol` lines 358–362, 363–391
|
|
1601
1656
|
|
|
1602
1657
|
Publishes fallback attempt 1 to `sourceCountAt(epochId) - 1`, using the slot `attempt` positions after the selected source, once `fallbackOpensAt(epochId, attempt)` is reached. Same checks as `commitEpoch`.
|
|
1603
1658
|
|
|
1604
1659
|
**Emits:** [`EpochCommitted`](#registry-event-epochcommitted).
|
|
1605
1660
|
|
|
1606
|
-
**Errors:** [`InvalidFallback`](#registry-error-invalidfallback), [`OnlyCommitter`](#registry-error-onlycommitter), [`AlreadyCommitted`](#registry-error-alreadycommitted), [`InvalidEpoch`](#registry-error-invalidepoch), [`FallbackNotOpen`](#registry-error-fallbacknotopen), [`AnchorUnavailable`](#registry-error-anchorunavailable), [`InvalidConfig`](#registry-error-invalidconfig), [`InvalidTime`](#registry-error-invalidtime), [`InvalidData`](#registry-error-invaliddata), [`ECDSAInvalidSignatureLength`](#registry-error-ecdsainvalidsignaturelength), [`ECDSAInvalidSignatureS`](#registry-error-ecdsainvalidsignatures), [`ECDSAInvalidSignature`](#registry-error-ecdsainvalidsignature), [`InvalidSigner`](#registry-error-invalidsigner), [`PacketTooLarge`](#registry-error-packettoolarge).
|
|
1661
|
+
**Errors:** [`InvalidFallback`](#registry-error-invalidfallback), [`OnlyCommitter`](#registry-error-onlycommitter), [`AlreadyCommitted`](#registry-error-alreadycommitted), [`InvalidEpoch`](#registry-error-invalidepoch), [`FallbackNotOpen`](#registry-error-fallbacknotopen), [`AnchorUnavailable`](#registry-error-anchorunavailable), [`InvalidConfig`](#registry-error-invalidconfig), [`InvalidTime`](#registry-error-invalidtime), [`InvalidData`](#registry-error-invaliddata), [`ECDSAInvalidSignatureLength`](#registry-error-ecdsainvalidsignaturelength), [`ECDSAInvalidSignatureS`](#registry-error-ecdsainvalidsignatures), [`ECDSAInvalidSignature`](#registry-error-ecdsainvalidsignature), [`InvalidSigner`](#registry-error-invalidsigner), [`BeaconGasTooLow`](#registry-error-beacongastoolow), [`PacketTooLarge`](#registry-error-packettoolarge).
|
|
1607
1662
|
|
|
1608
1663
|
### <a id="registry-recipes-and-catalogs"></a>Recipes and catalogs
|
|
1609
1664
|
|
|
@@ -1615,7 +1670,7 @@ Owner-only; on Arc Mainnet the owner is the DAO treasury Safe. A recipe or catal
|
|
|
1615
1670
|
function registerRecipe(string canonicalRequest, bytes template, string body) external returns (uint8 recipe)
|
|
1616
1671
|
```
|
|
1617
1672
|
|
|
1618
|
-
Selector `0x5add5c50` · Caller: Owner · Source: `EpochEntropy.sol` lines
|
|
1673
|
+
Selector `0x5add5c50` · Caller: Owner · Source: `EpochEntropy.sol` lines 141–148, 161–170
|
|
1619
1674
|
|
|
1620
1675
|
Appends an immutable recipe and returns its id, the next index. The canonical request is 1 to `MAX_REQUEST_BYTES` (1024) bytes, the body 1 to `MAX_BODY_BYTES` (2048) bytes, and the template must be a well-formed data template of at most `MAX_TEMPLATE_BYTES` (256) bytes; at most `MAX_RECIPES` (256) recipes exist. The contract does not check that the body canonicalizes to the request; keepers refuse a recipe whose body does not. A changed listing is registered as a new id.
|
|
1621
1676
|
|
|
@@ -1623,15 +1678,29 @@ Appends an immutable recipe and returns its id, the next index. The canonical re
|
|
|
1623
1678
|
|
|
1624
1679
|
**Errors:** [`OwnableUnauthorizedAccount`](#registry-error-ownableunauthorizedaccount), [`InvalidRecipe`](#registry-error-invalidrecipe), [`InvalidTemplate`](#registry-error-invalidtemplate).
|
|
1625
1680
|
|
|
1681
|
+
#### <a id="registry-fn-registerbeacon"></a>`registerBeacon`
|
|
1682
|
+
|
|
1683
|
+
```solidity
|
|
1684
|
+
function registerBeacon(address verifier, bytes32 chainHash, bytes publicKey, uint64 genesis, uint64 period, uint64 sampleRound, bytes sampleSignature) external returns (uint8 recipe)
|
|
1685
|
+
```
|
|
1686
|
+
|
|
1687
|
+
Selector `0x65afb221` · Caller: Owner · Source: `EpochEntropy.sol` lines 171–187
|
|
1688
|
+
|
|
1689
|
+
Appends a public randomness beacon as an immutable recipe and returns its id. Its canonical request, which is also its body, is `["drand","<chainHash>"]` with the hash in lowercase hex, and its template accepts one round number: 1 to 19 decimal digits without a leading zero. An epoch it serves commits round `r` as the data, the round's scheduled time `genesis + (r - 1) × period` as the timestamp and the beacon's signature of the round, which `verifier` checks under `publicKey`. Reverts `InvalidConfig` for a verifier without code, a zero `chainHash`, `genesis`, `period` or `sampleRound`, a `sampleRound` not yet scheduled, a key the verifier does not accept, or a `sampleSignature` of `sampleRound` it rejects, so that a malformed key or a verifier that misbehaves or needs more gas cannot register. The registration, like the recipe, never changes.
|
|
1690
|
+
|
|
1691
|
+
**Emits:** [`RecipeRegistered`](#registry-event-reciperegistered), [`BeaconRegistered`](#registry-event-beaconregistered).
|
|
1692
|
+
|
|
1693
|
+
**Errors:** [`OwnableUnauthorizedAccount`](#registry-error-ownableunauthorizedaccount), [`InvalidConfig`](#registry-error-invalidconfig), [`BeaconGasTooLow`](#registry-error-beacongastoolow), [`InvalidRecipe`](#registry-error-invalidrecipe).
|
|
1694
|
+
|
|
1626
1695
|
#### <a id="registry-fn-schedulecatalog"></a>`scheduleCatalog`
|
|
1627
1696
|
|
|
1628
1697
|
```solidity
|
|
1629
1698
|
function scheduleCatalog(uint8[] recipes, address[] signers, uint64 fromEpoch) external
|
|
1630
1699
|
```
|
|
1631
1700
|
|
|
1632
|
-
Selector `0x42984450` · Caller: Owner · Source: `EpochEntropy.sol` lines
|
|
1701
|
+
Selector `0x42984450` · Caller: Owner · Source: `EpochEntropy.sol` lines 268–294
|
|
1633
1702
|
|
|
1634
|
-
Schedules a catalog for epochs from `fromEpoch`, which must be at least two epochs after the current one: 1 to `MAX_SOURCES` (10) distinct registered recipe ids with one non-zero signer each, in slot order
|
|
1703
|
+
Schedules a catalog for epochs from `fromEpoch`, which must be at least two epochs after the current one: 1 to `MAX_SOURCES` (10) distinct registered recipe ids with one non-zero signer each, in slot order; the signer of a beacon recipe must be its `slotSigner`. Its hash is `keccak256(abi.encode(RECIPE_DOMAIN, recipes, signers))`. A pending version, one whose `fromEpoch` is two or more epochs after the current one, is replaced, so that version never applies. The version that takes effect at the next epoch is kept, as is every active one, because the next epoch's catalog is already fixed: its snapshot may be prepared and its requests open. The current epoch keeps its catalog.
|
|
1635
1704
|
|
|
1636
1705
|
**Emits:** [`CatalogScheduled`](#registry-event-catalogscheduled).
|
|
1637
1706
|
|
|
@@ -1643,7 +1712,7 @@ Schedules a catalog for epochs from `fromEpoch`, which must be at least two epoc
|
|
|
1643
1712
|
function initializeRecipeRegistry() external
|
|
1644
1713
|
```
|
|
1645
1714
|
|
|
1646
|
-
Selector `0x8700b456` · Caller: Owner, once per proxy, as the `upgradeToAndCall` data of the recipe-registry upgrade · Source: `EpochEntropy.sol` lines
|
|
1715
|
+
Selector `0x8700b456` · Caller: Owner, once per proxy, as the `upgradeToAndCall` data of the recipe-registry upgrade · Source: `EpochEntropy.sol` lines 105–113
|
|
1647
1716
|
|
|
1648
1717
|
Registers built-in recipes 0 to 5 on a registry initialized before the recipe registry, whose initial catalog selects recipes 0 to 3. It runs once per proxy (reinitializer version 2) and refuses a registry that already has recipes, which includes every registry initialized by this implementation, or a catalog scheduled under the earlier hardcoded recipe ids.
|
|
1649
1718
|
|
|
@@ -1661,7 +1730,7 @@ Owner-only functions revert `OwnableUnauthorizedAccount` for anyone else. No set
|
|
|
1661
1730
|
function setCommitter(address next) external
|
|
1662
1731
|
```
|
|
1663
1732
|
|
|
1664
|
-
Selector `0xdd51ce22` · Caller: Owner · Source: `EpochEntropy.sol` lines
|
|
1733
|
+
Selector `0xdd51ce22` · Caller: Owner · Source: `EpochEntropy.sol` lines 118–121
|
|
1665
1734
|
|
|
1666
1735
|
Changes the primary publishing address, which is also the keeper-share recipient the coordinator reads at each acceptance.
|
|
1667
1736
|
|
|
@@ -1675,7 +1744,7 @@ Changes the primary publishing address, which is also the keeper-share recipient
|
|
|
1675
1744
|
function setBackupCommitter(address account, bool allowed) external
|
|
1676
1745
|
```
|
|
1677
1746
|
|
|
1678
|
-
Selector `0xd870d0c6` · Caller: Owner · Source: `EpochEntropy.sol` lines
|
|
1747
|
+
Selector `0xd870d0c6` · Caller: Owner · Source: `EpochEntropy.sol` lines 122–135
|
|
1679
1748
|
|
|
1680
1749
|
Allows or removes a backup committer: a separate wallet that may call `commitEpoch` and `commitEpochFallback` under exactly the committer's rules, for example a follower keeper that takes over while the primary keeper is down. It has no other role, and the coordinator pays it the keeper share of the requests whose accepted proofs it submits itself. Reverts for the zero address, for allowing the current committer, for a call that does not change the address's status, and for more than `MAX_BACKUP_COMMITTERS` (4).
|
|
1681
1750
|
|
|
@@ -1737,7 +1806,7 @@ Completes the transfer to the caller and clears the nomination.
|
|
|
1737
1806
|
function renounceOwnership() external view
|
|
1738
1807
|
```
|
|
1739
1808
|
|
|
1740
|
-
Selector `0x715018a6` · Caller: Owner · Source: `EpochEntropy.sol` lines
|
|
1809
|
+
Selector `0x715018a6` · Caller: Owner · Source: `EpochEntropy.sol` lines 115–116
|
|
1741
1810
|
|
|
1742
1811
|
Disabled and declared `view`: the owner gets `RenounceDisabled` and anyone else `OwnableUnauthorizedAccount`, so the contract always has an owner and upgrade authority can only move through an accepted transfer.
|
|
1743
1812
|
|
|
@@ -1775,7 +1844,7 @@ ERC-1822 check used by `upgradeToAndCall`. Returns the ERC-1967 implementation s
|
|
|
1775
1844
|
function initialize(address[4] signers, address initialOwner, address initialCommitter) external
|
|
1776
1845
|
```
|
|
1777
1846
|
|
|
1778
|
-
Selector `0xfda9f5ca` · Caller: Once, by `D20Proxy` at deployment · Source: `EpochEntropy.sol` lines
|
|
1847
|
+
Selector `0xfda9f5ca` · Caller: Once, by `D20Proxy` at deployment · Source: `EpochEntropy.sol` lines 96–104
|
|
1779
1848
|
|
|
1780
1849
|
Sets the four initial-catalog signers of recipes 0 to 3, the owner and the committer, and registers built-in recipes 0 to 5. Epoch 1 starts 200 blocks after the initialization block.
|
|
1781
1850
|
|
|
@@ -1803,6 +1872,8 @@ Views returning values fixed in the implementation code.
|
|
|
1803
1872
|
| <a id="registry-fn-recipe_domain"></a>`RECIPE_DOMAIN` | `bytes32` | `keccak256("D20_EPOCH_RECIPES")` | `0xacea73c8` | Domain tag of catalog hashes. |
|
|
1804
1873
|
| <a id="registry-fn-select_domain"></a>`SELECT_DOMAIN` | `bytes32` | `keccak256("D20_EPOCH_SELECT")` | `0x10181587` | Domain tag of the source selector. |
|
|
1805
1874
|
| <a id="registry-fn-epoch_domain"></a>`EPOCH_DOMAIN` | `bytes32` | `keccak256("D20_EPOCH")` | `0xbece738c` | Domain tag of the epoch commitment. |
|
|
1875
|
+
| <a id="registry-fn-beacon_domain"></a>`BEACON_DOMAIN` | `bytes32` | `keccak256("D20_EPOCH_BEACON")` | `0x11083512` | Domain tag of `slotSigner`. |
|
|
1876
|
+
| <a id="registry-fn-beacon_verify_gas"></a>`BEACON_VERIFY_GAS` | `uint256` | `400_000` | `0x92c32ece` | Gas a beacon verifier gets for one round; `D20BeaconVerifier` uses about 175,000 of it. A call that cannot leave the verifier this much reverts `BeaconGasTooLow`. |
|
|
1806
1877
|
| <a id="registry-fn-upgrade_interface_version"></a>`UPGRADE_INTERFACE_VERSION` | `string` | `"5.0.0"` | `0xad3cb1cc` | OpenZeppelin UUPS interface version: upgrades go through `upgradeToAndCall` only. |
|
|
1807
1878
|
|
|
1808
1879
|
### <a id="registry-events"></a>Events
|
|
@@ -1815,9 +1886,9 @@ Views returning values fixed in the implementation code.
|
|
|
1815
1886
|
event EpochCommitted(uint64 indexed epochId, bytes32 indexed epochHash, bytes packet)
|
|
1816
1887
|
```
|
|
1817
1888
|
|
|
1818
|
-
Topic 0 `0xc9db8d1389570196eda0f2c6c4e2f78429c2f812db30b6b1022b5e0b5162ef72` · Emitted by: [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback) · Source: `EpochEntropy.sol` lines
|
|
1889
|
+
Topic 0 `0xc9db8d1389570196eda0f2c6c4e2f78429c2f812db30b6b1022b5e0b5162ef72` · Emitted by: [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback) · Source: `EpochEntropy.sol` lines 88, 388–390
|
|
1819
1890
|
|
|
1820
|
-
An epoch was published. `packet` is `abi.encode(canonicalRequest, attestation)`: decode it with `decodeEpochEvidencePacket` and verify with `replayEpochCommitment
|
|
1891
|
+
An epoch was published. `packet` is `abi.encode(canonicalRequest, attestation)`: decode it with `decodeEpochEvidencePacket` and verify with `replayEpochCommitment`, which needs the registration of a beacon recipe as well. Requests of the epoch now have a target block.
|
|
1821
1892
|
|
|
1822
1893
|
#### <a id="registry-event-reciperegistered"></a>`RecipeRegistered`
|
|
1823
1894
|
|
|
@@ -1825,9 +1896,19 @@ An epoch was published. `packet` is `abi.encode(canonicalRequest, attestation)`:
|
|
|
1825
1896
|
event RecipeRegistered(uint8 indexed recipe, bytes32 indexed queryHash, string canonicalRequest, bytes template, string body)
|
|
1826
1897
|
```
|
|
1827
1898
|
|
|
1828
|
-
Topic 0 `0xbc5c1e3f4647d7f37dc8b4fe5e26e7c58ae35b8c9fb1db0233ddedba0d7f5fd8` · Emitted by: [`registerRecipe`](#registry-fn-registerrecipe), [`initializeRecipeRegistry`](#registry-fn-initializereciperegistry), [`initialize`](#registry-fn-initialize) · Source: `EpochEntropy.sol` lines
|
|
1899
|
+
Topic 0 `0xbc5c1e3f4647d7f37dc8b4fe5e26e7c58ae35b8c9fb1db0233ddedba0d7f5fd8` · Emitted by: [`registerRecipe`](#registry-fn-registerrecipe), [`registerBeacon`](#registry-fn-registerbeacon), [`initializeRecipeRegistry`](#registry-fn-initializereciperegistry), [`initialize`](#registry-fn-initialize) · Source: `EpochEntropy.sol` lines 91, 169
|
|
1829
1900
|
|
|
1830
|
-
Recipe `recipe` was registered
|
|
1901
|
+
Recipe `recipe` was registered, by `registerRecipe` or by `registerBeacon`. The event carries the complete definition, so every recipe can be rebuilt from logs; `getRecipe` returns the same values.
|
|
1902
|
+
|
|
1903
|
+
#### <a id="registry-event-beaconregistered"></a>`BeaconRegistered`
|
|
1904
|
+
|
|
1905
|
+
```solidity
|
|
1906
|
+
event BeaconRegistered(uint8 indexed recipe, address indexed verifier, bytes32 indexed chainHash, bytes publicKey, uint64 genesis, uint64 period)
|
|
1907
|
+
```
|
|
1908
|
+
|
|
1909
|
+
Topic 0 `0x293a9d9da76ea51abf287fd8574e03634d02d6156cf7df7e901320c2de39bf96` · Emitted by: [`registerBeacon`](#registry-fn-registerbeacon) · Source: `EpochEntropy.sol` lines 93, 186
|
|
1910
|
+
|
|
1911
|
+
Recipe `recipe` is a beacon recipe: emitted right after its `RecipeRegistered` with the registration `beaconOf` returns (`verifier`, `chainHash`, `publicKey`, `genesis`, `period`).
|
|
1831
1912
|
|
|
1832
1913
|
#### <a id="registry-event-catalogscheduled"></a>`CatalogScheduled`
|
|
1833
1914
|
|
|
@@ -1835,9 +1916,9 @@ Recipe `recipe` was registered. The event carries the complete definition, so ev
|
|
|
1835
1916
|
event CatalogScheduled(uint64 indexed fromEpoch, bytes32 indexed catalogHash, uint8[] recipes, address[] signers)
|
|
1836
1917
|
```
|
|
1837
1918
|
|
|
1838
|
-
Topic 0 `0xc91bcd562b1edaabdb2772ada76957511610c715ef892b9c9af1f35be93c3c4f` · Emitted by: [`scheduleCatalog`](#registry-fn-schedulecatalog) · Source: `EpochEntropy.sol` lines
|
|
1919
|
+
Topic 0 `0xc91bcd562b1edaabdb2772ada76957511610c715ef892b9c9af1f35be93c3c4f` · Emitted by: [`scheduleCatalog`](#registry-fn-schedulecatalog) · Source: `EpochEntropy.sol` lines 90, 293
|
|
1839
1920
|
|
|
1840
|
-
A catalog was scheduled for epochs from `fromEpoch`: recipe ids and signers in slot order. A later `CatalogScheduled` emitted while this version
|
|
1921
|
+
A catalog was scheduled for epochs from `fromEpoch`: recipe ids and signers in slot order. A later `CatalogScheduled` emitted while this version is still pending, two or more epochs ahead, replaces it, so when rebuilding catalogs from history drop replaced versions, or read `catalogAt(epochId)`.
|
|
1841
1922
|
|
|
1842
1923
|
**Administration and upgrades**
|
|
1843
1924
|
|
|
@@ -1847,7 +1928,7 @@ A catalog was scheduled for epochs from `fromEpoch`: recipe ids and signers in s
|
|
|
1847
1928
|
event CommitterChanged(address indexed previousCommitter, address indexed newCommitter)
|
|
1848
1929
|
```
|
|
1849
1930
|
|
|
1850
|
-
Topic 0 `0x3f67cc70f736070aaac75db90cef1ab4047521b73e8a38d02852e8bf1a91e7e0` · Emitted by: [`setCommitter`](#registry-fn-setcommitter) · Source: `EpochEntropy.sol` lines
|
|
1931
|
+
Topic 0 `0x3f67cc70f736070aaac75db90cef1ab4047521b73e8a38d02852e8bf1a91e7e0` · Emitted by: [`setCommitter`](#registry-fn-setcommitter) · Source: `EpochEntropy.sol` lines 89, 120
|
|
1851
1932
|
|
|
1852
1933
|
New primary publishing address; it also receives the keeper share of proofs submitted by wallets the registry does not authorize.
|
|
1853
1934
|
|
|
@@ -1857,7 +1938,7 @@ New primary publishing address; it also receives the keeper share of proofs subm
|
|
|
1857
1938
|
event BackupCommitterSet(address indexed account, bool allowed)
|
|
1858
1939
|
```
|
|
1859
1940
|
|
|
1860
|
-
Topic 0 `0x20380b8c17d904db7d905a51f1538057d280a6cecca38882832ba0261b39fa66` · Emitted by: [`setBackupCommitter`](#registry-fn-setbackupcommitter) · Source: `EpochEntropy.sol` lines
|
|
1941
|
+
Topic 0 `0x20380b8c17d904db7d905a51f1538057d280a6cecca38882832ba0261b39fa66` · Emitted by: [`setBackupCommitter`](#registry-fn-setbackupcommitter) · Source: `EpochEntropy.sol` lines 92, 134
|
|
1861
1942
|
|
|
1862
1943
|
`account` may now publish epochs (`allowed` true) or no longer may (`allowed` false).
|
|
1863
1944
|
|
|
@@ -1907,7 +1988,7 @@ Topic 0 `0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2` ·
|
|
|
1907
1988
|
|
|
1908
1989
|
#### <a id="registry-error-invalidepoch"></a>`InvalidEpoch`
|
|
1909
1990
|
|
|
1910
|
-
`error InvalidEpoch()` · Selector `0xd5b25b63` · Source: `EpochEntropy.sol` lines
|
|
1991
|
+
`error InvalidEpoch()` · Selector `0xd5b25b63` · Source: `EpochEntropy.sol` lines 83, 284, 315
|
|
1911
1992
|
|
|
1912
1993
|
**Raised by:** [`epochStart`](#registry-fn-epochstart), [`getEpochSelection`](#registry-fn-getepochselection), [`getEpochFallbackSelection`](#registry-fn-getepochfallbackselection), [`fallbackOpensAt`](#registry-fn-fallbackopensat), [`checkpointEpoch`](#registry-fn-checkpointepoch), [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback), [`scheduleCatalog`](#registry-fn-schedulecatalog).
|
|
1913
1994
|
|
|
@@ -1917,7 +1998,7 @@ Epoch 0 was passed to `epochStart`, `fallbackOpensAt`, a selection view, `checkp
|
|
|
1917
1998
|
|
|
1918
1999
|
#### <a id="registry-error-preparationclosed"></a>`PreparationClosed`
|
|
1919
2000
|
|
|
1920
|
-
`error PreparationClosed()` · Selector `0x8e2a3c7d` · Source: `EpochEntropy.sol` lines
|
|
2001
|
+
`error PreparationClosed()` · Selector `0x8e2a3c7d` · Source: `EpochEntropy.sol` lines 83, 330
|
|
1921
2002
|
|
|
1922
2003
|
**Raised by:** [`getEpochSelection`](#registry-fn-getepochselection), [`getEpochFallbackSelection`](#registry-fn-getepochfallbackselection), [`checkpointEpoch`](#registry-fn-checkpointepoch).
|
|
1923
2004
|
|
|
@@ -1927,7 +2008,7 @@ The epoch has not started (`block.number` is below `epochStart(epochId)`), so it
|
|
|
1927
2008
|
|
|
1928
2009
|
#### <a id="registry-error-anchorunavailable"></a>`AnchorUnavailable`
|
|
1929
2010
|
|
|
1930
|
-
`error AnchorUnavailable()` · Selector `0x60776ed3` · Source: `EpochEntropy.sol` lines
|
|
2011
|
+
`error AnchorUnavailable()` · Selector `0x60776ed3` · Source: `EpochEntropy.sol` lines 83, 333
|
|
1931
2012
|
|
|
1932
2013
|
**Raised by:** [`getEpochSelection`](#registry-fn-getepochselection), [`getEpochFallbackSelection`](#registry-fn-getepochfallbackselection), [`checkpointEpoch`](#registry-fn-checkpointepoch), [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1933
2014
|
|
|
@@ -1939,7 +2020,7 @@ The anchor (hash of block `epochStart - 1`) was never checkpointed and is outsid
|
|
|
1939
2020
|
|
|
1940
2021
|
#### <a id="registry-error-onlycommitter"></a>`OnlyCommitter`
|
|
1941
2022
|
|
|
1942
|
-
`error OnlyCommitter()` · Selector `0xfffe5af3` · Source: `EpochEntropy.sol` lines
|
|
2023
|
+
`error OnlyCommitter()` · Selector `0xfffe5af3` · Source: `EpochEntropy.sol` lines 84, 364
|
|
1943
2024
|
|
|
1944
2025
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1945
2026
|
|
|
@@ -1949,7 +2030,7 @@ A commit from an address that is neither `committer()` nor an allowed backup com
|
|
|
1949
2030
|
|
|
1950
2031
|
#### <a id="registry-error-alreadycommitted"></a>`AlreadyCommitted`
|
|
1951
2032
|
|
|
1952
|
-
`error AlreadyCommitted()` · Selector `0xbfec5558` · Source: `EpochEntropy.sol` lines
|
|
2033
|
+
`error AlreadyCommitted()` · Selector `0xbfec5558` · Source: `EpochEntropy.sol` lines 84, 365
|
|
1953
2034
|
|
|
1954
2035
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1955
2036
|
|
|
@@ -1959,7 +2040,7 @@ The epoch already has a published packet.
|
|
|
1959
2040
|
|
|
1960
2041
|
#### <a id="registry-error-fallbacknotopen"></a>`FallbackNotOpen`
|
|
1961
2042
|
|
|
1962
|
-
`error FallbackNotOpen()` · Selector `0xf8635228` · Source: `EpochEntropy.sol` lines
|
|
2043
|
+
`error FallbackNotOpen()` · Selector `0xf8635228` · Source: `EpochEntropy.sol` lines 86, 366
|
|
1963
2044
|
|
|
1964
2045
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1965
2046
|
|
|
@@ -1969,7 +2050,7 @@ The epoch already has a published packet.
|
|
|
1969
2050
|
|
|
1970
2051
|
#### <a id="registry-error-invalidfallback"></a>`InvalidFallback`
|
|
1971
2052
|
|
|
1972
|
-
`error InvalidFallback()` · Selector `0x5a93724d` · Source: `EpochEntropy.sol` lines
|
|
2053
|
+
`error InvalidFallback()` · Selector `0x5a93724d` · Source: `EpochEntropy.sol` lines 86, 341, 349, 360
|
|
1973
2054
|
|
|
1974
2055
|
**Raised by:** [`getEpochFallbackSelection`](#registry-fn-getepochfallbackselection), [`fallbackOpensAt`](#registry-fn-fallbackopensat), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1975
2056
|
|
|
@@ -1979,17 +2060,17 @@ An attempt at or above `sourceCountAt(epochId)`, or attempt 0 passed to `commitE
|
|
|
1979
2060
|
|
|
1980
2061
|
#### <a id="registry-error-invalidtime"></a>`InvalidTime`
|
|
1981
2062
|
|
|
1982
|
-
`error InvalidTime()` · Selector `0x6f7eac26` · Source: `EpochEntropy.sol` lines
|
|
2063
|
+
`error InvalidTime()` · Selector `0x6f7eac26` · Source: `EpochEntropy.sol` lines 84, 368, 378
|
|
1983
2064
|
|
|
1984
2065
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1985
2066
|
|
|
1986
|
-
The attestation timestamp is in the future or more than `MAX_ATTESTATION_AGE` (240 seconds) before the publication block.
|
|
2067
|
+
The attestation timestamp is in the future or more than `MAX_ATTESTATION_AGE` (240 seconds) before the publication block, or, for a beacon recipe, is not the scheduled time of the round in the data.
|
|
1987
2068
|
|
|
1988
2069
|
**What to do:** A saved packet is never refreshed; its requests expire and are refunded.
|
|
1989
2070
|
|
|
1990
2071
|
#### <a id="registry-error-invaliddata"></a>`InvalidData`
|
|
1991
2072
|
|
|
1992
|
-
`error InvalidData()` · Selector `0x5cb045db` · Source: `EpochEntropy.sol` lines
|
|
2073
|
+
`error InvalidData()` · Selector `0x5cb045db` · Source: `EpochEntropy.sol` lines 84, 369–370
|
|
1993
2074
|
|
|
1994
2075
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
1995
2076
|
|
|
@@ -1999,13 +2080,23 @@ The signed data does not match the data template of the slot's recipe exactly, w
|
|
|
1999
2080
|
|
|
2000
2081
|
#### <a id="registry-error-invalidsigner"></a>`InvalidSigner`
|
|
2001
2082
|
|
|
2002
|
-
`error InvalidSigner()` · Selector `0x815e1d64` · Source: `EpochEntropy.sol` lines
|
|
2083
|
+
`error InvalidSigner()` · Selector `0x815e1d64` · Source: `EpochEntropy.sol` lines 84, 374, 379
|
|
2003
2084
|
|
|
2004
2085
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
2005
2086
|
|
|
2006
|
-
The signature does not recover to the slot's signer in the epoch's catalog.
|
|
2087
|
+
The signature does not recover to the slot's signer in the epoch's catalog, or, for a beacon recipe, the verifier of its registration did not accept it as the beacon's signature of the round in the data.
|
|
2088
|
+
|
|
2089
|
+
**What to do:** Use `catalogAt(epochId)` for the expected signer; for a beacon recipe check the round with `verifyBeacon`.
|
|
2090
|
+
|
|
2091
|
+
#### <a id="registry-error-beacongastoolow"></a>`BeaconGasTooLow`
|
|
2092
|
+
|
|
2093
|
+
`error BeaconGasTooLow()` · Selector `0x919ddbf6` · Source: `EpochEntropy.sol` lines 87, 220
|
|
2007
2094
|
|
|
2008
|
-
**
|
|
2095
|
+
**Raised by:** [`verifyBeacon`](#registry-fn-verifybeacon), [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback), [`registerBeacon`](#registry-fn-registerbeacon).
|
|
2096
|
+
|
|
2097
|
+
Too little gas was left to give the beacon verifier its whole `BEACON_VERIFY_GAS` allowance, in `registerBeacon`, `verifyBeacon` or a publication of a beacon epoch. It is raised instead of answering false, so a valid round is never read as invalid because the sender's gas limit was low.
|
|
2098
|
+
|
|
2099
|
+
**What to do:** Send the transaction with a higher gas limit; an `eth_call` of `verifyBeacon` needs about 461,000 gas.
|
|
2009
2100
|
|
|
2010
2101
|
#### <a id="registry-error-ecdsainvalidsignature"></a>`ECDSAInvalidSignature`
|
|
2011
2102
|
|
|
@@ -2039,7 +2130,7 @@ The signature has a high `s` value (OpenZeppelin `ECDSA`).
|
|
|
2039
2130
|
|
|
2040
2131
|
#### <a id="registry-error-packettoolarge"></a>`PacketTooLarge`
|
|
2041
2132
|
|
|
2042
|
-
`error PacketTooLarge()` · Selector `0xda85e8a5` · Source: `EpochEntropy.sol` lines
|
|
2133
|
+
`error PacketTooLarge()` · Selector `0xda85e8a5` · Source: `EpochEntropy.sol` lines 85, 389
|
|
2043
2134
|
|
|
2044
2135
|
**Raised by:** [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback).
|
|
2045
2136
|
|
|
@@ -2051,9 +2142,9 @@ The encoded packet exceeds `MAX_PACKET_BYTES` (2048).
|
|
|
2051
2142
|
|
|
2052
2143
|
#### <a id="registry-error-invalidrecipe"></a>`InvalidRecipe`
|
|
2053
2144
|
|
|
2054
|
-
`error InvalidRecipe()` · Selector `0x7b776f4c` · Source: `EpochEntropy.sol` lines
|
|
2145
|
+
`error InvalidRecipe()` · Selector `0x7b776f4c` · Source: `EpochEntropy.sol` lines 87, 165
|
|
2055
2146
|
|
|
2056
|
-
**Raised by:** [`registerRecipe`](#registry-fn-registerrecipe).
|
|
2147
|
+
**Raised by:** [`registerRecipe`](#registry-fn-registerrecipe), [`registerBeacon`](#registry-fn-registerbeacon).
|
|
2057
2148
|
|
|
2058
2149
|
`registerRecipe` got an empty canonical request or body, a canonical request over `MAX_REQUEST_BYTES` or a body over `MAX_BODY_BYTES`, or `MAX_RECIPES` recipes are already registered.
|
|
2059
2150
|
|
|
@@ -2061,7 +2152,7 @@ The encoded packet exceeds `MAX_PACKET_BYTES` (2048).
|
|
|
2061
2152
|
|
|
2062
2153
|
#### <a id="registry-error-invalidtemplate"></a>`InvalidTemplate`
|
|
2063
2154
|
|
|
2064
|
-
`error InvalidTemplate()` · Selector `0xec55b8cd` · Source: `EpochEntropy.sol` lines
|
|
2155
|
+
`error InvalidTemplate()` · Selector `0xec55b8cd` · Source: `EpochEntropy.sol` lines 87, 166
|
|
2065
2156
|
|
|
2066
2157
|
**Raised by:** [`registerRecipe`](#registry-fn-registerrecipe).
|
|
2067
2158
|
|
|
@@ -2069,13 +2160,23 @@ The encoded packet exceeds `MAX_PACKET_BYTES` (2048).
|
|
|
2069
2160
|
|
|
2070
2161
|
**What to do:** Build the template with `encodeDataTemplate`, which names the broken rule, before registering.
|
|
2071
2162
|
|
|
2163
|
+
#### <a id="registry-error-stringsinsufficienthexlength"></a>`StringsInsufficientHexLength`
|
|
2164
|
+
|
|
2165
|
+
`error StringsInsufficientHexLength(uint256 value, uint256 length)` · Selector `0xe22e27eb`
|
|
2166
|
+
|
|
2167
|
+
**Raised by:** no public function (declared by OpenZeppelin `Strings`).
|
|
2168
|
+
|
|
2169
|
+
Declared by OpenZeppelin `Strings`, which `registerBeacon` uses to write the chain hash as 32 bytes of hex. A 32-byte value always fits, so it cannot be raised.
|
|
2170
|
+
|
|
2171
|
+
**What to do:** None.
|
|
2172
|
+
|
|
2072
2173
|
#### <a id="registry-error-invalidconfig"></a>`InvalidConfig`
|
|
2073
2174
|
|
|
2074
|
-
`error InvalidConfig()` · Selector `0x35be3ac8` · Source: `EpochEntropy.sol` lines
|
|
2175
|
+
`error InvalidConfig()` · Selector `0x35be3ac8` · Source: `EpochEntropy.sol` lines 83, 99, 111, 119, 126, 128, 158, 180–182, 275, 279, 280
|
|
2075
2176
|
|
|
2076
|
-
**Raised by:** [`getRecipe`](#registry-fn-getrecipe), [`recipeRequest`](#registry-fn-reciperequest), [`getEpochSelection`](#registry-fn-getepochselection), [`getEpochFallbackSelection`](#registry-fn-getepochfallbackselection), [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback), [`scheduleCatalog`](#registry-fn-schedulecatalog), [`initializeRecipeRegistry`](#registry-fn-initializereciperegistry), [`setCommitter`](#registry-fn-setcommitter), [`setBackupCommitter`](#registry-fn-setbackupcommitter), [`initialize`](#registry-fn-initialize).
|
|
2177
|
+
**Raised by:** [`getRecipe`](#registry-fn-getrecipe), [`beaconOf`](#registry-fn-beaconof), [`recipeRequest`](#registry-fn-reciperequest), [`getEpochSelection`](#registry-fn-getepochselection), [`getEpochFallbackSelection`](#registry-fn-getepochfallbackselection), [`commitEpoch`](#registry-fn-commitepoch), [`commitEpochFallback`](#registry-fn-commitepochfallback), [`registerBeacon`](#registry-fn-registerbeacon), [`scheduleCatalog`](#registry-fn-schedulecatalog), [`initializeRecipeRegistry`](#registry-fn-initializereciperegistry), [`setCommitter`](#registry-fn-setcommitter), [`setBackupCommitter`](#registry-fn-setbackupcommitter), [`initialize`](#registry-fn-initialize).
|
|
2077
2178
|
|
|
2078
|
-
A zero signer or committer in `initialize`; a zero address in `setCommitter`; in `setBackupCommitter` the zero address, allowing the committer, an unchanged status or a fifth backup committer; in `scheduleCatalog` an empty or oversized catalog, mismatched lengths, a repeated or unregistered recipe or a
|
|
2179
|
+
A zero signer or committer in `initialize`; a zero address in `setCommitter`; in `setBackupCommitter` the zero address, allowing the committer, an unchanged status or a fifth backup committer; in `registerBeacon` a verifier without code, a zero chain hash, genesis, period or sample round, a sample round not yet scheduled, or a key or sample signature the verifier rejects; in `scheduleCatalog` an empty or oversized catalog, mismatched lengths, a repeated or unregistered recipe, a zero signer or a beacon recipe listed with a signer other than its `slotSigner`; `initializeRecipeRegistry` on a registry that already has recipes or a scheduled catalog; or a recipe id that is not registered, in `getRecipe`, `recipeRequest` and `beaconOf` or, on a registry upgraded without `initializeRecipeRegistry`, in selection and publication.
|
|
2079
2180
|
|
|
2080
2181
|
**What to do:** Correct the arguments; recipe ids run from 0 to `recipeCount() - 1`. A registry upgraded without the recipe step needs `initializeRecipeRegistry` from its owner.
|
|
2081
2182
|
|
|
@@ -2083,7 +2184,7 @@ A zero signer or committer in `initialize`; a zero address in `setCommitter`; in
|
|
|
2083
2184
|
|
|
2084
2185
|
`error OwnableUnauthorizedAccount(address account)` · Selector `0x118cdaa7`
|
|
2085
2186
|
|
|
2086
|
-
**Raised by:** [`registerRecipe`](#registry-fn-registerrecipe), [`scheduleCatalog`](#registry-fn-schedulecatalog), [`initializeRecipeRegistry`](#registry-fn-initializereciperegistry), [`setCommitter`](#registry-fn-setcommitter), [`setBackupCommitter`](#registry-fn-setbackupcommitter), [`transferOwnership`](#registry-fn-transferownership), [`acceptOwnership`](#registry-fn-acceptownership), [`renounceOwnership`](#registry-fn-renounceownership), [`upgradeToAndCall`](#registry-fn-upgradetoandcall).
|
|
2187
|
+
**Raised by:** [`registerRecipe`](#registry-fn-registerrecipe), [`registerBeacon`](#registry-fn-registerbeacon), [`scheduleCatalog`](#registry-fn-schedulecatalog), [`initializeRecipeRegistry`](#registry-fn-initializereciperegistry), [`setCommitter`](#registry-fn-setcommitter), [`setBackupCommitter`](#registry-fn-setbackupcommitter), [`transferOwnership`](#registry-fn-transferownership), [`acceptOwnership`](#registry-fn-acceptownership), [`renounceOwnership`](#registry-fn-renounceownership), [`upgradeToAndCall`](#registry-fn-upgradetoandcall).
|
|
2087
2188
|
|
|
2088
2189
|
`account` is not the owner (owner-only functions) or not the pending owner (`acceptOwnership`).
|
|
2089
2190
|
|
|
@@ -2101,7 +2202,7 @@ A zero signer or committer in `initialize`; a zero address in `setCommitter`; in
|
|
|
2101
2202
|
|
|
2102
2203
|
#### <a id="registry-error-renouncedisabled"></a>`RenounceDisabled`
|
|
2103
2204
|
|
|
2104
|
-
`error RenounceDisabled()` · Selector `0x89051165` · Source: `EpochEntropy.sol` lines
|
|
2205
|
+
`error RenounceDisabled()` · Selector `0x89051165` · Source: `EpochEntropy.sol` lines 85, 116
|
|
2105
2206
|
|
|
2106
2207
|
**Raised by:** [`renounceOwnership`](#registry-fn-renounceownership).
|
|
2107
2208
|
|
|
@@ -2188,3 +2289,120 @@ Declared by OpenZeppelin `Address` for the delegatecall in `upgradeToAndCall`. N
|
|
|
2188
2289
|
The initialization call made by `upgradeToAndCall` reverted without revert data.
|
|
2189
2290
|
|
|
2190
2291
|
**What to do:** Owner upgrade procedure only.
|
|
2292
|
+
|
|
2293
|
+
## <a id="verifier"></a>D20BeaconVerifier
|
|
2294
|
+
|
|
2295
|
+
The verifier of the registry's drand beacon recipe: stateless and deployed directly, not behind a proxy. `EpochEntropy` records its address in a recipe's registration (`beaconOf`) and calls `isValidPublicKey` and `verifyRound` under a fixed gas allowance. It checks the bls-bn254-unchained-on-g1 scheme of drand's evmnet: the group public key is a BN254 G2 point, round `r`'s signature is a G1 point on the RFC 9380 hash-to-curve of `keccak256` of `r` as 8 big-endian bytes, and keys and signatures use drand's serialization of 32-byte big-endian words (`x ‖ y` for G1, `x_im ‖ x_re ‖ y_im ‖ y_re` for G2). It is built on the unmodified kevincharm/bls-bn254 library recorded in `notices/PROVENANCE.md`.
|
|
2296
|
+
|
|
2297
|
+
Anyone can call it, for example to check a drand round inside another contract. `beaconVerifierAbi` from `@d20dao/vrf-sdk/abi` carries its ABI, and `verifyBeaconRound` in `@d20dao/vrf-sdk` computes the same check off-chain.
|
|
2298
|
+
|
|
2299
|
+
### <a id="verifier-verification"></a>Verification
|
|
2300
|
+
|
|
2301
|
+
Views, callable by anyone.
|
|
2302
|
+
|
|
2303
|
+
#### <a id="verifier-fn-isvalidpublickey"></a>`isValidPublicKey`
|
|
2304
|
+
|
|
2305
|
+
```solidity
|
|
2306
|
+
function isValidPublicKey(bytes publicKey) external pure returns (bool)
|
|
2307
|
+
```
|
|
2308
|
+
|
|
2309
|
+
Selector `0xc4c1cf54` · Caller: Anyone (view) · Source: `D20BeaconVerifier.sol` lines 28–34
|
|
2310
|
+
|
|
2311
|
+
Whether `publicKey` is 128 bytes, `x_im ‖ x_re ‖ y_im ‖ y_re`, encoding a point on the BN254 G2 curve with every coordinate below the field order. Subgroup membership is not checked here: the pairing precompile refuses a key outside the subgroup, so a verified signature under the key establishes it. `EpochEntropy` calls it when a beacon is registered.
|
|
2312
|
+
|
|
2313
|
+
#### <a id="verifier-fn-roundmessage"></a>`roundMessage`
|
|
2314
|
+
|
|
2315
|
+
```solidity
|
|
2316
|
+
function roundMessage(uint64 round) external view returns (uint256[2])
|
|
2317
|
+
```
|
|
2318
|
+
|
|
2319
|
+
Selector `0xfd5a7458` · Caller: Anyone (view) · Source: `D20BeaconVerifier.sol` lines 36–39
|
|
2320
|
+
|
|
2321
|
+
The G1 point that the signature of `round` signs: the RFC 9380 hash-to-curve of `keccak256` of the round as 8 big-endian bytes under `DST` (`expand_message_xmd` with `keccak256`, the Shallue-van de Woestijne map and the sum of two mapped field elements). `beaconRoundMessage` in `@d20dao/vrf-sdk` computes the same point off-chain.
|
|
2322
|
+
|
|
2323
|
+
**Errors:** [`BNAddFailed`](#verifier-error-bnaddfailed), [`ModExpFailed`](#verifier-error-modexpfailed).
|
|
2324
|
+
|
|
2325
|
+
#### <a id="verifier-fn-verifyround"></a>`verifyRound`
|
|
2326
|
+
|
|
2327
|
+
```solidity
|
|
2328
|
+
function verifyRound(bytes publicKey, uint64 round, bytes signature) external view returns (bool)
|
|
2329
|
+
```
|
|
2330
|
+
|
|
2331
|
+
Selector `0x3a1bc7c9` · Caller: Anyone (view) · Source: `D20BeaconVerifier.sol` lines 41–60
|
|
2332
|
+
|
|
2333
|
+
Whether `signature` (64 bytes, `x ‖ y`) is the beacon's signature of `round` under `publicKey`: the pairing of `signature` with the G2 generator equals the pairing of `roundMessage(round)` with `publicKey`. It returns false, without reverting, for a signature that is not 64 bytes, a key that fails `isValidPublicKey` and a signature whose coordinates are not below the field order or not on the curve. Otherwise it runs the pairing precompile with a fixed allowance of `PAIRING_GAS`, and a direct call needs about 285,000 gas. It reverts `InsufficientGas`, and never answers false, when too little gas is left to give the precompile that allowance, so a valid signature is not read as invalid for want of gas.
|
|
2334
|
+
|
|
2335
|
+
**Errors:** [`InsufficientGas`](#verifier-error-insufficientgas), [`BNAddFailed`](#verifier-error-bnaddfailed), [`ModExpFailed`](#verifier-error-modexpfailed).
|
|
2336
|
+
|
|
2337
|
+
### <a id="verifier-constants"></a>Constants
|
|
2338
|
+
|
|
2339
|
+
Views returning values fixed in the code.
|
|
2340
|
+
|
|
2341
|
+
| Constant | Returns | Value | Selector | Meaning |
|
|
2342
|
+
| --- | --- | --- | --- | --- |
|
|
2343
|
+
| <a id="verifier-fn-dst"></a>`DST` | `bytes` | `"BLS_SIG_BN254G1_XMD:KECCAK-256_SVDW_RO_NUL_"` | `0x5f7c7522` | RFC 9380 domain separation tag of the scheme's hash-to-curve. |
|
|
2344
|
+
| <a id="verifier-fn-pairing_gas"></a>`PAIRING_GAS` | `uint256` | `200_000` | `0x1848e02a` | Gas given to the pairing precompile (address 8). A two-pair check costs 113,000 under EIP-1108. |
|
|
2345
|
+
|
|
2346
|
+
### <a id="verifier-errors"></a>Errors
|
|
2347
|
+
|
|
2348
|
+
**Verification**
|
|
2349
|
+
|
|
2350
|
+
#### <a id="verifier-error-insufficientgas"></a>`InsufficientGas`
|
|
2351
|
+
|
|
2352
|
+
`error InsufficientGas()` · Selector `0x1c26714c` · Source: `D20BeaconVerifier.sol` lines 17, 57
|
|
2353
|
+
|
|
2354
|
+
**Raised by:** [`verifyRound`](#verifier-fn-verifyround).
|
|
2355
|
+
|
|
2356
|
+
Too little gas was left in `verifyRound` for the pairing precompile to get its whole `PAIRING_GAS` allowance.
|
|
2357
|
+
|
|
2358
|
+
**What to do:** Send the call with a higher gas limit; a direct call needs about 285,000 gas.
|
|
2359
|
+
|
|
2360
|
+
#### <a id="verifier-error-modexpfailed"></a>`ModExpFailed`
|
|
2361
|
+
|
|
2362
|
+
`error ModExpFailed(uint256 base, uint256 exponent, uint256 modulus)` · Selector `0xc6daf7ab` · Source: `vendor/bls-bn254/BLS.sol` lines 56, 399
|
|
2363
|
+
|
|
2364
|
+
**Raised by:** [`roundMessage`](#verifier-fn-roundmessage), [`verifyRound`](#verifier-fn-verifyround).
|
|
2365
|
+
|
|
2366
|
+
The modexp precompile (address 5), which the hash-to-curve calls with all remaining gas, failed: in practice the call ran out of gas.
|
|
2367
|
+
|
|
2368
|
+
**What to do:** Send the call with a higher gas limit.
|
|
2369
|
+
|
|
2370
|
+
#### <a id="verifier-error-bnaddfailed"></a>`BNAddFailed`
|
|
2371
|
+
|
|
2372
|
+
`error BNAddFailed(uint256[4] input)` · Selector `0x128e3f08` · Source: `vendor/bls-bn254/BLS.sol` lines 52, 113
|
|
2373
|
+
|
|
2374
|
+
**Raised by:** [`roundMessage`](#verifier-fn-roundmessage), [`verifyRound`](#verifier-fn-verifyround).
|
|
2375
|
+
|
|
2376
|
+
The bn256 addition precompile (address 6), which adds the two mapped points of the hash-to-curve, failed: in practice the call ran out of gas.
|
|
2377
|
+
|
|
2378
|
+
**What to do:** Send the call with a higher gas limit.
|
|
2379
|
+
|
|
2380
|
+
#### <a id="verifier-error-maptopointfailed"></a>`MapToPointFailed`
|
|
2381
|
+
|
|
2382
|
+
`error MapToPointFailed(uint256 noSqrt)` · Selector `0x396ec771` · Source: `vendor/bls-bn254/BLS.sol` lines 54, 329, 334, 339, 365
|
|
2383
|
+
|
|
2384
|
+
**Raised by:** no input known (check inside the vendored library).
|
|
2385
|
+
|
|
2386
|
+
Raised by the vendored library when its map of a field element to the curve finds no square root or a Legendre exponentiation returns an unexpected value. The Shallue-van de Woestijne map always yields a point, so no input should reach it.
|
|
2387
|
+
|
|
2388
|
+
**What to do:** None.
|
|
2389
|
+
|
|
2390
|
+
#### <a id="verifier-error-invalidfieldelement"></a>`InvalidFieldElement`
|
|
2391
|
+
|
|
2392
|
+
`error InvalidFieldElement(uint256 x)` · Selector `0xd53e9415` · Source: `vendor/bls-bn254/BLS.sol` lines 53, 310
|
|
2393
|
+
|
|
2394
|
+
**Raised by:** no input of this contract (check inside the vendored library).
|
|
2395
|
+
|
|
2396
|
+
The vendored library was asked to map a value at or above the field order. The hash-to-curve reduces its field elements below it first, so this contract cannot reach it.
|
|
2397
|
+
|
|
2398
|
+
**What to do:** None.
|
|
2399
|
+
|
|
2400
|
+
#### <a id="verifier-error-invaliddstlength"></a>`InvalidDSTLength`
|
|
2401
|
+
|
|
2402
|
+
`error InvalidDSTLength(bytes dst)` · Selector `0x26e4f9ba` · Source: `vendor/bls-bn254/BLS.sol` lines 55, 260
|
|
2403
|
+
|
|
2404
|
+
**Raised by:** no input of this contract (check inside the vendored library).
|
|
2405
|
+
|
|
2406
|
+
The domain separation tag is longer than 255 bytes. `DST` is 43 bytes, so this contract cannot reach it.
|
|
2407
|
+
|
|
2408
|
+
**What to do:** None.
|