├── .github └── workflows │ ├── checks.yml │ ├── test.yml │ └── tests.yml ├── .gitignore ├── .mocharc.json ├── .solhint.json ├── LICENSE ├── Makefile ├── README.md ├── artifacts ├── build-info │ ├── a57a0c8893a63b946905aefba5853e48.json │ └── d48d8c45439b66d353ec5b849f2f80d9.json ├── contracts │ ├── TellorPlayground.sol │ │ ├── TellorPlayground.dbg.json │ │ └── TellorPlayground.json │ ├── UsingTellor.sol │ │ ├── UsingTellor.dbg.json │ │ └── UsingTellor.json │ ├── interface │ │ └── ITellor.sol │ │ │ ├── ITellor.dbg.json │ │ │ └── ITellor.json │ ├── mocks │ │ └── BenchUsingTellor.sol │ │ │ ├── BenchUsingTellor.dbg.json │ │ │ └── BenchUsingTellor.json │ └── testing │ │ └── ImporterContract.sol │ │ ├── ImporterContract.dbg.json │ │ └── ImporterContract.json ├── polygongovernance │ └── contracts │ │ ├── Governance.sol │ │ ├── Governance.dbg.json │ │ └── Governance.json │ │ └── interfaces │ │ ├── IERC20.sol │ │ ├── IERC20.dbg.json │ │ └── IERC20.json │ │ └── IOracle.sol │ │ ├── IOracle.dbg.json │ │ └── IOracle.json ├── tellorflex │ └── contracts │ │ ├── TellorFlex.sol │ │ ├── TellorFlex.dbg.json │ │ └── TellorFlex.json │ │ └── interfaces │ │ └── IERC20.sol │ │ ├── IERC20.dbg.json │ │ └── IERC20.json └── usingtellor │ └── contracts │ ├── UsingTellor.sol │ ├── UsingTellor.dbg.json │ └── UsingTellor.json │ └── interface │ ├── IERC2362.sol │ ├── IERC2362.dbg.json │ └── IERC2362.json │ ├── IMappingContract.sol │ ├── IMappingContract.dbg.json │ └── IMappingContract.json │ └── ITellor.sol │ ├── Autopay.dbg.json │ ├── Autopay.json │ ├── ITellor.dbg.json │ └── ITellor.json ├── contracts ├── TellorPlayground.sol ├── UsingTellor.sol ├── interface │ └── ITellor.sol ├── mocks │ └── BenchUsingTellor.sol └── testing │ └── ImporterContract.sol ├── hardhat.config.js ├── package-lock.json ├── package.json └── test ├── e2eTests-UsingTellor.js ├── functionTests-UsingTellor.js └── helpers └── helpers.js /.github/workflows/checks.yml: -------------------------------------------------------------------------------- 1 | name: Checks 2 | on: 3 | push: 4 | branches: 5 | - master 6 | tags: 7 | - v* 8 | pull_request: 9 | 10 | jobs: 11 | Linting: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v2 16 | - name: Run Solhint 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: '14.x' 20 | - run: npm install -g solhint 21 | - run: make solhint 22 | Security: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v2 27 | - name: Slither Static Analysis 28 | uses: actions/setup-node@v1 29 | with: 30 | node-version: '14.x' 31 | - run: npm install 32 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Unit Test 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | test: 8 | 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | - name: Use Node.js 14 14 | uses: actions/setup-node@v3 15 | with: 16 | node-version: 14.x 17 | cache: 'npm' 18 | - run: npm i 19 | - run: npx hardhat test 20 | env: 21 | CI: true 22 | # These are not needed for the tests but 23 | # hardhat fails to start when not present. 24 | NODE_URL_RINKEBY: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 25 | NODE_URL_MAINNET: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 26 | PRIVATE_KEY: "00000000000000000000000000000000000000000000000000" 27 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | push: 4 | branches: 5 | - main 6 | tags: 7 | - v* 8 | pull_request: 9 | 10 | jobs: 11 | Tests: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Run tests 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: '14.x' 19 | - run: npm install 20 | - run: npx hardhat test 21 | env: 22 | CI: true 23 | # These are not needed for the tests but 24 | # hardhat fails to start when not present. 25 | NODE_URL_RINKEBY: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 26 | NODE_URL_MAINNET: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 27 | PRIVATE_KEY: "00000000000000000000000000000000000000000000000000" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /build 3 | /node_modules 4 | .env 5 | tmp 6 | cache 7 | **.DS_Store 8 | /cache 9 | -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": "hardhat/register", 3 | "timeout": 40000 4 | } 5 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "no-unused-vars": "error", 5 | "code-complexity": [ 6 | "warn", 7 | 7 8 | ], 9 | "compiler-version": [ 10 | "error", 11 | ">=0.8.0" 12 | ], 13 | "contract-name-camelcase": "error", 14 | "not-rely-on-time": "off", 15 | "reason-string": [ 16 | "warn", 17 | { 18 | "maxLength": 70 19 | } 20 | ], 21 | "func-visibility": [ 22 | "warn", 23 | { 24 | "ignoreConstructors": true 25 | } 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tellor 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | .PHONY: slither 4 | slither: 5 | slither . --exclude naming-convention,solc-version,pragma,external-function 6 | 7 | .PHONY: solhint 8 | solhint: 9 | solhint 'contracts/**/*.sol' -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Twitter WeAreTellor 4 | 5 |

6 | 7 | 8 | # Overview 9 | 10 | Use this package to install the Tellor User Contracts and integrate Tellor into your contracts. 11 | 12 | Once installed this will allow your contracts to inherit the functions from UsingTellor. 13 | 14 | #### How to Use 15 | Just inherit the UsingTellor contract, passing the Tellor address as a constructor argument: 16 | 17 | Here's an example 18 | ```solidity 19 | import "usingtellor/contracts/UsingTellor.sol"; 20 | 21 | contract PriceContract is UsingTellor { 22 | 23 | uint256 public btcPrice; 24 | 25 | // This contract now has access to all functions in UsingTellor 26 | constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {} 27 | 28 | function setBtcPrice() public { 29 | bytes memory _b = abi.encode("SpotPrice", abi.encode("btc", "usd")); 30 | bytes32 _btcQueryId = keccak256(_b); 31 | 32 | uint256 _timestamp; 33 | bytes memory _value; 34 | 35 | (_value, _timestamp) = _getDataBefore(_btcQueryId, block.timestamp - 1 hours); 36 | btcPrice = abi.decode(_value,(uint256)); 37 | } 38 | } 39 | ``` 40 | ##### Addresses: 41 | 42 | Find Tellor contract addresses [here](https://docs.tellor.io/tellor/the-basics/contracts-reference). 43 | 44 | 45 | #### Available Tellor functions: 46 | 47 | Children contracts have access to the following functions: 48 | 49 | ```solidity 50 | /** 51 | * @dev Retrieves the next value for the queryId after the specified timestamp 52 | * @param _queryId is the queryId to look up the value for 53 | * @param _timestamp after which to search for next value 54 | * @return _value the value retrieved 55 | * @return _timestampRetrieved the value's timestamp 56 | */ 57 | function _getDataAfter(bytes32 _queryId, uint256 _timestamp) 58 | internal 59 | view 60 | returns (bytes memory _value, uint256 _timestampRetrieved); 61 | 62 | /** 63 | * @dev Retrieves the latest value for the queryId before the specified timestamp 64 | * @param _queryId is the queryId to look up the value for 65 | * @param _timestamp before which to search for latest value 66 | * @return _value the value retrieved 67 | * @return _timestampRetrieved the value's timestamp 68 | */ 69 | function _getDataBefore(bytes32 _queryId, uint256 _timestamp) 70 | internal 71 | view 72 | returns (bytes memory _value, uint256 _timestampRetrieved); 73 | 74 | /** 75 | * @dev Retrieves next array index of data after the specified timestamp for the queryId 76 | * @param _queryId is the queryId to look up the index for 77 | * @param _timestamp is the timestamp after which to search for the next index 78 | * @return _found whether the index was found 79 | * @return _index the next index found after the specified timestamp 80 | */ 81 | function _getIndexForDataAfter(bytes32 _queryId, uint256 _timestamp) 82 | internal 83 | view 84 | returns (bool _found, uint256 _index); 85 | 86 | /** 87 | * @dev Retrieves latest array index of data before the specified timestamp for the queryId 88 | * @param _queryId is the queryId to look up the index for 89 | * @param _timestamp is the timestamp before which to search for the latest index 90 | * @return _found whether the index was found 91 | * @return _index the latest index found before the specified timestamp 92 | */ 93 | function _getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) 94 | internal 95 | view 96 | returns (bool _found, uint256 _index); 97 | 98 | /** 99 | * @dev Retrieves multiple uint256 values before the specified timestamp 100 | * @param _queryId the unique id of the data query 101 | * @param _timestamp the timestamp before which to search for values 102 | * @param _maxAge the maximum number of seconds before the _timestamp to search for values 103 | * @param _maxCount the maximum number of values to return 104 | * @return _values the values retrieved, ordered from oldest to newest 105 | * @return _timestamps the timestamps of the values retrieved 106 | */ 107 | function _getMultipleValuesBefore( 108 | bytes32 _queryId, 109 | uint256 _timestamp, 110 | uint256 _maxAge, 111 | uint256 _maxCount 112 | ) 113 | internal 114 | view 115 | returns (bytes[] memory _values, uint256[] memory _timestamps); 116 | 117 | /** 118 | * @dev Counts the number of values that have been submitted for the queryId 119 | * @param _queryId the id to look up 120 | * @return uint256 count of the number of values received for the queryId 121 | */ 122 | function _getNewValueCountbyQueryId(bytes32 _queryId) 123 | internal 124 | view 125 | returns (uint256); 126 | 127 | /** 128 | * @dev Returns the address of the reporter who submitted a value for a data ID at a specific time 129 | * @param _queryId is ID of the specific data feed 130 | * @param _timestamp is the timestamp to find a corresponding reporter for 131 | * @return address of the reporter who reported the value for the data ID at the given timestamp 132 | */ 133 | function _getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) 134 | internal 135 | view 136 | returns (address); 137 | 138 | /** 139 | * @dev Gets the timestamp for the value based on their index 140 | * @param _queryId is the id to look up 141 | * @param _index is the value index to look up 142 | * @return uint256 timestamp 143 | */ 144 | function _getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) 145 | internal 146 | view 147 | returns (uint256); 148 | 149 | /** 150 | * @dev Determines whether a value with a given queryId and timestamp has been disputed 151 | * @param _queryId is the value id to look up 152 | * @param _timestamp is the timestamp of the value to look up 153 | * @return bool true if queryId/timestamp is under dispute 154 | */ 155 | function _isInDispute(bytes32 _queryId, uint256 _timestamp) 156 | internal 157 | view 158 | returns (bool); 159 | 160 | /** 161 | * @dev Retrieve value from oracle based on queryId/timestamp 162 | * @param _queryId being requested 163 | * @param _timestamp to retrieve data/value from 164 | * @return bytes value for query/timestamp submitted 165 | */ 166 | function _retrieveData(bytes32 _queryId, uint256 _timestamp) 167 | internal 168 | view 169 | returns (bytes memory); 170 | ``` 171 | 172 | 173 | #### Tellor Playground: 174 | 175 | For ease of use, the `UsingTellor` repo comes with a version of [Tellor Playground](https://github.com/tellor-io/TellorPlayground) for easier testing. This version contains a few helper functions: 176 | 177 | ```solidity 178 | /** 179 | * @dev A mock function to submit a value to be read without miners needed 180 | * @param _queryId The tellorId to associate the value to 181 | * @param _value the value for the queryId 182 | * @param _nonce the current value count for the query id 183 | * @param _queryData the data used by reporters to fulfill the data query 184 | */ 185 | function submitValue(bytes32 _queryId, bytes calldata _value, uint256 _nonce, bytes memory _queryData) external; 186 | 187 | /** 188 | * @dev A mock function to create a dispute 189 | * @param _queryId The tellorId to be disputed 190 | * @param _timestamp the timestamp of the value to be disputed 191 | */ 192 | function beginDispute(bytes32 _queryId, uint256 _timestamp) external; 193 | ``` 194 | 195 | 196 | # Test 197 | Open a git bash terminal and run this code: 198 | 199 | ```bash 200 | git clone https://github.com/tellor-io/usingtellor.git 201 | cd usingtellor 202 | npm i 203 | npm test 204 | ``` 205 | 206 | # Implementing using Tellor 207 | See our documentation for implementing usingTellor [here.](https://docs.tellor.io/tellor/getting-data/introduction) 208 | 209 | # Keywords 210 | 211 | Decentralized oracle, price oracle, oracle, Tellor, TRB, Tributes, price data, smart contracts. 212 | -------------------------------------------------------------------------------- /artifacts/contracts/TellorPlayground.sol/TellorPlayground.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/UsingTellor.sol/UsingTellor.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d48d8c45439b66d353ec5b849f2f80d9.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/UsingTellor.sol/UsingTellor.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "UsingTellor", 4 | "sourceName": "contracts/UsingTellor.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "address payable", 10 | "name": "_tellor", 11 | "type": "address" 12 | } 13 | ], 14 | "stateMutability": "nonpayable", 15 | "type": "constructor" 16 | }, 17 | { 18 | "inputs": [], 19 | "name": "tellor", 20 | "outputs": [ 21 | { 22 | "internalType": "contract ITellor", 23 | "name": "", 24 | "type": "address" 25 | } 26 | ], 27 | "stateMutability": "view", 28 | "type": "function" 29 | } 30 | ], 31 | "bytecode": "0x608060405234801561001057600080fd5b5060405161012138038061012183398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610082565b600060208284031215610065578081fd5b81516001600160a01b038116811461007b578182fd5b9392505050565b6091806100906000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80631959ad5b14602d575b600080fd5b600054603f906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f3fea26469706673582212209e13ac27c1ceee85c2c3cec51c8f9b6f50bab721338b5c899492f57735dd397364736f6c63430008030033", 32 | "deployedBytecode": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c80631959ad5b14602d575b600080fd5b600054603f906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f3fea26469706673582212209e13ac27c1ceee85c2c3cec51c8f9b6f50bab721338b5c899492f57735dd397364736f6c63430008030033", 33 | "linkReferences": {}, 34 | "deployedLinkReferences": {} 35 | } 36 | -------------------------------------------------------------------------------- /artifacts/contracts/interface/ITellor.sol/ITellor.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d48d8c45439b66d353ec5b849f2f80d9.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interface/ITellor.sol/ITellor.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "ITellor", 4 | "sourceName": "contracts/interface/ITellor.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "bytes32", 10 | "name": "_queryId", 11 | "type": "bytes32" 12 | }, 13 | { 14 | "internalType": "uint256", 15 | "name": "_timestamp", 16 | "type": "uint256" 17 | } 18 | ], 19 | "name": "getDataBefore", 20 | "outputs": [ 21 | { 22 | "internalType": "bool", 23 | "name": "_ifRetrieve", 24 | "type": "bool" 25 | }, 26 | { 27 | "internalType": "bytes", 28 | "name": "_value", 29 | "type": "bytes" 30 | }, 31 | { 32 | "internalType": "uint256", 33 | "name": "_timestampRetrieved", 34 | "type": "uint256" 35 | } 36 | ], 37 | "stateMutability": "view", 38 | "type": "function" 39 | }, 40 | { 41 | "inputs": [ 42 | { 43 | "internalType": "bytes32", 44 | "name": "_queryId", 45 | "type": "bytes32" 46 | }, 47 | { 48 | "internalType": "uint256", 49 | "name": "_timestamp", 50 | "type": "uint256" 51 | } 52 | ], 53 | "name": "getIndexForDataBefore", 54 | "outputs": [ 55 | { 56 | "internalType": "bool", 57 | "name": "_found", 58 | "type": "bool" 59 | }, 60 | { 61 | "internalType": "uint256", 62 | "name": "_index", 63 | "type": "uint256" 64 | } 65 | ], 66 | "stateMutability": "view", 67 | "type": "function" 68 | }, 69 | { 70 | "inputs": [ 71 | { 72 | "internalType": "bytes32", 73 | "name": "_queryId", 74 | "type": "bytes32" 75 | } 76 | ], 77 | "name": "getNewValueCountbyQueryId", 78 | "outputs": [ 79 | { 80 | "internalType": "uint256", 81 | "name": "", 82 | "type": "uint256" 83 | } 84 | ], 85 | "stateMutability": "view", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [ 90 | { 91 | "internalType": "bytes32", 92 | "name": "_queryId", 93 | "type": "bytes32" 94 | }, 95 | { 96 | "internalType": "uint256", 97 | "name": "_timestamp", 98 | "type": "uint256" 99 | } 100 | ], 101 | "name": "getReporterByTimestamp", 102 | "outputs": [ 103 | { 104 | "internalType": "address", 105 | "name": "", 106 | "type": "address" 107 | } 108 | ], 109 | "stateMutability": "view", 110 | "type": "function" 111 | }, 112 | { 113 | "inputs": [ 114 | { 115 | "internalType": "bytes32", 116 | "name": "_queryId", 117 | "type": "bytes32" 118 | }, 119 | { 120 | "internalType": "uint256", 121 | "name": "_index", 122 | "type": "uint256" 123 | } 124 | ], 125 | "name": "getTimestampbyQueryIdandIndex", 126 | "outputs": [ 127 | { 128 | "internalType": "uint256", 129 | "name": "", 130 | "type": "uint256" 131 | } 132 | ], 133 | "stateMutability": "view", 134 | "type": "function" 135 | }, 136 | { 137 | "inputs": [ 138 | { 139 | "internalType": "bytes32", 140 | "name": "_queryId", 141 | "type": "bytes32" 142 | }, 143 | { 144 | "internalType": "uint256", 145 | "name": "_timestamp", 146 | "type": "uint256" 147 | } 148 | ], 149 | "name": "isInDispute", 150 | "outputs": [ 151 | { 152 | "internalType": "bool", 153 | "name": "", 154 | "type": "bool" 155 | } 156 | ], 157 | "stateMutability": "view", 158 | "type": "function" 159 | }, 160 | { 161 | "inputs": [ 162 | { 163 | "internalType": "bytes32", 164 | "name": "_queryId", 165 | "type": "bytes32" 166 | }, 167 | { 168 | "internalType": "uint256", 169 | "name": "_timestamp", 170 | "type": "uint256" 171 | } 172 | ], 173 | "name": "retrieveData", 174 | "outputs": [ 175 | { 176 | "internalType": "bytes", 177 | "name": "", 178 | "type": "bytes" 179 | } 180 | ], 181 | "stateMutability": "view", 182 | "type": "function" 183 | } 184 | ], 185 | "bytecode": "0x", 186 | "deployedBytecode": "0x", 187 | "linkReferences": {}, 188 | "deployedLinkReferences": {} 189 | } 190 | -------------------------------------------------------------------------------- /artifacts/contracts/mocks/BenchUsingTellor.sol/BenchUsingTellor.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d48d8c45439b66d353ec5b849f2f80d9.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/mocks/BenchUsingTellor.sol/BenchUsingTellor.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "BenchUsingTellor", 4 | "sourceName": "contracts/mocks/BenchUsingTellor.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "address payable", 10 | "name": "_tellor", 11 | "type": "address" 12 | } 13 | ], 14 | "stateMutability": "nonpayable", 15 | "type": "constructor" 16 | }, 17 | { 18 | "inputs": [ 19 | { 20 | "internalType": "bytes32", 21 | "name": "_queryId", 22 | "type": "bytes32" 23 | }, 24 | { 25 | "internalType": "uint256", 26 | "name": "_timestamp", 27 | "type": "uint256" 28 | } 29 | ], 30 | "name": "getDataAfter", 31 | "outputs": [ 32 | { 33 | "internalType": "bytes", 34 | "name": "_value", 35 | "type": "bytes" 36 | }, 37 | { 38 | "internalType": "uint256", 39 | "name": "_timestampRetrieved", 40 | "type": "uint256" 41 | } 42 | ], 43 | "stateMutability": "view", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [ 48 | { 49 | "internalType": "bytes32", 50 | "name": "_queryId", 51 | "type": "bytes32" 52 | }, 53 | { 54 | "internalType": "uint256", 55 | "name": "_timestamp", 56 | "type": "uint256" 57 | } 58 | ], 59 | "name": "getDataBefore", 60 | "outputs": [ 61 | { 62 | "internalType": "bytes", 63 | "name": "_value", 64 | "type": "bytes" 65 | }, 66 | { 67 | "internalType": "uint256", 68 | "name": "_timestampRetrieved", 69 | "type": "uint256" 70 | } 71 | ], 72 | "stateMutability": "view", 73 | "type": "function" 74 | }, 75 | { 76 | "inputs": [ 77 | { 78 | "internalType": "bytes32", 79 | "name": "_queryId", 80 | "type": "bytes32" 81 | }, 82 | { 83 | "internalType": "uint256", 84 | "name": "_timestamp", 85 | "type": "uint256" 86 | } 87 | ], 88 | "name": "getIndexForDataAfter", 89 | "outputs": [ 90 | { 91 | "internalType": "bool", 92 | "name": "_found", 93 | "type": "bool" 94 | }, 95 | { 96 | "internalType": "uint256", 97 | "name": "_index", 98 | "type": "uint256" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [ 106 | { 107 | "internalType": "bytes32", 108 | "name": "_queryId", 109 | "type": "bytes32" 110 | }, 111 | { 112 | "internalType": "uint256", 113 | "name": "_timestamp", 114 | "type": "uint256" 115 | } 116 | ], 117 | "name": "getIndexForDataBefore", 118 | "outputs": [ 119 | { 120 | "internalType": "bool", 121 | "name": "_found", 122 | "type": "bool" 123 | }, 124 | { 125 | "internalType": "uint256", 126 | "name": "_index", 127 | "type": "uint256" 128 | } 129 | ], 130 | "stateMutability": "view", 131 | "type": "function" 132 | }, 133 | { 134 | "inputs": [ 135 | { 136 | "internalType": "bytes32", 137 | "name": "_queryId", 138 | "type": "bytes32" 139 | }, 140 | { 141 | "internalType": "uint256", 142 | "name": "_timestamp", 143 | "type": "uint256" 144 | }, 145 | { 146 | "internalType": "uint256", 147 | "name": "_maxAge", 148 | "type": "uint256" 149 | }, 150 | { 151 | "internalType": "uint256", 152 | "name": "_maxCount", 153 | "type": "uint256" 154 | } 155 | ], 156 | "name": "getMultipleValuesBefore", 157 | "outputs": [ 158 | { 159 | "internalType": "bytes[]", 160 | "name": "_values", 161 | "type": "bytes[]" 162 | }, 163 | { 164 | "internalType": "uint256[]", 165 | "name": "_timestamps", 166 | "type": "uint256[]" 167 | } 168 | ], 169 | "stateMutability": "view", 170 | "type": "function" 171 | }, 172 | { 173 | "inputs": [ 174 | { 175 | "internalType": "bytes32", 176 | "name": "_queryId", 177 | "type": "bytes32" 178 | } 179 | ], 180 | "name": "getNewValueCountbyQueryId", 181 | "outputs": [ 182 | { 183 | "internalType": "uint256", 184 | "name": "", 185 | "type": "uint256" 186 | } 187 | ], 188 | "stateMutability": "view", 189 | "type": "function" 190 | }, 191 | { 192 | "inputs": [ 193 | { 194 | "internalType": "bytes32", 195 | "name": "_queryId", 196 | "type": "bytes32" 197 | }, 198 | { 199 | "internalType": "uint256", 200 | "name": "_timestamp", 201 | "type": "uint256" 202 | } 203 | ], 204 | "name": "getReporterByTimestamp", 205 | "outputs": [ 206 | { 207 | "internalType": "address", 208 | "name": "", 209 | "type": "address" 210 | } 211 | ], 212 | "stateMutability": "view", 213 | "type": "function" 214 | }, 215 | { 216 | "inputs": [ 217 | { 218 | "internalType": "bytes32", 219 | "name": "_queryId", 220 | "type": "bytes32" 221 | }, 222 | { 223 | "internalType": "uint256", 224 | "name": "_index", 225 | "type": "uint256" 226 | } 227 | ], 228 | "name": "getTimestampbyQueryIdandIndex", 229 | "outputs": [ 230 | { 231 | "internalType": "uint256", 232 | "name": "", 233 | "type": "uint256" 234 | } 235 | ], 236 | "stateMutability": "view", 237 | "type": "function" 238 | }, 239 | { 240 | "inputs": [ 241 | { 242 | "internalType": "bytes32", 243 | "name": "_queryId", 244 | "type": "bytes32" 245 | }, 246 | { 247 | "internalType": "uint256", 248 | "name": "_timestamp", 249 | "type": "uint256" 250 | } 251 | ], 252 | "name": "isInDispute", 253 | "outputs": [ 254 | { 255 | "internalType": "bool", 256 | "name": "", 257 | "type": "bool" 258 | } 259 | ], 260 | "stateMutability": "view", 261 | "type": "function" 262 | }, 263 | { 264 | "inputs": [ 265 | { 266 | "internalType": "bytes32", 267 | "name": "_queryId", 268 | "type": "bytes32" 269 | }, 270 | { 271 | "internalType": "uint256", 272 | "name": "_timestamp", 273 | "type": "uint256" 274 | } 275 | ], 276 | "name": "retrieveData", 277 | "outputs": [ 278 | { 279 | "internalType": "bytes", 280 | "name": "", 281 | "type": "bytes" 282 | } 283 | ], 284 | "stateMutability": "view", 285 | "type": "function" 286 | }, 287 | { 288 | "inputs": [], 289 | "name": "tellor", 290 | "outputs": [ 291 | { 292 | "internalType": "contract ITellor", 293 | "name": "", 294 | "type": "address" 295 | } 296 | ], 297 | "stateMutability": "view", 298 | "type": "function" 299 | } 300 | ], 301 | "bytecode": "0x608060405234801561001057600080fd5b5060405161108b38038061108b83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610082565b600060208284031215610065578081fd5b81516001600160a01b038116811461007b578182fd5b9392505050565b610ffa806100916000396000f3fe608060405234801561001057600080fd5b50600436106100b95760003560e01c8063a792765f11610081578063e07c54861161005b578063e07c5486146101c3578063f66f49c3146101d6578063fcd4a546146101e9576100b9565b8063a792765f1461017d578063c5958af914610190578063ce5e11bf146101b0576100b9565b80631959ad5b146100be57806329449085146100ee57806344e87f911461011857806364ee3c6d1461013b57806377b03e0d1461015c575b600080fd5b6000546100d1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101016100fc366004610d48565b61020a565b6040805192151583526020830191909152016100e5565b61012b610126366004610d48565b610223565b60405190151581526020016100e5565b61014e610149366004610d48565b610236565b6040516100e5929190610ec5565b61016f61016a366004610d30565b610244565b6040519081526020016100e5565b61014e61018b366004610d48565b610257565b6101a361019e366004610d48565b610265565b6040516100e59190610eb2565b61016f6101be366004610d48565b610271565b6100d16101d1366004610d48565b61027d565b6101016101e4366004610d48565b610289565b6101fc6101f7366004610d69565b610296565b6040516100e5929190610e19565b60008061021784846102b3565b915091505b9250929050565b600061022f8383610336565b9392505050565b6060600061021784846103ba565b600061024f82610413565b90505b919050565b606060006102178484610490565b606061022f8383610526565b600061022f83836105ae565b600061022f8383610632565b60008061021784846106b6565b6060806102a586868686610877565b915091505b94509492505050565b60008054604051632944908560e01b8152600481018590526024810184905282916001600160a01b031690632944908590604401604080518083038186803b1580156102fe57600080fd5b505afa158015610312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102179190610d05565b600080546040516344e87f9160e01b815260048101859052602481018490526001600160a01b03909116906344e87f919060440160206040518083038186803b15801561038257600080fd5b505afa158015610396573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610c96565b606060008060006103cb86866106b6565b91509150816103f2576000604051806020016040528060008152509093509350505061021c565b6103fc86826105ae565b92506104088684610526565b935050509250929050565b600080546040516377b03e0d60e01b8152600481018490526001600160a01b03909116906377b03e0d9060240160206040518083038186803b15801561045857600080fd5b505afa15801561046c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024f9190610dd5565b6000805460405163a792765f60e01b81526004810185905260248101849052606092916001600160a01b03169063a792765f9060440160006040518083038186803b1580156104de57600080fd5b505afa1580156104f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261051a9190810190610cb0565b90969095509350505050565b60005460405163c5958af960e01b815260048101849052602481018390526060916001600160a01b03169063c5958af99060440160006040518083038186803b15801561057257600080fd5b505afa158015610586573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261022f9190810190610d9a565b6000805460405163ce5e11bf60e01b815260048101859052602481018490526001600160a01b039091169063ce5e11bf9060440160206040518083038186803b1580156105fa57600080fd5b505afa15801561060e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610dd5565b6000805460405163703e2a4360e11b815260048101859052602481018490526001600160a01b039091169063e07c54869060440160206040518083038186803b15801561067e57600080fd5b505afa158015610692573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610c6f565b60008060006106c485610413565b9050806106d857600080925092505061021c565b806106e281610f66565b91506001905060008083816106f78a836105ae565b9050888111610712576000809750975050505050505061021c565b61071c8a846105ae565b90508881111561072b57600094505b84156107e257600261073d8484610ee7565b6107479190610eff565b93506107538a856105ae565b9050888111156107995760006107738b61076e600188610f1f565b6105ae565b90508981116107855760009550610793565b610790600186610f1f565b92505b506107dd565b60006107aa8b61076e876001610ee7565b9050898111156107cd5760009550846107c281610f7d565b9550508091506107db565b6107d8856001610ee7565b93505b505b61072b565b6107ec8a82610336565b610802576001849750975050505050505061021c565b61080c8a82610336565b801561081757508584105b1561083a578361082681610f7d565b9450506108338a856105ae565b9050610802565b858414801561084e575061084e8a82610336565b15610865576000809750975050505050505061021c565b6001849750975050505050505061021c565b6060806000806108908861088b888a610f1f565b6106b6565b91509150816108e15760408051600080825260208201909252906108c4565b60608152602001906001900390816108af5790505b5060408051600081526020810190915290945092506102aa915050565b60006108ed89896102b3565b909350905082610940576040805160008082526020820190925290610922565b606081526020019060019003908161090d5790505b5060408051600081526020810190915290955093506102aa92505050565b60008060008867ffffffffffffffff81111561096c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610995578160200160208202803683370190505b5090505b88831080156109bc575084826109b0866001610ee7565b6109ba9190610f1f565b115b15610a2e5760006109d18d61076e8588610f1f565b90506109dd8d82610336565b610a1b5780828581518110610a0257634e487b7160e01b600052603260045260246000fd5b602090810291909101015283610a1781610f7d565b9450505b82610a2581610f7d565b93505050610999565b60008367ffffffffffffffff811115610a5757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a8a57816020015b6060815260200190600190039081610a755790505b50905060008467ffffffffffffffff811115610ab657634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610adf578160200160208202803683370190505b50905060005b85811015610bc5578381610afa600189610f1f565b610b049190610f1f565b81518110610b2257634e487b7160e01b600052603260045260246000fd5b6020026020010151828281518110610b4a57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050610b878f838381518110610b7a57634e487b7160e01b600052603260045260246000fd5b6020026020010151610526565b838281518110610ba757634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080610bbd90610f7d565b915050610ae5565b50909d909c509a5050505050505050505050565b8051801515811461025257600080fd5b600082601f830112610bf9578081fd5b815167ffffffffffffffff80821115610c1457610c14610fae565b604051601f8301601f19908116603f01168101908282118183101715610c3c57610c3c610fae565b81604052838152866020858801011115610c54578485fd5b610c65846020830160208901610f36565b9695505050505050565b600060208284031215610c80578081fd5b81516001600160a01b038116811461022f578182fd5b600060208284031215610ca7578081fd5b61022f82610bd9565b600080600060608486031215610cc4578182fd5b610ccd84610bd9565b9250602084015167ffffffffffffffff811115610ce8578283fd5b610cf486828701610be9565b925050604084015190509250925092565b60008060408385031215610d17578182fd5b610d2083610bd9565b9150602083015190509250929050565b600060208284031215610d41578081fd5b5035919050565b60008060408385031215610d5a578182fd5b50508035926020909101359150565b60008060008060808587031215610d7e578081fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610dab578081fd5b815167ffffffffffffffff811115610dc1578182fd5b610dcd84828501610be9565b949350505050565b600060208284031215610de6578081fd5b5051919050565b60008151808452610e05816020860160208601610f36565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b86010192506020808801855b83811015610e6f57605f19888703018552610e5d868351610ded565b95509382019390820190600101610e41565b505085840381870152865180855287820194820193509150845b82811015610ea557845184529381019392810192600101610e89565b5091979650505050505050565b60006020825261022f6020830184610ded565b600060408252610ed86040830185610ded565b90508260208301529392505050565b60008219821115610efa57610efa610f98565b500190565b600082610f1a57634e487b7160e01b81526012600452602481fd5b500490565b600082821015610f3157610f31610f98565b500390565b60005b83811015610f51578181015183820152602001610f39565b83811115610f60576000848401525b50505050565b600081610f7557610f75610f98565b506000190190565b6000600019821415610f9157610f91610f98565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122001d7b9cb8ae736c4ffe0d77f29db85b7bc705ac8874f27963a62381702f3791064736f6c63430008030033", 302 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b95760003560e01c8063a792765f11610081578063e07c54861161005b578063e07c5486146101c3578063f66f49c3146101d6578063fcd4a546146101e9576100b9565b8063a792765f1461017d578063c5958af914610190578063ce5e11bf146101b0576100b9565b80631959ad5b146100be57806329449085146100ee57806344e87f911461011857806364ee3c6d1461013b57806377b03e0d1461015c575b600080fd5b6000546100d1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101016100fc366004610d48565b61020a565b6040805192151583526020830191909152016100e5565b61012b610126366004610d48565b610223565b60405190151581526020016100e5565b61014e610149366004610d48565b610236565b6040516100e5929190610ec5565b61016f61016a366004610d30565b610244565b6040519081526020016100e5565b61014e61018b366004610d48565b610257565b6101a361019e366004610d48565b610265565b6040516100e59190610eb2565b61016f6101be366004610d48565b610271565b6100d16101d1366004610d48565b61027d565b6101016101e4366004610d48565b610289565b6101fc6101f7366004610d69565b610296565b6040516100e5929190610e19565b60008061021784846102b3565b915091505b9250929050565b600061022f8383610336565b9392505050565b6060600061021784846103ba565b600061024f82610413565b90505b919050565b606060006102178484610490565b606061022f8383610526565b600061022f83836105ae565b600061022f8383610632565b60008061021784846106b6565b6060806102a586868686610877565b915091505b94509492505050565b60008054604051632944908560e01b8152600481018590526024810184905282916001600160a01b031690632944908590604401604080518083038186803b1580156102fe57600080fd5b505afa158015610312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102179190610d05565b600080546040516344e87f9160e01b815260048101859052602481018490526001600160a01b03909116906344e87f919060440160206040518083038186803b15801561038257600080fd5b505afa158015610396573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610c96565b606060008060006103cb86866106b6565b91509150816103f2576000604051806020016040528060008152509093509350505061021c565b6103fc86826105ae565b92506104088684610526565b935050509250929050565b600080546040516377b03e0d60e01b8152600481018490526001600160a01b03909116906377b03e0d9060240160206040518083038186803b15801561045857600080fd5b505afa15801561046c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024f9190610dd5565b6000805460405163a792765f60e01b81526004810185905260248101849052606092916001600160a01b03169063a792765f9060440160006040518083038186803b1580156104de57600080fd5b505afa1580156104f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261051a9190810190610cb0565b90969095509350505050565b60005460405163c5958af960e01b815260048101849052602481018390526060916001600160a01b03169063c5958af99060440160006040518083038186803b15801561057257600080fd5b505afa158015610586573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261022f9190810190610d9a565b6000805460405163ce5e11bf60e01b815260048101859052602481018490526001600160a01b039091169063ce5e11bf9060440160206040518083038186803b1580156105fa57600080fd5b505afa15801561060e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610dd5565b6000805460405163703e2a4360e11b815260048101859052602481018490526001600160a01b039091169063e07c54869060440160206040518083038186803b15801561067e57600080fd5b505afa158015610692573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022f9190610c6f565b60008060006106c485610413565b9050806106d857600080925092505061021c565b806106e281610f66565b91506001905060008083816106f78a836105ae565b9050888111610712576000809750975050505050505061021c565b61071c8a846105ae565b90508881111561072b57600094505b84156107e257600261073d8484610ee7565b6107479190610eff565b93506107538a856105ae565b9050888111156107995760006107738b61076e600188610f1f565b6105ae565b90508981116107855760009550610793565b610790600186610f1f565b92505b506107dd565b60006107aa8b61076e876001610ee7565b9050898111156107cd5760009550846107c281610f7d565b9550508091506107db565b6107d8856001610ee7565b93505b505b61072b565b6107ec8a82610336565b610802576001849750975050505050505061021c565b61080c8a82610336565b801561081757508584105b1561083a578361082681610f7d565b9450506108338a856105ae565b9050610802565b858414801561084e575061084e8a82610336565b15610865576000809750975050505050505061021c565b6001849750975050505050505061021c565b6060806000806108908861088b888a610f1f565b6106b6565b91509150816108e15760408051600080825260208201909252906108c4565b60608152602001906001900390816108af5790505b5060408051600081526020810190915290945092506102aa915050565b60006108ed89896102b3565b909350905082610940576040805160008082526020820190925290610922565b606081526020019060019003908161090d5790505b5060408051600081526020810190915290955093506102aa92505050565b60008060008867ffffffffffffffff81111561096c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610995578160200160208202803683370190505b5090505b88831080156109bc575084826109b0866001610ee7565b6109ba9190610f1f565b115b15610a2e5760006109d18d61076e8588610f1f565b90506109dd8d82610336565b610a1b5780828581518110610a0257634e487b7160e01b600052603260045260246000fd5b602090810291909101015283610a1781610f7d565b9450505b82610a2581610f7d565b93505050610999565b60008367ffffffffffffffff811115610a5757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a8a57816020015b6060815260200190600190039081610a755790505b50905060008467ffffffffffffffff811115610ab657634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610adf578160200160208202803683370190505b50905060005b85811015610bc5578381610afa600189610f1f565b610b049190610f1f565b81518110610b2257634e487b7160e01b600052603260045260246000fd5b6020026020010151828281518110610b4a57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050610b878f838381518110610b7a57634e487b7160e01b600052603260045260246000fd5b6020026020010151610526565b838281518110610ba757634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080610bbd90610f7d565b915050610ae5565b50909d909c509a5050505050505050505050565b8051801515811461025257600080fd5b600082601f830112610bf9578081fd5b815167ffffffffffffffff80821115610c1457610c14610fae565b604051601f8301601f19908116603f01168101908282118183101715610c3c57610c3c610fae565b81604052838152866020858801011115610c54578485fd5b610c65846020830160208901610f36565b9695505050505050565b600060208284031215610c80578081fd5b81516001600160a01b038116811461022f578182fd5b600060208284031215610ca7578081fd5b61022f82610bd9565b600080600060608486031215610cc4578182fd5b610ccd84610bd9565b9250602084015167ffffffffffffffff811115610ce8578283fd5b610cf486828701610be9565b925050604084015190509250925092565b60008060408385031215610d17578182fd5b610d2083610bd9565b9150602083015190509250929050565b600060208284031215610d41578081fd5b5035919050565b60008060408385031215610d5a578182fd5b50508035926020909101359150565b60008060008060808587031215610d7e578081fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610dab578081fd5b815167ffffffffffffffff811115610dc1578182fd5b610dcd84828501610be9565b949350505050565b600060208284031215610de6578081fd5b5051919050565b60008151808452610e05816020860160208601610f36565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b86010192506020808801855b83811015610e6f57605f19888703018552610e5d868351610ded565b95509382019390820190600101610e41565b505085840381870152865180855287820194820193509150845b82811015610ea557845184529381019392810192600101610e89565b5091979650505050505050565b60006020825261022f6020830184610ded565b600060408252610ed86040830185610ded565b90508260208301529392505050565b60008219821115610efa57610efa610f98565b500190565b600082610f1a57634e487b7160e01b81526012600452602481fd5b500490565b600082821015610f3157610f31610f98565b500390565b60005b83811015610f51578181015183820152602001610f39565b83811115610f60576000848401525b50505050565b600081610f7557610f75610f98565b506000190190565b6000600019821415610f9157610f91610f98565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fdfea264697066735822122001d7b9cb8ae736c4ffe0d77f29db85b7bc705ac8874f27963a62381702f3791064736f6c63430008030033", 303 | "linkReferences": {}, 304 | "deployedLinkReferences": {} 305 | } 306 | -------------------------------------------------------------------------------- /artifacts/contracts/testing/ImporterContract.sol/ImporterContract.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/testing/ImporterContract.sol/ImporterContract.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "ImporterContract", 4 | "sourceName": "contracts/testing/ImporterContract.sol", 5 | "abi": [], 6 | "bytecode": "0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122047adc6e43ca311c03367cbbceeff3a70ae84162dbb2fe19592f0a68b9b32676e64736f6c63430008030033", 7 | "deployedBytecode": "0x6080604052600080fdfea264697066735822122047adc6e43ca311c03367cbbceeff3a70ae84162dbb2fe19592f0a68b9b32676e64736f6c63430008030033", 8 | "linkReferences": {}, 9 | "deployedLinkReferences": {} 10 | } 11 | -------------------------------------------------------------------------------- /artifacts/polygongovernance/contracts/Governance.sol/Governance.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/polygongovernance/contracts/interfaces/IERC20.sol/IERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/polygongovernance/contracts/interfaces/IERC20.sol/IERC20.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC20", 4 | "sourceName": "polygongovernance/contracts/interfaces/IERC20.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "address", 10 | "name": "account", 11 | "type": "address" 12 | } 13 | ], 14 | "name": "balanceOf", 15 | "outputs": [ 16 | { 17 | "internalType": "uint256", 18 | "name": "", 19 | "type": "uint256" 20 | } 21 | ], 22 | "stateMutability": "view", 23 | "type": "function" 24 | }, 25 | { 26 | "inputs": [ 27 | { 28 | "internalType": "address", 29 | "name": "recipient", 30 | "type": "address" 31 | }, 32 | { 33 | "internalType": "uint256", 34 | "name": "amount", 35 | "type": "uint256" 36 | } 37 | ], 38 | "name": "transfer", 39 | "outputs": [ 40 | { 41 | "internalType": "bool", 42 | "name": "", 43 | "type": "bool" 44 | } 45 | ], 46 | "stateMutability": "nonpayable", 47 | "type": "function" 48 | }, 49 | { 50 | "inputs": [ 51 | { 52 | "internalType": "address", 53 | "name": "sender", 54 | "type": "address" 55 | }, 56 | { 57 | "internalType": "address", 58 | "name": "recipient", 59 | "type": "address" 60 | }, 61 | { 62 | "internalType": "uint256", 63 | "name": "amount", 64 | "type": "uint256" 65 | } 66 | ], 67 | "name": "transferFrom", 68 | "outputs": [ 69 | { 70 | "internalType": "bool", 71 | "name": "", 72 | "type": "bool" 73 | } 74 | ], 75 | "stateMutability": "nonpayable", 76 | "type": "function" 77 | } 78 | ], 79 | "bytecode": "0x", 80 | "deployedBytecode": "0x", 81 | "linkReferences": {}, 82 | "deployedLinkReferences": {} 83 | } 84 | -------------------------------------------------------------------------------- /artifacts/polygongovernance/contracts/interfaces/IOracle.sol/IOracle.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/polygongovernance/contracts/interfaces/IOracle.sol/IOracle.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IOracle", 4 | "sourceName": "polygongovernance/contracts/interfaces/IOracle.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "bytes32", 10 | "name": "_queryId", 11 | "type": "bytes32" 12 | }, 13 | { 14 | "internalType": "uint256", 15 | "name": "_timestamp", 16 | "type": "uint256" 17 | } 18 | ], 19 | "name": "getBlockNumberByTimestamp", 20 | "outputs": [ 21 | { 22 | "internalType": "uint256", 23 | "name": "", 24 | "type": "uint256" 25 | } 26 | ], 27 | "stateMutability": "view", 28 | "type": "function" 29 | }, 30 | { 31 | "inputs": [ 32 | { 33 | "internalType": "bytes32", 34 | "name": "_queryId", 35 | "type": "bytes32" 36 | }, 37 | { 38 | "internalType": "uint256", 39 | "name": "_timestamp", 40 | "type": "uint256" 41 | } 42 | ], 43 | "name": "getDataBefore", 44 | "outputs": [ 45 | { 46 | "internalType": "bool", 47 | "name": "_ifRetrieve", 48 | "type": "bool" 49 | }, 50 | { 51 | "internalType": "bytes", 52 | "name": "_value", 53 | "type": "bytes" 54 | }, 55 | { 56 | "internalType": "uint256", 57 | "name": "_timestampRetrieved", 58 | "type": "uint256" 59 | } 60 | ], 61 | "stateMutability": "view", 62 | "type": "function" 63 | }, 64 | { 65 | "inputs": [ 66 | { 67 | "internalType": "bytes32", 68 | "name": "_queryId", 69 | "type": "bytes32" 70 | }, 71 | { 72 | "internalType": "uint256", 73 | "name": "_timestamp", 74 | "type": "uint256" 75 | } 76 | ], 77 | "name": "getReporterByTimestamp", 78 | "outputs": [ 79 | { 80 | "internalType": "address", 81 | "name": "", 82 | "type": "address" 83 | } 84 | ], 85 | "stateMutability": "view", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [ 90 | { 91 | "internalType": "address", 92 | "name": "_reporter", 93 | "type": "address" 94 | } 95 | ], 96 | "name": "getReportsSubmittedByAddress", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [], 109 | "name": "getStakeAmount", 110 | "outputs": [ 111 | { 112 | "internalType": "uint256", 113 | "name": "", 114 | "type": "uint256" 115 | } 116 | ], 117 | "stateMutability": "view", 118 | "type": "function" 119 | }, 120 | { 121 | "inputs": [ 122 | { 123 | "internalType": "address", 124 | "name": "_stakerAddress", 125 | "type": "address" 126 | } 127 | ], 128 | "name": "getStakerInfo", 129 | "outputs": [ 130 | { 131 | "internalType": "uint256", 132 | "name": "", 133 | "type": "uint256" 134 | }, 135 | { 136 | "internalType": "uint256", 137 | "name": "", 138 | "type": "uint256" 139 | }, 140 | { 141 | "internalType": "uint256", 142 | "name": "", 143 | "type": "uint256" 144 | }, 145 | { 146 | "internalType": "uint256", 147 | "name": "", 148 | "type": "uint256" 149 | }, 150 | { 151 | "internalType": "uint256", 152 | "name": "", 153 | "type": "uint256" 154 | }, 155 | { 156 | "internalType": "uint256", 157 | "name": "", 158 | "type": "uint256" 159 | }, 160 | { 161 | "internalType": "uint256", 162 | "name": "", 163 | "type": "uint256" 164 | }, 165 | { 166 | "internalType": "uint256", 167 | "name": "", 168 | "type": "uint256" 169 | } 170 | ], 171 | "stateMutability": "view", 172 | "type": "function" 173 | }, 174 | { 175 | "inputs": [], 176 | "name": "getTokenAddress", 177 | "outputs": [ 178 | { 179 | "internalType": "address", 180 | "name": "", 181 | "type": "address" 182 | } 183 | ], 184 | "stateMutability": "view", 185 | "type": "function" 186 | }, 187 | { 188 | "inputs": [ 189 | { 190 | "internalType": "bytes32", 191 | "name": "_queryId", 192 | "type": "bytes32" 193 | }, 194 | { 195 | "internalType": "uint256", 196 | "name": "_timestamp", 197 | "type": "uint256" 198 | } 199 | ], 200 | "name": "removeValue", 201 | "outputs": [], 202 | "stateMutability": "nonpayable", 203 | "type": "function" 204 | }, 205 | { 206 | "inputs": [ 207 | { 208 | "internalType": "bytes32", 209 | "name": "_queryId", 210 | "type": "bytes32" 211 | }, 212 | { 213 | "internalType": "uint256", 214 | "name": "_timestamp", 215 | "type": "uint256" 216 | } 217 | ], 218 | "name": "retrieveData", 219 | "outputs": [ 220 | { 221 | "internalType": "bytes", 222 | "name": "", 223 | "type": "bytes" 224 | } 225 | ], 226 | "stateMutability": "view", 227 | "type": "function" 228 | }, 229 | { 230 | "inputs": [ 231 | { 232 | "internalType": "address", 233 | "name": "_reporter", 234 | "type": "address" 235 | }, 236 | { 237 | "internalType": "address", 238 | "name": "_recipient", 239 | "type": "address" 240 | } 241 | ], 242 | "name": "slashReporter", 243 | "outputs": [ 244 | { 245 | "internalType": "uint256", 246 | "name": "", 247 | "type": "uint256" 248 | } 249 | ], 250 | "stateMutability": "nonpayable", 251 | "type": "function" 252 | } 253 | ], 254 | "bytecode": "0x", 255 | "deployedBytecode": "0x", 256 | "linkReferences": {}, 257 | "deployedLinkReferences": {} 258 | } 259 | -------------------------------------------------------------------------------- /artifacts/tellorflex/contracts/TellorFlex.sol/TellorFlex.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/tellorflex/contracts/interfaces/IERC20.sol/IERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/tellorflex/contracts/interfaces/IERC20.sol/IERC20.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC20", 4 | "sourceName": "tellorflex/contracts/interfaces/IERC20.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "address", 10 | "name": "account", 11 | "type": "address" 12 | } 13 | ], 14 | "name": "balanceOf", 15 | "outputs": [ 16 | { 17 | "internalType": "uint256", 18 | "name": "", 19 | "type": "uint256" 20 | } 21 | ], 22 | "stateMutability": "view", 23 | "type": "function" 24 | }, 25 | { 26 | "inputs": [ 27 | { 28 | "internalType": "address", 29 | "name": "recipient", 30 | "type": "address" 31 | }, 32 | { 33 | "internalType": "uint256", 34 | "name": "amount", 35 | "type": "uint256" 36 | } 37 | ], 38 | "name": "transfer", 39 | "outputs": [ 40 | { 41 | "internalType": "bool", 42 | "name": "", 43 | "type": "bool" 44 | } 45 | ], 46 | "stateMutability": "nonpayable", 47 | "type": "function" 48 | }, 49 | { 50 | "inputs": [ 51 | { 52 | "internalType": "address", 53 | "name": "sender", 54 | "type": "address" 55 | }, 56 | { 57 | "internalType": "address", 58 | "name": "recipient", 59 | "type": "address" 60 | }, 61 | { 62 | "internalType": "uint256", 63 | "name": "amount", 64 | "type": "uint256" 65 | } 66 | ], 67 | "name": "transferFrom", 68 | "outputs": [ 69 | { 70 | "internalType": "bool", 71 | "name": "", 72 | "type": "bool" 73 | } 74 | ], 75 | "stateMutability": "nonpayable", 76 | "type": "function" 77 | } 78 | ], 79 | "bytecode": "0x", 80 | "deployedBytecode": "0x", 81 | "linkReferences": {}, 82 | "deployedLinkReferences": {} 83 | } 84 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/UsingTellor.sol/UsingTellor.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/UsingTellor.sol/UsingTellor.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "UsingTellor", 4 | "sourceName": "usingtellor/contracts/UsingTellor.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "address payable", 10 | "name": "_tellor", 11 | "type": "address" 12 | } 13 | ], 14 | "stateMutability": "nonpayable", 15 | "type": "constructor" 16 | }, 17 | { 18 | "inputs": [ 19 | { 20 | "internalType": "bytes32", 21 | "name": "_queryId", 22 | "type": "bytes32" 23 | }, 24 | { 25 | "internalType": "uint256", 26 | "name": "_timestamp", 27 | "type": "uint256" 28 | } 29 | ], 30 | "name": "getDataAfter", 31 | "outputs": [ 32 | { 33 | "internalType": "bytes", 34 | "name": "_value", 35 | "type": "bytes" 36 | }, 37 | { 38 | "internalType": "uint256", 39 | "name": "_timestampRetrieved", 40 | "type": "uint256" 41 | } 42 | ], 43 | "stateMutability": "view", 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [ 48 | { 49 | "internalType": "bytes32", 50 | "name": "_queryId", 51 | "type": "bytes32" 52 | }, 53 | { 54 | "internalType": "uint256", 55 | "name": "_timestamp", 56 | "type": "uint256" 57 | } 58 | ], 59 | "name": "getDataBefore", 60 | "outputs": [ 61 | { 62 | "internalType": "bytes", 63 | "name": "_value", 64 | "type": "bytes" 65 | }, 66 | { 67 | "internalType": "uint256", 68 | "name": "_timestampRetrieved", 69 | "type": "uint256" 70 | } 71 | ], 72 | "stateMutability": "view", 73 | "type": "function" 74 | }, 75 | { 76 | "inputs": [ 77 | { 78 | "internalType": "bytes32", 79 | "name": "_queryId", 80 | "type": "bytes32" 81 | }, 82 | { 83 | "internalType": "uint256", 84 | "name": "_timestamp", 85 | "type": "uint256" 86 | } 87 | ], 88 | "name": "getIndexForDataAfter", 89 | "outputs": [ 90 | { 91 | "internalType": "bool", 92 | "name": "_found", 93 | "type": "bool" 94 | }, 95 | { 96 | "internalType": "uint256", 97 | "name": "_index", 98 | "type": "uint256" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [ 106 | { 107 | "internalType": "bytes32", 108 | "name": "_queryId", 109 | "type": "bytes32" 110 | }, 111 | { 112 | "internalType": "uint256", 113 | "name": "_timestamp", 114 | "type": "uint256" 115 | } 116 | ], 117 | "name": "getIndexForDataBefore", 118 | "outputs": [ 119 | { 120 | "internalType": "bool", 121 | "name": "_found", 122 | "type": "bool" 123 | }, 124 | { 125 | "internalType": "uint256", 126 | "name": "_index", 127 | "type": "uint256" 128 | } 129 | ], 130 | "stateMutability": "view", 131 | "type": "function" 132 | }, 133 | { 134 | "inputs": [ 135 | { 136 | "internalType": "bytes32", 137 | "name": "_queryId", 138 | "type": "bytes32" 139 | }, 140 | { 141 | "internalType": "uint256", 142 | "name": "_timestamp", 143 | "type": "uint256" 144 | }, 145 | { 146 | "internalType": "uint256", 147 | "name": "_maxAge", 148 | "type": "uint256" 149 | }, 150 | { 151 | "internalType": "uint256", 152 | "name": "_maxCount", 153 | "type": "uint256" 154 | } 155 | ], 156 | "name": "getMultipleValuesBefore", 157 | "outputs": [ 158 | { 159 | "internalType": "bytes[]", 160 | "name": "_values", 161 | "type": "bytes[]" 162 | }, 163 | { 164 | "internalType": "uint256[]", 165 | "name": "_timestamps", 166 | "type": "uint256[]" 167 | } 168 | ], 169 | "stateMutability": "view", 170 | "type": "function" 171 | }, 172 | { 173 | "inputs": [ 174 | { 175 | "internalType": "bytes32", 176 | "name": "_queryId", 177 | "type": "bytes32" 178 | } 179 | ], 180 | "name": "getNewValueCountbyQueryId", 181 | "outputs": [ 182 | { 183 | "internalType": "uint256", 184 | "name": "", 185 | "type": "uint256" 186 | } 187 | ], 188 | "stateMutability": "view", 189 | "type": "function" 190 | }, 191 | { 192 | "inputs": [ 193 | { 194 | "internalType": "bytes32", 195 | "name": "_queryId", 196 | "type": "bytes32" 197 | }, 198 | { 199 | "internalType": "uint256", 200 | "name": "_timestamp", 201 | "type": "uint256" 202 | } 203 | ], 204 | "name": "getReporterByTimestamp", 205 | "outputs": [ 206 | { 207 | "internalType": "address", 208 | "name": "", 209 | "type": "address" 210 | } 211 | ], 212 | "stateMutability": "view", 213 | "type": "function" 214 | }, 215 | { 216 | "inputs": [ 217 | { 218 | "internalType": "bytes32", 219 | "name": "_queryId", 220 | "type": "bytes32" 221 | }, 222 | { 223 | "internalType": "uint256", 224 | "name": "_index", 225 | "type": "uint256" 226 | } 227 | ], 228 | "name": "getTimestampbyQueryIdandIndex", 229 | "outputs": [ 230 | { 231 | "internalType": "uint256", 232 | "name": "", 233 | "type": "uint256" 234 | } 235 | ], 236 | "stateMutability": "view", 237 | "type": "function" 238 | }, 239 | { 240 | "inputs": [], 241 | "name": "idMappingContract", 242 | "outputs": [ 243 | { 244 | "internalType": "contract IMappingContract", 245 | "name": "", 246 | "type": "address" 247 | } 248 | ], 249 | "stateMutability": "view", 250 | "type": "function" 251 | }, 252 | { 253 | "inputs": [ 254 | { 255 | "internalType": "bytes32", 256 | "name": "_queryId", 257 | "type": "bytes32" 258 | }, 259 | { 260 | "internalType": "uint256", 261 | "name": "_timestamp", 262 | "type": "uint256" 263 | } 264 | ], 265 | "name": "isInDispute", 266 | "outputs": [ 267 | { 268 | "internalType": "bool", 269 | "name": "", 270 | "type": "bool" 271 | } 272 | ], 273 | "stateMutability": "view", 274 | "type": "function" 275 | }, 276 | { 277 | "inputs": [ 278 | { 279 | "internalType": "bytes32", 280 | "name": "_queryId", 281 | "type": "bytes32" 282 | }, 283 | { 284 | "internalType": "uint256", 285 | "name": "_timestamp", 286 | "type": "uint256" 287 | } 288 | ], 289 | "name": "retrieveData", 290 | "outputs": [ 291 | { 292 | "internalType": "bytes", 293 | "name": "", 294 | "type": "bytes" 295 | } 296 | ], 297 | "stateMutability": "view", 298 | "type": "function" 299 | }, 300 | { 301 | "inputs": [ 302 | { 303 | "internalType": "address", 304 | "name": "_addy", 305 | "type": "address" 306 | } 307 | ], 308 | "name": "setIdMappingContract", 309 | "outputs": [], 310 | "stateMutability": "nonpayable", 311 | "type": "function" 312 | }, 313 | { 314 | "inputs": [], 315 | "name": "tellor", 316 | "outputs": [ 317 | { 318 | "internalType": "contract ITellor", 319 | "name": "", 320 | "type": "address" 321 | } 322 | ], 323 | "stateMutability": "view", 324 | "type": "function" 325 | }, 326 | { 327 | "inputs": [ 328 | { 329 | "internalType": "bytes32", 330 | "name": "_id", 331 | "type": "bytes32" 332 | } 333 | ], 334 | "name": "valueFor", 335 | "outputs": [ 336 | { 337 | "internalType": "int256", 338 | "name": "_value", 339 | "type": "int256" 340 | }, 341 | { 342 | "internalType": "uint256", 343 | "name": "_timestamp", 344 | "type": "uint256" 345 | }, 346 | { 347 | "internalType": "uint256", 348 | "name": "_statusCode", 349 | "type": "uint256" 350 | } 351 | ], 352 | "stateMutability": "view", 353 | "type": "function" 354 | } 355 | ], 356 | "bytecode": "0x608060405234801561001057600080fd5b5060405161123e38038061123e83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610082565b600060208284031215610065578081fd5b81516001600160a01b038116811461007b578182fd5b9392505050565b6111ad806100916000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063a792765f1161008c578063e07c548611610066578063e07c54861461021c578063f66f49c31461022f578063f78eea8314610242578063fcd4a54614610270576100ea565b8063a792765f146101d6578063c5958af9146101e9578063ce5e11bf14610209576100ea565b80632af8aae0116100c85780632af8aae01461015e57806344e87f911461017157806364ee3c6d1461019457806377b03e0d146101b5576100ea565b8063193b505b146100ef5780631959ad5b146101045780632944908514610134575b600080fd5b6101026100fd366004610dda565b610291565b005b600054610117906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610147610142366004610edc565b6102d6565b60408051921515835260208301919091520161012b565b600154610117906001600160a01b031681565b61018461017f366004610edc565b610365565b604051901515815260200161012b565b6101a76101a2366004610edc565b6103f0565b60405161012b929190611041565b6101c86101c3366004610eac565b610449565b60405190815260200161012b565b6101a76101e4366004610edc565b6104ce565b6101fc6101f7366004610edc565b610564565b60405161012b919061102e565b6101c8610217366004610edc565b6105ec565b61011761022a366004610edc565b610670565b61014761023d366004610edc565b6106f4565b610255610250366004610eac565b6108b0565b6040805193845260208401929092529082015260600161012b565b61028361027e366004610efd565b610980565b60405161012b929190610f95565b6001546001600160a01b0316156102a757600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60008054604051632944908560e01b8152600481018590526024810184905282916001600160a01b031690632944908590604401604080518083038186803b15801561032157600080fd5b505afa158015610335573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103599190610e81565b915091505b9250929050565b600080546040516344e87f9160e01b815260048101859052602481018490526001600160a01b03909116906344e87f919060440160206040518083038186803b1580156103b157600080fd5b505afa1580156103c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e99190610e12565b9392505050565b6060600080600061040186866106f4565b9150915081610428576000604051806020016040528060008152509093509350505061035e565b61043286826105ec565b925061043e8684610564565b935050509250929050565b600080546040516377b03e0d60e01b8152600481018490526001600160a01b03909116906377b03e0d9060240160206040518083038186803b15801561048e57600080fd5b505afa1580156104a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c69190610ec4565b90505b919050565b6000805460405163a792765f60e01b81526004810185905260248101849052606092916001600160a01b03169063a792765f9060440160006040518083038186803b15801561051c57600080fd5b505afa158015610530573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105589190810190610e2c565b90969095509350505050565b60005460405163c5958af960e01b815260048101849052602481018390526060916001600160a01b03169063c5958af99060440160006040518083038186803b1580156105b057600080fd5b505afa1580156105c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103e99190810190610f2e565b6000805460405163ce5e11bf60e01b815260048101859052602481018490526001600160a01b039091169063ce5e11bf9060440160206040518083038186803b15801561063857600080fd5b505afa15801561064c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e99190610ec4565b6000805460405163703e2a4360e11b815260048101859052602481018490526001600160a01b039091169063e07c54869060440160206040518083038186803b1580156106bc57600080fd5b505afa1580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e99190610df6565b600080600061070285610449565b90508061071657600080925092505061035e565b8061072081611101565b91506001905060008083816107358a836105ec565b9050888111610750576000809750975050505050505061035e565b61075a8a846105ec565b90508881111561076957600094505b841561081b57600261077b8484611063565b610785919061107b565b93506107918a856105ec565b9050888111156107d25760006107ac8b6102176001886110ba565b90508981116107be57600095506107cc565b6107c96001866110ba565b92505b50610816565b60006107e38b610217876001611063565b9050898111156108065760009550846107fb81611118565b955050809150610814565b610811856001611063565b93505b505b610769565b6108258a82610365565b61083b576001849750975050505050505061035e565b6108458a82610365565b801561085057508584105b15610873578361085f81611118565b94505061086c8a856105ec565b905061083b565b858414801561088757506108878a82610365565b1561089e576000809750975050505050505061035e565b6001849750975050505050505061035e565b6001546040516387a475fd60e01b8152600481018390526000918291829182916001600160a01b03909116906387a475fd9060240160206040518083038186803b1580156108fd57600080fd5b505afa158015610911573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109359190610ec4565b90506060610948826101e4426001611063565b9450905083610964576000806101949450945094505050610979565b600061096f82610cdf565b955060c893505050505b9193909250565b6060806000806109948861023d888a6110ba565b91509150816109e55760408051600080825260208201909252906109c8565b60608152602001906001900390816109b35790505b506040805160008152602081019091529094509250610cd6915050565b60006109f189896102d6565b909350905082610a44576040805160008082526020820190925290610a26565b6060815260200190600190039081610a115790505b506040805160008152602081019091529095509350610cd692505050565b60008060008867ffffffffffffffff811115610a7057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a99578160200160208202803683370190505b5090505b8883108015610ac057508482610ab4866001611063565b610abe91906110ba565b115b15610b32576000610ad58d61021785886110ba565b9050610ae18d82610365565b610b1f5780828581518110610b0657634e487b7160e01b600052603260045260246000fd5b602090810291909101015283610b1b81611118565b9450505b82610b2981611118565b93505050610a9d565b60008367ffffffffffffffff811115610b5b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610b8e57816020015b6060815260200190600190039081610b795790505b50905060008467ffffffffffffffff811115610bba57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610be3578160200160208202803683370190505b50905060005b85811015610cc9578381610bfe6001896110ba565b610c0891906110ba565b81518110610c2657634e487b7160e01b600052603260045260246000fd5b6020026020010151828281518110610c4e57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050610c8b8f838381518110610c7e57634e487b7160e01b600052603260045260246000fd5b6020026020010151610564565b838281518110610cab57634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080610cc190611118565b915050610be9565b5090985096505050505050505b94509492505050565b6000805b8251811015610d3e57828181518110610d0c57634e487b7160e01b600052603260045260246000fd5b016020015160f81c610d208361010061109b565b610d2a9190611063565b915080610d3681611118565b915050610ce3565b50919050565b805180151581146104c957600080fd5b600082601f830112610d64578081fd5b815167ffffffffffffffff80821115610d7f57610d7f611149565b604051601f8301601f19908116603f01168101908282118183101715610da757610da7611149565b81604052838152866020858801011115610dbf578485fd5b610dd08460208301602089016110d1565b9695505050505050565b600060208284031215610deb578081fd5b81356103e98161115f565b600060208284031215610e07578081fd5b81516103e98161115f565b600060208284031215610e23578081fd5b6103e982610d44565b600080600060608486031215610e40578182fd5b610e4984610d44565b9250602084015167ffffffffffffffff811115610e64578283fd5b610e7086828701610d54565b925050604084015190509250925092565b60008060408385031215610e93578182fd5b610e9c83610d44565b9150602083015190509250929050565b600060208284031215610ebd578081fd5b5035919050565b600060208284031215610ed5578081fd5b5051919050565b60008060408385031215610eee578182fd5b50508035926020909101359150565b60008060008060808587031215610f12578081fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610f3f578081fd5b815167ffffffffffffffff811115610f55578182fd5b610f6184828501610d54565b949350505050565b60008151808452610f818160208601602086016110d1565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b86010192506020808801855b83811015610feb57605f19888703018552610fd9868351610f69565b95509382019390820190600101610fbd565b505085840381870152865180855287820194820193509150845b8281101561102157845184529381019392810192600101611005565b5091979650505050505050565b6000602082526103e96020830184610f69565b6000604082526110546040830185610f69565b90508260208301529392505050565b6000821982111561107657611076611133565b500190565b60008261109657634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156110b5576110b5611133565b500290565b6000828210156110cc576110cc611133565b500390565b60005b838110156110ec5781810151838201526020016110d4565b838111156110fb576000848401525b50505050565b60008161111057611110611133565b506000190190565b600060001982141561112c5761112c611133565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461117457600080fd5b5056fea2646970667358221220d925f50347774f002c777d494fb2a05b6c8be2b39672a88bd7c665e93795370464736f6c63430008030033", 357 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063a792765f1161008c578063e07c548611610066578063e07c54861461021c578063f66f49c31461022f578063f78eea8314610242578063fcd4a54614610270576100ea565b8063a792765f146101d6578063c5958af9146101e9578063ce5e11bf14610209576100ea565b80632af8aae0116100c85780632af8aae01461015e57806344e87f911461017157806364ee3c6d1461019457806377b03e0d146101b5576100ea565b8063193b505b146100ef5780631959ad5b146101045780632944908514610134575b600080fd5b6101026100fd366004610dda565b610291565b005b600054610117906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610147610142366004610edc565b6102d6565b60408051921515835260208301919091520161012b565b600154610117906001600160a01b031681565b61018461017f366004610edc565b610365565b604051901515815260200161012b565b6101a76101a2366004610edc565b6103f0565b60405161012b929190611041565b6101c86101c3366004610eac565b610449565b60405190815260200161012b565b6101a76101e4366004610edc565b6104ce565b6101fc6101f7366004610edc565b610564565b60405161012b919061102e565b6101c8610217366004610edc565b6105ec565b61011761022a366004610edc565b610670565b61014761023d366004610edc565b6106f4565b610255610250366004610eac565b6108b0565b6040805193845260208401929092529082015260600161012b565b61028361027e366004610efd565b610980565b60405161012b929190610f95565b6001546001600160a01b0316156102a757600080fd5b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60008054604051632944908560e01b8152600481018590526024810184905282916001600160a01b031690632944908590604401604080518083038186803b15801561032157600080fd5b505afa158015610335573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103599190610e81565b915091505b9250929050565b600080546040516344e87f9160e01b815260048101859052602481018490526001600160a01b03909116906344e87f919060440160206040518083038186803b1580156103b157600080fd5b505afa1580156103c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e99190610e12565b9392505050565b6060600080600061040186866106f4565b9150915081610428576000604051806020016040528060008152509093509350505061035e565b61043286826105ec565b925061043e8684610564565b935050509250929050565b600080546040516377b03e0d60e01b8152600481018490526001600160a01b03909116906377b03e0d9060240160206040518083038186803b15801561048e57600080fd5b505afa1580156104a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c69190610ec4565b90505b919050565b6000805460405163a792765f60e01b81526004810185905260248101849052606092916001600160a01b03169063a792765f9060440160006040518083038186803b15801561051c57600080fd5b505afa158015610530573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105589190810190610e2c565b90969095509350505050565b60005460405163c5958af960e01b815260048101849052602481018390526060916001600160a01b03169063c5958af99060440160006040518083038186803b1580156105b057600080fd5b505afa1580156105c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103e99190810190610f2e565b6000805460405163ce5e11bf60e01b815260048101859052602481018490526001600160a01b039091169063ce5e11bf9060440160206040518083038186803b15801561063857600080fd5b505afa15801561064c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e99190610ec4565b6000805460405163703e2a4360e11b815260048101859052602481018490526001600160a01b039091169063e07c54869060440160206040518083038186803b1580156106bc57600080fd5b505afa1580156106d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e99190610df6565b600080600061070285610449565b90508061071657600080925092505061035e565b8061072081611101565b91506001905060008083816107358a836105ec565b9050888111610750576000809750975050505050505061035e565b61075a8a846105ec565b90508881111561076957600094505b841561081b57600261077b8484611063565b610785919061107b565b93506107918a856105ec565b9050888111156107d25760006107ac8b6102176001886110ba565b90508981116107be57600095506107cc565b6107c96001866110ba565b92505b50610816565b60006107e38b610217876001611063565b9050898111156108065760009550846107fb81611118565b955050809150610814565b610811856001611063565b93505b505b610769565b6108258a82610365565b61083b576001849750975050505050505061035e565b6108458a82610365565b801561085057508584105b15610873578361085f81611118565b94505061086c8a856105ec565b905061083b565b858414801561088757506108878a82610365565b1561089e576000809750975050505050505061035e565b6001849750975050505050505061035e565b6001546040516387a475fd60e01b8152600481018390526000918291829182916001600160a01b03909116906387a475fd9060240160206040518083038186803b1580156108fd57600080fd5b505afa158015610911573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109359190610ec4565b90506060610948826101e4426001611063565b9450905083610964576000806101949450945094505050610979565b600061096f82610cdf565b955060c893505050505b9193909250565b6060806000806109948861023d888a6110ba565b91509150816109e55760408051600080825260208201909252906109c8565b60608152602001906001900390816109b35790505b506040805160008152602081019091529094509250610cd6915050565b60006109f189896102d6565b909350905082610a44576040805160008082526020820190925290610a26565b6060815260200190600190039081610a115790505b506040805160008152602081019091529095509350610cd692505050565b60008060008867ffffffffffffffff811115610a7057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610a99578160200160208202803683370190505b5090505b8883108015610ac057508482610ab4866001611063565b610abe91906110ba565b115b15610b32576000610ad58d61021785886110ba565b9050610ae18d82610365565b610b1f5780828581518110610b0657634e487b7160e01b600052603260045260246000fd5b602090810291909101015283610b1b81611118565b9450505b82610b2981611118565b93505050610a9d565b60008367ffffffffffffffff811115610b5b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610b8e57816020015b6060815260200190600190039081610b795790505b50905060008467ffffffffffffffff811115610bba57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610be3578160200160208202803683370190505b50905060005b85811015610cc9578381610bfe6001896110ba565b610c0891906110ba565b81518110610c2657634e487b7160e01b600052603260045260246000fd5b6020026020010151828281518110610c4e57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050610c8b8f838381518110610c7e57634e487b7160e01b600052603260045260246000fd5b6020026020010151610564565b838281518110610cab57634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080610cc190611118565b915050610be9565b5090985096505050505050505b94509492505050565b6000805b8251811015610d3e57828181518110610d0c57634e487b7160e01b600052603260045260246000fd5b016020015160f81c610d208361010061109b565b610d2a9190611063565b915080610d3681611118565b915050610ce3565b50919050565b805180151581146104c957600080fd5b600082601f830112610d64578081fd5b815167ffffffffffffffff80821115610d7f57610d7f611149565b604051601f8301601f19908116603f01168101908282118183101715610da757610da7611149565b81604052838152866020858801011115610dbf578485fd5b610dd08460208301602089016110d1565b9695505050505050565b600060208284031215610deb578081fd5b81356103e98161115f565b600060208284031215610e07578081fd5b81516103e98161115f565b600060208284031215610e23578081fd5b6103e982610d44565b600080600060608486031215610e40578182fd5b610e4984610d44565b9250602084015167ffffffffffffffff811115610e64578283fd5b610e7086828701610d54565b925050604084015190509250925092565b60008060408385031215610e93578182fd5b610e9c83610d44565b9150602083015190509250929050565b600060208284031215610ebd578081fd5b5035919050565b600060208284031215610ed5578081fd5b5051919050565b60008060408385031215610eee578182fd5b50508035926020909101359150565b60008060008060808587031215610f12578081fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215610f3f578081fd5b815167ffffffffffffffff811115610f55578182fd5b610f6184828501610d54565b949350505050565b60008151808452610f818160208601602086016110d1565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b86010192506020808801855b83811015610feb57605f19888703018552610fd9868351610f69565b95509382019390820190600101610fbd565b505085840381870152865180855287820194820193509150845b8281101561102157845184529381019392810192600101611005565b5091979650505050505050565b6000602082526103e96020830184610f69565b6000604082526110546040830185610f69565b90508260208301529392505050565b6000821982111561107657611076611133565b500190565b60008261109657634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156110b5576110b5611133565b500290565b6000828210156110cc576110cc611133565b500390565b60005b838110156110ec5781810151838201526020016110d4565b838111156110fb576000848401525b50505050565b60008161111057611110611133565b506000190190565b600060001982141561112c5761112c611133565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461117457600080fd5b5056fea2646970667358221220d925f50347774f002c777d494fb2a05b6c8be2b39672a88bd7c665e93795370464736f6c63430008030033", 358 | "linkReferences": {}, 359 | "deployedLinkReferences": {} 360 | } 361 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/IERC2362.sol/IERC2362.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/IERC2362.sol/IERC2362.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC2362", 4 | "sourceName": "usingtellor/contracts/interface/IERC2362.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "bytes32", 10 | "name": "_id", 11 | "type": "bytes32" 12 | } 13 | ], 14 | "name": "valueFor", 15 | "outputs": [ 16 | { 17 | "internalType": "int256", 18 | "name": "", 19 | "type": "int256" 20 | }, 21 | { 22 | "internalType": "uint256", 23 | "name": "", 24 | "type": "uint256" 25 | }, 26 | { 27 | "internalType": "uint256", 28 | "name": "", 29 | "type": "uint256" 30 | } 31 | ], 32 | "stateMutability": "view", 33 | "type": "function" 34 | } 35 | ], 36 | "bytecode": "0x", 37 | "deployedBytecode": "0x", 38 | "linkReferences": {}, 39 | "deployedLinkReferences": {} 40 | } 41 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/IMappingContract.sol/IMappingContract.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/IMappingContract.sol/IMappingContract.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IMappingContract", 4 | "sourceName": "usingtellor/contracts/interface/IMappingContract.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "bytes32", 10 | "name": "_id", 11 | "type": "bytes32" 12 | } 13 | ], 14 | "name": "getTellorID", 15 | "outputs": [ 16 | { 17 | "internalType": "bytes32", 18 | "name": "", 19 | "type": "bytes32" 20 | } 21 | ], 22 | "stateMutability": "view", 23 | "type": "function" 24 | } 25 | ], 26 | "bytecode": "0x", 27 | "deployedBytecode": "0x", 28 | "linkReferences": {}, 29 | "deployedLinkReferences": {} 30 | } 31 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/ITellor.sol/Autopay.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/ITellor.sol/Autopay.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Autopay", 4 | "sourceName": "usingtellor/contracts/interface/ITellor.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "getStakeAmount", 9 | "outputs": [ 10 | { 11 | "internalType": "uint256", 12 | "name": "", 13 | "type": "uint256" 14 | } 15 | ], 16 | "stateMutability": "view", 17 | "type": "function" 18 | }, 19 | { 20 | "inputs": [], 21 | "name": "stakeAmount", 22 | "outputs": [ 23 | { 24 | "internalType": "uint256", 25 | "name": "", 26 | "type": "uint256" 27 | } 28 | ], 29 | "stateMutability": "view", 30 | "type": "function" 31 | }, 32 | { 33 | "inputs": [], 34 | "name": "token", 35 | "outputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "", 39 | "type": "address" 40 | } 41 | ], 42 | "stateMutability": "view", 43 | "type": "function" 44 | } 45 | ], 46 | "bytecode": "0x", 47 | "deployedBytecode": "0x", 48 | "linkReferences": {}, 49 | "deployedLinkReferences": {} 50 | } 51 | -------------------------------------------------------------------------------- /artifacts/usingtellor/contracts/interface/ITellor.sol/ITellor.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a57a0c8893a63b946905aefba5853e48.json" 4 | } 5 | -------------------------------------------------------------------------------- /contracts/TellorPlayground.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract TellorPlayground { 5 | // Events 6 | event Approval( 7 | address indexed owner, 8 | address indexed spender, 9 | uint256 value 10 | ); 11 | event NewReport( 12 | bytes32 _queryId, 13 | uint256 _time, 14 | bytes _value, 15 | uint256 _nonce, 16 | bytes _queryData, 17 | address _reporter 18 | ); 19 | event NewStaker(address _staker, uint256 _amount); 20 | event StakeWithdrawRequested(address _staker, uint256 _amount); 21 | event StakeWithdrawn(address _staker); 22 | event Transfer(address indexed from, address indexed to, uint256 value); 23 | 24 | // Storage 25 | mapping(bytes32 => mapping(uint256 => bool)) public isDisputed; //queryId -> timestamp -> value 26 | mapping(bytes32 => mapping(uint256 => address)) public reporterByTimestamp; 27 | mapping(address => StakeInfo) stakerDetails; //mapping from a persons address to their staking info 28 | mapping(bytes32 => uint256[]) public timestamps; 29 | mapping(bytes32 => uint256) public tips; // mapping of data IDs to the amount of TRB they are tipped 30 | mapping(bytes32 => mapping(uint256 => bytes)) public values; //queryId -> timestamp -> value 31 | mapping(bytes32 => uint256[]) public voteRounds; // mapping of vote identifier hashes to an array of dispute IDs 32 | mapping(address => mapping(address => uint256)) private _allowances; 33 | mapping(address => uint256) private _balances; 34 | 35 | uint256 public stakeAmount; 36 | uint256 public constant timeBasedReward = 5e17; // time based reward for a reporter for successfully submitting a value 37 | uint256 public tipsInContract; // number of tips within the contract 38 | uint256 public voteCount; 39 | address public token; 40 | uint256 private _totalSupply; 41 | string private _name; 42 | string private _symbol; 43 | uint8 private _decimals; 44 | 45 | // Structs 46 | struct StakeInfo { 47 | uint256 startDate; //stake start date 48 | uint256 stakedBalance; // staked balance 49 | uint256 lockedBalance; // amount locked for withdrawal 50 | uint256 reporterLastTimestamp; // timestamp of reporter's last reported value 51 | uint256 reportsSubmitted; // total number of reports submitted by reporter 52 | } 53 | 54 | // Functions 55 | /** 56 | * @dev Initializes playground parameters 57 | */ 58 | constructor() { 59 | _name = "TellorPlayground"; 60 | _symbol = "TRBP"; 61 | _decimals = 18; 62 | token = address(this); 63 | } 64 | 65 | /** 66 | * @dev Mock function for adding staking rewards. No rewards actually given to stakers 67 | * @param _amount Amount of TRB to be added to the contract 68 | */ 69 | function addStakingRewards(uint256 _amount) external { 70 | require(_transferFrom(msg.sender, address(this), _amount)); 71 | } 72 | 73 | /** 74 | * @dev Approves amount that an address is alowed to spend of behalf of another 75 | * @param _spender The address which is allowed to spend the tokens 76 | * @param _amount The amount that msg.sender is allowing spender to use 77 | * @return bool Whether the transaction succeeded 78 | * 79 | */ 80 | function approve(address _spender, uint256 _amount) external returns (bool){ 81 | _approve(msg.sender, _spender, _amount); 82 | return true; 83 | } 84 | 85 | /** 86 | * @dev A mock function to create a dispute 87 | * @param _queryId The tellorId to be disputed 88 | * @param _timestamp the timestamp of the value to be disputed 89 | */ 90 | function beginDispute(bytes32 _queryId, uint256 _timestamp) external { 91 | values[_queryId][_timestamp] = bytes(""); 92 | isDisputed[_queryId][_timestamp] = true; 93 | voteCount++; 94 | voteRounds[keccak256(abi.encodePacked(_queryId, _timestamp))].push( 95 | voteCount 96 | ); 97 | } 98 | 99 | /** 100 | * @dev Allows a reporter to submit stake 101 | * @param _amount amount of tokens to stake 102 | */ 103 | function depositStake(uint256 _amount) external { 104 | StakeInfo storage _staker = stakerDetails[msg.sender]; 105 | if (_staker.lockedBalance > 0) { 106 | if (_staker.lockedBalance >= _amount) { 107 | _staker.lockedBalance -= _amount; 108 | } else { 109 | require( 110 | _transferFrom( 111 | msg.sender, 112 | address(this), 113 | _amount - _staker.lockedBalance 114 | ) 115 | ); 116 | _staker.lockedBalance = 0; 117 | } 118 | } else { 119 | require(_transferFrom(msg.sender, address(this), _amount)); 120 | } 121 | _staker.startDate = block.timestamp; // This resets their stake start date to now 122 | _staker.stakedBalance += _amount; 123 | emit NewStaker(msg.sender, _amount); 124 | } 125 | 126 | /** 127 | * @dev Public function to mint tokens to the given address 128 | * @param _user The address which will receive the tokens 129 | */ 130 | function faucet(address _user) external { 131 | _mint(_user, 1000 ether); 132 | } 133 | 134 | /** 135 | * @dev Allows a reporter to request to withdraw their stake 136 | * @param _amount amount of staked tokens requesting to withdraw 137 | */ 138 | function requestStakingWithdraw(uint256 _amount) external { 139 | StakeInfo storage _staker = stakerDetails[msg.sender]; 140 | require( 141 | _staker.stakedBalance >= _amount, 142 | "insufficient staked balance" 143 | ); 144 | _staker.startDate = block.timestamp; 145 | _staker.lockedBalance += _amount; 146 | _staker.stakedBalance -= _amount; 147 | emit StakeWithdrawRequested(msg.sender, _amount); 148 | } 149 | 150 | /** 151 | * @dev A mock function to submit a value to be read without reporter staking needed 152 | * @param _queryId the ID to associate the value to 153 | * @param _value the value for the queryId 154 | * @param _nonce the current value count for the query id 155 | * @param _queryData the data used by reporters to fulfill the data query 156 | */ 157 | // slither-disable-next-line timestamp 158 | function submitValue( 159 | bytes32 _queryId, 160 | bytes calldata _value, 161 | uint256 _nonce, 162 | bytes memory _queryData 163 | ) external { 164 | require(keccak256(_value) != keccak256(""), "value must be submitted"); 165 | require( 166 | _nonce == timestamps[_queryId].length || _nonce == 0, 167 | "nonce must match timestamp index" 168 | ); 169 | require( 170 | _queryId == keccak256(_queryData) || uint256(_queryId) <= 100, 171 | "id must be hash of bytes data" 172 | ); 173 | values[_queryId][block.timestamp] = _value; 174 | timestamps[_queryId].push(block.timestamp); 175 | reporterByTimestamp[_queryId][block.timestamp] = msg.sender; 176 | stakerDetails[msg.sender].reporterLastTimestamp = block.timestamp; 177 | stakerDetails[msg.sender].reportsSubmitted++; 178 | emit NewReport( 179 | _queryId, 180 | block.timestamp, 181 | _value, 182 | _nonce, 183 | _queryData, 184 | msg.sender 185 | ); 186 | } 187 | 188 | /** 189 | * @dev Transfer tokens from one user to another 190 | * @param _recipient The destination address 191 | * @param _amount The amount of tokens, including decimals, to transfer 192 | * @return bool If the transfer succeeded 193 | */ 194 | function transfer(address _recipient, uint256 _amount) 195 | public 196 | returns (bool) 197 | { 198 | _transfer(msg.sender, _recipient, _amount); 199 | return true; 200 | } 201 | 202 | /** 203 | * @dev Transfer tokens from user to another 204 | * @param _sender The address which owns the tokens 205 | * @param _recipient The destination address 206 | * @param _amount The quantity of tokens to transfer 207 | * @return bool Whether the transfer succeeded 208 | */ 209 | function transferFrom( 210 | address _sender, 211 | address _recipient, 212 | uint256 _amount 213 | ) public returns (bool) { 214 | _transfer(_sender, _recipient, _amount); 215 | _approve( 216 | _sender, 217 | msg.sender, 218 | _allowances[_sender][msg.sender] - _amount 219 | ); 220 | return true; 221 | } 222 | 223 | /** 224 | * @dev Withdraws a reporter's stake 225 | */ 226 | function withdrawStake() external { 227 | StakeInfo storage _s = stakerDetails[msg.sender]; 228 | // Ensure reporter is locked and that enough time has passed 229 | require(block.timestamp - _s.startDate >= 7 days, "7 days didn't pass"); 230 | require(_s.lockedBalance > 0, "reporter not locked for withdrawal"); 231 | _transfer(address(this), msg.sender, _s.lockedBalance); 232 | _s.lockedBalance = 0; 233 | emit StakeWithdrawn(msg.sender); 234 | } 235 | 236 | // Getters 237 | /** 238 | * @dev Returns the amount that an address is alowed to spend of behalf of another 239 | * @param _owner The address which owns the tokens 240 | * @param _spender The address that will use the tokens 241 | * @return uint256 The amount of allowed tokens 242 | */ 243 | function allowance(address _owner, address _spender) external view returns (uint256){ 244 | return _allowances[_owner][_spender]; 245 | } 246 | 247 | /** 248 | * @dev Returns the balance of a given user. 249 | * @param _account user address 250 | * @return uint256 user's token balance 251 | */ 252 | function balanceOf(address _account) external view returns (uint256) { 253 | return _balances[_account]; 254 | } 255 | 256 | /** 257 | * @dev Returns the number of decimals used to get its user representation. 258 | * @return uint8 the number of decimals; used only for display purposes 259 | */ 260 | function decimals() external view returns (uint8) { 261 | return _decimals; 262 | } 263 | 264 | /** 265 | * @dev Retrieves the latest value for the queryId before the specified timestamp 266 | * @param _queryId is the queryId to look up the value for 267 | * @param _timestamp before which to search for latest value 268 | * @return _ifRetrieve bool true if able to retrieve a non-zero value 269 | * @return _value the value retrieved 270 | * @return _timestampRetrieved the value's timestamp 271 | */ 272 | function getDataBefore(bytes32 _queryId, uint256 _timestamp) 273 | external 274 | view 275 | returns ( 276 | bool _ifRetrieve, 277 | bytes memory _value, 278 | uint256 _timestampRetrieved 279 | ) 280 | { 281 | (bool _found, uint256 _index) = getIndexForDataBefore( 282 | _queryId, 283 | _timestamp 284 | ); 285 | if (!_found) return (false, bytes(""), 0); 286 | _timestampRetrieved = getTimestampbyQueryIdandIndex(_queryId, _index); 287 | _value = values[_queryId][_timestampRetrieved]; 288 | return (true, _value, _timestampRetrieved); 289 | } 290 | 291 | /** 292 | * @dev Retrieves latest array index of data before the specified timestamp for the queryId 293 | * @param _queryId is the queryId to look up the index for 294 | * @param _timestamp is the timestamp before which to search for the latest index 295 | * @return _found whether the index was found 296 | * @return _index the latest index found before the specified timestamp 297 | */ 298 | // slither-disable-next-line calls-loop 299 | function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) 300 | public 301 | view 302 | returns (bool _found, uint256 _index) 303 | { 304 | uint256 _count = getNewValueCountbyQueryId(_queryId); 305 | if (_count > 0) { 306 | uint256 _middle; 307 | uint256 _start = 0; 308 | uint256 _end = _count - 1; 309 | uint256 _time; 310 | //Checking Boundaries to short-circuit the algorithm 311 | _time = getTimestampbyQueryIdandIndex(_queryId, _start); 312 | if (_time >= _timestamp) return (false, 0); 313 | _time = getTimestampbyQueryIdandIndex(_queryId, _end); 314 | if (_time < _timestamp) { 315 | while (isInDispute(_queryId, _time) && _end > 0) { 316 | _end--; 317 | _time = getTimestampbyQueryIdandIndex(_queryId, _end); 318 | } 319 | if (_end == 0 && isInDispute(_queryId, _time)) { 320 | return (false, 0); 321 | } 322 | return (true, _end); 323 | } 324 | //Since the value is within our boundaries, do a binary search 325 | while (true) { 326 | _middle = (_end - _start) / 2 + 1 + _start; 327 | _time = getTimestampbyQueryIdandIndex(_queryId, _middle); 328 | if (_time < _timestamp) { 329 | //get immediate next value 330 | uint256 _nextTime = getTimestampbyQueryIdandIndex( 331 | _queryId, 332 | _middle + 1 333 | ); 334 | if (_nextTime >= _timestamp) { 335 | if (!isInDispute(_queryId, _time)) { 336 | // _time is correct 337 | return (true, _middle); 338 | } else { 339 | // iterate backwards until we find a non-disputed value 340 | while ( 341 | isInDispute(_queryId, _time) && _middle > 0 342 | ) { 343 | _middle--; 344 | _time = getTimestampbyQueryIdandIndex( 345 | _queryId, 346 | _middle 347 | ); 348 | } 349 | if (_middle == 0 && isInDispute(_queryId, _time)) { 350 | return (false, 0); 351 | } 352 | // _time is correct 353 | return (true, _middle); 354 | } 355 | } else { 356 | //look from middle + 1(next value) to end 357 | _start = _middle + 1; 358 | } 359 | } else { 360 | uint256 _prevTime = getTimestampbyQueryIdandIndex( 361 | _queryId, 362 | _middle - 1 363 | ); 364 | if (_prevTime < _timestamp) { 365 | if (!isInDispute(_queryId, _prevTime)) { 366 | // _prevTime is correct 367 | return (true, _middle - 1); 368 | } else { 369 | // iterate backwards until we find a non-disputed value 370 | _middle--; 371 | while ( 372 | isInDispute(_queryId, _prevTime) && _middle > 0 373 | ) { 374 | _middle--; 375 | _prevTime = getTimestampbyQueryIdandIndex( 376 | _queryId, 377 | _middle 378 | ); 379 | } 380 | if ( 381 | _middle == 0 && isInDispute(_queryId, _prevTime) 382 | ) { 383 | return (false, 0); 384 | } 385 | // _prevtime is correct 386 | return (true, _middle); 387 | } 388 | } else { 389 | //look from start to middle -1(prev value) 390 | _end = _middle - 1; 391 | } 392 | } 393 | } 394 | } 395 | return (false, 0); 396 | } 397 | 398 | /** 399 | * @dev Counts the number of values that have been submitted for a given ID 400 | * @param _queryId the ID to look up 401 | * @return uint256 count of the number of values received for the queryId 402 | */ 403 | function getNewValueCountbyQueryId(bytes32 _queryId) 404 | public 405 | view 406 | returns (uint256) 407 | { 408 | return timestamps[_queryId].length; 409 | } 410 | 411 | /** 412 | * @dev Returns the reporter for a given timestamp and queryId 413 | * @param _queryId bytes32 version of the queryId 414 | * @param _timestamp uint256 timestamp of report 415 | * @return address of data reporter 416 | */ 417 | function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) 418 | external 419 | view 420 | returns (address) 421 | { 422 | return reporterByTimestamp[_queryId][_timestamp]; 423 | } 424 | 425 | /** 426 | * @dev Returns mock stake amount 427 | * @return uint256 stake amount 428 | */ 429 | function getStakeAmount() external view returns (uint256) { 430 | return stakeAmount; 431 | } 432 | 433 | /** 434 | * @dev Allows users to retrieve all information about a staker 435 | * @param _stakerAddress address of staker inquiring about 436 | * @return uint startDate of staking 437 | * @return uint current amount staked 438 | * @return uint current amount locked for withdrawal 439 | * @return uint reward debt used to calculate staking reward 440 | * @return uint reporter's last reported timestamp 441 | * @return uint total number of reports submitted by reporter 442 | * @return uint governance vote count when first staked 443 | * @return uint number of votes case by staker when first staked 444 | * @return uint whether staker is counted in totalStakers 445 | */ 446 | function getStakerInfo(address _stakerAddress) 447 | external 448 | view 449 | returns ( 450 | uint256, 451 | uint256, 452 | uint256, 453 | uint256, 454 | uint256, 455 | uint256, 456 | uint256, 457 | uint256, 458 | bool 459 | ) 460 | { 461 | StakeInfo storage _staker = stakerDetails[_stakerAddress]; 462 | return ( 463 | _staker.startDate, 464 | _staker.stakedBalance, 465 | _staker.lockedBalance, 466 | 0, // reward debt 467 | _staker.reporterLastTimestamp, 468 | _staker.reportsSubmitted, 469 | 0, // start vote count 470 | 0, // start vote tally 471 | false 472 | ); 473 | } 474 | 475 | /** 476 | * @dev Gets the timestamp for the value based on their index 477 | * @param _queryId is the queryId to look up 478 | * @param _index is the value index to look up 479 | * @return uint256 timestamp 480 | */ 481 | function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) 482 | public 483 | view 484 | returns (uint256) 485 | { 486 | uint256 _len = timestamps[_queryId].length; 487 | if (_len == 0 || _len <= _index) return 0; 488 | return timestamps[_queryId][_index]; 489 | } 490 | 491 | /** 492 | * @dev Returns an array of voting rounds for a given vote 493 | * @param _hash is the identifier hash for a vote 494 | * @return uint256[] memory dispute IDs of the vote rounds 495 | */ 496 | function getVoteRounds(bytes32 _hash) public view returns (uint256[] memory){ 497 | return voteRounds[_hash]; 498 | } 499 | 500 | /** 501 | * @dev Returns the governance address of the contract 502 | * @return address (this address) 503 | */ 504 | function governance() external view returns (address) { 505 | return address(this); 506 | } 507 | 508 | /** 509 | * @dev Returns whether a given value is disputed 510 | * @param _queryId unique ID of the data feed 511 | * @param _timestamp timestamp of the value 512 | * @return bool whether the value is disputed 513 | */ 514 | function isInDispute(bytes32 _queryId, uint256 _timestamp) 515 | public 516 | view 517 | returns (bool) 518 | { 519 | return isDisputed[_queryId][_timestamp]; 520 | } 521 | 522 | /** 523 | * @dev Returns the name of the token. 524 | * @return string name of the token 525 | */ 526 | function name() external view returns (string memory) { 527 | return _name; 528 | } 529 | 530 | /** 531 | * @dev Retrieves value from oracle based on queryId/timestamp 532 | * @param _queryId being requested 533 | * @param _timestamp to retrieve data/value from 534 | * @return bytes value for queryId/timestamp submitted 535 | */ 536 | function retrieveData(bytes32 _queryId, uint256 _timestamp) 537 | external 538 | view 539 | returns (bytes memory) 540 | { 541 | return values[_queryId][_timestamp]; 542 | } 543 | 544 | /** 545 | * @dev Returns the symbol of the token. 546 | * @return string symbol of the token 547 | */ 548 | function symbol() external view returns (string memory) { 549 | return _symbol; 550 | } 551 | 552 | /** 553 | * @dev Returns the total supply of the token. 554 | * @return uint256 total supply of token 555 | */ 556 | function totalSupply() external view returns (uint256) { 557 | return _totalSupply; 558 | } 559 | 560 | // Internal functions 561 | /** 562 | * @dev Internal function to approve tokens for the user 563 | * @param _owner The owner of the tokens 564 | * @param _spender The address which is allowed to spend the tokens 565 | * @param _amount The amount that msg.sender is allowing spender to use 566 | */ 567 | function _approve( 568 | address _owner, 569 | address _spender, 570 | uint256 _amount 571 | ) internal { 572 | require(_owner != address(0), "ERC20: approve from the zero address"); 573 | require(_spender != address(0), "ERC20: approve to the zero address"); 574 | _allowances[_owner][_spender] = _amount; 575 | emit Approval(_owner, _spender, _amount); 576 | } 577 | 578 | /** 579 | * @dev Internal function to burn tokens for the user 580 | * @param _account The address whose tokens to burn 581 | * @param _amount The quantity of tokens to burn 582 | */ 583 | function _burn(address _account, uint256 _amount) internal{ 584 | require(_account != address(0), "ERC20: burn from the zero address"); 585 | _balances[_account] -= _amount; 586 | _totalSupply -= _amount; 587 | emit Transfer(_account, address(0), _amount); 588 | } 589 | 590 | /** 591 | * @dev Internal function to create new tokens for the user 592 | * @param _account The address which receives minted tokens 593 | * @param _amount The quantity of tokens to min 594 | */ 595 | function _mint(address _account, uint256 _amount) internal{ 596 | require(_account != address(0), "ERC20: mint to the zero address"); 597 | _totalSupply += _amount; 598 | _balances[_account] += _amount; 599 | emit Transfer(address(0), _account, _amount); 600 | } 601 | 602 | /** 603 | * @dev Internal function to perform token transfer 604 | * @param _sender The address which owns the tokens 605 | * @param _recipient The destination address 606 | * @param _amount The quantity of tokens to transfer 607 | */ 608 | function _transfer( 609 | address _sender, 610 | address _recipient, 611 | uint256 _amount 612 | ) internal{ 613 | require(_sender != address(0), "ERC20: transfer from the zero address"); 614 | require( _recipient != address(0),"ERC20: transfer to the zero address"); 615 | _balances[_sender] -= _amount; 616 | _balances[_recipient] += _amount; 617 | emit Transfer(_sender, _recipient, _amount); 618 | } 619 | 620 | /** 621 | * @dev Allows this contract to transfer tokens from one user to another 622 | * @param _sender The address which owns the tokens 623 | * @param _recipient The destination address 624 | * @param _amount The quantity of tokens to transfer 625 | * @return bool Whether the transfer succeeded 626 | */ 627 | function _transferFrom( 628 | address _sender, 629 | address _recipient, 630 | uint256 _amount 631 | ) internal returns (bool) { 632 | _transfer(_sender, _recipient, _amount); 633 | _approve( 634 | _sender, 635 | msg.sender, 636 | _allowances[_sender][address(this)] - _amount 637 | ); 638 | return true; 639 | } 640 | } -------------------------------------------------------------------------------- /contracts/UsingTellor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.0; 3 | 4 | import "./interface/ITellor.sol"; 5 | 6 | /** 7 | @author Tellor Inc 8 | @title UsingTellor 9 | @dev This contract helps smart contracts read data from Tellor 10 | */ 11 | contract UsingTellor{ 12 | ITellor public tellor; 13 | 14 | /*Constructor*/ 15 | /** 16 | * @dev the constructor sets the oracle address in storage 17 | * @param _tellor is the Tellor Oracle address 18 | */ 19 | constructor(address payable _tellor) { 20 | tellor = ITellor(_tellor); 21 | } 22 | 23 | /*Getters*/ 24 | /** 25 | * @dev Retrieves the next value for the queryId after the specified timestamp 26 | * @param _queryId is the queryId to look up the value for 27 | * @param _timestamp after which to search for next value 28 | * @return _value the value retrieved 29 | * @return _timestampRetrieved the value's timestamp 30 | */ 31 | function _getDataAfter(bytes32 _queryId, uint256 _timestamp) 32 | internal 33 | view 34 | returns (bytes memory _value, uint256 _timestampRetrieved) 35 | { 36 | (bool _found, uint256 _index) = _getIndexForDataAfter( 37 | _queryId, 38 | _timestamp 39 | ); 40 | if (!_found) { 41 | return ("", 0); 42 | } 43 | _timestampRetrieved = _getTimestampbyQueryIdandIndex(_queryId, _index); 44 | _value = _retrieveData(_queryId, _timestampRetrieved); 45 | return (_value, _timestampRetrieved); 46 | } 47 | 48 | /** 49 | * @dev Retrieves the latest value for the queryId before the specified timestamp 50 | * @param _queryId is the queryId to look up the value for 51 | * @param _timestamp before which to search for latest value 52 | * @return _value the value retrieved 53 | * @return _timestampRetrieved the value's timestamp 54 | */ 55 | function _getDataBefore(bytes32 _queryId, uint256 _timestamp) 56 | internal 57 | view 58 | returns (bytes memory _value, uint256 _timestampRetrieved) 59 | { 60 | (, _value, _timestampRetrieved) = tellor.getDataBefore( 61 | _queryId, 62 | _timestamp 63 | ); 64 | } 65 | 66 | /** 67 | * @dev Retrieves latest array index of data before the specified timestamp for the queryId 68 | * @param _queryId is the queryId to look up the index for 69 | * @param _timestamp is the timestamp before which to search for the latest index 70 | * @return _found whether the index was found 71 | * @return _index the latest index found before the specified timestamp 72 | */ 73 | // slither-disable-next-line calls-loop 74 | function _getIndexForDataAfter(bytes32 _queryId, uint256 _timestamp) 75 | internal 76 | view 77 | returns (bool _found, uint256 _index) 78 | { 79 | uint256 _count = _getNewValueCountbyQueryId(_queryId); 80 | if (_count == 0) return (false, 0); 81 | _count--; 82 | bool _search = true; // perform binary search 83 | uint256 _middle = 0; 84 | uint256 _start = 0; 85 | uint256 _end = _count; 86 | uint256 _timestampRetrieved; 87 | // checking boundaries to short-circuit the algorithm 88 | _timestampRetrieved = _getTimestampbyQueryIdandIndex(_queryId, _end); 89 | if (_timestampRetrieved <= _timestamp) return (false, 0); 90 | _timestampRetrieved = _getTimestampbyQueryIdandIndex(_queryId, _start); 91 | if (_timestampRetrieved > _timestamp) { 92 | // candidate found, check for disputes 93 | _search = false; 94 | } 95 | // since the value is within our boundaries, do a binary search 96 | while (_search) { 97 | _middle = (_end + _start) / 2; 98 | _timestampRetrieved = _getTimestampbyQueryIdandIndex( 99 | _queryId, 100 | _middle 101 | ); 102 | if (_timestampRetrieved > _timestamp) { 103 | // get immediate previous value 104 | uint256 _prevTime = _getTimestampbyQueryIdandIndex( 105 | _queryId, 106 | _middle - 1 107 | ); 108 | if (_prevTime <= _timestamp) { 109 | // candidate found, check for disputes 110 | _search = false; 111 | } else { 112 | // look from start to middle -1(prev value) 113 | _end = _middle - 1; 114 | } 115 | } else { 116 | // get immediate next value 117 | uint256 _nextTime = _getTimestampbyQueryIdandIndex( 118 | _queryId, 119 | _middle + 1 120 | ); 121 | if (_nextTime > _timestamp) { 122 | // candidate found, check for disputes 123 | _search = false; 124 | _middle++; 125 | _timestampRetrieved = _nextTime; 126 | } else { 127 | // look from middle + 1(next value) to end 128 | _start = _middle + 1; 129 | } 130 | } 131 | } 132 | // candidate found, check for disputed values 133 | if (!_isInDispute(_queryId, _timestampRetrieved)) { 134 | // _timestampRetrieved is correct 135 | return (true, _middle); 136 | } else { 137 | // iterate forward until we find a non-disputed value 138 | while ( 139 | _isInDispute(_queryId, _timestampRetrieved) && _middle < _count 140 | ) { 141 | _middle++; 142 | _timestampRetrieved = _getTimestampbyQueryIdandIndex( 143 | _queryId, 144 | _middle 145 | ); 146 | } 147 | if ( 148 | _middle == _count && _isInDispute(_queryId, _timestampRetrieved) 149 | ) { 150 | return (false, 0); 151 | } 152 | // _timestampRetrieved is correct 153 | return (true, _middle); 154 | } 155 | } 156 | 157 | /** 158 | * @dev Retrieves latest array index of data before the specified timestamp for the queryId 159 | * @param _queryId is the queryId to look up the index for 160 | * @param _timestamp is the timestamp before which to search for the latest index 161 | * @return _found whether the index was found 162 | * @return _index the latest index found before the specified timestamp 163 | */ 164 | // slither-disable-next-line calls-loop 165 | function _getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) 166 | internal 167 | view 168 | returns (bool _found, uint256 _index) 169 | { 170 | return tellor.getIndexForDataBefore(_queryId, _timestamp); 171 | } 172 | 173 | /** 174 | * @dev Retrieves multiple uint256 values before the specified timestamp 175 | * @param _queryId the unique id of the data query 176 | * @param _timestamp the timestamp before which to search for values 177 | * @param _maxAge the maximum number of seconds before the _timestamp to search for values 178 | * @param _maxCount the maximum number of values to return 179 | * @return _values the values retrieved, ordered from oldest to newest 180 | * @return _timestamps the timestamps of the values retrieved 181 | */ 182 | function _getMultipleValuesBefore( 183 | bytes32 _queryId, 184 | uint256 _timestamp, 185 | uint256 _maxAge, 186 | uint256 _maxCount 187 | ) 188 | internal 189 | view 190 | returns (bytes[] memory _values, uint256[] memory _timestamps) 191 | { 192 | // get index of first possible value 193 | (bool _ifRetrieve, uint256 _startIndex) = _getIndexForDataAfter( 194 | _queryId, 195 | _timestamp - _maxAge 196 | ); 197 | // no value within range 198 | if (!_ifRetrieve) { 199 | return (new bytes[](0), new uint256[](0)); 200 | } 201 | uint256 _endIndex; 202 | // get index of last possible value 203 | (_ifRetrieve, _endIndex) = _getIndexForDataBefore(_queryId, _timestamp); 204 | // no value before _timestamp 205 | if (!_ifRetrieve) { 206 | return (new bytes[](0), new uint256[](0)); 207 | } 208 | uint256 _valCount = 0; 209 | uint256 _index = 0; 210 | uint256[] memory _timestampsArrayTemp = new uint256[](_maxCount); 211 | // generate array of non-disputed timestamps within range 212 | while (_valCount < _maxCount && _endIndex + 1 - _index > _startIndex) { 213 | uint256 _timestampRetrieved = _getTimestampbyQueryIdandIndex( 214 | _queryId, 215 | _endIndex - _index 216 | ); 217 | if (!_isInDispute(_queryId, _timestampRetrieved)) { 218 | _timestampsArrayTemp[_valCount] = _timestampRetrieved; 219 | _valCount++; 220 | } 221 | _index++; 222 | } 223 | 224 | bytes[] memory _valuesArray = new bytes[](_valCount); 225 | uint256[] memory _timestampsArray = new uint256[](_valCount); 226 | // retrieve values and reverse timestamps order 227 | for (uint256 _i = 0; _i < _valCount; _i++) { 228 | _timestampsArray[_i] = _timestampsArrayTemp[_valCount - 1 - _i]; 229 | _valuesArray[_i] = _retrieveData(_queryId, _timestampsArray[_i]); 230 | } 231 | return (_valuesArray, _timestampsArray); 232 | } 233 | 234 | /** 235 | * @dev Counts the number of values that have been submitted for the queryId 236 | * @param _queryId the id to look up 237 | * @return uint256 count of the number of values received for the queryId 238 | */ 239 | function _getNewValueCountbyQueryId(bytes32 _queryId) 240 | internal 241 | view 242 | returns (uint256) 243 | { 244 | return tellor.getNewValueCountbyQueryId(_queryId); 245 | } 246 | 247 | /** 248 | * @dev Returns the address of the reporter who submitted a value for a data ID at a specific time 249 | * @param _queryId is ID of the specific data feed 250 | * @param _timestamp is the timestamp to find a corresponding reporter for 251 | * @return address of the reporter who reported the value for the data ID at the given timestamp 252 | */ 253 | function _getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) 254 | internal 255 | view 256 | returns (address) 257 | { 258 | return tellor.getReporterByTimestamp(_queryId, _timestamp); 259 | } 260 | 261 | /** 262 | * @dev Gets the timestamp for the value based on their index 263 | * @param _queryId is the id to look up 264 | * @param _index is the value index to look up 265 | * @return uint256 timestamp 266 | */ 267 | function _getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) 268 | internal 269 | view 270 | returns (uint256) 271 | { 272 | return tellor.getTimestampbyQueryIdandIndex(_queryId, _index); 273 | } 274 | 275 | /** 276 | * @dev Determines whether a value with a given queryId and timestamp has been disputed 277 | * @param _queryId is the value id to look up 278 | * @param _timestamp is the timestamp of the value to look up 279 | * @return bool true if queryId/timestamp is under dispute 280 | */ 281 | function _isInDispute(bytes32 _queryId, uint256 _timestamp) 282 | internal 283 | view 284 | returns (bool) 285 | { 286 | return tellor.isInDispute(_queryId, _timestamp); 287 | } 288 | 289 | /** 290 | * @dev Retrieve value from oracle based on queryId/timestamp 291 | * @param _queryId being requested 292 | * @param _timestamp to retrieve data/value from 293 | * @return bytes value for query/timestamp submitted 294 | */ 295 | function _retrieveData(bytes32 _queryId, uint256 _timestamp) 296 | internal 297 | view 298 | returns (bytes memory) 299 | { 300 | return tellor.retrieveData(_queryId, _timestamp); 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /contracts/interface/ITellor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.0; 3 | 4 | interface ITellor { 5 | function getNewValueCountbyQueryId(bytes32 _queryId) external view returns (uint256); 6 | function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) external view returns (uint256); 7 | function retrieveData(bytes32 _queryId, uint256 _timestamp) external view returns (bytes memory); 8 | function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) external view returns (address); 9 | function getDataBefore(bytes32 _queryId, uint256 _timestamp) external view returns(bool _ifRetrieve, bytes memory _value, uint256 _timestampRetrieved); 10 | function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) external view returns (bool _found, uint256 _index); 11 | function isInDispute(bytes32 _queryId, uint256 _timestamp) external view returns (bool); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/mocks/BenchUsingTellor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.8.0; 3 | 4 | import "../UsingTellor.sol"; 5 | 6 | /** 7 | * @title UserContract 8 | * This contract inherits UsingTellor for simulating user interaction 9 | */ 10 | contract BenchUsingTellor is UsingTellor { 11 | constructor(address payable _tellor) UsingTellor(_tellor) {} 12 | 13 | function getDataAfter(bytes32 _queryId, uint256 _timestamp) 14 | external 15 | view 16 | returns (bytes memory _value, uint256 _timestampRetrieved) 17 | { 18 | return _getDataAfter(_queryId, _timestamp); 19 | } 20 | 21 | function getDataBefore(bytes32 _queryId, uint256 _timestamp) 22 | external 23 | view 24 | returns (bytes memory _value, uint256 _timestampRetrieved) 25 | { 26 | return _getDataBefore(_queryId, _timestamp); 27 | } 28 | 29 | function getIndexForDataAfter(bytes32 _queryId, uint256 _timestamp) 30 | external 31 | view 32 | returns (bool _found, uint256 _index) 33 | { 34 | return _getIndexForDataAfter(_queryId, _timestamp); 35 | } 36 | 37 | function getIndexForDataBefore(bytes32 _queryId, uint256 _timestamp) 38 | external 39 | view 40 | returns (bool _found, uint256 _index) 41 | { 42 | return _getIndexForDataBefore(_queryId, _timestamp); 43 | } 44 | 45 | function getMultipleValuesBefore( 46 | bytes32 _queryId, 47 | uint256 _timestamp, 48 | uint256 _maxAge, 49 | uint256 _maxCount 50 | ) 51 | external 52 | view 53 | returns (bytes[] memory _values, uint256[] memory _timestamps) 54 | { 55 | return _getMultipleValuesBefore(_queryId, _timestamp, _maxAge, _maxCount); 56 | } 57 | 58 | function getNewValueCountbyQueryId(bytes32 _queryId) 59 | external 60 | view 61 | returns (uint256) 62 | { 63 | return _getNewValueCountbyQueryId(_queryId); 64 | } 65 | 66 | function getReporterByTimestamp(bytes32 _queryId, uint256 _timestamp) 67 | external 68 | view 69 | returns (address) 70 | { 71 | return _getReporterByTimestamp(_queryId, _timestamp); 72 | } 73 | 74 | function getTimestampbyQueryIdandIndex(bytes32 _queryId, uint256 _index) 75 | external 76 | view 77 | returns (uint256) 78 | { 79 | return _getTimestampbyQueryIdandIndex(_queryId, _index); 80 | } 81 | 82 | function isInDispute(bytes32 _queryId, uint256 _timestamp) 83 | external 84 | view 85 | returns (bool) 86 | { 87 | return _isInDispute(_queryId, _timestamp); 88 | } 89 | 90 | function retrieveData(bytes32 _queryId, uint256 _timestamp) 91 | external 92 | view 93 | returns (bytes memory) 94 | { 95 | return _retrieveData(_queryId, _timestamp); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /contracts/testing/ImporterContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | import { TellorFlex } from "tellorflex/contracts/TellorFlex.sol"; 4 | import { Governance } from "polygongovernance/contracts/Governance.sol"; 5 | 6 | pragma solidity 0.8.3; 7 | 8 | contract ImporterContract {} -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type import('hardhat/config').HardhatUserConfig 3 | */ 4 | require("@nomiclabs/hardhat-waffle"); 5 | require("@nomiclabs/hardhat-ethers"); 6 | 7 | module.exports = { 8 | solidity: { 9 | compilers: [ 10 | { 11 | version: "0.8.3", 12 | settings: { 13 | optimizer: { 14 | enabled: true, 15 | runs: 300 16 | } 17 | } 18 | } 19 | ] 20 | }, 21 | networks: { 22 | hardhat: { 23 | }, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "usingtellor", 3 | "version": "5.0.5", 4 | "main": "hardhat.config.js", 5 | "directories": { 6 | "test": "test" 7 | }, 8 | "devDependencies": { 9 | "@nomiclabs/hardhat-ethers": "^2.0.5", 10 | "@nomiclabs/hardhat-waffle": "^2.0.6", 11 | "babel-eslint": "^10.1.0", 12 | "chai": "^4.3.6", 13 | "eslint": "^8.10.0", 14 | "ethereum-waffle": "^4.0.10", 15 | "ethers": "^5.6.0", 16 | "ethlint": "^1.2.5", 17 | "hardhat": "2.11.2", 18 | "prettier": "^2.6.2", 19 | "prettier-plugin-solidity": "^1.0.0-beta.19", 20 | "solc": "^0.8.12", 21 | "solium": "^1.2.5" 22 | }, 23 | "dependencies": { 24 | "dotenv": "^16.0.1", 25 | "eth-json-rpc-filters": "^4.2.2", 26 | "ethereumjs-tx": "^2.1.2", 27 | "polygongovernance": "github:tellor-io/governance", 28 | "tellorflex": "github:tellor-io/tellorFlex" 29 | }, 30 | "scripts": { 31 | "test": "npx hardhat test" 32 | }, 33 | "repository": { 34 | "type": "git", 35 | "url": "https://github.com/tellor-io/usingtellor" 36 | }, 37 | "author": "Tellor", 38 | "license": "MIT", 39 | "homepage": "https://github.com/tellor-io/usingtellor" 40 | } 41 | -------------------------------------------------------------------------------- /test/e2eTests-UsingTellor.js: -------------------------------------------------------------------------------- 1 | const { expect, assert } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | const h = require("./helpers/helpers"); 4 | let abiCoder = new ethers.utils.AbiCoder 5 | 6 | const QUERY_DATA_1 = h.uintTob32(1); 7 | const QUERY_ID_1 = h.hash(QUERY_DATA_1); 8 | 9 | describe("UsingTellor E2E Tests", function() { 10 | 11 | let bench 12 | let oracle, gov, token 13 | let mappingContract; 14 | let owner, addr0, addr1, addr2; 15 | 16 | const abiCoder = new ethers.utils.AbiCoder(); 17 | const TRB_QUERY_DATA_ARGS = abiCoder.encode(['string', 'string'], ['trb', 'usd']); 18 | const TRB_QUERY_DATA = abiCoder.encode(['string', 'bytes'], ['SpotPrice', TRB_QUERY_DATA_ARGS]); 19 | const TRB_QUERY_ID = ethers.utils.keccak256(TRB_QUERY_DATA); 20 | 21 | beforeEach(async function () { 22 | [owner, addr1, addr2] = await ethers.getSigners(); 23 | 24 | const TellorPlayground = await ethers.getContractFactory("TellorPlayground"); 25 | token = await TellorPlayground.deploy(); 26 | await token.deployed(); 27 | 28 | const TellorFlex = await ethers.getContractFactory("TellorFlex"); 29 | oracle = await TellorFlex.deploy(token.address, 86400/2, h.toWei("15"), h.toWei("1500"), h.toWei(".001"), TRB_QUERY_ID); 30 | 31 | const Governance = await ethers.getContractFactory("Governance"); 32 | gov = await Governance.deploy(oracle.address, owner.address); 33 | await gov.deployed(); 34 | 35 | await oracle.init(gov.address); 36 | 37 | const BenchUsingTellor = await ethers.getContractFactory("BenchUsingTellor"); 38 | bench = await BenchUsingTellor.deploy(oracle.address); 39 | await bench.deployed(); 40 | 41 | // stake 42 | await token.connect(addr1).approve(oracle.address, h.toWei("10000")); 43 | await token.connect(addr2).approve(oracle.address, h.toWei("10000")); 44 | for(i=0; i<10; i++) { 45 | await token.faucet(addr1.address) 46 | await token.faucet(addr2.address) 47 | } 48 | await oracle.connect(addr1).depositStake(h.toWei("10000")); 49 | await oracle.connect(addr2).depositStake(h.toWei("10000")); 50 | 51 | await token.faucet(owner.address) 52 | await token.connect(owner).approve(gov.address, h.toWei("10000")); 53 | }); 54 | 55 | it("getDataAfter without disputes", async function() { 56 | // setup 57 | let queryData1 = h.uintTob32(1); 58 | let queryId1 = h.hash(queryData1); 59 | 60 | // no data 61 | dataRetrieved = await bench.getDataAfter(queryId1,1) 62 | expect(dataRetrieved[0]).to.equal('0x') 63 | expect(dataRetrieved[1]).to.equal(0) 64 | 65 | 66 | // one data point 67 | await oracle.connect(addr1).submitValue(queryId1,150,0,queryData1) 68 | blocky1 = await h.getBlock() 69 | 70 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp - 1) 71 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 72 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 73 | 74 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp) 75 | expect(dataRetrieved[0]).to.equal('0x') 76 | expect(dataRetrieved[1]).to.equal(0) 77 | 78 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp + 1) 79 | expect(dataRetrieved[0]).to.equal('0x') 80 | expect(dataRetrieved[1]).to.equal(0) 81 | 82 | 83 | // two data points 84 | await h.advanceTime(10) 85 | await oracle.connect(addr1).submitValue(queryId1,160,1,queryData1) 86 | blocky2 = await h.getBlock() 87 | 88 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp - 1) 89 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 90 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 91 | 92 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp) 93 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 94 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 95 | 96 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp + 1) 97 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 98 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 99 | 100 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp) 101 | expect(dataRetrieved[0]).to.equal('0x') 102 | expect(dataRetrieved[1]).to.equal(0) 103 | 104 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp + 1) 105 | expect(dataRetrieved[0]).to.equal('0x') 106 | expect(dataRetrieved[1]).to.equal(0) 107 | 108 | 109 | // three data points 110 | await h.advanceTime(10) 111 | await oracle.connect(addr1).submitValue(queryId1,170,2,queryData1) 112 | blocky3 = await h.getBlock() 113 | 114 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp - 1) 115 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 116 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 117 | 118 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp) 119 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 120 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 121 | 122 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp + 1) 123 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 124 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 125 | 126 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp) 127 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 128 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 129 | 130 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp + 1) 131 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 132 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 133 | 134 | dataRetrieved = await bench.getDataAfter(queryId1,blocky3.timestamp) 135 | expect(dataRetrieved[0]).to.equal('0x') 136 | expect(dataRetrieved[1]).to.equal(0) 137 | 138 | dataRetrieved = await bench.getDataAfter(queryId1,blocky3.timestamp + 1) 139 | expect(dataRetrieved[0]).to.equal('0x') 140 | expect(dataRetrieved[1]).to.equal(0) 141 | 142 | 143 | // four data points 144 | await h.advanceTime(10) 145 | await oracle.connect(addr1).submitValue(queryId1,180,3,queryData1) 146 | blocky4 = await h.getBlock() 147 | 148 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp - 1) 149 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 150 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 151 | 152 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp) 153 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 154 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 155 | 156 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp + 1) 157 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 158 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 159 | 160 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp) 161 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 162 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 163 | 164 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp + 1) 165 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 166 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 167 | 168 | dataRetrieved = await bench.getDataAfter(queryId1,blocky3.timestamp) 169 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 170 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 171 | 172 | dataRetrieved = await bench.getDataAfter(queryId1,blocky3.timestamp + 1) 173 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 174 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 175 | 176 | dataRetrieved = await bench.getDataAfter(queryId1,blocky4.timestamp) 177 | expect(dataRetrieved[0]).to.equal('0x') 178 | expect(dataRetrieved[1]).to.equal(0) 179 | 180 | dataRetrieved = await bench.getDataAfter(queryId1,blocky4.timestamp + 1) 181 | expect(dataRetrieved[0]).to.equal('0x') 182 | expect(dataRetrieved[1]).to.equal(0) 183 | 184 | 185 | // five data points 186 | await h.advanceTime(10) 187 | await oracle.connect(addr1).submitValue(queryId1,190,4,queryData1) 188 | blocky5 = await h.getBlock() 189 | 190 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp - 1) 191 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 192 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 193 | 194 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp) 195 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 196 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 197 | 198 | dataRetrieved = await bench.getDataAfter(queryId1,blocky1.timestamp + 1) 199 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 200 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 201 | 202 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp) 203 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 204 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 205 | 206 | dataRetrieved = await bench.getDataAfter(queryId1,blocky2.timestamp + 1) 207 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 208 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 209 | 210 | dataRetrieved = await bench.getDataAfter(queryId1,blocky3.timestamp) 211 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 212 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 213 | 214 | dataRetrieved = await bench.getDataAfter(queryId1,blocky3.timestamp + 1) 215 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 216 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 217 | 218 | dataRetrieved = await bench.getDataAfter(queryId1,blocky4.timestamp) 219 | expect(dataRetrieved[0]).to.equal(h.bytes(190)) 220 | expect(dataRetrieved[1]).to.equal(blocky5.timestamp) 221 | 222 | dataRetrieved = await bench.getDataAfter(queryId1,blocky4.timestamp + 1) 223 | expect(dataRetrieved[0]).to.equal(h.bytes(190)) 224 | expect(dataRetrieved[1]).to.equal(blocky5.timestamp) 225 | 226 | dataRetrieved = await bench.getDataAfter(queryId1,blocky5.timestamp) 227 | expect(dataRetrieved[0]).to.equal('0x') 228 | expect(dataRetrieved[1]).to.equal(0) 229 | }) 230 | 231 | it("getDataAfter, one disputed data point", async function() { 232 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 150, 0, QUERY_DATA_1) 233 | blocky1 = await h.getBlock() 234 | await gov.beginDispute(QUERY_ID_1, blocky1.timestamp) 235 | 236 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp - 1) 237 | expect(dataRetrieved[0]).to.equal('0x') 238 | expect(dataRetrieved[1]).to.equal(0) 239 | 240 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp) 241 | expect(dataRetrieved[0]).to.equal('0x') 242 | expect(dataRetrieved[1]).to.equal(0) 243 | 244 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp + 1) 245 | expect(dataRetrieved[0]).to.equal('0x') 246 | expect(dataRetrieved[1]).to.equal(0) 247 | }) 248 | 249 | it("getDataAfter, 2 values, one dispute", async function() { 250 | // disputed, non-disputed 251 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 150, 0, QUERY_DATA_1) 252 | blocky1 = await h.getBlock() 253 | 254 | await h.advanceTime(10) 255 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 160, 1, QUERY_DATA_1) 256 | blocky2 = await h.getBlock() 257 | 258 | await gov.beginDispute(QUERY_ID_1, blocky1.timestamp) 259 | 260 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp - 1) 261 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 262 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 263 | 264 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp) 265 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 266 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 267 | 268 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp + 1) 269 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 270 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 271 | 272 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp) 273 | expect(dataRetrieved[0]).to.equal('0x') 274 | expect(dataRetrieved[1]).to.equal(0) 275 | 276 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp + 1) 277 | expect(dataRetrieved[0]).to.equal('0x') 278 | expect(dataRetrieved[1]).to.equal(0) 279 | 280 | 281 | // non-disputed, disputed 282 | let queryData2 = h.uintTob32(2) 283 | let queryId2 = h.hash(queryData2) 284 | 285 | await oracle.connect(addr2).submitValue(queryId2, 150, 0, queryData2) 286 | blocky1 = await h.getBlock() 287 | 288 | await oracle.connect(addr2).submitValue(queryId2, 160, 1, queryData2) 289 | blocky2 = await h.getBlock() 290 | 291 | await gov.beginDispute(queryId2, blocky2.timestamp) 292 | 293 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp - 1) 294 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 295 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 296 | 297 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp) 298 | expect(dataRetrieved[0]).to.equal('0x') 299 | expect(dataRetrieved[1]).to.equal(0) 300 | 301 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp + 1) 302 | expect(dataRetrieved[0]).to.equal('0x') 303 | expect(dataRetrieved[1]).to.equal(0) 304 | 305 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp) 306 | expect(dataRetrieved[0]).to.equal('0x') 307 | expect(dataRetrieved[1]).to.equal(0) 308 | 309 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp + 1) 310 | expect(dataRetrieved[0]).to.equal('0x') 311 | expect(dataRetrieved[1]).to.equal(0) 312 | }) 313 | 314 | it("getDataAfter, 3 values, 1 dispute", async function() { 315 | // disputed, non-disputed, non-disputed 316 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 150, 0, QUERY_DATA_1) 317 | blocky1 = await h.getBlock() 318 | 319 | await h.advanceTime(10) 320 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 160, 1, QUERY_DATA_1) 321 | blocky2 = await h.getBlock() 322 | 323 | await h.advanceTime(10) 324 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 170, 2, QUERY_DATA_1) 325 | blocky3 = await h.getBlock() 326 | 327 | await gov.beginDispute(QUERY_ID_1, blocky1.timestamp) 328 | 329 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp - 1) 330 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 331 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 332 | 333 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp) 334 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 335 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 336 | 337 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp + 1) 338 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 339 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 340 | 341 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp) 342 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 343 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 344 | 345 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp + 1) 346 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 347 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 348 | 349 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky3.timestamp) 350 | expect(dataRetrieved[0]).to.equal('0x') 351 | expect(dataRetrieved[1]).to.equal(0) 352 | 353 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky3.timestamp + 1) 354 | expect(dataRetrieved[0]).to.equal('0x') 355 | expect(dataRetrieved[1]).to.equal(0) 356 | 357 | 358 | // non-disputed, disputed, non-disputed 359 | let queryData2 = h.uintTob32(2) 360 | let queryId2 = h.hash(queryData2) 361 | 362 | await oracle.connect(addr2).submitValue(queryId2, 150, 0, queryData2) 363 | blocky1 = await h.getBlock() 364 | 365 | await h.advanceTime(10) 366 | await oracle.connect(addr2).submitValue(queryId2, 160, 1, queryData2) 367 | blocky2 = await h.getBlock() 368 | 369 | await h.advanceTime(10) 370 | await oracle.connect(addr2).submitValue(queryId2, 170, 2, queryData2) 371 | blocky3 = await h.getBlock() 372 | 373 | await gov.beginDispute(queryId2, blocky2.timestamp) 374 | 375 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp - 1) 376 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 377 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 378 | 379 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp) 380 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 381 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 382 | 383 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp + 1) 384 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 385 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 386 | 387 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp) 388 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 389 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 390 | 391 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp + 1) 392 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 393 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 394 | 395 | dataRetrieved = await bench.getDataAfter(queryId2, blocky3.timestamp) 396 | expect(dataRetrieved[0]).to.equal('0x') 397 | expect(dataRetrieved[1]).to.equal(0) 398 | 399 | dataRetrieved = await bench.getDataAfter(queryId2, blocky3.timestamp + 1) 400 | expect(dataRetrieved[0]).to.equal('0x') 401 | expect(dataRetrieved[1]).to.equal(0) 402 | 403 | 404 | // non-disputed, non-disputed, disputed 405 | let queryData3 = h.uintTob32(3) 406 | let queryId3 = h.hash(queryData3) 407 | 408 | await oracle.connect(addr2).submitValue(queryId3, 150, 0, queryData3) 409 | blocky1 = await h.getBlock() 410 | 411 | await h.advanceTime(10) 412 | await oracle.connect(addr2).submitValue(queryId3, 160, 1, queryData3) 413 | blocky2 = await h.getBlock() 414 | 415 | await h.advanceTime(10) 416 | await oracle.connect(addr2).submitValue(queryId3, 170, 2, queryData3) 417 | blocky3 = await h.getBlock() 418 | 419 | await gov.beginDispute(queryId3, blocky3.timestamp) 420 | 421 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp - 1) 422 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 423 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 424 | 425 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp) 426 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 427 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 428 | 429 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp + 1) 430 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 431 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 432 | 433 | dataRetrieved = await bench.getDataAfter(queryId3, blocky2.timestamp) 434 | expect(dataRetrieved[0]).to.equal('0x') 435 | expect(dataRetrieved[1]).to.equal(0) 436 | 437 | dataRetrieved = await bench.getDataAfter(queryId3, blocky2.timestamp + 1) 438 | expect(dataRetrieved[0]).to.equal('0x') 439 | expect(dataRetrieved[1]).to.equal(0) 440 | 441 | dataRetrieved = await bench.getDataAfter(queryId3, blocky3.timestamp) 442 | expect(dataRetrieved[0]).to.equal('0x') 443 | expect(dataRetrieved[1]).to.equal(0) 444 | 445 | dataRetrieved = await bench.getDataAfter(queryId3, blocky3.timestamp + 1) 446 | expect(dataRetrieved[0]).to.equal('0x') 447 | expect(dataRetrieved[1]).to.equal(0) 448 | }) 449 | 450 | it("getDataAfter, 3 values, 2 to 3 disputes", async function() { 451 | // disputed, disputed, non-disputed 452 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 150, 0, h.uintTob32(1)) 453 | blocky1 = await h.getBlock() 454 | 455 | await h.advanceTime(10) 456 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 160, 1, h.uintTob32(1)) 457 | blocky2 = await h.getBlock() 458 | 459 | await h.advanceTime(10) 460 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 170, 2, h.uintTob32(1)) 461 | blocky3 = await h.getBlock() 462 | 463 | await gov.beginDispute(QUERY_ID_1, blocky1.timestamp) 464 | await gov.beginDispute(QUERY_ID_1, blocky2.timestamp) 465 | 466 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp - 1) 467 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 468 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 469 | 470 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp) 471 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 472 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 473 | 474 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp + 1) 475 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 476 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 477 | 478 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp) 479 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 480 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 481 | 482 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp + 1) 483 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 484 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 485 | 486 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky3.timestamp) 487 | expect(dataRetrieved[0]).to.equal('0x') 488 | expect(dataRetrieved[1]).to.equal(0) 489 | 490 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky3.timestamp + 1) 491 | expect(dataRetrieved[0]).to.equal('0x') 492 | expect(dataRetrieved[1]).to.equal(0) 493 | 494 | 495 | // disputed, non-disputed, disputed 496 | queryData2 = h.uintTob32(2) 497 | queryId2 = h.hash(queryData2) 498 | await oracle.connect(addr2).submitValue(queryId2, 150, 0, queryData2) 499 | blocky1 = await h.getBlock() 500 | 501 | await h.advanceTime(10) 502 | await oracle.connect(addr2).submitValue(queryId2, 160, 1, queryData2) 503 | blocky2 = await h.getBlock() 504 | 505 | await h.advanceTime(10) 506 | await oracle.connect(addr2).submitValue(queryId2, 170, 2, queryData2) 507 | blocky3 = await h.getBlock() 508 | 509 | await gov.beginDispute(queryId2, blocky1.timestamp) 510 | await gov.beginDispute(queryId2, blocky3.timestamp) 511 | 512 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp - 1) 513 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 514 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 515 | 516 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp) 517 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 518 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 519 | 520 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp + 1) 521 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 522 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 523 | 524 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp) 525 | expect(dataRetrieved[0]).to.equal('0x') 526 | expect(dataRetrieved[1]).to.equal(0) 527 | 528 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp + 1) 529 | expect(dataRetrieved[0]).to.equal('0x') 530 | expect(dataRetrieved[1]).to.equal(0) 531 | 532 | dataRetrieved = await bench.getDataAfter(queryId2, blocky3.timestamp) 533 | expect(dataRetrieved[0]).to.equal('0x') 534 | expect(dataRetrieved[1]).to.equal(0) 535 | 536 | dataRetrieved = await bench.getDataAfter(queryId2, blocky3.timestamp + 1) 537 | expect(dataRetrieved[0]).to.equal('0x') 538 | expect(dataRetrieved[1]).to.equal(0) 539 | 540 | 541 | // non-disputed, disputed, disputed 542 | queryData3 = h.uintTob32(3) 543 | queryId3 = h.hash(queryData3) 544 | 545 | await oracle.connect(addr2).submitValue(queryId3, 150, 0, queryData3) 546 | blocky1 = await h.getBlock() 547 | 548 | await h.advanceTime(10) 549 | await oracle.connect(addr2).submitValue(queryId3, 160, 1, queryData3) 550 | blocky2 = await h.getBlock() 551 | 552 | await h.advanceTime(10) 553 | await oracle.connect(addr2).submitValue(queryId3, 170, 2, queryData3) 554 | blocky3 = await h.getBlock() 555 | 556 | await gov.beginDispute(queryId3, blocky2.timestamp) 557 | await gov.beginDispute(queryId3, blocky3.timestamp) 558 | 559 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp - 1) 560 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 561 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 562 | 563 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp) 564 | expect(dataRetrieved[0]).to.equal('0x') 565 | expect(dataRetrieved[1]).to.equal(0) 566 | 567 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp + 1) 568 | expect(dataRetrieved[0]).to.equal('0x') 569 | expect(dataRetrieved[1]).to.equal(0) 570 | 571 | dataRetrieved = await bench.getDataAfter(queryId3, blocky2.timestamp) 572 | expect(dataRetrieved[0]).to.equal('0x') 573 | expect(dataRetrieved[1]).to.equal(0) 574 | 575 | dataRetrieved = await bench.getDataAfter(queryId3, blocky2.timestamp + 1) 576 | expect(dataRetrieved[0]).to.equal('0x') 577 | expect(dataRetrieved[1]).to.equal(0) 578 | 579 | dataRetrieved = await bench.getDataAfter(queryId3, blocky3.timestamp) 580 | expect(dataRetrieved[0]).to.equal('0x') 581 | expect(dataRetrieved[1]).to.equal(0) 582 | 583 | dataRetrieved = await bench.getDataAfter(queryId3, blocky3.timestamp + 1) 584 | expect(dataRetrieved[0]).to.equal('0x') 585 | expect(dataRetrieved[1]).to.equal(0) 586 | 587 | 588 | // disputed, disputed, disputed 589 | await gov.beginDispute(queryId3, blocky1.timestamp) 590 | 591 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp - 1) 592 | expect(dataRetrieved[0]).to.equal('0x') 593 | expect(dataRetrieved[1]).to.equal(0) 594 | 595 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp) 596 | expect(dataRetrieved[0]).to.equal('0x') 597 | expect(dataRetrieved[1]).to.equal(0) 598 | 599 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp + 1) 600 | expect(dataRetrieved[0]).to.equal('0x') 601 | expect(dataRetrieved[1]).to.equal(0) 602 | }) 603 | 604 | it("getDataAfter, 4 values, 1 dispute", async function() { 605 | // disputed, non-disputed, non-disputed, non-disputed 606 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 150, 0, QUERY_DATA_1) 607 | blocky1 = await h.getBlock() 608 | 609 | await h.advanceTime(10) 610 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 160, 1, QUERY_DATA_1) 611 | blocky2 = await h.getBlock() 612 | 613 | await h.advanceTime(10) 614 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 170, 2, QUERY_DATA_1) 615 | blocky3 = await h.getBlock() 616 | 617 | await h.advanceTime(10) 618 | await oracle.connect(addr2).submitValue(QUERY_ID_1, 180, 3, QUERY_DATA_1) 619 | blocky4 = await h.getBlock() 620 | 621 | await gov.beginDispute(QUERY_ID_1, blocky1.timestamp) 622 | 623 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp - 1) 624 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 625 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 626 | 627 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp) 628 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 629 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 630 | 631 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky1.timestamp + 1) 632 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 633 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 634 | 635 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp) 636 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 637 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 638 | 639 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky2.timestamp + 1) 640 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 641 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 642 | 643 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky3.timestamp) 644 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 645 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 646 | 647 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky3.timestamp + 1) 648 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 649 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 650 | 651 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky4.timestamp) 652 | expect(dataRetrieved[0]).to.equal('0x') 653 | expect(dataRetrieved[1]).to.equal(0) 654 | 655 | dataRetrieved = await bench.getDataAfter(QUERY_ID_1, blocky4.timestamp + 1) 656 | expect(dataRetrieved[0]).to.equal('0x') 657 | expect(dataRetrieved[1]).to.equal(0) 658 | 659 | 660 | // non-disputed, disputed, non-disputed, non-disputed 661 | queryData2 = h.uintTob32(2) 662 | queryId2 = h.hash(queryData2) 663 | 664 | await oracle.connect(addr2).submitValue(queryId2, 150, 0, queryData2) 665 | blocky1 = await h.getBlock() 666 | 667 | await h.advanceTime(10) 668 | await oracle.connect(addr2).submitValue(queryId2, 160, 1, queryData2) 669 | blocky2 = await h.getBlock() 670 | 671 | await h.advanceTime(10) 672 | await oracle.connect(addr2).submitValue(queryId2, 170, 2, queryData2) 673 | blocky3 = await h.getBlock() 674 | 675 | await h.advanceTime(10) 676 | await oracle.connect(addr2).submitValue(queryId2, 180, 3, queryData2) 677 | blocky4 = await h.getBlock() 678 | 679 | await gov.beginDispute(queryId2, blocky2.timestamp) 680 | 681 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp - 1) 682 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 683 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 684 | 685 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp) 686 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 687 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 688 | 689 | dataRetrieved = await bench.getDataAfter(queryId2, blocky1.timestamp + 1) 690 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 691 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 692 | 693 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp) 694 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 695 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 696 | 697 | dataRetrieved = await bench.getDataAfter(queryId2, blocky2.timestamp + 1) 698 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 699 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 700 | 701 | dataRetrieved = await bench.getDataAfter(queryId2, blocky3.timestamp) 702 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 703 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 704 | 705 | dataRetrieved = await bench.getDataAfter(queryId2, blocky3.timestamp + 1) 706 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 707 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 708 | 709 | dataRetrieved = await bench.getDataAfter(queryId2, blocky4.timestamp) 710 | expect(dataRetrieved[0]).to.equal('0x') 711 | expect(dataRetrieved[1]).to.equal(0) 712 | 713 | dataRetrieved = await bench.getDataAfter(queryId2, blocky4.timestamp + 1) 714 | expect(dataRetrieved[0]).to.equal('0x') 715 | expect(dataRetrieved[1]).to.equal(0) 716 | 717 | 718 | // non-disputed, non-disputed, disputed, non-disputed 719 | queryData3 = h.uintTob32(3) 720 | queryId3 = h.hash(queryData3) 721 | 722 | await oracle.connect(addr2).submitValue(queryId3, 150, 0, queryData3) 723 | blocky1 = await h.getBlock() 724 | 725 | await h.advanceTime(10) 726 | await oracle.connect(addr2).submitValue(queryId3, 160, 1, queryData3) 727 | blocky2 = await h.getBlock() 728 | 729 | await h.advanceTime(10) 730 | await oracle.connect(addr2).submitValue(queryId3, 170, 2, queryData3) 731 | blocky3 = await h.getBlock() 732 | 733 | await h.advanceTime(10) 734 | await oracle.connect(addr2).submitValue(queryId3, 180, 3, queryData3) 735 | blocky4 = await h.getBlock() 736 | 737 | await gov.beginDispute(queryId3, blocky3.timestamp) 738 | 739 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp - 1) 740 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 741 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 742 | 743 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp) 744 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 745 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 746 | 747 | dataRetrieved = await bench.getDataAfter(queryId3, blocky1.timestamp + 1) 748 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 749 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 750 | 751 | dataRetrieved = await bench.getDataAfter(queryId3, blocky2.timestamp) 752 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 753 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 754 | 755 | dataRetrieved = await bench.getDataAfter(queryId3, blocky2.timestamp + 1) 756 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 757 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 758 | 759 | dataRetrieved = await bench.getDataAfter(queryId3, blocky3.timestamp) 760 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 761 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 762 | 763 | dataRetrieved = await bench.getDataAfter(queryId3, blocky3.timestamp + 1) 764 | expect(dataRetrieved[0]).to.equal(h.bytes(180)) 765 | expect(dataRetrieved[1]).to.equal(blocky4.timestamp) 766 | 767 | dataRetrieved = await bench.getDataAfter(queryId3, blocky4.timestamp) 768 | expect(dataRetrieved[0]).to.equal('0x') 769 | expect(dataRetrieved[1]).to.equal(0) 770 | 771 | dataRetrieved = await bench.getDataAfter(queryId3, blocky4.timestamp + 1) 772 | expect(dataRetrieved[0]).to.equal('0x') 773 | expect(dataRetrieved[1]).to.equal(0) 774 | 775 | 776 | // non-disputed, non-disputed, non-disputed, disputed 777 | queryData4 = h.uintTob32(4) 778 | queryId4 = h.hash(queryData4) 779 | 780 | await oracle.connect(addr2).submitValue(queryId4, 150, 0, queryData4) 781 | blocky1 = await h.getBlock() 782 | 783 | await h.advanceTime(10) 784 | await oracle.connect(addr2).submitValue(queryId4, 160, 1, queryData4) 785 | blocky2 = await h.getBlock() 786 | 787 | await h.advanceTime(10) 788 | await oracle.connect(addr2).submitValue(queryId4, 170, 2, queryData4) 789 | blocky3 = await h.getBlock() 790 | 791 | await h.advanceTime(10) 792 | await oracle.connect(addr2).submitValue(queryId4, 180, 3, queryData4) 793 | blocky4 = await h.getBlock() 794 | 795 | await gov.beginDispute(queryId4, blocky4.timestamp) 796 | 797 | dataRetrieved = await bench.getDataAfter(queryId4, blocky1.timestamp - 1) 798 | expect(dataRetrieved[0]).to.equal(h.bytes(150)) 799 | expect(dataRetrieved[1]).to.equal(blocky1.timestamp) 800 | 801 | dataRetrieved = await bench.getDataAfter(queryId4, blocky1.timestamp) 802 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 803 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 804 | 805 | dataRetrieved = await bench.getDataAfter(queryId4, blocky1.timestamp + 1) 806 | expect(dataRetrieved[0]).to.equal(h.bytes(160)) 807 | expect(dataRetrieved[1]).to.equal(blocky2.timestamp) 808 | 809 | dataRetrieved = await bench.getDataAfter(queryId4, blocky2.timestamp) 810 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 811 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 812 | 813 | dataRetrieved = await bench.getDataAfter(queryId4, blocky2.timestamp + 1) 814 | expect(dataRetrieved[0]).to.equal(h.bytes(170)) 815 | expect(dataRetrieved[1]).to.equal(blocky3.timestamp) 816 | 817 | dataRetrieved = await bench.getDataAfter(queryId4, blocky3.timestamp) 818 | expect(dataRetrieved[0]).to.equal('0x') 819 | expect(dataRetrieved[1]).to.equal(0) 820 | 821 | dataRetrieved = await bench.getDataAfter(queryId4, blocky3.timestamp + 1) 822 | expect(dataRetrieved[0]).to.equal('0x') 823 | expect(dataRetrieved[1]).to.equal(0) 824 | 825 | dataRetrieved = await bench.getDataAfter(queryId4, blocky4.timestamp) 826 | expect(dataRetrieved[0]).to.equal('0x') 827 | expect(dataRetrieved[1]).to.equal(0) 828 | 829 | dataRetrieved = await bench.getDataAfter(queryId4, blocky4.timestamp + 1) 830 | expect(dataRetrieved[0]).to.equal('0x') 831 | expect(dataRetrieved[1]).to.equal(0) 832 | }) 833 | 834 | it("getMultipleValuesBefore", async function() { 835 | // submit 4 values 836 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(150),0, TRB_QUERY_DATA) 837 | blocky1 = await h.getBlock() 838 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(160),0, TRB_QUERY_DATA) 839 | blocky2 = await h.getBlock() 840 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(170),0, TRB_QUERY_DATA) 841 | blocky3 = await h.getBlock() 842 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(180),0, TRB_QUERY_DATA) 843 | blocky4 = await h.getBlock() 844 | 845 | await h.advanceTime(10) 846 | blockyNow0 = await h.getBlock() 847 | 848 | // dispute 2nd value 849 | await gov.beginDispute(TRB_QUERY_ID, blocky2.timestamp) 850 | 851 | // check from blockyNow 852 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 4) 853 | expect(result[0].length).to.equal(3) 854 | expect(result[1].length).to.equal(3) 855 | expect(result[0][0]).to.equal(h.uintTob32(150)) 856 | expect(result[1][0]).to.equal(blocky1.timestamp) 857 | expect(result[0][1]).to.equal(h.uintTob32(170)) 858 | expect(result[1][1]).to.equal(blocky3.timestamp) 859 | expect(result[0][2]).to.equal(h.uintTob32(180)) 860 | expect(result[1][2]).to.equal(blocky4.timestamp) 861 | 862 | // check from blocky4 863 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky4.timestamp, 3600, 4) 864 | expect(result[0].length).to.equal(2) 865 | expect(result[1].length).to.equal(2) 866 | expect(result[0][0]).to.equal(h.uintTob32(150)) 867 | expect(result[1][0]).to.equal(blocky1.timestamp) 868 | expect(result[0][1]).to.equal(h.uintTob32(170)) 869 | expect(result[1][1]).to.equal(blocky3.timestamp) 870 | 871 | // check from blocky3 872 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky3.timestamp, 3600, 4) 873 | expect(result[0].length).to.equal(1) 874 | expect(result[1].length).to.equal(1) 875 | expect(result[0][0]).to.equal(h.uintTob32(150)) 876 | expect(result[1][0]).to.equal(blocky1.timestamp) 877 | 878 | // check from blocky2 879 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky2.timestamp, 3600, 4) 880 | expect(result[0].length).to.equal(1) 881 | expect(result[1].length).to.equal(1) 882 | expect(result[0][0]).to.equal(h.uintTob32(150)) 883 | expect(result[1][0]).to.equal(blocky1.timestamp) 884 | 885 | // check from blocky1 886 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky1.timestamp, 3600, 4) 887 | expect(result[0].length).to.equal(0) 888 | expect(result[1].length).to.equal(0) 889 | 890 | // dispute 3rd value 891 | await gov.beginDispute(TRB_QUERY_ID, blocky3.timestamp) 892 | 893 | // check from blockyNow 894 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 4) 895 | expect(result[0].length).to.equal(2) 896 | expect(result[1].length).to.equal(2) 897 | expect(result[0][0]).to.equal(h.uintTob32(150)) 898 | expect(result[1][0]).to.equal(blocky1.timestamp) 899 | expect(result[0][1]).to.equal(h.uintTob32(180)) 900 | expect(result[1][1]).to.equal(blocky4.timestamp) 901 | 902 | // check from blocky4 903 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky4.timestamp, 3600, 4) 904 | expect(result[0].length).to.equal(1) 905 | expect(result[1].length).to.equal(1) 906 | expect(result[0][0]).to.equal(h.uintTob32(150)) 907 | expect(result[1][0]).to.equal(blocky1.timestamp) 908 | 909 | // check from blocky3 910 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky3.timestamp, 3600, 4) 911 | expect(result[0].length).to.equal(1) 912 | expect(result[1].length).to.equal(1) 913 | expect(result[0][0]).to.equal(h.uintTob32(150)) 914 | expect(result[1][0]).to.equal(blocky1.timestamp) 915 | 916 | // check from blocky2 917 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky2.timestamp, 3600, 4) 918 | expect(result[0].length).to.equal(1) 919 | expect(result[1].length).to.equal(1) 920 | expect(result[0][0]).to.equal(h.uintTob32(150)) 921 | expect(result[1][0]).to.equal(blocky1.timestamp) 922 | 923 | // check from blocky1 924 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky1.timestamp, 3600, 4) 925 | expect(result[0].length).to.equal(0) 926 | expect(result[1].length).to.equal(0) 927 | }) 928 | }) -------------------------------------------------------------------------------- /test/functionTests-UsingTellor.js: -------------------------------------------------------------------------------- 1 | const { expect, assert } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | const h = require("./helpers/helpers"); 4 | let abiCoder = new ethers.utils.AbiCoder 5 | 6 | const precision = BigInt(1e18); 7 | const FAUCET_AMOUNT = BigInt(1000) * precision; 8 | const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; 9 | 10 | describe("UsingTellor Function Tests", function() { 11 | 12 | let bench 13 | let oracle, gov, token 14 | let mappingContract; 15 | let owner, addr0, addr1, addr2; 16 | 17 | const abiCoder = new ethers.utils.AbiCoder(); 18 | const TRB_QUERY_DATA_ARGS = abiCoder.encode(['string', 'string'], ['trb', 'usd']); 19 | const TRB_QUERY_DATA = abiCoder.encode(['string', 'bytes'], ['SpotPrice', TRB_QUERY_DATA_ARGS]); 20 | const TRB_QUERY_ID = ethers.utils.keccak256(TRB_QUERY_DATA); 21 | 22 | beforeEach(async function () { 23 | [owner, addr1, addr2] = await ethers.getSigners(); 24 | 25 | const TellorPlayground = await ethers.getContractFactory("TellorPlayground"); 26 | token = await TellorPlayground.deploy(); 27 | await token.deployed(); 28 | 29 | const TellorFlex = await ethers.getContractFactory("TellorFlex"); 30 | oracle = await TellorFlex.deploy(token.address, 86400/2, h.toWei("15"), h.toWei("1500"), h.toWei(".001"), TRB_QUERY_ID); 31 | 32 | const Governance = await ethers.getContractFactory("Governance"); 33 | gov = await Governance.deploy(oracle.address, owner.address); 34 | await gov.deployed(); 35 | 36 | await oracle.init(gov.address); 37 | 38 | const BenchUsingTellor = await ethers.getContractFactory("BenchUsingTellor"); 39 | bench = await BenchUsingTellor.deploy(oracle.address); 40 | await bench.deployed(); 41 | 42 | // stake 43 | await token.connect(addr1).approve(oracle.address, h.toWei("10000")); 44 | await token.connect(addr2).approve(oracle.address, h.toWei("10000")); 45 | for(i=0; i<10; i++) { 46 | await token.faucet(addr1.address) 47 | await token.faucet(addr2.address) 48 | } 49 | await oracle.connect(addr1).depositStake(h.toWei("10000")); 50 | await oracle.connect(addr2).depositStake(h.toWei("10000")); 51 | }); 52 | 53 | it("retrieveData()", async function() { 54 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 55 | blocky1 = await h.getBlock() 56 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,160,1,TRB_QUERY_DATA) 57 | blocky2 = await h.getBlock() 58 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,170,2,TRB_QUERY_DATA) 59 | blocky3 = await h.getBlock() 60 | expect(await bench.retrieveData(TRB_QUERY_ID, blocky1.timestamp)).to.equal(h.bytes(150)) 61 | expect(await bench.retrieveData(TRB_QUERY_ID, blocky2.timestamp)).to.equal(h.bytes(160)) 62 | expect(await bench.retrieveData(TRB_QUERY_ID, blocky3.timestamp)).to.equal(h.bytes(170)) 63 | }) 64 | 65 | it("getNewValueCountbyQueryId", async function() { 66 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 67 | expect(await bench.getNewValueCountbyQueryId(TRB_QUERY_ID)).to.equal(1) 68 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,160,1,TRB_QUERY_DATA) 69 | expect(await bench.getNewValueCountbyQueryId(TRB_QUERY_ID)).to.equal(2) 70 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,170,2,TRB_QUERY_DATA) 71 | expect(await bench.getNewValueCountbyQueryId(TRB_QUERY_ID)).to.equal(3) 72 | }) 73 | 74 | it("getTimestampbyQueryIdandIndex()", async function() { 75 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 76 | blocky1 = await h.getBlock() 77 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,160,1,TRB_QUERY_DATA) 78 | blocky2 = await h.getBlock() 79 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,170,2,TRB_QUERY_DATA) 80 | blocky3 = await h.getBlock() 81 | expect(await bench.getTimestampbyQueryIdandIndex(TRB_QUERY_ID, 0)).to.equal(blocky1.timestamp) 82 | expect(await bench.getTimestampbyQueryIdandIndex(TRB_QUERY_ID, 1)).to.equal(blocky2.timestamp) 83 | expect(await bench.getTimestampbyQueryIdandIndex(TRB_QUERY_ID, 2)).to.equal(blocky3.timestamp) 84 | }) 85 | 86 | it("getIndexForDataBefore()", async function() { 87 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 88 | blocky1 = await h.getBlock() 89 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,160,1,TRB_QUERY_DATA) 90 | blocky2 = await h.getBlock() 91 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,170,2,TRB_QUERY_DATA) 92 | blocky3 = await h.getBlock() 93 | index = await bench.getIndexForDataBefore(TRB_QUERY_ID, blocky3.timestamp) 94 | expect(index[0]) 95 | expect(index[1]).to.equal(1) 96 | }) 97 | 98 | it("getDataBefore()", async function() { 99 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 100 | blocky1 = await h.getBlock() 101 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,160,1,TRB_QUERY_DATA) 102 | blocky2 = await h.getBlock() 103 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,170,2,TRB_QUERY_DATA) 104 | blocky3 = await h.getBlock() 105 | dataBefore = await bench.getDataBefore(TRB_QUERY_ID, blocky2.timestamp) 106 | expect(dataBefore[0]).to.equal(h.bytes(150)) 107 | expect(dataBefore[1]).to.equal(blocky1.timestamp) 108 | }) 109 | 110 | it("isInDispute()", async function() { 111 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 112 | blocky1 = await h.getBlock() 113 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,160,1,TRB_QUERY_DATA) 114 | blocky2 = await h.getBlock() 115 | expect(await bench.isInDispute(TRB_QUERY_ID, blocky1.timestamp)).to.be.false; 116 | await token.faucet(addr1.address) 117 | await token.connect(addr1).approve(gov.address, h.toWei("1000")); 118 | await gov.connect(addr1).beginDispute(TRB_QUERY_ID, blocky1.timestamp) 119 | expect(await bench.isInDispute(TRB_QUERY_ID, blocky1.timestamp)) 120 | expect(await bench.isInDispute(TRB_QUERY_ID, blocky2.timestamp)).to.be.false; 121 | gov.connect(addr1).beginDispute(TRB_QUERY_ID, blocky2.timestamp) 122 | expect(await bench.isInDispute(TRB_QUERY_ID, blocky2.timestamp)) 123 | }) 124 | 125 | it("tellor()", async function() { 126 | expect(await bench.tellor()).to.equal(oracle.address) 127 | }) 128 | 129 | it("getIndexForDataAfter()", async function() { 130 | blocky0 = await h.getBlock() 131 | result = await bench.getIndexForDataAfter(TRB_QUERY_ID, blocky0.timestamp) 132 | expect(result[0]).to.be.false 133 | expect(result[1]).to.equal(0) 134 | 135 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(150),0,TRB_QUERY_DATA) 136 | blocky1 = await h.getBlock() 137 | 138 | result = await bench.getIndexForDataAfter(TRB_QUERY_ID, blocky0.timestamp) 139 | expect(result[0]).to.be.true 140 | expect(result[1]).to.equal(0) 141 | result = await bench.getIndexForDataAfter(TRB_QUERY_ID, blocky1.timestamp) 142 | expect(result[0]).to.be.false 143 | expect(result[1]).to.equal(0) 144 | 145 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(160),1,TRB_QUERY_DATA) 146 | blocky2 = await h.getBlock() 147 | 148 | result = await bench.getIndexForDataAfter(TRB_QUERY_ID, blocky0.timestamp) 149 | expect(result[0]).to.be.true 150 | expect(result[1]).to.equal(0) 151 | result = await bench.getIndexForDataAfter(TRB_QUERY_ID, blocky1.timestamp) 152 | expect(result[0]).to.be.true 153 | expect(result[1]).to.equal(1) 154 | result = await bench.getIndexForDataAfter(TRB_QUERY_ID, blocky2.timestamp) 155 | expect(result[0]).to.be.false 156 | expect(result[1]).to.equal(0) 157 | }) 158 | 159 | it("getDataAfter()", async function() { 160 | blocky0 = await h.getBlock() 161 | // result = await bench.getDataAfter(TRB_QUERY_ID, blocky0.timestamp) 162 | // expect(result[0]).to.equal(TRB_QUERY_DATA) 163 | // expect(result[1]).to.equal(0) 164 | 165 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(150),0,TRB_QUERY_DATA) 166 | blocky1 = await h.getBlock() 167 | 168 | result = await bench.getDataAfter(TRB_QUERY_ID, blocky0.timestamp) 169 | expect(result[0]).to.equal(h.uintTob32(150)) 170 | expect(result[1]).to.equal(blocky1.timestamp) 171 | result = await bench.getDataAfter(TRB_QUERY_ID, blocky1.timestamp) 172 | expect(result[0]).to.equal('0x') 173 | expect(result[1]).to.equal(0) 174 | 175 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(160),1,TRB_QUERY_DATA) 176 | blocky2 = await h.getBlock() 177 | 178 | result = await bench.getDataAfter(TRB_QUERY_ID, blocky0.timestamp) 179 | expect(result[0]).to.equal(h.uintTob32(150)) 180 | expect(result[1]).to.equal(blocky1.timestamp) 181 | result = await bench.getDataAfter(TRB_QUERY_ID, blocky1.timestamp) 182 | expect(result[0]).to.equal(h.uintTob32(160)) 183 | expect(result[1]).to.equal(blocky2.timestamp) 184 | result = await bench.getDataAfter(TRB_QUERY_ID, blocky2.timestamp) 185 | expect(result[0]).to.equal('0x') 186 | expect(result[1]).to.equal(0) 187 | }) 188 | 189 | it("getMultipleValuesBefore", async function() { 190 | // submit 2 values 191 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(150),0,TRB_QUERY_DATA) 192 | blocky1 = await h.getBlock() 193 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(160),0,TRB_QUERY_DATA) 194 | blocky2 = await h.getBlock() 195 | await h.advanceTime(10) 196 | blockyNow0 = await h.getBlock() 197 | 198 | // 1 hour before 1st submission 199 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky1.timestamp - 3600, 3600, 4) 200 | expect(result[0].length).to.equal(0) 201 | expect(result[1].length).to.equal(0) 202 | 203 | // maxCount = 4 204 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 4) 205 | expect(result[0].length).to.equal(2) 206 | expect(result[1].length).to.equal(2) 207 | expect(result[0][0]).to.equal(h.uintTob32(150)) 208 | expect(result[0][1]).to.equal(h.uintTob32(160)) 209 | expect(result[1][0]).to.equal(blocky1.timestamp) 210 | expect(result[1][1]).to.equal(blocky2.timestamp) 211 | 212 | // maxCount = 3 213 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 3) 214 | expect(result[0].length).to.equal(2) 215 | expect(result[1].length).to.equal(2) 216 | expect(result[0][0]).to.equal(h.uintTob32(150)) 217 | expect(result[0][1]).to.equal(h.uintTob32(160)) 218 | expect(result[1][0]).to.equal(blocky1.timestamp) 219 | expect(result[1][1]).to.equal(blocky2.timestamp) 220 | 221 | // maxCount = 2 222 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 2) 223 | expect(result[0].length).to.equal(2) 224 | expect(result[1].length).to.equal(2) 225 | expect(result[0][0]).to.equal(h.uintTob32(150)) 226 | expect(result[0][1]).to.equal(h.uintTob32(160)) 227 | expect(result[1][0]).to.equal(blocky1.timestamp) 228 | expect(result[1][1]).to.equal(blocky2.timestamp) 229 | 230 | // maxCount = 1 231 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 1) 232 | expect(result[0].length).to.equal(1) 233 | expect(result[1].length).to.equal(1) 234 | expect(result[0][0]).to.equal(h.uintTob32(160)) 235 | expect(result[1][0]).to.equal(blocky2.timestamp) 236 | 237 | // maxAge = 5 238 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 5, 4) 239 | expect(result[0].length).to.equal(0) 240 | expect(result[1].length).to.equal(0) 241 | 242 | // submit another 2 values 243 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(170),0,TRB_QUERY_DATA) 244 | blocky3 = await h.getBlock() 245 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID,h.uintTob32(180),0,TRB_QUERY_DATA) 246 | blocky4 = await h.getBlock() 247 | await h.advanceTime(10) 248 | blockyNow1 = await h.getBlock() 249 | 250 | // maxCount = 6, don't update blocky 251 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow0.timestamp, 3600, 6) 252 | expect(result[0].length).to.equal(2) 253 | expect(result[1].length).to.equal(2) 254 | expect(result[0][0]).to.equal(h.uintTob32(150)) 255 | expect(result[0][1]).to.equal(h.uintTob32(160)) 256 | expect(result[1][0]).to.equal(blocky1.timestamp) 257 | expect(result[1][1]).to.equal(blocky2.timestamp) 258 | 259 | // maxCount = 6, update blocky 260 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow1.timestamp, 3600, 6) 261 | expect(result[0].length).to.equal(4) 262 | expect(result[1].length).to.equal(4) 263 | expect(result[0][0]).to.equal(h.uintTob32(150)) 264 | expect(result[0][1]).to.equal(h.uintTob32(160)) 265 | expect(result[0][2]).to.equal(h.uintTob32(170)) 266 | expect(result[0][3]).to.equal(h.uintTob32(180)) 267 | expect(result[1][0]).to.equal(blocky1.timestamp) 268 | expect(result[1][1]).to.equal(blocky2.timestamp) 269 | expect(result[1][2]).to.equal(blocky3.timestamp) 270 | expect(result[1][3]).to.equal(blocky4.timestamp) 271 | 272 | // maxCount = 5 273 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow1.timestamp, 3600, 5) 274 | expect(result[0].length).to.equal(4) 275 | expect(result[1].length).to.equal(4) 276 | expect(result[0][0]).to.equal(h.uintTob32(150)) 277 | expect(result[0][1]).to.equal(h.uintTob32(160)) 278 | expect(result[0][2]).to.equal(h.uintTob32(170)) 279 | expect(result[0][3]).to.equal(h.uintTob32(180)) 280 | expect(result[1][0]).to.equal(blocky1.timestamp) 281 | expect(result[1][1]).to.equal(blocky2.timestamp) 282 | expect(result[1][2]).to.equal(blocky3.timestamp) 283 | expect(result[1][3]).to.equal(blocky4.timestamp) 284 | 285 | // maxCount = 4 286 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow1.timestamp, 3600, 4) 287 | expect(result[0].length).to.equal(4) 288 | expect(result[1].length).to.equal(4) 289 | expect(result[0][0]).to.equal(h.uintTob32(150)) 290 | expect(result[0][1]).to.equal(h.uintTob32(160)) 291 | expect(result[0][2]).to.equal(h.uintTob32(170)) 292 | expect(result[0][3]).to.equal(h.uintTob32(180)) 293 | expect(result[1][0]).to.equal(blocky1.timestamp) 294 | expect(result[1][1]).to.equal(blocky2.timestamp) 295 | expect(result[1][2]).to.equal(blocky3.timestamp) 296 | expect(result[1][3]).to.equal(blocky4.timestamp) 297 | 298 | // maxCount = 3 299 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow1.timestamp, 3600, 3) 300 | expect(result[0].length).to.equal(3) 301 | expect(result[1].length).to.equal(3) 302 | expect(result[0][0]).to.equal(h.uintTob32(160)) 303 | expect(result[0][1]).to.equal(h.uintTob32(170)) 304 | expect(result[0][2]).to.equal(h.uintTob32(180)) 305 | expect(result[1][0]).to.equal(blocky2.timestamp) 306 | expect(result[1][1]).to.equal(blocky3.timestamp) 307 | expect(result[1][2]).to.equal(blocky4.timestamp) 308 | 309 | // maxCount = 2 310 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow1.timestamp, 3600, 2) 311 | expect(result[0].length).to.equal(2) 312 | expect(result[1].length).to.equal(2) 313 | expect(result[0][0]).to.equal(h.uintTob32(170)) 314 | expect(result[0][1]).to.equal(h.uintTob32(180)) 315 | expect(result[1][0]).to.equal(blocky3.timestamp) 316 | expect(result[1][1]).to.equal(blocky4.timestamp) 317 | 318 | // maxCount = 1 319 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blockyNow1.timestamp, 3600, 1) 320 | expect(result[0].length).to.equal(1) 321 | expect(result[1].length).to.equal(1) 322 | expect(result[0][0]).to.equal(h.uintTob32(180)) 323 | expect(result[1][0]).to.equal(blocky4.timestamp) 324 | 325 | result = await bench.getMultipleValuesBefore(TRB_QUERY_ID, blocky4.timestamp, 100, 3) 326 | }) 327 | 328 | it("getReporterByTimestamp()", async function() { 329 | await oracle.connect(addr1).submitValue(TRB_QUERY_ID, 150, 0, TRB_QUERY_DATA) 330 | blocky1 = await h.getBlock() 331 | expect(await bench.getReporterByTimestamp(TRB_QUERY_ID, blocky1.timestamp)).to.equal(addr1.address) 332 | await oracle.connect(addr2).submitValue(TRB_QUERY_ID,160,0,TRB_QUERY_DATA) 333 | blocky2 = await h.getBlock() 334 | expect(await bench.getReporterByTimestamp(TRB_QUERY_ID, blocky2.timestamp)).to.equal(addr2.address) 335 | }) 336 | }); 337 | -------------------------------------------------------------------------------- /test/helpers/helpers.js: -------------------------------------------------------------------------------- 1 | const { ethers } = require("hardhat"); 2 | 3 | const hash = ethers.utils.keccak256; 4 | var assert = require('assert'); 5 | 6 | const takeFifteen = async () => { 7 | await advanceTime(60 * 18); 8 | }; 9 | 10 | 11 | advanceTime = async (time) =>{ 12 | await network.provider.send("evm_increaseTime", [time]) 13 | await network.provider.send("evm_mine") 14 | } 15 | 16 | async function expectThrow(promise) { 17 | try { 18 | await promise; 19 | } catch (error) { 20 | const invalidOpcode = error.message.search("invalid opcode") >= 0; 21 | const outOfGas = error.message.search("out of gas") >= 0; 22 | const revert = error.message.search("revert") >= 0; 23 | assert( 24 | invalidOpcode || outOfGas || revert, 25 | "Expected throw, got '" + error + "' instead" 26 | ); 27 | return; 28 | } 29 | assert.fail("Expected throw not received"); 30 | } 31 | 32 | function to18(n) { 33 | return ethers.BigNumber.from(n).mul(ethers.BigNumber.from(10).pow(18)) 34 | } 35 | 36 | function tob32(n){ 37 | return ethers.utils.formatBytes32String(n) 38 | } 39 | 40 | function uintTob32(n){ 41 | let vars = ethers.utils.hexlify(n) 42 | vars = vars.slice(2) 43 | while(vars.length < 64){ 44 | vars = "0" + vars 45 | } 46 | vars = "0x" + vars 47 | return vars 48 | } 49 | 50 | function bytes(n){ 51 | return ethers.utils.hexlify(n) 52 | } 53 | 54 | function getBlock(){ 55 | return ethers.provider.getBlock() 56 | } 57 | 58 | function toWei(n){ 59 | return ethers.utils.parseEther(n) 60 | } 61 | 62 | function fromWei(n){ 63 | return ethers.utils.formatEther(n) 64 | } 65 | 66 | module.exports = { 67 | timeTarget: 240, 68 | hash, 69 | zeroAddress:"0x0000000000000000000000000000000000000000", 70 | to18, 71 | uintTob32, 72 | tob32, 73 | bytes, 74 | getBlock, 75 | advanceTime, 76 | takeFifteen, 77 | toWei, 78 | fromWei, 79 | expectThrow, 80 | }; 81 | --------------------------------------------------------------------------------