-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathIScribe.sol
245 lines (212 loc) · 10.3 KB
/
IScribe.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import {IChronicle} from "chronicle-std/IChronicle.sol";
import {LibSecp256k1} from "./libs/LibSecp256k1.sol";
interface IScribe is IChronicle {
/// @dev PokeData encapsulates a value and its age.
struct PokeData {
uint128 val;
uint32 age;
}
/// @dev SchnorrData encapsulates a (aggregated) Schnorr signature.
/// Schnorr signatures are used to prove a PokeData's integrity.
struct SchnorrData {
bytes32 signature;
address commitment;
bytes feedIds;
}
/// @dev ECDSAData encapsulates an ECDSA signature.
struct ECDSAData {
uint8 v;
bytes32 r;
bytes32 s;
}
/// @notice Thrown if a poked value's age is not greater than the oracle's
/// current value's age.
/// @param givenAge The poked value's age.
/// @param currentAge The oracle's current value's age.
error StaleMessage(uint32 givenAge, uint32 currentAge);
/// @notice Thrown if a poked value's age is greater than the current
/// time.
/// @param givenAge The poked value's age.
/// @param currentTimestamp The current time.
error FutureMessage(uint32 givenAge, uint32 currentTimestamp);
/// @notice Thrown if Schnorr signature not signed by exactly bar many
/// signers.
/// @param numberSigners The number of signers for given Schnorr signature.
/// @param bar The bar security parameter.
error BarNotReached(uint8 numberSigners, uint8 bar);
/// @notice Thrown if given feed id invalid.
/// @param feedId The invalid feed id.
error InvalidFeedId(uint8 feedId);
/// @notice Thrown if double signing attempted.
/// @param feedId The id of the feed attempting to double sign.
error DoubleSigningAttempted(uint8 feedId);
/// @notice Thrown if Schnorr signature verification failed.
error SchnorrSignatureInvalid();
/// @notice Emitted when oracle was successfully poked.
/// @param caller The caller's address.
/// @param val The value poked.
/// @param age The age of the value poked.
event Poked(address indexed caller, uint128 val, uint32 age);
/// @notice Emitted when new feed lifted.
/// @param caller The caller's address.
/// @param feed The feed address lifted.
event FeedLifted(address indexed caller, address indexed feed);
/// @notice Emitted when feed dropped.
/// @param caller The caller's address.
/// @param feed The feed address dropped.
event FeedDropped(address indexed caller, address indexed feed);
/// @notice Emitted when bar updated.
/// @param caller The caller's address.
/// @param oldBar The old bar's value.
/// @param newBar The new bar's value.
event BarUpdated(address indexed caller, uint8 oldBar, uint8 newBar);
/// @notice Returns the feed registration message.
/// @dev This message must be signed by a feed in order to be lifted.
/// @return feedRegistrationMessage Chronicle Protocol's feed registration
/// message.
function feedRegistrationMessage()
external
view
returns (bytes32 feedRegistrationMessage);
/// @notice Returns the bar security parameter.
/// @return bar The bar security parameter.
function bar() external view returns (uint8 bar);
/// @notice Returns the number of decimals of the oracle's value.
/// @dev Provides partial compatibility with Chainlink's
/// IAggregatorV3Interface.
/// @return decimals The oracle value's number of decimals.
function decimals() external view returns (uint8 decimals);
/// @notice Returns the oracle's latest value.
/// @dev Provides partial compatibility with Chainlink's
/// IAggregatorV3Interface.
/// @return roundId 1.
/// @return answer The oracle's latest value.
/// @return startedAt 0.
/// @return updatedAt The timestamp of oracle's latest update.
/// @return answeredInRound 1.
function latestRoundData()
external
view
returns (
uint80 roundId,
int answer,
uint startedAt,
uint updatedAt,
uint80 answeredInRound
);
/// @notice Returns the oracle's latest value.
/// @dev Provides partial compatibility with Chainlink's
/// IAggregatorV3Interface.
/// @custom:deprecated See https://docs.chain.link/data-feeds/api-reference/#latestanswer.
/// @return answer The oracle's latest value.
function latestAnswer() external view returns (int);
/// @notice Pokes the oracle.
/// @dev Expects `pokeData`'s age to be greater than the timestamp of the
/// last successful poke.
/// @dev Expects `pokeData`'s age to not be greater than the current time.
/// @dev Expects `schnorrData` to prove `pokeData`'s integrity.
/// See `isAcceptableSchnorrSignatureNow(bytes32,SchnorrData)(bool)`.
/// @param pokeData The PokeData being poked.
/// @param schnorrData The SchnorrData proving the `pokeData`'s
/// integrity.
function poke(PokeData calldata pokeData, SchnorrData calldata schnorrData)
external;
/// @notice Returns whether the Schnorr signature `schnorrData` is
/// currently acceptable for message `message`.
/// @dev Note that a valid Schnorr signature is only acceptable if the
/// signature was signed by exactly bar many feeds.
/// For more info, see `bar()(uint8)` and `feeds()(address[])`.
/// @dev Note that bar and feeds are configurable, meaning a once acceptable
/// Schnorr signature may become unacceptable in the future.
/// @param message The message expected to be signed via `schnorrData`.
/// @param schnorrData The SchnorrData to verify whether it proves
/// the `message`'s integrity.
/// @return ok True if Schnorr signature is acceptable, false otherwise.
function isAcceptableSchnorrSignatureNow(
bytes32 message,
SchnorrData calldata schnorrData
) external view returns (bool ok);
/// @notice Returns the message expected to be signed via Schnorr for
/// `pokeData`.
/// @dev The message is defined as:
/// H(tag ‖ H(wat ‖ pokeData)), where H() is the keccak256 function.
/// @param pokeData The pokeData to create the message for.
/// @return pokeMessage Message for `pokeData`.
function constructPokeMessage(PokeData calldata pokeData)
external
view
returns (bytes32 pokeMessage);
/// @notice Returns whether address `who` is a feed.
/// @param who The address to check.
/// @return isFeed True if `who` is feed, false otherwise.
function feeds(address who) external view returns (bool isFeed);
/// @notice Returns whether feed id `feedId` is a feed and, if so, the
/// feed's address.
/// @param feedId The feed id to check.
/// @return isFeed True if `feedId` is a feed, false otherwise.
/// @return feed Address of the feed with id `feedId` if `feedId` is a feed,
/// zero-address otherwise.
function feeds(uint8 feedId)
external
view
returns (bool isFeed, address feed);
/// @notice Returns list of feed addresses.
/// @dev Note that this function has a high gas consumption and is not
/// intended to be called onchain.
/// @return feeds List of feed addresses.
function feeds() external view returns (address[] memory feeds);
/// @notice Lifts public key `pubKey` to being a feed.
/// @dev Only callable by auth'ed address.
/// @dev The message expected to be signed by `ecdsaData` is defined via
/// `feedRegistrationMessage()(bytes32)`.
/// @custom:security The lift function's proof of possession is vulnerable
/// to rogue-key attacks. Additional verification MUST be
/// performed before lifting to ensure a feed's public key
/// validity.
/// @param pubKey The public key of the feed.
/// @param ecdsaData ECDSA signed message by the feed's public key.
/// @return feedId The id of the newly lifted feed.
function lift(LibSecp256k1.Point memory pubKey, ECDSAData memory ecdsaData)
external
returns (uint8 feedId);
/// @notice Lifts public keys `pubKeys` to being feeds.
/// @dev Only callable by auth'ed address.
/// @dev The message expected to be signed by `ecdsaDatas` is defined via
/// `feedRegistrationMessage()(bytes32)`.
/// @custom:security The lift function's proof of possession is vulnerable
/// to rogue-key attacks. Additional verification MUST be
/// performed before lifting to ensure a feed's public key
/// validity.
/// @param pubKeys The public keys of the feeds.
/// @param ecdsaDatas ECDSA signed message by the feeds' public keys.
/// @return List of feed ids of the newly lifted feeds.
function lift(
LibSecp256k1.Point[] memory pubKeys,
ECDSAData[] memory ecdsaDatas
) external returns (uint8[] memory);
/// @notice Drops feed with id `feedId`.
/// @dev Only callable by auth'ed address.
/// @param feedId The feed id to drop.
function drop(uint8 feedId) external;
/// @notice Drops feeds with ids' `feedIds`.
/// @dev Only callable by auth'ed address.
/// @param feedIds The feed ids to drop.
function drop(uint8[] memory feedIds) external;
/// @notice Updates the bar security parameters to `bar`.
/// @dev Only callable by auth'ed address.
/// @dev Reverts if `bar` is zero.
/// @param bar The value to update bar to.
function setBar(uint8 bar) external;
/// @notice Returns the oracle's current value.
/// @custom:deprecated Use `tryRead()(bool,uint)` instead.
/// @return value The oracle's current value if it exists, zero otherwise.
/// @return isValid True if value exists, false otherwise.
function peek() external view returns (uint value, bool isValid);
/// @notice Returns the oracle's current value.
/// @custom:deprecated Use `tryRead()(bool,uint)` instead.
/// @return value The oracle's current value if it exists, zero otherwise.
/// @return isValid True if value exists, false otherwise.
function peep() external view returns (uint value, bool isValid);
}