Skip to content

Commit

Permalink
Merge pull request #110 from tellor-io/adrExpand
Browse files Browse the repository at this point in the history
adr changes
  • Loading branch information
brendaloya authored Apr 5, 2024
2 parents 5512a97 + 24e3fb0 commit da50f08
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 29 deletions.
35 changes: 27 additions & 8 deletions adr/adr001 - chain size limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,44 @@
## Changelog

- 2024-02-21: initial version
- 2024-04-02: formatting

## Context

Layer is limited in many ways:
* blockSize - how many reports can fit into a block (queryIds with one reporter or multiple reporters on a given queryId)
* validator Size - how many signatures can fit into ETH block? Do we expect ETH to be the main chain data is bridged to?
* voteExtension size limit - How many signatures can we add to vote extensions (queryId's aggregated x validators needed to hit 2/3 consnesns)?
* If we don't use voteExtensions, how many signatures can we fit into a block?
* How fast does our chain grow in size?
Layer is limited in many ways. This ADR is meant to go over the limits relating to each design decision.


### General State growth

## Alternative Approaches
How fast does our chain grow in size?
What measures / designs are in place for pruning state?

### Blocksize limits

What is the current blockLimit?
How many reports can fit into a block
- How many different queryIds with one reporter?
- How many reporters can we fit in with one given queryId?
How many transfers can fit into a block?


### Validator Size limits

How many signatures can fit into ETH block? Do we expect ETH to be the main chain data is bridged to?

### Vote extension limits

VoteExtension size limit - How many signatures can we add to vote extensions (queryId's aggregated x validators needed to hit 2/3 consnesns)?

If we don't use voteExtensions, how many signatures can we fit into a block (i.e. store them in the next block)

## Alternate approaches to state growth

### Cap number of reporters (like validators)

You could cap the number of reporters at the total level. This problem is that we would then be forcing anyone who wants to report to stake a large amount or tip a validator who potentially doesn't care about their small data point (the LINK problem of no one supporting your illiquid coin). If you want to use it purely optimistically, you shouldn't need to worry about having too much stake.

#### Cap number of reporters per report
### Cap number of reporters per report

You could take only the top 150 (for example) reports. That way only the top guys would get rewards on the big queries, but the lesser people would still be able to compete on the lesser reported/illiquid/or optimistic queries.

Expand Down
9 changes: 5 additions & 4 deletions adr/adr002 - queryId time frame structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
## Changelog

- 2024-03-06: initial version
- 2024-04-23: clarity

## Context

Expand All @@ -20,23 +21,23 @@ The commit reveal cycle is still intact and reveals can be anytime before reveal

### time frame starts when first commit happens

One approach would be to have shorter report time frames, but the window doesn't start right after the tip, but rather on the first report. This would allow for queries that are not seeking consensus, to just have a tip with a short time frame, and then once one party reports, it is basically over and handled by disputes. The issue we had with this is that it unties the time frame from the tip. Usually if you tip, you want some certainty around when you get the data. It also gives the false impression to the tipper that they should expect the data in some time frame. If you tip for a manual query and it has a time frame of one hour, you would expect it to be reported in one hour. The time frame in our mind is tied to how long it should be expected to take reporters to get the data.
One approach would be to have shorter report time frames where the window doesn't start right after the tip, but rather on the first report. This would allow for queries that are not seeking consensus to just have a tip with a short time frame, and then once one party reports, it is basically over and handled by disputes. The issue we had with this is that it unties the time frame from the tip. Usually if you tip, you want some certainty around when you get the data. It also gives the false impression to the tipper that they should expect the data in some time frame. If you tip for a manual query and it has a time frame of one hour, you would expect it to be reported in one hour. The time frame concept in our mind is tied to how long it should be expected to take reporters to get the data. If longer is needed, then the data spec itself is just likely not well defined or supported and work should be done on that front.

### time frame restarts if no one reports

One option would be to just restart the time frame if no one reports. This would work, but no one might be reporting because the tip is too low. It's also unclear if the report is still even needed if the time frame ends. Additionally if you have lots of restarting time frames, it could clutter or spam the chain very easily.

### refund tip if no report

I think the argument against is that the reason no one reported is that the tip was too low. It would also be easy to spam the chain with small tips or for unsupported queryId's, if you know that you'll get your tokens back. Additionally, voting power is given on tips, and more tracking would need to be put in place in regards to refunds.
I think the argument against this is that the reason no one reported is that the tip was too low. It would also be easy to spam the chain with small tips or for unsupported queryId's if you know that you'll get your tokens back. Additionally, voting power is given on tips, and more tracking would need to be put in place in regards to refunds.

### all reveals done in reveal window

The problem here is that for longer time frames, reporters will need to wait until the right block and then have a limited time (right now 2 blocks) to reveal. If they go down or need to maintain a long list of reveals to submit in the future, this could be computationally expensive. In order to just allow the reporter to decide their comfort level in being mirrored (they have to split rewards with parties mirroring them), we allow reveals at any stage. Not to mention, that large parties will not mirror smaller ones. If a large party mirrors a smaller one, the smaller party can submit a bad value and dispute the larger party right away to make back their funds.
Unde this option, you wait until a period right after the time frame for all reveals to happen. The problem here is that for longer time frames, reporters will need to wait until the right block and then have a limited time (right now 2 blocks) to reveal. If the reporter software goes down or they need to maintain a long list of reveals to submit in the future, this could be computationally expensive. In order to just allow the reporter to decide their comfort level in being mirrored (they have to split rewards with parties mirroring them), we allow reveals at any stage. Not to mention, that large parties will not mirror smaller ones. If a large party mirrors a smaller one, the smaller party can submit a bad value and dispute the larger party right away to make back their funds.

### new tips start a new window

New tips could start a new window, in order to have faster reports (e.g. if the time frame is an hour, you could stack the tips 30 minutes apart to get reports every 30 minutes), however the technical difficulty comes into play when figuring out which time frame a report is for. When setting a report time frame, parties should be aware that the time frame is the fastest that the data will be available, so if they need faster data, they should set a shorter time frame. Longer time frame queries are expected to be slower moving data, such as prediction market answers or data queries that have a time frame attached (e.g. what is the ETH block header at 10:35:00 UTC).
New tips could start a new window (versus being added to currently open tip), in order to have faster reports (e.g. if the time frame is an hour, you could stack the tips 30 minutes apart to get reports every 30 minutes), however the technical difficulty comes into play when figuring out which time frame a report is for. When setting a report time frame, parties should be aware that the time frame is the fastest that the data will be available, so if they need faster data, they should set a shorter time frame. Longer time frame queries are expected to be slower moving data, such as prediction market answers or data queries that have a time frame attached (e.g. what is the ETH block header at 10:35:00 UTC).

### no commits, only revealed data

Expand Down
5 changes: 3 additions & 2 deletions adr/adr1003 - time based rewards eligibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
## Changelog

- 2024-02-22: initial version
- 20204-04-02: clarity

## Context

Expand All @@ -15,7 +16,7 @@ a) subsidizes users needing to tip
b) provides a heart beat for the system in absence of tips (reporters are then around ready to report and we can all see they are reporting accurately)


The issue in just distributing inflationary rewards to all reported data is that there becomes an incentive to report more (unneeded) data in order to increase the amount of rewards given to your reporter. For instance if you have 10 reporters (equal weight) and they all report for BTC/USD, then they would split the inflationary rewards (if they have unequal weight it would be distributed based upon reporting weight). The problem is what happens when one of those parties reports for TRB/BTC (imagine a query that only they support)? For calculation purposes, let's say they report for 9 new queries that only they support. If the inflation is split based on total reported queries, they had 9 reports and all other reporters (equal weight) also had 9, so our attacker would get 50% of the rewards.
The issue in just distributing inflationary rewards to all reported data is that there becomes an incentive to report more (unneeded) data in order to increase the amount of rewards given to your reporter. For instance if you have 10 reporters (equal weight) and they all report for BTC/USD, then they would split the inflationary rewards (if they have unequal weight it would be distributed based upon reporting weight). The problem is what happens when one of those parties reports for a query that only they support. For calculation purposes, let's say they don't just do it for one, but report for 9 new queries that only they support. If the inflation is split based on total reported queries, they had 9 reports(all ones they only support) and all other reporters (equal weight) also had 9 (just for BTC/USD). Unfotunately if you split the time based reward by weight given, the attacker would get 50% of the rewards.

In order to prevent this we only give inflationary rewards to cycle list queries (queries that have been voted on by governance that everyone should support at a base level).

Expand All @@ -32,7 +33,7 @@ An easy solution is to keep the inflation for validators and not reporters. Thi

### only cycle rewards if consensus reached

A discussed option was to only provide inflationary rewards to queries that hit consnensus. This sort of solves the problem, but there would still be the issue that some parties would want to support queries that had 66% support vs those with 100% support. There would also be a race to submit for more things, (e.g. if I do more than everyone else I'll get more), which could be good, but it would fill up the chain unnecessarilty.
A discussed option was to only provide inflationary rewards to queries that hit consnensus. This sort of solves the problem, but there would still be the issue that some parties would want to support queries that had 66% support vs those with 100% support.

### weight only used once

Expand Down
10 changes: 6 additions & 4 deletions adr/adr1004 - fees on tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,25 @@
## Changelog

- 2024-02-21: initial version
- 2024-04-01:
- 2024-04-01: added to discussion
- 2024-04-02: expanded upon alternative options

## Context

A fee on tips is necessary to discourage vote farming and spaming the network by tippig data that has no support.

The 2% fee on tips was chosen arbitrarily.
The 2% fee on tips was chosen relatively arbitrarily, but is consistent with the 2% fee that has been present on previous versions of [Tellor's autopay contract](https://github.com/tellor-io/autoPay).


## Alternative Approaches

### No Fee
Implemeting no fee has been discarted since the old version of tellor because it can encorage vote farming. In Layer, reporters will not earn voting weight per report count, however, users will so a fee is still necessary.

Rather than a fee for profit, the fee in the tellor system acts more as a spam prevention tool. Removing the fee is unfortunately not an option as it can encourage vote farming. In Layer, users who tip recieve vote power based upon how much they tip. An attack vector is present where someone could just tip a query only they support, report for it, and gain voting power without losing funds. The fee prevents this (or makes it costly). In old tellor, reporters could earn voting weight per report count (and double the effectiveness of this attack), however that has been removed in Layer in favor of reporter weight.

### Higher fee

We could just increase that 2% fee to something like 5 or 10%. Although this could be a solution, limiting that fee is important because it supports having on-chain tips (can be tracked for governance/ usage purposes) vs off-chain.
We could just increase that 2% fee to something like 5 or 10%. Although this could be a solution, limiting that fee is important because it supports having on-chain tips (can be tracked for governance/ usage purposes) vs off-chain. The big discussion to continue to analyze is balancing the need for a fee (to prevent vote farming attacks) and the risk of the fee being too high that only off-chain tips are used and we lose the ability to give actual users voting power (a say in the validity of the data).


## Issues / Notes on Implementation
Expand Down
8 changes: 5 additions & 3 deletions adr/adr1005 - handling of tips after report.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,28 @@
- 2024-02-21: initial version
- 2024-03-07: changed to escrow account vs stake
- 2024-04-01: made the distiction clearer for tips not going into the reporter stake (we should discuss since your last update, did not match what I thought we decided on-BL.)
- 2024-04-02: clarity / wording changes

## Context

In layer, when a user sends free floating tokens as a tip, the party(ies) that report for that queryId in the reporting window are given the tip. Once reported for, these tips are locked in an escrow account that can be withdrawn but observing the same waiting period as unstaking. The tokens are then free floating and the reporter can decide to stake them or not.

Tellor governance is structured, namely to prevent people from farming voting power. If tips were not locked, a party could tip a random query that only they know how to report for. They could report, then tip those exact same tokens, thus looping them in order to look like there is ton of tip demand for this query and increase their 'user' and 'reporter' voting power. The two methods to prevent this are a) a 2% fee on tips and b) locking the tip in escrow. Now if the party wishes to withdraw that tip, they will have to wait the 21 day unbonding period, similar to the unstaking.
One of the goals of the Tellor governance structure is to prevent people from farming voting power. If tips were not locked, a party could tip a random query that only they know how to report for. They could report, then tip those exact same tokens, thus looping them in order to look like there is ton of tip demand for this query and increase their 'user' and 'reporter' voting power. The two methods to prevent this are a) a 2% fee on tips and b) locking the tip in escrow. Now if the party wishes to withdraw that tip, they will have to wait the 21 day unbonding period, similar to the unstaking.

Another potential attack is that they could use tipping to bypass the deposit stake caps. Notably, they could tip a large portion of the entire staked supply (e.g. 66%) and halt the chain or force a fork.
Another potential attack is that they could use tipping to bypass the deposit stake caps. Notably, they could tip a large portion of the entire staked supply (e.g. 66%) and then halt the chain or force a fork.


## Alternative Approaches

### Higher fee burn on tips

The other method we could do is just increase that 2% fee to something like 5 or 10%, thus completely draining the attacker if they did this method. Although this could be a solution, limiting that fee is important because it supports having on-chain tips (can be tracked for governance/ usage purposes) vs off-chain.
The other method we could do is just increase that 2% fee to something like 5 or 10%, thus completely draining the attacker if they did this method. Although this could be a solution, limiting that fee is important because it supports having on-chain tips (can be tracked for governance/ usage purposes) vs off-chain. It also only mildly fixes the depositStake bypass.


### Tips locked as stake and limit the amount
We could just lock the tips as stake, but then tipping a query only you report is essentially a "deposit stake" function. This could be handled by just limiting the amount you could unlock, but this dual structure could cause issues for tracking voting power and stake. Keeping it in a separate escrow was deemed cleaner in the code.


### just cap tip size or total amount

One could just cap the tip size, but this could easily be avoided by just splitting up tips. We had also discussed limiting total tips to some % of total stake (e.g. 2%), but then a) you could get around the deposits by just tipping smaller amounts for fast queries; and b) you could potentially censor the system by capping out the amount of tips (i.e. if you tip to the limit, now no one can do a legitimate tip).
Expand Down
Loading

0 comments on commit da50f08

Please sign in to comment.