CORIONplatform / solidity

GNU General Public License v3.0
12 stars 9 forks source link

Provider/Schelling reward calculation problem #160

Open gundas opened 6 years ago

gundas commented 6 years ago

The Schelling calculates Global Schelling Reward based on Total Tokens Supply.

_reward = safeMul(getTotalSupply(), interestRate) / interestRateM / 100;

The Provider contract uses separately calculated schellingSupply to distribute the reward.

Imagine a simple situation with 2 COR holders:

Now, the calculation which calculates the connected client's reward is:

data.senderReward = safeAdd(data.senderReward, safeMul(safeMul(data.schellingReward, data.clientSupply) / data.schellingSupply, data.rate) / 100);

To simplify (and omit the data.rate calculation):

(schellingReward * clientSupply)/SchellingSupply = (250 * 1000)/1000 =250

So the provider and client reward for 1000 COR when emission is 2.5% becomes 250 instead of 25. 25% instead of 2.5%. This situation is not public provider specific - it is caused by the difference between Schelling Supply and Total Token Supply (which will always be bigger due to clients not connected to any provider or due to public providers' funds).

Provider related reward calculation also suffers from the same problem.

I think this could be fixed in a few ways:

  1. stop calculating SchellingSupply in the provider contract and always set it to Total Tokens Supply with every new Schelling round together with Reward. I think this would be best, since a lot of code could be deleted from the Provider contract.
  2. do not calculate the Global Reward, together with the new Schelling round set only Emission Rate %, and then Provider contract would calculate a Reward for each client based only on Client Supply and the Emission Rate. Again, a simplification. The drawback - more code changes and there will not be a single number which would denote the historical Global Reward for each round (only the Emission Rate).
  3. calculate Global Reward from SchellingSupply (instead of Total Supply of Tokens) in the Provider contract. This is the most complex solution.

For cases 1. and 3. one might need to worry about the rounding error - so that the Provider contract does not run out of balance when distributing the rewards.