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

[Performance] Don't go into main loop if it is last period for vesting and unlock #141

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from

Conversation

axiongsupra
Copy link

No description provided.

@axiongsupra
Copy link
Author

@sjoshisupra I think this is trickier than I expected since I need to write separate test cases to cover whether the remaining amount is divisible or not. I have the implementation passed all the test cases now. I will write additional test cases later.

Copy link

@sjoshisupra sjoshisupra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If schedule is 2/10, 3/10, 1/10, then add two test cases

  1. Directly fast forward to a point from the beginning where 5/10 would be vested
  2. Directly fast forward to a case from the beginning where 7/10 would be vested
    In both cases above that exactly needed amount is vested and nothing more.

Comment on lines 65 to 67
if ((x_raw as u256) % (y_raw as u256) != 0) {
result = result + 1;
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this logic needed here? When you divide two fixed point values and want to return a fixed point value, no scaling is needed. I don't see any reason why if the remainder is non-zero, we should add 1 to the result.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also check that divisor is non zero before performing the division.

Comment on lines 58 to 70

/// Returns x / y. The result cannot be greater than MAX_U128.
public fun divide(x: FixedPoint64, y: FixedPoint64): FixedPoint64 {
let x_raw = get_raw_value(x);
let y_raw = get_raw_value(y);
// If it is divisable, return the result. If not, return the result + 1.
let result = (x_raw as u256) / (y_raw as u256);
if ((x_raw as u256) % (y_raw as u256) != 0) {
result = result + 1;
};
assert!(result <= MAX_U128, ERATIO_OUT_OF_RANGE);
create_from_raw_value((result as u128))
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this division is correct. If both numbers have 64 bit allotted for fractional value, after division, the fraction would disappear. I believe x_raw << 64 would be required before performing the division to ensure result still has 64 bit fractional bits.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't even need it right now as we did not use this anymore. Do we need to keep this function?

@axiongsupra
Copy link
Author

If schedule is 2/10, 3/10, 1/10, then add two test cases

  1. Directly fast forward to a point from the beginning where 5/10 would be vested
  2. Directly fast forward to a case from the beginning where 7/10 would be vested
    In both cases above that exactly needed amount is vested and nothing more.

Test cases are added. 5/10 needs an addition of 2 and 7/10 needs an addition of 3 for the assertions. This behavior is also consistent with dev branch.

contract_address) * 2);
vest(contract_address);
vested_amount = vested_amount + fraction(shareholder_share, 5, 10);
assert!(coin::balance<SupraCoin>(shareholder_address) + 2 == vested_amount, 0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this + 2 required in assert? @axiongsupra

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sjoshisupra The actual vested value for each iteration is 199, 299. So in total would be 498 while the calculated vested amount is 500.

contract_address) * 4);
vest(contract_address);
vested_amount = vested_amount + fraction(shareholder_share, 7, 10);
assert!(coin::balance<SupraCoin>(shareholder_address) + 3 == vested_amount, 0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@axiongsupra why is this + 3 required here? Given that 2/10, 3/10, 1/10 can multiply perfectly with 1000.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual vested value is 199, 299, 99, 99 so in total is 696 while the calculated vested amount is 699 in vested_amount = vested_amount + fraction(shareholder_share, 7, 10)

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

Successfully merging this pull request may close these issues.

2 participants