EnormousCloud / api3-dao-tracker

API3 DAO Tracker
https://enormous.cloud/dao/api3/tracker/
MIT License
3 stars 1 forks source link

Incorrect information about staking rewards not providing voting power #1

Closed bbenligiray closed 3 years ago

bbenligiray commented 3 years ago

https://enormous.cloud/dao/api3/tracker/wallets reads

There were 1,299,275 API3 tokens minted and locked as staking rewards with no voting power.

The staking rewards are staked by default even while they are locked (though they can be unstaked), which would grant voting power to the staker

EnormousCloud commented 3 years ago

Thanks for sharing this @bbenligiray

While this might be true (I can't claim my numbers from logs are fully matching yet), let me share you the following case that illustrates why I added that particular wording:

https://enormous.cloud/dao/api3/tracker/wallets/0xe4b08cbd7057f05aa7e9dbb83cf1511dc7fb3b10

I believe you will see the same in the event logs of your wallet - you will not see the amount of minted rewards during CastVote - just yours and delegations.

So, if I look at events logs and trust them without looking at smart contract, I can't see that rewards are added to the voting power during actual voting. And at first glance - the number of user shares that goes into CastVote is actual users' voting power.

Such cases made me add this wording to avoid confusion and to be closer to matching numbers, because I see no evidence so far that voting power was granted on locked rewards and see the evidence of the opposite. While I obviously believe the intention to include it in the code of contract, I don't know the reason why it is not added. So I am probably still missing something.

bbenligiray commented 3 years ago

Okay, I see the reason now. This is about that thing where you stake 1000 API3 but if you try to unstake immediately you get 999.9....

The voting weights are in pool shares, not number of tokens. (All token amounts are in Wei) Initially, each pool share is worth 1 API3 (implemented by seeding the pool by pretending to stake 1 API3 and creating 1 pool share in return that nobody owns). Say we both staked 500 API3 each. We each get 500 pool shares because the price is 1:1. Now the total staked is 1+500+500=1001 and the total pool shares is 1+500+500=1001 (share price remains the same). Using the shares to calculate, my voting weight is 500/1001=~50%.

A reward of 100 API3 gets paid out. Reward payouts don't affect the shares, so now the total staked is 1001+100=1101, total shares is 1001 and we still both have 500 shares. My voting weight is still calculated using the shares (500/1001=~50%). However, total staked is 1101 and total shares is 1001, so the reward payout increased the share price to 1101/1001=~1.01 in API3. So my 500 shares used to calculate my voting power actually represent 500*1.01=505 API3, i.e., my reward counts to my voting power.

Although this doesn't matter in this case yet because both parties still hold 50% of the voting power and it wouldn't matter if the reward counted to voting power, it becomes significant when someone stakes after the reward is paid out. Now, the share price has increased, so staking 500 API3 will grant 500/1.01=~495 pool shares, and the fact that my reward is staked gives me an advantage in voting power against people that didn't receive this reward.

EnormousCloud commented 3 years ago

So do you agree overall that current wording is so far accurate for main net and I can close this thread?

Unlocked rewards obviously affect voting power and deserve a separate paragraph.

So can I trust absolute number of voting power in CastVote, whatever mind-blowing calculation is behind it?

bbenligiray commented 3 years ago

The issue is about the wording here

There were 1,299,275 API3 tokens minted and locked as staking rewards with no voting power.

because the locked staking rewards do grant voting power when staked back. So the fix could be just removing the bold portion.

I elaborated on the implementation in case there are issues caused by the same misunderstanding that are not as apparent. For example, if the voting power % at https://enormous.cloud/dao/api3/tracker/wallets is calculated by dividing by total staked instead of total shares (which is not the case but just giving it as an example).

EnormousCloud commented 3 years ago

ok, my point is The proper fix would be to give the exact number of minted tokens that granted voting power, and exact number of minted tokens that don't. Removing the wording definitely leads to misunderstanding that all those minted tokens give you voting power with no conditions, which doesn't seem to be true, as the current rewards that you see on were not a part of the voting and they indeed had no voting power unless you show me the opposite in smart contract logs

I will research this dance with "staking back" to have more voting power, this probably would answer some of the related questions, and will keep this thread open meanwhile

The voting power % on wallets is not calculated by dividing total staked, it is based on the shares from the events logs. But there is no perfect match still, probably because of cases with unstaking.

bbenligiray commented 3 years ago

I think the discrepancy is when I say "voting power", I'm referring to the % weight, while you're referring to the absolute number of pool shares (which is understandable because that's what userVotingPower() returns). As a design choice, we always use token amounts and not the shares on the dashboard because shares are an implementation detail and the user shouldn't have to understand that to be able to use the dashboard. Similarly, when displaying voting power, we always use %. I guess in this more detailed display it would be appropriate to show the inner workings too.

Minted tokens grant voting power by default (because they are minted in the staked state). If they are unstaked, they no longer grant voting power. However, there is a bit of an ambiguity here: Say my staked tokens went from 500 to 505 because of the reward. Then I unstaked 5 tokens. Did I unstake my reward, or a portion of my initial? So exactly measuring how much of the locked rewards are staked/grant voting power is not possible if anyone has unstaked partially. I proposed

There were 1,299,275 API3 tokens minted and locked as staking rewards.

as a fix because this doesn't state anything about these tokens granting voting power or not, it's just an objective fact about the total amount of locked staking rewards.