A CLI dashboard & alerts app for monitoring and disputing bad values reported to Tellor oracles.
The Disputable Values Monitor is a tool that anyone can use to:
- Monitor / view data submitted to Tellor oracle contracts
- Send Discord alerts for unusual data submissions
- Automatically dispute wildly inaccurate values
- A discord server where you can create a channel and a bot for recieving alerts sent by the Disputable Values Monitor via webhook. See the "Making a Webhook" section of the Discord documentation here.
- Install Python 3.9 and/or verify that it is the current version:
python -V
The output should be:
Python 3.9.XX
Note: Other versions (e.g. Python 3.8 or 3.10) are not compatible with the Disputable Values Monitor.
- Clone the repo and change directory:
git clone https://github.com/tellor-io/disputable-values-monitor
cd disputable-values-monitor
- Create a python environment for installation:
python3 -m venv env
- Install
pip install poetry && poetry install
mv venv/lib/python3.9/site-packages/vars.example.sh vars.sh
- Edit
vars.sh
with your favorite text editor replacing the dummy url with the url for your Discord bot's webhook. - Set
MONITOR_NAME
with a memorable name for your DVM process. - Export environment variables:
source vars.sh
- Initialize telliot configuration:
poetry run telliot config init
You should now have a telliot
folder in your home directory.
- Open
~/telliot/endpoints.yaml
with your favorite text editor. The Disputable-Values-Monitor will check reports on each chain that is configured in this list. Remove the networks that you don't want to monitor, and provide and endpoint url for those that you do. For example, if you want to monitor reports on Ethereum Mainnet and Sepolia testnet, your endpoints.yaml file should look like this:
type: EndpointList
endpoints:
- type: RPCEndpoint
chain_id: 1
network: mainnet
provider: Infura
url: https://YOUR_MAINNET_ENDPOINT
explorer: https://etherscan.io
- type: RPCEndpoint
chain_id: 11155111
network: sepolia
provider: Infura
url: https://YOUR_SEPOLIA_ENDPOINT
explorer: https://sepolia.etherscan.io/
- Start the Disputable-Values-Monitor for Alerts only:
poetry run cli
Enter y
to confirm alerts only.
-c
or --confidence-threshold
: to specify a percentage threshold for recieving alerts (unavailable if -d is used). The default is 10% or -c 0.1
-w
or --wait
: The wait time (in seconds) between event checks to reduce calls to the RPC endpoint. The default is seven seconds or -w 7
-av
: to get an alert for all NewReport
events (regardless of whether they are disputable or not).
Disclaimer: *Disputing Tellor values requires staking TRB tokens that can be lost if the community votes in favor of the reporter. There is no guarantee that this software will correctly identify bad values. Use this auto-disputing functionality at your own risk. Experimenting on a testnet before using any real funds is HIGHLY recommended.
- Create a telliot account using the private key for the address that holds your TRB to be used for dispute fees and gas (ETH, or other) for network fees:
telliot account add AccountName 0xYOUR_PRIVATE_KEY 1 10 137 11155111
Where 1 10 137 11155111
are the network IDs for the networks you want to be able to use with this account.
- Edit
dipsuter-config.yaml
. Each spot price query must be configured here for auto-disputing. ETH/USD Spot price and EVM call query type are included by default. Different spot price feeds can be added by providing thequery_id
,threshold
type
andamount
.
The provided configuation is for auto-disputing any ETH/USD value that is 75% different from the value calculated by the DVM:
# AutoDisputer configuration file
feeds: # please reference https://github.com/tellor-io/dataSpecs/tree/main/types for examples of QueryTypes w/ Query Parameters
- query_id: "0x83a7f3d48786ac2667503a61e8c415438ed2922eb86a2906e4ee66d9a2ce4992"
threshold:
type: Percentage
amount: 0.75 # 75%
- Start the Disputable-Values-Monitor with the Auto-Disputer enabled:
cli -d -a AccountName
Note: If the -c
and -d
are used at the same time, the confidence-threshold for alerts only will be ignored. Alternate configuations may require a seperate instance of the DVM.
-w
or --wait
: The wait time (in seconds) between event checks to reduce calls to the RPC endpoint. The default is seven seconds or -w 7
-av
: to get an alert for all NewReport
events (regardless of whether they are disputable or not).
The Auto-disputer is a complex event listener for any EVM chain, but specifically it listens for NewReport events on the Tellor network(s) the user wants to monitor.
When the Auto-disputer receives new NewReport events, it parses the reported value from the log, then compares the reported value to the trusted value from the Tellor reporter reference implementation, telliot.
In order to auto-dispute, users need to define what a "disputable value" is. To do this, users can set "thresholds" for feeds they want to monitor. Thresholds in the auto-disputer serve to set cutoffs between a healthy value and a disputable value. Users can pick from three types of thresholds: range, percentage, and equality.
Range -- if the difference between the reported value and the telliot value is greater than or equal to a set amount, dispute!
Ex. If the reported value is 250, and the telliot value is 1000, and the monitoring threshold is a range of 500, then the difference is 750 (it is >= to the range amount of 500), and the value is disputable! Therefore, a reported value of 501, in this case, would not be disputable. The smaller the range, the more strict the threshold.
Percentage -- if the difference between the telliot value and the reported value is greater than or equal to a set percentage of the telliot value, dispute! The smaller the percentage, the more strict the threshold.
Ex. If the reported value is 250, and the telliot value is 1000, and the percentage threshold is 0.50 (50%), then the percent difference is 75% of the telliot value (1000), and the value is disputable! Therefore, a reported value of 750, in this case, would not be disputable.
Equality -- if there is any difference between the reported value and the telliot value, send a dispute!
Ex. If the reported value is "abc123", and the telliot value is "abc1234", then the value is disputable! However, to prevent false disputes due to checksummed addresses, the equality threshold sees "0xABC" and "0xabc" as equal.
Range thresholds best monitor high variance price feeds where the percent difference in price between sources is an unreliable indicator of a bad value. They are incompatibale, however, with non-numeric data feeds.
Percentage thresholds best monitor standard price feeds. The percentage is measured relative to the telliot value, not the reported value. In other words, if the telliot value is 1000, a 25% difference is 25% of 1000. Like range thresholds, percentage thresholds are incompatibable with non-numeric data feeds.
Equality thresholds best monitor data feeds where there is only one right answer. For example, EVMCall
requests should be exactly equal to their expected telliot response. They aren't very useful for price feeds, though.
- Install Python 3.9
- Install Poetry
Clone repo:
git clone https://github.com/tellor-io/disputable-values-monitor.git
Change directory:
cd disputable-values-monitor
Install dependencies with Poetry:
poetry env use 3.9
poetry install
Run tests:
poetry run pytest
Format/lint code:
poetry run pre-commit run --all-files
Check type hinting:
poetry run mypy --strict src --implicit-reexport --ignore-missing-imports --disable-error-code misc
Generate requirements.txt in case you have installed new dependencies:
poetry export -f requirements.txt --output requirements.txt --without-hashes
- Ensure all tests are passing on
main
branch. - Remove "dev" from version in the
pyproject.toml
file. Example: version = "0.0.5dev" --> version = "0.0.5". - On github, go to "Releases" -> "Draft a new release" -> "Choose a tag".
- Write in a new tag that corresponds with the version in
pyproject.toml
file. Example: v0.0.5 - If the tag is v.0.0.5, the release title should be Release 0.0.5.
- Click Auto-generate release notes.
- Check the box for This is a pre-release.
- Click Publish release.
- Navigate to the Actions tab from the main page of the package on github and make sure the release workflow completes successfully.
- Check to make sure the new version was released to test PyPI here.
- Test downloading and using the new version of the package from test PyPI (example).
- Navigate back to the pre-release you just made and click edit (the pencil icon).
- Uncheck the This is a pre-release box.
- Publish the release.
- Make sure the release github action goes through.
- Download and test the new release on PyPI official here.
- Change the package version in pyproject.toml to be the next development version. For example, if you just released version 0.0.5, change version to be "0.0.6dev0".