Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tweak the STO calculation implementation #301

Open
marv-engine opened this issue Jan 25, 2015 · 2 comments
Open

tweak the STO calculation implementation #301

marv-engine opened this issue Jan 25, 2015 · 2 comments

Comments

@marv-engine
Copy link

@m21 @zathras-crypto @dexX7 @dacoinminster @CraigSellars @msgilligan @achamely

Re:

Implementation Note: It is possible, even likely, that the number of coins calculated to be transferred to an owner's address will have to be rounded to comply with the precision for representing quantities of that coin. To reward the owners of the largest quantities and to try to ensure they receive full distributions, the following method must be used: compute the amount for the largest holder and, if necessary, round that amount up to the nearest unit that can be represented for the currency. Then subtract that rounded amount from the total to be distributed and repeat for the next largest holder until there are no more coins to be distributed.

If I understand the current implementation, the amount that goes to each owner is calculated based on the owner's proportion to the total amount owned by everyone but the STO sender.

Here's my recommendation, and what I envisioned when I wrote the sentence:

Then subtract that rounded amount from the total to be distributed and repeat for the next largest holder until there are no more coins to be distributed.

After subtracting the rounded amount from the total to be distributed, use the resulting remaining total rather than the original total, in the calculation of the amount to be distributed to the next largest owner. This means that the next largest owner will have a larger percentage of a smaller amount. Mathematically the amount for each owner works out exactly the same, but my approach can result in more digits of precision because each remaining owner's percentage increases as the total amount decreases. Using the original total for each owner will result in smaller and smaller percentages calculated, which could approach 0.

@dexX7
Copy link
Member

dexX7 commented Jan 25, 2015

@marv-engine: do you have an example to show the difference? I'm not yet sure, if there is one.

Regarding the implementation: it's currently not sufficient imho, as the SendToManyOwners test and some others I tested with showed, and I pushed a PR to handle the full range of numbers.

The core logic is currently (in a bit more expressive form):

double percentage = (double) ownersBalance / (double) totalTokens;
double piece = percentage * (double) amountToDistribute;
int64_t shouldReceive = (int64_t) ceil(piece);

To avoid fractional numbers altogether, I solely use integer math and changed it to:

int128_t temp = (int128_t) ownersBalance * (int128_t) amountToDistribute;
int128_t piece = 1 + ((temp - 1) / (int128_t) totalTokens);
int64_t shouldReceive = (int64_t) piece;

Both then update the amount left:

int64_t willReallyReceive = min(amountLeft, shouldReceive);
amountLeft = amountLeft - willReallyReceive;

Edit: int/int always rounds down, e.g.:

9223372036854775807 / 9223372036854775806 = 1
9223372036854775806 / 9223372036854775807 = 0

And 1 + (divident - 1) / divisor can be used to round the result of a divsion up.

@marv-engine
Copy link
Author

@dexX7 I don't know if there is a difference, but it seems less likely to underflow or overflow. If that's not the case, then we can close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants