diff --git a/README.md b/README.md index 1127f25..16e6114 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,58 @@ You must pass a file containing the transactions with `--rewards filename.json`. Note, the stipend is used here to revert if the stipend is greater than the current balance. It will not affect the transactions in any way, because they have alredy been generated. There are no tests. + +# MORE INFORMATION ABOUT THE CALCULATION AND DISTRIBUTION PROCESS, IMPORTED FROM GREEN'S DOCS: + +[Github Repo](https://github.com/kleros/tag-registry-rewards) + +### Setting Up Environment + +Clone the repo. You do not need to fill in the private key until the disbursement step comes in. + +## Generating Rewards + +This is done through two steps. This should be properly explained in the README.md in the repo, but as a refresher, you run the script through `yarn start` with parameters. + +### fetch + +After the period has ellapsed, run with `--mode fetch`, dates should get filled in by default. In case the period has not ellapsed yet and you want to fetch the tags of an incomplete period, or a custom period enclosed by a start of an end, you can use `--start 2024-02-01` and `--end 2024-02-19`. Just read the manual. + +Fetch will take a while, this is usually the longest step. Mainly, checking each address to ensure its bytecode is not length 0 (that is, ensuring each address is a contract). This could be removed, tbh, since we're trusting the registries anyway, and all registries enforce the addresses contain smart contracts. Just be careful, since I think it was closely linked to a function checking whether if a contract was in an awarded chain. + +After this step is complete, it will create a file in the `files` directory, `${timestamp}_queries.txt`. Click on the Dune Query link the terminal printed. Copy and paste each parameter into the Dune frontend. + +> Known bug: if a parameter is empty, the Dune Query will break. To the maintainer, ammend the script to make it print a list containing a single valid address in case the parameter would be empty otherwise, e.g. `0x0000000000000000000000000000000000000000`. This is not an issue because the script will only use the gas spent by the contract if there is a tag associated with the address, it will just not be used. The only purpose is to prevent it from crashing. + +After filling in the values, press F12 and move to the Network tab, you need to make sure you intercept the result. Run the query in _Medium_ tier to prevent Dune from halting after 2min of compute. It will cost credit, but somehow they're free? Just don't abuse this. +If Kleros coop ever pays for a Dune Query API Key because it needs it for some reason, then this _fetch_ step should be merged with the next one. + +Anyway, once you do this and the query is resolved, copy the json you got from the response. Paste it into a file, e.g. `gas.json`, and clean it up so that it only contains the array inside `execution_data`, or whatever it is called. + +### generate + +Running the _fetch_ step should have created a `${timestamp}_tags.json` file under the `files` directory. Pass it as the `--tags` parameter, like in the README. Also, pass the JSON you just made through this Dune sequence of steps, as the `--gas` parameter. + +This step should be almost instantaneous. After it is run, it should create a (not aptly named) `${timestamp}.json`, which contains an array of recipients and amounts, a (not aptly named) `${timestamp}.csv`, which is a table containing some info about the rationale behind each reward, contract, etc. And `${timestamp}_tx.csv`, which is another table with a sum of the rewards per recipient address. + +After this is generated, it it customary to make a Google Docs Calc Sheet file, with two tables created by importing the CSV files above, and sharing it on the Kleros Telegram. They are implied to be disbursed after 24h, to give a grace period in case a community member (usually, a contributor) notices issues. + +### Disbursing + +> This process is admitably unsafe, follow at your own risk, I am only documenting how I have been doing it so far. Having a hot wallet private key in a .env is extremely unsafe. Despite having used the same one for one year and a half, I have been paranoid about it and I have never let the stPNK sit on there for more than half an hour until disbursing. This process could easily be modernized, or refactored into using a solution such as disperse.app. + +If you have not before, make a hot wallet (e.g. with MetaMask), you will send the stPNK to it when performing the disbursement step. You should also send some xDAI to it, to pay for gas. + +Send stPNK to it, not xPNK. You can wrap and unwrap xPNK <-> stPNK in [Kleros Court](court.kleros.io). Do not send xPNK to it. It can be recovered, but still, save the hassle. + +You can run the script with `--mode send --rewards ${thing}.json`. It will print the address, in case you need it, and tell you its balance. It will abort disbursement in case there are not enough stPNK in balance, so you should be able to run it. + +# Patching up the system + +In the future, nonEVM chains might be supported. That is perfectly fine according to CAIP-10, which is the standard utilized in the `rich-address` property type used in Curate. This script does not support nonEVM chains, but it could through some refactoring. A solution to obtain tx_count, or gas_count, or whatever equivalent should be looked for. Also, checking if something is a contract or not, if that hasn't been removed already. + +The codebase should not be difficult to understand, but it does many different things, I would take a week to understand. It touches Subgraph, Dune SQL (and arguably scraping), Curate specifics, some math with Ethers.js to generate the rewards that has not been documented or explained. + +## Current algorithm to gen rewards distribution explained badly + +There is a maximum amount, currently 1000 PNK. Imagine that as blades of grass. If a blade of grass exceeds the amount, we track it. We also track those who did not exceed the amount. We put the exceeders in a bag, award the max amount to each. Then put the underperformers in a different bag, and calculate "rewards" once again, as if we were only awarding the leftovers to the underperformers. That's why there's recursion.