Handle precision error case in tokenize shares and change shareToken to map 1:1 with shares #19
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
High level changelog
I would recommend viewing this PR commit by commit to differentiate these two changes
Context on shares and tokens
In the SDK, delegations are denominated using shares - and are converted to tokens when necessary using the validator's exchange rate. This way, when a validator is slashed, the number of shares remains the same, but the number of tokens (and thus the exchange rate) decreases.
Example:
→ This creates a delegation record with 1000 shares
→ Now Validator X has only 950k tokens, but still 1M shares (exchange rate of 0.95)
→ Alice's delegation still has 1000 shares, but those shares are now worth 950 tokens
→ Bob receives 1052.6 shares (1000 ATOM / 0.95 exchange rate = 1052.6 shares)
→ Those shares are worth 1000 ATOM (1052.6 shares * 0.95 exchange rate = 1000 ATOM)
Change #1 - Handle precision error during tokenization
Context
Due to the decimal to integer conversion that happens between shares and tokens, there is the potential for precision error to cause the loss of a token during unbonding. This situation has been present in the SDK and was not a consequence of LSM. Often on mainnet cosmoshub, if a validator has had more than 1 slash and has a long decimal exchange rate, undelegating
X
will return onlyX-1
tokens.How this relates to LSM: During the
TokenizeShares
transaction, the tokenizer's delegation record is removed and replaced with a new delegation record that has a TokenizeShareModuleAccount as the owner. Similarly, inRedeemTokensForShares
, the TokenizeShareModuleAccount's delegation record is replaced with a new one owned by the tokenizer. Under the hood, in both of these functions, theUnbond
function is called to remove the original record, and thenDelegate
is called to create the new one.The Issue:
TokenizeShares
attempts to callUnbond
andDelegate
with the same amount, but if theUnbond
step returned 1 less token due to a precision error, theDelegate
step would fail due to insufficient funds. The impact is that it would cause tokenization's to fail anytime there was precision error.Changelog
Delegate
call in Tokenization to use the amount returned from theUnbond
call, instead of the amount specified as a message parameterUnbond
call, where the new amount isn't knownmsg.Amount
variable for clarifyChange #2 - Changed LSM share tokens to map 1:1 with shares
Context
Currently LSM share tokens are returned 1:1 based on the number of delegated tokens that are tokenized (e.g. tokenizing 1 ATOM, returns 1 LSM share token). However, it makes more sense to return the share tokens such that they map 1:1 with delegation's shares, for the following reasons:
Changelog
Since shares is used under the hood, the only necessary changes here were on the minting/burning of LSM share tokens in
TokenizeShares
andRedeemTokensForShares
- no accounting or record keeping changes were required.TokenizeShares
to return share tokens 1:1 with sharesRedeemTokensForShares
by removing conversion of shareToken to shares (as it is now unnecessary)