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,273 @@
1
+ pragma solidity ^0.5.0;
2
+
3
+ import "./LinkTokenReceiver.sol";
4
+ import "./interfaces/ChainlinkRequestInterface.sol";
5
+ import "./interfaces/OracleInterface.sol";
6
+ import "./interfaces/LinkTokenInterface.sol";
7
+ import "./interfaces/WithdrawalInterface.sol";
8
+ import "./vendor/Ownable.sol";
9
+ import "./vendor/SafeMath.sol";
10
+
11
+ /**
12
+ * @title The Chainlink Oracle contract
13
+ * @notice Node operators can deploy this contract to fulfill requests sent to them
14
+ */
15
+ contract Oracle is ChainlinkRequestInterface, OracleInterface, Ownable, LinkTokenReceiver, WithdrawalInterface {
16
+ using SafeMath for uint256;
17
+
18
+ uint256 constant public EXPIRY_TIME = 5 minutes;
19
+ uint256 constant private MINIMUM_CONSUMER_GAS_LIMIT = 400000;
20
+ // We initialize fields to 1 instead of 0 so that the first invocation
21
+ // does not cost more gas.
22
+ uint256 constant private ONE_FOR_CONSISTENT_GAS_COST = 1;
23
+
24
+ LinkTokenInterface internal LinkToken;
25
+ mapping(bytes32 => bytes32) private commitments;
26
+ mapping(address => bool) private authorizedNodes;
27
+ uint256 private withdrawableTokens = ONE_FOR_CONSISTENT_GAS_COST;
28
+
29
+ event OracleRequest(
30
+ bytes32 indexed specId,
31
+ address requester,
32
+ bytes32 requestId,
33
+ uint256 payment,
34
+ address callbackAddr,
35
+ bytes4 callbackFunctionId,
36
+ uint256 cancelExpiration,
37
+ uint256 dataVersion,
38
+ bytes data
39
+ );
40
+
41
+ event CancelOracleRequest(
42
+ bytes32 indexed requestId
43
+ );
44
+
45
+ /**
46
+ * @notice Deploy with the address of the LINK token
47
+ * @dev Sets the LinkToken address for the imported LinkTokenInterface
48
+ * @param _link The address of the LINK token
49
+ */
50
+ constructor(address _link) public Ownable() {
51
+ LinkToken = LinkTokenInterface(_link); // external but already deployed and unalterable
52
+ }
53
+
54
+ /**
55
+ * @notice Creates the Chainlink request
56
+ * @dev Stores the hash of the params as the on-chain commitment for the request.
57
+ * Emits OracleRequest event for the Chainlink node to detect.
58
+ * @param _sender The sender of the request
59
+ * @param _payment The amount of payment given (specified in wei)
60
+ * @param _specId The Job Specification ID
61
+ * @param _callbackAddress The callback address for the response
62
+ * @param _callbackFunctionId The callback function ID for the response
63
+ * @param _nonce The nonce sent by the requester
64
+ * @param _dataVersion The specified data version
65
+ * @param _data The CBOR payload of the request
66
+ */
67
+ function oracleRequest(
68
+ address _sender,
69
+ uint256 _payment,
70
+ bytes32 _specId,
71
+ address _callbackAddress,
72
+ bytes4 _callbackFunctionId,
73
+ uint256 _nonce,
74
+ uint256 _dataVersion,
75
+ bytes calldata _data
76
+ )
77
+ external
78
+ onlyLINK
79
+ checkCallbackAddress(_callbackAddress)
80
+ {
81
+ bytes32 requestId = keccak256(abi.encodePacked(_sender, _nonce));
82
+ require(commitments[requestId] == 0, "Must use a unique ID");
83
+ // solhint-disable-next-line not-rely-on-time
84
+ uint256 expiration = now.add(EXPIRY_TIME);
85
+
86
+ commitments[requestId] = keccak256(
87
+ abi.encodePacked(
88
+ _payment,
89
+ _callbackAddress,
90
+ _callbackFunctionId,
91
+ expiration
92
+ )
93
+ );
94
+
95
+ emit OracleRequest(
96
+ _specId,
97
+ _sender,
98
+ requestId,
99
+ _payment,
100
+ _callbackAddress,
101
+ _callbackFunctionId,
102
+ expiration,
103
+ _dataVersion,
104
+ _data);
105
+ }
106
+
107
+ /**
108
+ * @notice Called by the Chainlink node to fulfill requests
109
+ * @dev Given params must hash back to the commitment stored from `oracleRequest`.
110
+ * Will call the callback address' callback function without bubbling up error
111
+ * checking in a `require` so that the node can get paid.
112
+ * @param _requestId The fulfillment request ID that must match the requester's
113
+ * @param _payment The payment amount that will be released for the oracle (specified in wei)
114
+ * @param _callbackAddress The callback address to call for fulfillment
115
+ * @param _callbackFunctionId The callback function ID to use for fulfillment
116
+ * @param _expiration The expiration that the node should respond by before the requester can cancel
117
+ * @param _data The data to return to the consuming contract
118
+ * @return Status if the external call was successful
119
+ */
120
+ function fulfillOracleRequest(
121
+ bytes32 _requestId,
122
+ uint256 _payment,
123
+ address _callbackAddress,
124
+ bytes4 _callbackFunctionId,
125
+ uint256 _expiration,
126
+ bytes32 _data
127
+ )
128
+ external
129
+ onlyAuthorizedNode
130
+ isValidRequest(_requestId)
131
+ returns (bool)
132
+ {
133
+ bytes32 paramsHash = keccak256(
134
+ abi.encodePacked(
135
+ _payment,
136
+ _callbackAddress,
137
+ _callbackFunctionId,
138
+ _expiration
139
+ )
140
+ );
141
+ require(commitments[_requestId] == paramsHash, "Params do not match request ID");
142
+ withdrawableTokens = withdrawableTokens.add(_payment);
143
+ delete commitments[_requestId];
144
+ require(gasleft() >= MINIMUM_CONSUMER_GAS_LIMIT, "Must provide consumer enough gas");
145
+ // All updates to the oracle's fulfillment should come before calling the
146
+ // callback(addr+functionId) as it is untrusted.
147
+ // See: https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern
148
+ (bool success, ) = _callbackAddress.call(abi.encodeWithSelector(_callbackFunctionId, _requestId, _data)); // solhint-disable-line avoid-low-level-calls
149
+ return success;
150
+ }
151
+
152
+ /**
153
+ * @notice Use this to check if a node is authorized for fulfilling requests
154
+ * @param _node The address of the Chainlink node
155
+ * @return The authorization status of the node
156
+ */
157
+ function getAuthorizationStatus(address _node) external view returns (bool) {
158
+ return authorizedNodes[_node];
159
+ }
160
+
161
+ /**
162
+ * @notice Sets the fulfillment permission for a given node. Use `true` to allow, `false` to disallow.
163
+ * @param _node The address of the Chainlink node
164
+ * @param _allowed Bool value to determine if the node can fulfill requests
165
+ */
166
+ function setFulfillmentPermission(address _node, bool _allowed) external onlyOwner {
167
+ authorizedNodes[_node] = _allowed;
168
+ }
169
+
170
+ /**
171
+ * @notice Allows the node operator to withdraw earned LINK to a given address
172
+ * @dev The owner of the contract can be another wallet and does not have to be a Chainlink node
173
+ * @param _recipient The address to send the LINK token to
174
+ * @param _amount The amount to send (specified in wei)
175
+ */
176
+ function withdraw(address _recipient, uint256 _amount)
177
+ external
178
+ onlyOwner
179
+ hasAvailableFunds(_amount)
180
+ {
181
+ withdrawableTokens = withdrawableTokens.sub(_amount);
182
+ assert(LinkToken.transfer(_recipient, _amount));
183
+ }
184
+
185
+ /**
186
+ * @notice Displays the amount of LINK that is available for the node operator to withdraw
187
+ * @dev We use `ONE_FOR_CONSISTENT_GAS_COST` in place of 0 in storage
188
+ * @return The amount of withdrawable LINK on the contract
189
+ */
190
+ function withdrawable() external view onlyOwner returns (uint256) {
191
+ return withdrawableTokens.sub(ONE_FOR_CONSISTENT_GAS_COST);
192
+ }
193
+
194
+ /**
195
+ * @notice Allows requesters to cancel requests sent to this oracle contract. Will transfer the LINK
196
+ * sent for the request back to the requester's address.
197
+ * @dev Given params must hash to a commitment stored on the contract in order for the request to be valid
198
+ * Emits CancelOracleRequest event.
199
+ * @param _requestId The request ID
200
+ * @param _payment The amount of payment given (specified in wei)
201
+ * @param _callbackFunc The requester's specified callback address
202
+ * @param _expiration The time of the expiration for the request
203
+ */
204
+ function cancelOracleRequest(
205
+ bytes32 _requestId,
206
+ uint256 _payment,
207
+ bytes4 _callbackFunc,
208
+ uint256 _expiration
209
+ ) external {
210
+ bytes32 paramsHash = keccak256(
211
+ abi.encodePacked(
212
+ _payment,
213
+ msg.sender,
214
+ _callbackFunc,
215
+ _expiration)
216
+ );
217
+ require(paramsHash == commitments[_requestId], "Params do not match request ID");
218
+ // solhint-disable-next-line not-rely-on-time
219
+ require(_expiration <= now, "Request is not expired");
220
+
221
+ delete commitments[_requestId];
222
+ emit CancelOracleRequest(_requestId);
223
+
224
+ assert(LinkToken.transfer(msg.sender, _payment));
225
+ }
226
+
227
+ /**
228
+ * @notice Returns the address of the LINK token
229
+ * @dev This is the public implementation for chainlinkTokenAddress, which is
230
+ * an internal method of the ChainlinkClient contract
231
+ */
232
+ function getChainlinkToken() public view returns (address) {
233
+ return address(LinkToken);
234
+ }
235
+
236
+ // MODIFIERS
237
+
238
+ /**
239
+ * @dev Reverts if amount requested is greater than withdrawable balance
240
+ * @param _amount The given amount to compare to `withdrawableTokens`
241
+ */
242
+ modifier hasAvailableFunds(uint256 _amount) {
243
+ require(withdrawableTokens >= _amount.add(ONE_FOR_CONSISTENT_GAS_COST), "Amount requested is greater than withdrawable balance");
244
+ _;
245
+ }
246
+
247
+ /**
248
+ * @dev Reverts if request ID does not exist
249
+ * @param _requestId The given request ID to check in stored `commitments`
250
+ */
251
+ modifier isValidRequest(bytes32 _requestId) {
252
+ require(commitments[_requestId] != 0, "Must have a valid requestId");
253
+ _;
254
+ }
255
+
256
+ /**
257
+ * @dev Reverts if `msg.sender` is not authorized to fulfill requests
258
+ */
259
+ modifier onlyAuthorizedNode() {
260
+ require(authorizedNodes[msg.sender] || msg.sender == owner(), "Not an authorized node to fulfill requests");
261
+ _;
262
+ }
263
+
264
+ /**
265
+ * @dev Reverts if the callback address is the LINK token
266
+ * @param _to The callback address
267
+ */
268
+ modifier checkCallbackAddress(address _to) {
269
+ require(_to != address(LinkToken), "Cannot callback to LINK");
270
+ _;
271
+ }
272
+
273
+ }
@@ -0,0 +1,305 @@
1
+ pragma solidity 0.5.0;
2
+
3
+ import "./ChainlinkClient.sol";
4
+ import "./LinkTokenReceiver.sol";
5
+ import "./Median.sol";
6
+ import "./vendor/Ownable.sol";
7
+ import "./vendor/SafeMath.sol";
8
+
9
+ /**
10
+ * @title PreCoordinator is a contract that builds on-chain service agreements
11
+ * using the current architecture of 1 request to 1 oracle contract.
12
+ * @dev This contract accepts requests as service agreement IDs and loops over
13
+ * the corresponding list of oracles to create distinct requests to each one.
14
+ */
15
+ contract PreCoordinator is ChainlinkClient, Ownable, ChainlinkRequestInterface, LinkTokenReceiver {
16
+ using SafeMath for uint256;
17
+
18
+ uint256 constant private MAX_ORACLE_COUNT = 45;
19
+
20
+ uint256 private globalNonce;
21
+
22
+ struct ServiceAgreement {
23
+ uint256 totalPayment;
24
+ uint256 minResponses;
25
+ uint256 activeRequests;
26
+ address[] oracles;
27
+ bytes32[] jobIds;
28
+ uint256[] payments;
29
+ }
30
+
31
+ struct Requester {
32
+ bytes4 callbackFunctionId;
33
+ address sender;
34
+ address callbackAddress;
35
+ int256[] responses;
36
+ }
37
+
38
+ // Service Agreement ID => ServiceAgreement
39
+ mapping(bytes32 => ServiceAgreement) internal serviceAgreements;
40
+ // Local Request ID => Service Agreement ID
41
+ mapping(bytes32 => bytes32) internal serviceAgreementRequests;
42
+ // Requester's Request ID => Requester
43
+ mapping(bytes32 => Requester) internal requesters;
44
+ // Local Request ID => Requester's Request ID
45
+ mapping(bytes32 => bytes32) internal requests;
46
+
47
+ event NewServiceAgreement(bytes32 indexed saId, uint256 payment, uint256 minresponses);
48
+ event ServiceAgreementRequested(bytes32 indexed saId, bytes32 indexed requestId, uint256 payment);
49
+ event ServiceAgreementResponseReceived(bytes32 indexed saId, bytes32 indexed requestId, address indexed oracle, int256 answer);
50
+ event ServiceAgreementAnswerUpdated(bytes32 indexed saId, bytes32 indexed requestId, int256 answer);
51
+ event ServiceAgreementDeleted(bytes32 indexed saId);
52
+
53
+ /**
54
+ * @notice Deploy the contract with a specified address for the LINK
55
+ * and Oracle contract addresses
56
+ * @dev Sets the storage for the specified addresses
57
+ * @param _link The address of the LINK token contract
58
+ */
59
+ constructor(address _link) public {
60
+ if(_link == address(0)) {
61
+ setPublicChainlinkToken();
62
+ } else {
63
+ setChainlinkToken(_link);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @notice Allows the owner of the contract to create new service agreements
69
+ * with multiple oracles. Each oracle will have their own Job ID and can have
70
+ * their own payment amount.
71
+ * @dev The globalNonce keeps service agreement IDs unique. Assume one cannot
72
+ * create the max uint256 number of service agreements in the same block.
73
+ * @param _minResponses The minimum number of responses before the requesting
74
+ * contract is called with the response data.
75
+ * @param _oracles The list of oracle contract addresses.
76
+ * @param _jobIds The corresponding list of Job IDs.
77
+ * @param _payments The corresponding list of payment amounts.
78
+ */
79
+ function createServiceAgreement(
80
+ uint256 _minResponses,
81
+ address[] calldata _oracles,
82
+ bytes32[] calldata _jobIds,
83
+ uint256[] calldata _payments
84
+ )
85
+ external onlyOwner returns (bytes32 saId)
86
+ {
87
+ require(_minResponses > 0, "Min responses must be > 0");
88
+ require(_oracles.length == _jobIds.length && _oracles.length == _payments.length, "Unmet length");
89
+ require(_oracles.length <= MAX_ORACLE_COUNT, "Cannot have more than 45 oracles");
90
+ require(_oracles.length >= _minResponses, "Invalid min responses");
91
+ uint256 totalPayment;
92
+ for (uint i = 0; i < _payments.length; i++) {
93
+ totalPayment = totalPayment.add(_payments[i]);
94
+ }
95
+ saId = keccak256(abi.encodePacked(globalNonce, now));
96
+ globalNonce++; // yes, let it overflow
97
+ serviceAgreements[saId] = ServiceAgreement(totalPayment, _minResponses, 0, _oracles, _jobIds, _payments);
98
+
99
+ emit NewServiceAgreement(saId, totalPayment, _minResponses);
100
+ }
101
+
102
+ /**
103
+ * @notice This is a helper function to retrieve the details of a service agreement
104
+ * by its given service agreement ID.
105
+ * @dev This function is used instead of the public mapping to return the values
106
+ * of the arrays: oracles, jobIds, and payments.
107
+ */
108
+ function getServiceAgreement(bytes32 _saId)
109
+ external view returns
110
+ (
111
+ uint256 totalPayment,
112
+ uint256 minResponses,
113
+ uint256 activeRequests,
114
+ address[] memory oracles,
115
+ bytes32[] memory jobIds,
116
+ uint256[] memory payments
117
+ )
118
+ {
119
+ return
120
+ (
121
+ serviceAgreements[_saId].totalPayment,
122
+ serviceAgreements[_saId].minResponses,
123
+ serviceAgreements[_saId].activeRequests,
124
+ serviceAgreements[_saId].oracles,
125
+ serviceAgreements[_saId].jobIds,
126
+ serviceAgreements[_saId].payments
127
+ );
128
+ }
129
+
130
+ /**
131
+ * @notice Deletes a service agreement from storage
132
+ * @dev Use this with caution since there may be responses waiting to come
133
+ * back for a service agreement. This can be monitored off-chain by looking
134
+ * for the ServiceAgreementRequested event.
135
+ * @param _saId The service agreement ID
136
+ */
137
+ function deleteServiceAgreement(bytes32 _saId)
138
+ external
139
+ onlyOwner
140
+ whenNotActive(_saId)
141
+ {
142
+ delete serviceAgreements[_saId];
143
+ emit ServiceAgreementDeleted(_saId);
144
+ }
145
+
146
+ /**
147
+ * @notice Returns the address of the LINK token
148
+ * @dev This is the public implementation for chainlinkTokenAddress, which is
149
+ * an internal method of the ChainlinkClient contract
150
+ */
151
+ function getChainlinkToken() public view returns (address) {
152
+ return chainlinkTokenAddress();
153
+ }
154
+
155
+ /**
156
+ * @notice Creates the Chainlink request
157
+ * @dev Stores the hash of the params as the on-chain commitment for the request.
158
+ * Emits OracleRequest event for the Chainlink node to detect.
159
+ * @param _sender The sender of the request
160
+ * @param _payment The amount of payment given (specified in wei)
161
+ * @param _saId The Job Specification ID
162
+ * @param _callbackAddress The callback address for the response
163
+ * @param _callbackFunctionId The callback function ID for the response
164
+ * @param _nonce The nonce sent by the requester
165
+ * @param _data The CBOR payload of the request
166
+ */
167
+ function oracleRequest(
168
+ address _sender,
169
+ uint256 _payment,
170
+ bytes32 _saId,
171
+ address _callbackAddress,
172
+ bytes4 _callbackFunctionId,
173
+ uint256 _nonce,
174
+ uint256,
175
+ bytes calldata _data
176
+ )
177
+ external
178
+ onlyLINK
179
+ checkCallbackAddress(_callbackAddress)
180
+ {
181
+ uint256 totalPayment = serviceAgreements[_saId].totalPayment;
182
+ // this revert message does not bubble up
183
+ require(_payment >= totalPayment, "Insufficient payment");
184
+ bytes32 callbackRequestId = keccak256(abi.encodePacked(_sender, _nonce));
185
+ require(requesters[callbackRequestId].sender == address(0), "Nonce already in-use");
186
+ requesters[callbackRequestId].callbackFunctionId = _callbackFunctionId;
187
+ requesters[callbackRequestId].callbackAddress = _callbackAddress;
188
+ requesters[callbackRequestId].sender = _sender;
189
+ createRequests(_saId, callbackRequestId, _data);
190
+ if (_payment > totalPayment) {
191
+ uint256 overage = _payment.sub(totalPayment);
192
+ LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress());
193
+ assert(_link.transfer(_sender, overage));
194
+ }
195
+ }
196
+
197
+ /**
198
+ * @dev Creates Chainlink requests to each oracle in the service agreement with the
199
+ * same data payload supplied by the requester
200
+ * @param _saId The service agreement ID
201
+ * @param _incomingRequestId The requester-supplied request ID
202
+ * @param _data The data payload (request parameters) to send to each oracle
203
+ */
204
+ function createRequests(bytes32 _saId, bytes32 _incomingRequestId, bytes memory _data) private {
205
+ ServiceAgreement memory sa = serviceAgreements[_saId];
206
+ require(sa.minResponses > 0, "Invalid service agreement");
207
+ Chainlink.Request memory request;
208
+ bytes32 outgoingRequestId;
209
+ serviceAgreements[_saId].activeRequests = serviceAgreements[_saId].activeRequests.add(1);
210
+ emit ServiceAgreementRequested(_saId, _incomingRequestId, sa.totalPayment);
211
+ for (uint i = 0; i < sa.oracles.length; i++) {
212
+ request = buildChainlinkRequest(sa.jobIds[i], address(this), this.chainlinkCallback.selector);
213
+ request.setBuffer(_data);
214
+ outgoingRequestId = sendChainlinkRequestTo(sa.oracles[i], request, sa.payments[i]);
215
+ requests[outgoingRequestId] = _incomingRequestId;
216
+ serviceAgreementRequests[outgoingRequestId] = _saId;
217
+ }
218
+ }
219
+
220
+ /**
221
+ * @notice The fulfill method from requests created by this contract
222
+ * @dev The recordChainlinkFulfillment protects this function from being called
223
+ * by anyone other than the oracle address that the request was sent to
224
+ * @param _requestId The ID that was generated for the request
225
+ * @param _data The answer provided by the oracle
226
+ */
227
+ function chainlinkCallback(bytes32 _requestId, int256 _data)
228
+ external
229
+ recordChainlinkFulfillment(_requestId)
230
+ returns (bool)
231
+ {
232
+ uint256 minResponses = serviceAgreements[serviceAgreementRequests[_requestId]].minResponses;
233
+ bytes32 cbRequestId = requests[_requestId];
234
+ bytes32 saId = serviceAgreementRequests[_requestId];
235
+ delete requests[_requestId];
236
+ delete serviceAgreementRequests[_requestId];
237
+ emit ServiceAgreementResponseReceived(saId, cbRequestId, msg.sender, _data);
238
+ if (requesters[cbRequestId].responses.push(_data) == minResponses) {
239
+ serviceAgreements[saId].activeRequests = serviceAgreements[saId].activeRequests.sub(1);
240
+ Requester memory req = requesters[cbRequestId];
241
+ delete requesters[cbRequestId];
242
+ int256 result = Median.calculate(req.responses);
243
+ emit ServiceAgreementAnswerUpdated(saId, cbRequestId, result);
244
+ // solhint-disable-next-line avoid-low-level-calls
245
+ (bool success, ) = req.callbackAddress.call(abi.encodeWithSelector(req.callbackFunctionId, cbRequestId, result));
246
+ return success;
247
+ }
248
+ return true;
249
+ }
250
+
251
+ /**
252
+ * @notice Allows the owner to withdraw any LINK balance on the contract
253
+ * @dev The only valid case for there to be remaining LINK on this contract
254
+ * is if a user accidentally sent LINK directly to this contract's address.
255
+ */
256
+ function withdrawLink() external onlyOwner {
257
+ LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress());
258
+ require(_link.transfer(msg.sender, _link.balanceOf(address(this))), "Unable to transfer");
259
+ }
260
+
261
+ /**
262
+ * @notice Call this method if no response is received within 5 minutes
263
+ * @param _requestId The ID that was generated for the request to cancel
264
+ * @param _payment The payment specified for the request to cancel
265
+ * @param _callbackFunctionId The bytes4 callback function ID specified for
266
+ * the request to cancel
267
+ * @param _expiration The expiration generated for the request to cancel
268
+ */
269
+ function cancelOracleRequest(
270
+ bytes32 _requestId,
271
+ uint256 _payment,
272
+ bytes4 _callbackFunctionId,
273
+ uint256 _expiration
274
+ )
275
+ external
276
+ {
277
+ bytes32 cbRequestId = requests[_requestId];
278
+ delete requests[_requestId];
279
+ delete serviceAgreementRequests[_requestId];
280
+ Requester memory req = requesters[cbRequestId];
281
+ require(req.sender == msg.sender, "Only requester can cancel");
282
+ delete requesters[cbRequestId];
283
+ cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
284
+ LinkTokenInterface _link = LinkTokenInterface(chainlinkTokenAddress());
285
+ require(_link.transfer(req.sender, _payment), "Unable to transfer");
286
+ }
287
+
288
+ /**
289
+ * @dev Reverts if the Service Agreement has active callbacks
290
+ * @param _saId The service agreement ID
291
+ */
292
+ modifier whenNotActive(bytes32 _saId) {
293
+ require(serviceAgreements[_saId].activeRequests == 0, "Cannot delete while active");
294
+ _;
295
+ }
296
+
297
+ /**
298
+ * @dev Reverts if the callback address is the LINK token
299
+ * @param _to The callback address
300
+ */
301
+ modifier checkCallbackAddress(address _to) {
302
+ require(_to != chainlinkTokenAddress(), "Cannot callback to LINK");
303
+ _;
304
+ }
305
+ }
@@ -0,0 +1,12 @@
1
+ pragma solidity ^0.5.0;
2
+
3
+ interface AggregatorInterface {
4
+ function latestAnswer() external view returns (int256);
5
+ function latestTimestamp() external view returns (uint256);
6
+ function latestRound() external view returns (uint256);
7
+ function getAnswer(uint256 roundId) external view returns (int256);
8
+ function getTimestamp(uint256 roundId) external view returns (uint256);
9
+
10
+ event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp);
11
+ event NewRound(uint256 indexed roundId, address indexed startedBy);
12
+ }