chai-link 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (322) hide show
  1. package/README.md +5 -0
  2. package/contracts/Aggregator.sol +420 -0
  3. package/contracts/AggregatorProxy.sol +99 -0
  4. package/contracts/Chainlink.sol +125 -0
  5. package/contracts/ChainlinkClient.sol +262 -0
  6. package/contracts/Chainlinked.sol +141 -0
  7. package/contracts/Migrations.sol +23 -0
  8. package/contracts/Oracle.sol +320 -0
  9. package/contracts/Pointer.sol +9 -0
  10. package/contracts/interfaces/AggregatorInterface.sol +12 -0
  11. package/contracts/interfaces/ChainlinkRequestInterface.sol +21 -0
  12. package/contracts/interfaces/ENSInterface.sol +26 -0
  13. package/contracts/interfaces/LinkTokenInterface.sol +16 -0
  14. package/contracts/interfaces/OracleInterface.sol +16 -0
  15. package/contracts/interfaces/PointerInterface.sol +5 -0
  16. package/contracts/tests/BasicConsumer.sol +13 -0
  17. package/contracts/tests/ConcreteChainlink.sol +76 -0
  18. package/contracts/tests/ConcreteChainlinked.sol +100 -0
  19. package/contracts/tests/ConcreteSignedSafeMath.sol +16 -0
  20. package/contracts/tests/Consumer.sol +47 -0
  21. package/contracts/tests/EmptyOracle.sol +19 -0
  22. package/contracts/tests/GetterSetter.sol +45 -0
  23. package/contracts/tests/MaliciousChainlink.sol +76 -0
  24. package/contracts/tests/MaliciousChainlinked.sol +109 -0
  25. package/contracts/tests/MaliciousConsumer.sol +54 -0
  26. package/contracts/tests/MaliciousRequester.sol +52 -0
  27. package/contracts/tests/UpdatableConsumer.sol +24 -0
  28. package/contracts/vendor/Buffer.sol +301 -0
  29. package/contracts/vendor/CBOR.sol +71 -0
  30. package/contracts/vendor/ENS.sol +26 -0
  31. package/contracts/vendor/ENSRegistry.sol +99 -0
  32. package/contracts/vendor/ENSResolver.sol +5 -0
  33. package/contracts/vendor/Ownable.sol +64 -0
  34. package/contracts/vendor/PublicResolver.sol +238 -0
  35. package/contracts/vendor/SafeMath.sol +52 -0
  36. package/contracts/vendor/SignedSafeMath.sol +21 -0
  37. package/dist/artifacts/Aggregator.json +580 -0
  38. package/dist/artifacts/AggregatorInterface.json +172 -0
  39. package/dist/artifacts/AggregatorProxy.json +294 -0
  40. package/dist/artifacts/BasicConsumer.json +250 -0
  41. package/dist/artifacts/Buffer.json +52 -0
  42. package/dist/artifacts/CBOR.json +56 -0
  43. package/dist/artifacts/Chainlink.json +60 -0
  44. package/dist/artifacts/ChainlinkClient.json +125 -0
  45. package/dist/artifacts/ChainlinkRequestInterface.json +121 -0
  46. package/dist/artifacts/Chainlinked.json +129 -0
  47. package/dist/artifacts/ConcreteChainlink.json +190 -0
  48. package/dist/artifacts/ConcreteChainlinked.json +387 -0
  49. package/dist/artifacts/ConcreteSignedSafeMath.json +80 -0
  50. package/dist/artifacts/Consumer.json +227 -0
  51. package/dist/artifacts/ENS.json +259 -0
  52. package/dist/artifacts/ENSInterface.json +259 -0
  53. package/dist/artifacts/ENSRegistry.json +269 -0
  54. package/dist/artifacts/ENSResolver.json +72 -0
  55. package/dist/artifacts/EmptyOracle.json +259 -0
  56. package/dist/artifacts/GetterSetter.json +278 -0
  57. package/dist/artifacts/LinkTokenInterface.json +292 -0
  58. package/dist/artifacts/MaliciousChainlink.json +60 -0
  59. package/dist/artifacts/MaliciousChainlinked.json +137 -0
  60. package/dist/artifacts/MaliciousConsumer.json +288 -0
  61. package/dist/artifacts/MaliciousRequester.json +266 -0
  62. package/dist/artifacts/Migrations.json +115 -0
  63. package/dist/artifacts/Oracle.json +426 -0
  64. package/dist/artifacts/OracleInterface.json +161 -0
  65. package/dist/artifacts/Ownable.json +125 -0
  66. package/dist/artifacts/Pointer.json +78 -0
  67. package/dist/artifacts/PointerInterface.json +67 -0
  68. package/dist/artifacts/PublicResolver.json +503 -0
  69. package/dist/artifacts/SafeMath.json +52 -0
  70. package/dist/artifacts/SignedSafeMath.json +52 -0
  71. package/dist/artifacts/UpdatableConsumer.json +287 -0
  72. package/dist/src/LinkToken.d.ts +40 -0
  73. package/dist/src/LinkToken.json +164 -0
  74. package/dist/src/contract.d.ts +13 -0
  75. package/dist/src/contract.js +3 -0
  76. package/dist/src/contract.js.map +1 -0
  77. package/dist/src/debug.d.ts +8 -0
  78. package/dist/src/debug.js +17 -0
  79. package/dist/src/debug.js.map +1 -0
  80. package/dist/src/generated/Aggregator.d.ts +372 -0
  81. package/dist/src/generated/AggregatorFactory.d.ts +13 -0
  82. package/dist/src/generated/AggregatorFactory.js +505 -0
  83. package/dist/src/generated/AggregatorFactory.js.map +1 -0
  84. package/dist/src/generated/AggregatorInterface.d.ts +110 -0
  85. package/dist/src/generated/AggregatorInterfaceFactory.d.ts +6 -0
  86. package/dist/src/generated/AggregatorInterfaceFactory.js +133 -0
  87. package/dist/src/generated/AggregatorInterfaceFactory.js.map +1 -0
  88. package/dist/src/generated/AggregatorProxy.d.ts +196 -0
  89. package/dist/src/generated/AggregatorProxyFactory.d.ts +12 -0
  90. package/dist/src/generated/AggregatorProxyFactory.js +263 -0
  91. package/dist/src/generated/AggregatorProxyFactory.js.map +1 -0
  92. package/dist/src/generated/BasicConsumer.d.ts +154 -0
  93. package/dist/src/generated/BasicConsumerFactory.d.ts +13 -0
  94. package/dist/src/generated/BasicConsumerFactory.js +183 -0
  95. package/dist/src/generated/BasicConsumerFactory.js.map +1 -0
  96. package/dist/src/generated/ChainlinkClient.d.ts +58 -0
  97. package/dist/src/generated/ChainlinkClientFactory.d.ts +12 -0
  98. package/dist/src/generated/ChainlinkClientFactory.js +66 -0
  99. package/dist/src/generated/ChainlinkClientFactory.js.map +1 -0
  100. package/dist/src/generated/ChainlinkRequestInterface.d.ts +139 -0
  101. package/dist/src/generated/ChainlinkRequestInterfaceFactory.d.ts +6 -0
  102. package/dist/src/generated/ChainlinkRequestInterfaceFactory.js +82 -0
  103. package/dist/src/generated/ChainlinkRequestInterfaceFactory.js.map +1 -0
  104. package/dist/src/generated/Chainlinked.d.ts +55 -0
  105. package/dist/src/generated/ChainlinkedFactory.d.ts +12 -0
  106. package/dist/src/generated/ChainlinkedFactory.js +66 -0
  107. package/dist/src/generated/ChainlinkedFactory.js.map +1 -0
  108. package/dist/src/generated/ConcreteChainlink.d.ts +158 -0
  109. package/dist/src/generated/ConcreteChainlinkFactory.d.ts +12 -0
  110. package/dist/src/generated/ConcreteChainlinkFactory.js +155 -0
  111. package/dist/src/generated/ConcreteChainlinkFactory.js.map +1 -0
  112. package/dist/src/generated/ConcreteChainlinked.d.ts +300 -0
  113. package/dist/src/generated/ConcreteChainlinkedFactory.d.ts +12 -0
  114. package/dist/src/generated/ConcreteChainlinkedFactory.js +320 -0
  115. package/dist/src/generated/ConcreteChainlinkedFactory.js.map +1 -0
  116. package/dist/src/generated/ConcreteSignedSafeMath.d.ts +50 -0
  117. package/dist/src/generated/ConcreteSignedSafeMathFactory.d.ts +12 -0
  118. package/dist/src/generated/ConcreteSignedSafeMathFactory.js +53 -0
  119. package/dist/src/generated/ConcreteSignedSafeMathFactory.js.map +1 -0
  120. package/dist/src/generated/Consumer.d.ts +151 -0
  121. package/dist/src/generated/ConsumerFactory.d.ts +12 -0
  122. package/dist/src/generated/ConsumerFactory.js +164 -0
  123. package/dist/src/generated/ConsumerFactory.js.map +1 -0
  124. package/dist/src/generated/ENS.d.ts +171 -0
  125. package/dist/src/generated/ENSFactory.d.ts +6 -0
  126. package/dist/src/generated/ENSFactory.js +220 -0
  127. package/dist/src/generated/ENSFactory.js.map +1 -0
  128. package/dist/src/generated/ENSInterface.d.ts +174 -0
  129. package/dist/src/generated/ENSInterfaceFactory.d.ts +6 -0
  130. package/dist/src/generated/ENSInterfaceFactory.js +220 -0
  131. package/dist/src/generated/ENSInterfaceFactory.js.map +1 -0
  132. package/dist/src/generated/ENSRegistry.d.ts +171 -0
  133. package/dist/src/generated/ENSRegistryFactory.d.ts +12 -0
  134. package/dist/src/generated/ENSRegistryFactory.js +242 -0
  135. package/dist/src/generated/ENSRegistryFactory.js.map +1 -0
  136. package/dist/src/generated/ENSResolver.d.ts +45 -0
  137. package/dist/src/generated/ENSResolverFactory.d.ts +6 -0
  138. package/dist/src/generated/ENSResolverFactory.js +33 -0
  139. package/dist/src/generated/ENSResolverFactory.js.map +1 -0
  140. package/dist/src/generated/EmptyOracle.d.ts +228 -0
  141. package/dist/src/generated/EmptyOracleFactory.d.ts +12 -0
  142. package/dist/src/generated/EmptyOracleFactory.js +228 -0
  143. package/dist/src/generated/EmptyOracleFactory.js.map +1 -0
  144. package/dist/src/generated/GetterSetter.d.ts +207 -0
  145. package/dist/src/generated/GetterSetterFactory.d.ts +12 -0
  146. package/dist/src/generated/GetterSetterFactory.js +255 -0
  147. package/dist/src/generated/GetterSetterFactory.js.map +1 -0
  148. package/dist/src/generated/LinkToken.d.ts +243 -0
  149. package/dist/src/generated/LinkTokenFactory.d.ts +12 -0
  150. package/dist/src/generated/LinkTokenFactory.js +329 -0
  151. package/dist/src/generated/LinkTokenFactory.js.map +1 -0
  152. package/dist/src/generated/LinkTokenInterface.d.ts +230 -0
  153. package/dist/src/generated/LinkTokenInterfaceFactory.d.ts +6 -0
  154. package/dist/src/generated/LinkTokenInterfaceFactory.js +253 -0
  155. package/dist/src/generated/LinkTokenInterfaceFactory.js.map +1 -0
  156. package/dist/src/generated/MaliciousChainlinked.d.ts +58 -0
  157. package/dist/src/generated/MaliciousChainlinkedFactory.d.ts +12 -0
  158. package/dist/src/generated/MaliciousChainlinkedFactory.js +66 -0
  159. package/dist/src/generated/MaliciousChainlinkedFactory.js.map +1 -0
  160. package/dist/src/generated/MaliciousConsumer.d.ts +179 -0
  161. package/dist/src/generated/MaliciousConsumerFactory.d.ts +12 -0
  162. package/dist/src/generated/MaliciousConsumerFactory.js +221 -0
  163. package/dist/src/generated/MaliciousConsumerFactory.js.map +1 -0
  164. package/dist/src/generated/MaliciousRequester.d.ts +161 -0
  165. package/dist/src/generated/MaliciousRequesterFactory.d.ts +12 -0
  166. package/dist/src/generated/MaliciousRequesterFactory.js +191 -0
  167. package/dist/src/generated/MaliciousRequesterFactory.js.map +1 -0
  168. package/dist/src/generated/Migrations.d.ts +87 -0
  169. package/dist/src/generated/MigrationsFactory.d.ts +12 -0
  170. package/dist/src/generated/MigrationsFactory.js +92 -0
  171. package/dist/src/generated/MigrationsFactory.js.map +1 -0
  172. package/dist/src/generated/Oracle.d.ts +362 -0
  173. package/dist/src/generated/OracleFactory.d.ts +12 -0
  174. package/dist/src/generated/OracleFactory.js +383 -0
  175. package/dist/src/generated/OracleFactory.js.map +1 -0
  176. package/dist/src/generated/OracleInterface.d.ts +144 -0
  177. package/dist/src/generated/OracleInterfaceFactory.d.ts +6 -0
  178. package/dist/src/generated/OracleInterfaceFactory.js +122 -0
  179. package/dist/src/generated/OracleInterfaceFactory.js.map +1 -0
  180. package/dist/src/generated/Ownable.d.ts +91 -0
  181. package/dist/src/generated/OwnableFactory.d.ts +12 -0
  182. package/dist/src/generated/OwnableFactory.js +102 -0
  183. package/dist/src/generated/OwnableFactory.js.map +1 -0
  184. package/dist/src/generated/Pointer.d.ts +45 -0
  185. package/dist/src/generated/PointerFactory.d.ts +12 -0
  186. package/dist/src/generated/PointerFactory.js +55 -0
  187. package/dist/src/generated/PointerFactory.js.map +1 -0
  188. package/dist/src/generated/PointerInterface.d.ts +48 -0
  189. package/dist/src/generated/PointerInterfaceFactory.d.ts +6 -0
  190. package/dist/src/generated/PointerInterfaceFactory.js +28 -0
  191. package/dist/src/generated/PointerInterfaceFactory.js.map +1 -0
  192. package/dist/src/generated/PublicResolver.d.ts +336 -0
  193. package/dist/src/generated/PublicResolverFactory.d.ts +12 -0
  194. package/dist/src/generated/PublicResolverFactory.js +476 -0
  195. package/dist/src/generated/PublicResolverFactory.js.map +1 -0
  196. package/dist/src/generated/UpdatableConsumer.d.ts +180 -0
  197. package/dist/src/generated/UpdatableConsumerFactory.d.ts +13 -0
  198. package/dist/src/generated/UpdatableConsumerFactory.js +220 -0
  199. package/dist/src/generated/UpdatableConsumerFactory.js.map +1 -0
  200. package/dist/src/generated/index.d.ts +44 -0
  201. package/dist/src/generated/index.js +41 -0
  202. package/dist/src/generated/index.js.map +1 -0
  203. package/dist/src/helpers.d.ts +144 -0
  204. package/dist/src/helpers.js +358 -0
  205. package/dist/src/helpers.js.map +1 -0
  206. package/dist/src/helpers.test.d.ts +1 -0
  207. package/dist/src/helpers.test.js +21 -0
  208. package/dist/src/helpers.test.js.map +1 -0
  209. package/dist/src/index.d.ts +8 -0
  210. package/dist/src/index.js +27 -0
  211. package/dist/src/index.js.map +1 -0
  212. package/dist/src/matchers.d.ts +2 -0
  213. package/dist/src/matchers.js +7 -0
  214. package/dist/src/matchers.js.map +1 -0
  215. package/dist/src/provider.d.ts +5 -0
  216. package/dist/src/provider.js +15 -0
  217. package/dist/src/provider.js.map +1 -0
  218. package/dist/src/wallet.d.ts +35 -0
  219. package/dist/src/wallet.js +64 -0
  220. package/dist/src/wallet.js.map +1 -0
  221. package/dist/test/Aggregator.test.d.ts +1 -0
  222. package/dist/test/Aggregator.test.js +581 -0
  223. package/dist/test/Aggregator.test.js.map +1 -0
  224. package/dist/test/AggregatorProxy.test.d.ts +1 -0
  225. package/dist/test/AggregatorProxy.test.js +179 -0
  226. package/dist/test/AggregatorProxy.test.js.map +1 -0
  227. package/dist/test/BasicConsumer.test.d.ts +1 -0
  228. package/dist/test/BasicConsumer.test.js +180 -0
  229. package/dist/test/BasicConsumer.test.js.map +1 -0
  230. package/dist/test/Chainlinked.test.d.ts +1 -0
  231. package/dist/test/Chainlinked.test.js +11 -0
  232. package/dist/test/Chainlinked.test.js.map +1 -0
  233. package/dist/test/ConcreteChainlink.test.d.ts +1 -0
  234. package/dist/test/ConcreteChainlink.test.js +163 -0
  235. package/dist/test/ConcreteChainlink.test.js.map +1 -0
  236. package/dist/test/ConcreteChainlinked.test.d.ts +1 -0
  237. package/dist/test/ConcreteChainlinked.test.js +182 -0
  238. package/dist/test/ConcreteChainlinked.test.js.map +1 -0
  239. package/dist/test/GetterSetter.test.d.ts +1 -0
  240. package/dist/test/GetterSetter.test.js +76 -0
  241. package/dist/test/GetterSetter.test.js.map +1 -0
  242. package/dist/test/Oracle.test.d.ts +1 -0
  243. package/dist/test/Oracle.test.js +669 -0
  244. package/dist/test/Oracle.test.js.map +1 -0
  245. package/dist/test/Pointer.test.d.ts +1 -0
  246. package/dist/test/Pointer.test.js +35 -0
  247. package/dist/test/Pointer.test.js.map +1 -0
  248. package/dist/test/SignedSafeMath.test.d.ts +1 -0
  249. package/dist/test/SignedSafeMath.test.js +75 -0
  250. package/dist/test/SignedSafeMath.test.js.map +1 -0
  251. package/dist/test/UpdatableConsumer.test.d.ts +1 -0
  252. package/dist/test/UpdatableConsumer.test.js +144 -0
  253. package/dist/test/UpdatableConsumer.test.js.map +1 -0
  254. package/dist/tsconfig.tsbuildinfo +7737 -0
  255. package/package.json +50 -0
  256. package/r1z9aogk.cjs +1 -0
  257. package/v0.5/contracts/Chainlink.sol +125 -0
  258. package/v0.5/contracts/ChainlinkClient.sol +263 -0
  259. package/v0.5/contracts/LinkTokenReceiver.sol +70 -0
  260. package/v0.5/contracts/Median.sol +108 -0
  261. package/v0.5/contracts/Migrations.sol +23 -0
  262. package/v0.5/contracts/Oracle.sol +273 -0
  263. package/v0.5/contracts/PreCoordinator.sol +305 -0
  264. package/v0.5/contracts/dev/AggregatorInterface.sol +12 -0
  265. package/v0.5/contracts/dev/Coordinator.sol +411 -0
  266. package/v0.5/contracts/dev/CoordinatorInterface.sol +14 -0
  267. package/v0.5/contracts/dev/OracleSignaturesDecoder.sol +24 -0
  268. package/v0.5/contracts/dev/Owned.sol +61 -0
  269. package/v0.5/contracts/dev/PrepaidAggregator.sol +621 -0
  270. package/v0.5/contracts/dev/SafeMath128.sol +110 -0
  271. package/v0.5/contracts/dev/SafeMath32.sol +110 -0
  272. package/v0.5/contracts/dev/SafeMath64.sol +110 -0
  273. package/v0.5/contracts/dev/SchnorrSECP256K1.sol +147 -0
  274. package/v0.5/contracts/dev/ServiceAgreementDecoder.sol +59 -0
  275. package/v0.5/contracts/dev/VRF.sol +382 -0
  276. package/v0.5/contracts/dev/Whitelisted.sol +41 -0
  277. package/v0.5/contracts/dev/WhitelistedAggregator.sol +80 -0
  278. package/v0.5/contracts/interfaces/ChainlinkRequestInterface.sol +21 -0
  279. package/v0.5/contracts/interfaces/ENSInterface.sol +26 -0
  280. package/v0.5/contracts/interfaces/LinkTokenInterface.sol +16 -0
  281. package/v0.5/contracts/interfaces/OracleInterface.sol +16 -0
  282. package/v0.5/contracts/interfaces/PointerInterface.sol +5 -0
  283. package/v0.5/contracts/interfaces/WithdrawalInterface.sol +16 -0
  284. package/v0.5/contracts/tests/BasicConsumer.sol +13 -0
  285. package/v0.5/contracts/tests/ChainlinkTestHelper.sol +75 -0
  286. package/v0.5/contracts/tests/Consumer.sol +55 -0
  287. package/v0.5/contracts/tests/EmptyAggregator.sol +34 -0
  288. package/v0.5/contracts/tests/GetterSetter.sol +45 -0
  289. package/v0.5/contracts/tests/MaliciousChainlink.sol +75 -0
  290. package/v0.5/contracts/tests/MaliciousChainlinkClient.sol +109 -0
  291. package/v0.5/contracts/tests/MaliciousConsumer.sol +54 -0
  292. package/v0.5/contracts/tests/MaliciousRequester.sol +52 -0
  293. package/v0.5/contracts/tests/MeanAggregator.sol +75 -0
  294. package/v0.5/contracts/tests/MedianTestHelper.sol +15 -0
  295. package/v0.5/contracts/tests/OwnedTestHelper.sol +16 -0
  296. package/v0.5/contracts/tests/ServiceAgreementConsumer.sol +30 -0
  297. package/v0.5/contracts/vendor/Buffer.sol +301 -0
  298. package/v0.5/contracts/vendor/CBOR.sol +71 -0
  299. package/v0.5/contracts/vendor/ENSResolver.sol +5 -0
  300. package/v0.5/contracts/vendor/Ownable.sol +65 -0
  301. package/v0.5/contracts/vendor/SafeMath.sol +107 -0
  302. package/v0.5/contracts/vendor/SignedSafeMath.sol +22 -0
  303. package/v0.6/contracts/Chainlink.sol +125 -0
  304. package/v0.6/contracts/ChainlinkClient.sol +263 -0
  305. package/v0.6/contracts/LinkTokenReceiver.sol +70 -0
  306. package/v0.6/contracts/Oracle.sol +276 -0
  307. package/v0.6/contracts/interfaces/ChainlinkRequestInterface.sol +21 -0
  308. package/v0.6/contracts/interfaces/ENSInterface.sol +26 -0
  309. package/v0.6/contracts/interfaces/LinkTokenInterface.sol +16 -0
  310. package/v0.6/contracts/interfaces/OracleInterface.sol +16 -0
  311. package/v0.6/contracts/interfaces/PointerInterface.sol +5 -0
  312. package/v0.6/contracts/interfaces/WithdrawalInterface.sol +16 -0
  313. package/v0.6/contracts/tests/BasicConsumer.sol +13 -0
  314. package/v0.6/contracts/tests/Consumer.sol +55 -0
  315. package/v0.6/contracts/vendor/Buffer.sol +301 -0
  316. package/v0.6/contracts/vendor/CBOR.sol +71 -0
  317. package/v0.6/contracts/vendor/ENSResolver.sol +5 -0
  318. package/v0.6/contracts/vendor/Ownable.sol +65 -0
  319. package/v0.6/contracts/vendor/SafeMath.sol +107 -0
  320. package/zos.json +8 -0
  321. package/zos.rinkeby.json +104 -0
  322. package/zos.ropsten.json +104 -0
@@ -0,0 +1,621 @@
1
+ pragma solidity 0.5.0;
2
+
3
+ import "../Median.sol";
4
+ import "../vendor/SafeMath.sol";
5
+ import "./SafeMath128.sol";
6
+ import "./SafeMath64.sol";
7
+ import "./SafeMath32.sol";
8
+ import "../interfaces/LinkTokenInterface.sol";
9
+ import "../interfaces/WithdrawalInterface.sol";
10
+ import "./AggregatorInterface.sol";
11
+ import "./Owned.sol";
12
+
13
+ /**
14
+ * @title The Prepaid Aggregator contract
15
+ * @notice Node handles aggregating data pushed in from off-chain, and unlocks
16
+ * payment for oracles as they report. Oracles' submissions are gathered in
17
+ * rounds, with each round aggregating the submissions for each oracle into a
18
+ * single answer. The latest aggregated answer is exposed as well as historical
19
+ * answers and their updated at timestamp.
20
+ */
21
+ contract PrepaidAggregator is AggregatorInterface, Owned, WithdrawalInterface {
22
+ using SafeMath for uint256;
23
+ using SafeMath128 for uint128;
24
+ using SafeMath64 for uint64;
25
+ using SafeMath32 for uint32;
26
+
27
+ struct Round {
28
+ int256 answer;
29
+ uint64 startedAt;
30
+ uint64 updatedAt;
31
+ uint32 answeredInRound;
32
+ RoundDetails details;
33
+ }
34
+
35
+ struct RoundDetails {
36
+ int256[] answers;
37
+ uint32 maxAnswers;
38
+ uint32 minAnswers;
39
+ uint32 timeout;
40
+ uint128 paymentAmount;
41
+ }
42
+
43
+ struct OracleStatus {
44
+ uint128 withdrawable;
45
+ uint32 startingRound;
46
+ uint32 endingRound;
47
+ uint32 lastReportedRound;
48
+ uint32 lastStartedRound;
49
+ int256 latestAnswer;
50
+ }
51
+
52
+ uint128 public allocatedFunds;
53
+ uint128 public availableFunds;
54
+
55
+ // Round related params
56
+ uint128 public paymentAmount;
57
+ uint32 public oracleCount;
58
+ uint32 public maxAnswerCount;
59
+ uint32 public minAnswerCount;
60
+ uint32 public restartDelay;
61
+ uint32 public timeout;
62
+ uint8 public decimals;
63
+ bytes32 public description;
64
+
65
+ uint32 private reportingRoundId;
66
+ uint32 internal latestRoundId;
67
+ LinkTokenInterface private LINK;
68
+ mapping(address => OracleStatus) private oracles;
69
+ mapping(uint32 => Round) internal rounds;
70
+
71
+ event AvailableFundsUpdated(uint256 indexed amount);
72
+ event RoundDetailsUpdated(
73
+ uint128 indexed paymentAmount,
74
+ uint32 indexed minAnswerCount,
75
+ uint32 indexed maxAnswerCount,
76
+ uint32 restartDelay,
77
+ uint32 timeout // measured in seconds
78
+ );
79
+ event OracleAdded(address indexed oracle);
80
+ event OracleRemoved(address indexed oracle);
81
+
82
+ uint32 constant private ROUND_MAX = 2**32-1;
83
+
84
+ /**
85
+ * @notice Deploy with the address of the LINK token and initial payment amount
86
+ * @dev Sets the LinkToken address and amount of LINK paid
87
+ * @param _link The address of the LINK token
88
+ * @param _paymentAmount The amount paid of LINK paid to each oracle per response
89
+ * @param _timeout is the number of seconds after the previous round that are
90
+ * allowed to lapse before allowing an oracle to skip an unfinished round
91
+ */
92
+ constructor(
93
+ address _link,
94
+ uint128 _paymentAmount,
95
+ uint32 _timeout,
96
+ uint8 _decimals,
97
+ bytes32 _description
98
+ ) public {
99
+ LINK = LinkTokenInterface(_link);
100
+ paymentAmount = _paymentAmount;
101
+ timeout = _timeout;
102
+ decimals = _decimals;
103
+ description = _description;
104
+ }
105
+
106
+ /**
107
+ * @notice called by oracles when they have witnessed a need to update
108
+ * @param _round is the ID of the round this answer pertains to
109
+ * @param _answer is the updated data that the oracle is submitting
110
+ */
111
+ function updateAnswer(uint256 _round, int256 _answer)
112
+ external
113
+ onlyValidRoundId(uint32(_round))
114
+ onlyValidOracleRound(uint32(_round))
115
+ {
116
+ startNewRound(uint32(_round));
117
+ recordSubmission(_answer, uint32(_round));
118
+ updateRoundAnswer(uint32(_round));
119
+ payOracle(uint32(_round));
120
+ deleteRound(uint32(_round));
121
+ }
122
+
123
+ /**
124
+ * @notice called by the owner to add a new Oracle and update the round
125
+ * related parameters
126
+ * @param _oracle is the address of the new Oracle being added
127
+ * @param _minAnswers is the new minimum answer count for each round
128
+ * @param _maxAnswers is the new maximum answer count for each round
129
+ * @param _restartDelay is the number of rounds an Oracle has to wait before
130
+ * they can initiate a round
131
+ */
132
+ function addOracle(
133
+ address _oracle,
134
+ uint32 _minAnswers,
135
+ uint32 _maxAnswers,
136
+ uint32 _restartDelay
137
+ )
138
+ external
139
+ onlyOwner()
140
+ onlyUnenabledAddress(_oracle)
141
+ {
142
+ require(oracleCount < 42, "cannot add more than 42 oracles");
143
+ oracles[_oracle].startingRound = getStartingRound(_oracle);
144
+ oracles[_oracle].endingRound = ROUND_MAX;
145
+ oracleCount += 1;
146
+
147
+ emit OracleAdded(_oracle);
148
+
149
+ updateFutureRounds(paymentAmount, _minAnswers, _maxAnswers, _restartDelay, timeout);
150
+ }
151
+
152
+ /**
153
+ * @notice called by the owner to remove an Oracle and update the round
154
+ * related parameters
155
+ * @param _oracle is the address of the Oracle being removed
156
+ * @param _minAnswers is the new minimum answer count for each round
157
+ * @param _maxAnswers is the new maximum answer count for each round
158
+ * @param _restartDelay is the number of rounds an Oracle has to wait before
159
+ * they can initiate a round
160
+ */
161
+ function removeOracle(
162
+ address _oracle,
163
+ uint32 _minAnswers,
164
+ uint32 _maxAnswers,
165
+ uint32 _restartDelay
166
+ )
167
+ external
168
+ onlyOwner()
169
+ onlyEnabledAddress(_oracle)
170
+ {
171
+ oracleCount -= 1;
172
+ oracles[_oracle].endingRound = reportingRoundId;
173
+
174
+ emit OracleRemoved(_oracle);
175
+
176
+ updateFutureRounds(paymentAmount, _minAnswers, _maxAnswers, _restartDelay, timeout);
177
+ }
178
+
179
+ /**
180
+ * @notice update the round and payment related parameters for subsequent
181
+ * rounds
182
+ * @param _newPaymentAmount is the payment amount for subsequent rounds
183
+ * @param _minAnswers is the new minimum answer count for each round
184
+ * @param _maxAnswers is the new maximum answer count for each round
185
+ * @param _restartDelay is the number of rounds an Oracle has to wait before
186
+ * they can initiate a round
187
+ */
188
+ function updateFutureRounds(
189
+ uint128 _newPaymentAmount,
190
+ uint32 _minAnswers,
191
+ uint32 _maxAnswers,
192
+ uint32 _restartDelay,
193
+ uint32 _timeout
194
+ )
195
+ public
196
+ onlyOwner()
197
+ onlyValidRange(_minAnswers, _maxAnswers, _restartDelay)
198
+ {
199
+ paymentAmount = _newPaymentAmount;
200
+ minAnswerCount = _minAnswers;
201
+ maxAnswerCount = _maxAnswers;
202
+ restartDelay = _restartDelay;
203
+ timeout = _timeout;
204
+
205
+ emit RoundDetailsUpdated(
206
+ paymentAmount,
207
+ _minAnswers,
208
+ _maxAnswers,
209
+ _restartDelay,
210
+ _timeout
211
+ );
212
+ }
213
+
214
+ /**
215
+ * @notice recalculate the amount of LINK available for payouts
216
+ */
217
+ function updateAvailableFunds()
218
+ public
219
+ {
220
+ uint128 pastAvailableFunds = availableFunds;
221
+
222
+ uint256 available = LINK.balanceOf(address(this)).sub(allocatedFunds);
223
+ availableFunds = uint128(available);
224
+
225
+ if (pastAvailableFunds != available) {
226
+ emit AvailableFundsUpdated(available);
227
+ }
228
+ }
229
+
230
+ /**
231
+ * @notice query the available amount of LINK for an oracle to withdraw
232
+ */
233
+ function withdrawable()
234
+ external
235
+ view
236
+ returns (uint256)
237
+ {
238
+ return oracles[msg.sender].withdrawable;
239
+ }
240
+
241
+ /**
242
+ * @notice get the most recently reported answer
243
+ */
244
+ function latestAnswer()
245
+ external
246
+ view
247
+ returns (int256)
248
+ {
249
+ return _latestAnswer();
250
+ }
251
+
252
+ /**
253
+ * @notice get the most recent updated at timestamp
254
+ */
255
+ function latestTimestamp()
256
+ external
257
+ view
258
+ returns (uint256)
259
+ {
260
+ return _latestTimestamp();
261
+ }
262
+
263
+ /**
264
+ * @notice get the ID of the last updated round
265
+ */
266
+ function latestRound()
267
+ external
268
+ view
269
+ returns (uint256)
270
+ {
271
+ return latestRoundId;
272
+ }
273
+
274
+ /**
275
+ * @notice get the ID of the round most recently reported on
276
+ */
277
+ function reportingRound()
278
+ external
279
+ view
280
+ returns (uint256)
281
+ {
282
+ return reportingRoundId;
283
+ }
284
+
285
+ /**
286
+ * @notice get past rounds answers
287
+ * @param _roundId the round number to retrieve the answer for
288
+ */
289
+ function getAnswer(uint256 _roundId)
290
+ external
291
+ view
292
+ returns (int256)
293
+ {
294
+ return _getAnswer(_roundId);
295
+ }
296
+
297
+ /**
298
+ * @notice get timestamp when an answer was last updated
299
+ * @param _roundId the round number to retrieve the updated timestamp for
300
+ */
301
+ function getTimestamp(uint256 _roundId)
302
+ external
303
+ view
304
+ returns (uint256)
305
+ {
306
+ return _getTimestamp(_roundId);
307
+ }
308
+
309
+ /**
310
+ * @notice get the timed out status of a given round
311
+ * @param _roundId the round number to retrieve the timed out status for
312
+ */
313
+ function getTimedOutStatus(uint256 _roundId)
314
+ external
315
+ view
316
+ returns (bool)
317
+ {
318
+ uint32 roundId = uint32(_roundId);
319
+ uint32 answeredIn = rounds[roundId].answeredInRound;
320
+ return answeredIn > 0 && answeredIn != roundId;
321
+ }
322
+
323
+ /**
324
+ * @notice get the round ID that an answer was originally reported in
325
+ * @param _roundId the round number to retrieve the answer for
326
+ */
327
+ function getOriginatingRoundOfAnswer(uint256 _roundId)
328
+ external
329
+ view
330
+ returns (uint256)
331
+ {
332
+ return rounds[uint32(_roundId)].answeredInRound;
333
+ }
334
+
335
+ /**
336
+ * @notice transfers the oracle's LINK to another address
337
+ * @param _recipient is the address to send the LINK to
338
+ * @param _amount is the amount of LINK to send
339
+ */
340
+ function withdraw(address _recipient, uint256 _amount)
341
+ external
342
+ {
343
+ uint128 amount = uint128(_amount);
344
+ uint128 available = oracles[msg.sender].withdrawable;
345
+ require(available >= amount, "Insufficient balance");
346
+
347
+ oracles[msg.sender].withdrawable = available.sub(amount);
348
+ allocatedFunds = allocatedFunds.sub(amount);
349
+
350
+ assert(LINK.transfer(_recipient, uint256(amount)));
351
+ }
352
+
353
+ /**
354
+ * @notice transfers the owner's LINK to another address
355
+ * @param _recipient is the address to send the LINK to
356
+ * @param _amount is the amount of LINK to send
357
+ */
358
+ function withdrawFunds(address _recipient, uint256 _amount)
359
+ external
360
+ onlyOwner()
361
+ {
362
+ require(availableFunds >= _amount, "Insufficient funds");
363
+ require(LINK.transfer(_recipient, _amount), "LINK transfer failed");
364
+ updateAvailableFunds();
365
+ }
366
+
367
+ /**
368
+ * @notice get the latest submission for any oracle
369
+ * @param _oracle is the address to lookup the latest submission for
370
+ */
371
+ function latestSubmission(address _oracle)
372
+ external
373
+ view
374
+ returns (int256, uint256)
375
+ {
376
+ return (oracles[_oracle].latestAnswer, oracles[_oracle].lastReportedRound);
377
+ }
378
+
379
+ /**
380
+ * @notice called through LINK's transferAndCall to update available funds
381
+ * in the same transaction as the funds were transfered to the aggregator
382
+ */
383
+ function onTokenTransfer(address, uint256, bytes memory) public {
384
+ updateAvailableFunds();
385
+ }
386
+
387
+ /**
388
+ * Internal
389
+ */
390
+
391
+ /**
392
+ * @dev Internal implementation for latestAnswer
393
+ */
394
+ function _latestAnswer()
395
+ internal
396
+ view
397
+ returns (int256)
398
+ {
399
+ return rounds[latestRoundId].answer;
400
+ }
401
+
402
+ /**
403
+ * @dev Internal implementation of latestTimestamp
404
+ */
405
+ function _latestTimestamp()
406
+ internal
407
+ view
408
+ returns (uint256)
409
+ {
410
+ return rounds[latestRoundId].updatedAt;
411
+ }
412
+
413
+ /**
414
+ * @dev Internal implementation of getAnswer
415
+ */
416
+ function _getAnswer(uint256 _roundId)
417
+ internal
418
+ view
419
+ returns (int256)
420
+ {
421
+ return rounds[uint32(_roundId)].answer;
422
+ }
423
+
424
+ /**
425
+ * @dev Internal implementation of getTimestamp
426
+ */
427
+ function _getTimestamp(uint256 _roundId)
428
+ internal
429
+ view
430
+ returns (uint256)
431
+ {
432
+ return rounds[uint32(_roundId)].updatedAt;
433
+ }
434
+
435
+ /**
436
+ * Private
437
+ */
438
+
439
+ function startNewRound(uint32 _id)
440
+ private
441
+ ifNewRound(_id)
442
+ ifDelayed(_id)
443
+ {
444
+ updateTimedOutRoundInfo(_id.sub(1));
445
+
446
+ reportingRoundId = _id;
447
+ rounds[_id].details.maxAnswers = maxAnswerCount;
448
+ rounds[_id].details.minAnswers = minAnswerCount;
449
+ rounds[_id].details.paymentAmount = paymentAmount;
450
+ rounds[_id].details.timeout = timeout;
451
+ rounds[_id].startedAt = uint64(block.timestamp);
452
+
453
+ oracles[msg.sender].lastStartedRound = _id;
454
+
455
+ emit NewRound(_id, msg.sender);
456
+ }
457
+
458
+ function updateTimedOutRoundInfo(uint32 _id)
459
+ private
460
+ ifTimedOut(_id)
461
+ onlyWithPreviousAnswer(_id)
462
+ {
463
+ uint32 prevId = _id.sub(1);
464
+ rounds[_id].answer = rounds[prevId].answer;
465
+ rounds[_id].answeredInRound = rounds[prevId].answeredInRound;
466
+ rounds[_id].updatedAt = uint64(block.timestamp);
467
+
468
+ delete rounds[_id].details;
469
+ }
470
+
471
+ function updateRoundAnswer(uint32 _id)
472
+ private
473
+ ifMinAnswersReceived(_id)
474
+ {
475
+ int256 newAnswer = Median.calculate(rounds[_id].details.answers);
476
+ rounds[_id].answer = newAnswer;
477
+ rounds[_id].updatedAt = uint64(block.timestamp);
478
+ rounds[_id].answeredInRound = _id;
479
+ latestRoundId = _id;
480
+
481
+ emit AnswerUpdated(newAnswer, _id, now);
482
+ }
483
+
484
+ function payOracle(uint32 _id)
485
+ private
486
+ {
487
+ uint128 payment = rounds[_id].details.paymentAmount;
488
+ uint128 available = availableFunds.sub(payment);
489
+
490
+ availableFunds = available;
491
+ allocatedFunds = allocatedFunds.add(payment);
492
+ oracles[msg.sender].withdrawable = oracles[msg.sender].withdrawable.add(payment);
493
+
494
+ emit AvailableFundsUpdated(available);
495
+ }
496
+
497
+ function recordSubmission(int256 _answer, uint32 _id)
498
+ private
499
+ onlyWhenAcceptingAnswers(_id)
500
+ {
501
+ rounds[_id].details.answers.push(_answer);
502
+ oracles[msg.sender].lastReportedRound = _id;
503
+ oracles[msg.sender].latestAnswer = _answer;
504
+ }
505
+
506
+ function deleteRound(uint32 _id)
507
+ private
508
+ ifMaxAnswersReceived(_id)
509
+ {
510
+ delete rounds[_id].details;
511
+ }
512
+
513
+ function timedOut(uint32 _id)
514
+ private
515
+ view
516
+ returns (bool)
517
+ {
518
+ uint64 startedAt = rounds[_id].startedAt;
519
+ uint32 roundTimeout = rounds[_id].details.timeout;
520
+ return startedAt > 0 && roundTimeout > 0 && startedAt.add(roundTimeout) < block.timestamp;
521
+ }
522
+
523
+ function finished(uint32 _id)
524
+ private
525
+ view
526
+ returns (bool)
527
+ {
528
+ return rounds[_id].updatedAt > 0;
529
+ }
530
+
531
+ function getStartingRound(address _oracle)
532
+ private
533
+ view
534
+ returns (uint32)
535
+ {
536
+ uint32 currentRound = reportingRoundId;
537
+ if (currentRound != 0 && currentRound == oracles[_oracle].endingRound) {
538
+ return currentRound;
539
+ }
540
+ return currentRound.add(1);
541
+ }
542
+
543
+ /**
544
+ * Modifiers
545
+ */
546
+
547
+ modifier onlyValidOracleRound(uint32 _id) {
548
+ uint32 startingRound = oracles[msg.sender].startingRound;
549
+ require(startingRound != 0, "Only updatable by whitelisted oracles");
550
+ require(startingRound <= _id, "New oracles cannot participate in in-progress rounds");
551
+ require(oracles[msg.sender].endingRound >= _id, "Oracle has been removed from whitelist");
552
+ require(oracles[msg.sender].lastReportedRound < _id, "Cannot update round reports");
553
+ _;
554
+ }
555
+
556
+ modifier ifMinAnswersReceived(uint32 _id) {
557
+ if (rounds[_id].details.answers.length >= rounds[_id].details.minAnswers) {
558
+ _;
559
+ }
560
+ }
561
+
562
+ modifier ifMaxAnswersReceived(uint32 _id) {
563
+ if (rounds[_id].details.answers.length == rounds[_id].details.maxAnswers) {
564
+ _;
565
+ }
566
+ }
567
+
568
+ modifier onlyWhenAcceptingAnswers(uint32 _id) {
569
+ require(rounds[_id].details.maxAnswers != 0, "Round not currently eligible for reporting");
570
+ _;
571
+ }
572
+
573
+ modifier ifNewRound(uint32 _id) {
574
+ if (_id == reportingRoundId.add(1)) {
575
+ _;
576
+ }
577
+ }
578
+
579
+ modifier ifDelayed(uint32 _id) {
580
+ uint256 lastStarted = oracles[msg.sender].lastStartedRound;
581
+ if (_id > lastStarted + restartDelay || lastStarted == 0) {
582
+ _;
583
+ }
584
+ }
585
+
586
+ modifier onlyValidRoundId(uint32 _id) {
587
+ require(_id == reportingRoundId || _id == reportingRoundId.add(1), "Must report on current round");
588
+ require(_id == 1 || finished(_id.sub(1)) || timedOut(_id.sub(1)), "Not eligible to bump round");
589
+ _;
590
+ }
591
+
592
+ modifier onlyValidRange(uint32 _min, uint32 _max, uint32 _restartDelay) {
593
+ uint32 oracleNum = oracleCount; // Save on storage reads
594
+ require(oracleNum >= _max, "Cannot have the answer max higher oracle count");
595
+ require(_max >= _min, "Cannot have the answer minimum higher the max");
596
+ require(oracleNum == 0 || oracleNum > _restartDelay, "Restart delay must be less than oracle count");
597
+ _;
598
+ }
599
+
600
+ modifier onlyUnenabledAddress(address _oracle) {
601
+ require(oracles[_oracle].endingRound != ROUND_MAX, "Address is already recorded as an oracle");
602
+ _;
603
+ }
604
+
605
+ modifier onlyEnabledAddress(address _oracle) {
606
+ require(oracles[_oracle].endingRound == ROUND_MAX, "Address is not a whitelisted oracle");
607
+ _;
608
+ }
609
+
610
+ modifier ifTimedOut(uint32 _id) {
611
+ if (timedOut(_id)) {
612
+ _;
613
+ }
614
+ }
615
+
616
+ modifier onlyWithPreviousAnswer(uint32 _id) {
617
+ require(rounds[_id.sub(1)].updatedAt != 0, "Must have a previous answer to pull from");
618
+ _;
619
+ }
620
+
621
+ }