Open ueco-jb opened 2 years ago
Let's update the interest calculation from https://github.com/confio/lendex/issues/47 before starting this issue, as that may change some of the accumulated errors.
Some concrete proposals we can try:
panicked at 'called
Result::unwrap()on an
Errvalue: Cannot process zero tokens
no longer happens when trying to send 1 TokenThis should "fix" the major problems associated with this issue. And those test cases showing where rounding still happens will serve as documentation if we really want to root out the last issue.
Another idea - as likely some rounding issue will pop anyway, create a function/macro similar to assert_eq
, which will include some offset to include that rounding error (currently it's 1-2 top):
// offset = 0.2%
assert_eq_with_offset!(1000, 1002, offset)
Just as a helper in tests.
Let's do this after #109 since that PR affects the calculations.
At this point, this is about reviewing if we still have significant rounding issues. Minor ones are expected.
Initial MULTIPLIER to 100,000 (that is 100,000 shares to 1 token), which should provide more accuracy
Demo with simple frontend has shown that this is still an issue. To the point, where depositing and immediate withdrawal of 10000 tokens ended up with bug, because available amount was actually 9999.
Couple loose ideas: 0) We should stick to the rule - perform as least (or as late) as possible changing denoms and corresponding amounts. 1) Review token contract implementation, so that we perform as few multiplications as possible, for example here. https://github.com/confio/isotonic/blob/main/contracts/isotonic-token/src/contract.rs#L104-L115 Maybe we could cut some stuff down, or simplify it in specific cases. 2) Expand our tests, so that for example after 100 iterations of transactions from A to B and reversed account balances are exactly the same.
To the point, where depositing and immediate withdrawal of 10000 tokens ended up with bug, because available amount was actually 9999.
I think we will always have off by 1 rounding. The issue we had earlier is when I saw 3 or 4 units, which seemed to amplify over time.
If you do 100 trades and end up off by 100, that is more of an issue than doing 100 trades and being off by 1 or 2. We cannot reduce rounding errors below 1, but let's try to keep them from accumulating and compounding
I understand the cause and that it will happen, but still - I'm trying to figure out how should we accomodate the fact, that user might not be able to withdraw all tokens he just deposited. It's not even about interest rates that changes the amounts.
We don't want frontend to adjust any values, right? I wonder how we could mitigate that rounding issues, so at least user is able to perform operations on actual amounts that are displayed.
If I deposit 100 ATOM and withdraw 99.999999 ATOM, that is a bit odd, but not a major problem IMO.
If I wait a few days, it will be 100.102315 or something like that anyway.
People are used to paying a few tokens in gas every transaction, so a loss of a millionth or two is not an issue... unless that builds up to 0.1 loss after a few months (or letting the tokens sit)
If I deposit 100 ATOM and withdraw 99.999999 ATOM, that is a bit odd
What I'm considering:
because for me user's convinence should probably come first
Ah, I see the issue.
Let's figure this out when we start integrating the frontend, and figure out where they need to do this. Maybe there is a "max" button that just prefills the largest amount (via query) and we should ensure that works.
There's still an issue I mentioned and Ethan reflected: https://github.com/confio/isotonic/issues/40#issuecomment-1077917177 I think this still could/should be somehow tracked, because it's not yet decided whether that should be frontned or contracts
Aaaand I've just proven there's still a problem with a deposit(x) -> withdraw(x) scenario in some cases. Reopening.
The problem seems to be around how we calculate the transferable
amount. Maybe some kind of edge case code is in order?
Suggestion: If Alice has 0 debt in TotalCreditLine, transferable_amount
simply returns ∞ without doing pointless division?
Note (Ethan): Please tackle #47 first, as mentioned in my comment
Solve them, once and for all!
Some operations currently might panic (in tests):
might panic with:
or
One of many examples. Basically every place that contains calulations that included fractions is prone to errors. Especially observable while doing interest rate charge computations.
Ethan suggested changing
MULTIPLIER
1% to 1 permille (1/1000) for better "accuracy": https://github.com/confio/lendex/blob/main/contracts/lendex-token/src/contract.rs#L53 although this is still not perfect and rounding errors still occues (rarely though).