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

TEST-7: add exchange rate #17

Closed
wants to merge 6 commits into from
Closed

TEST-7: add exchange rate #17

wants to merge 6 commits into from

Conversation

riley-stride
Copy link
Contributor

@riley-stride riley-stride commented May 17, 2022

DO NOT MERGE, LOGIC NOT FINISHED YET

Summary:

Implemented logic to calculate the exchange rate between stToken/Token at deposit and unbonding. The main complication along the way is not being able to figure out how to get return values out of asynchronous ICQ calls, so having to write the result to state rather than handle it in-memory. This required the creation of interchainstaking store variables.

We need rigorous testing in this code (it’s exploitable); this is just a v0 of the logic.

Pointers for review:

  • Most logic lives in stride/x/stakeibc/keeper/exchange_rate.go, where two functions live:
    - getStTokenExchRate calcalates the exchange rate between stAsset/Asset using as a helper the ICQQueryHostBalance function. We use BankKeeper's GetSupply function to calculate supply of stAsset (same approach as QS to calculating stAsset supply). For deposits, inclOutstandingRewards param should be true, for withdrawals, false.
    - ICQQueryHostBalance submits an ICQ call to measure the amount of tokens on host chain either across all delegation accounts, delegated, or in outstanding accrued rewards. Results are written to the host_zone state rather than returned (due to technical limitations described in summary).
  • In proto/stakeibc/host_zone.proto, added connectionID, denominations and state variables used to calc exchange rate (they're updated to measure host zone delegations and balances). Removed rewardsAccount.
  • In stride/proto/stakeibc/params.proto, remove unused ica_account.proto import
  • In stride/x/stakeibc/keeper/exchange_rate.go, replace BinaryCodec with Codec (the former does not allow for cdc.UnmarshalJSON calls required in exchange_rate calc, the latter does. Also, add bankKeeper for exchange_rate stAsset supply calcs.
  • Create stride/x/stakeibc/keeper/zones.go, containing helpers for zones. We could move these functions to zones.go to simplify. <==**TODO move to zones.go **
  • In stride/x/stakeibc/types/keys.go, added prefixes. We may not need these. <==**TODO remove these **

For more details see Jira TEST-7

Note I had to add third_party folder to get this working

@riley-stride riley-stride requested review from shellvish and asalzmann and removed request for shellvish May 17, 2022 21:31
@asalzmann
Copy link
Contributor

Can you add more detail in the summary on the specific files / functions to pay attention to in this PR? It would make it easier for me to give a good review, it's hard to do so when so many LOC have changed (especially when the logic is sensitive).

Thought Vishal did a good job of this here as an example! #14

@riley-stride
Copy link
Contributor Author

Is the content of TEST-7 in Jira what you're looking for? https://stridelabs.atlassian.net/jira/software/projects/TEST/boards/2?selectedIssue=TEST-7. Generally been putting much more detail there than the PRs but happy to copy over or format like Vishal's #14 if that makes things easier

@riley-stride
Copy link
Contributor Author

This should be a cleaner PR now that I moved third_party to its own branch

@asalzmann
Copy link
Contributor

Ticket has the high level context yeah - a couple of bullet point style pointers from the ticket tasks to files / places in code that implement the relevant logic would still be helpful so that I know which parts of the code require the most attention as a reviewer (especially on large PRs that have >1k LOC)

@riley-stride
Copy link
Contributor Author

Ticket has the high level context yeah - a couple of bullet point style pointers from the ticket tasks to files / places in code that implement the relevant logic would still be helpful so that I know which parts of the code require the most attention as a reviewer (especially on large PRs that have >1k LOC)

Thanks this makes a lot of sense. Updated the comments.

@riley-stride riley-stride marked this pull request as draft May 27, 2022 09:55
Copy link
Contributor

@asalzmann asalzmann left a comment

Choose a reason for hiding this comment

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

Cool to see this coming together! Realize this is a draft but left a few comments

const (
HostZoneKey = "HostZone-value-"
HostZoneCountKey = "HostZone-count-"
prefixZone = iota + 1
Copy link
Contributor

Choose a reason for hiding this comment

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

I think iota just resolves to 0, are all of these keys 1? Should they be strings?

repeated Validator blacklistedValidators = 4;
repeated ICAAccount rewardsAccount = 5;
repeated ICAAccount feeAccount = 6;
uint64 id = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Changing proto field ids around like this is risky in production (had a similar comment on another PR that went into depth here) but probably ok given we haven't launched any testnet / mainnet yet

string channelId = 4;
string connectionID = 5;
repeated Validator validators = 6;
repeated ICAAccount delegationAccounts = 7;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a rewardsAccount and a feeAccount here? Also, commented on another PR that all of these ICAAccounts should be singular fields (I think)

(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
string totalAllBalances = 12 [
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
string totalAllBalances = 12 [
string totalBalances = 12 [

}

switch query_type {
case "totalBalance":
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does the syntax for these queries come from? Looks like we're using camelcase?

)

// is this the right keeper?
func (k Keeper) getStTokenExchRate(ctx sdk.Context, hostZone types.HostZone, inclOutstandingRewards bool) (sdk.Dec, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func (k Keeper) getStTokenExchRate(ctx sdk.Context, hostZone types.HostZone, inclOutstandingRewards bool) (sdk.Dec, error) {
func (k Keeper) updateStTokenExchRate(ctx sdk.Context, hostZone types.HostZone, inclOutstandingRewards bool) (sdk.Dec, error) {

suggest this name change so that it's clear this updates the store, and the exchange rate can then be fetched from the store

supplyOfStTokens := k.bankKeeper.GetSupply(ctx, hostZone.StDenom)
k.Logger(ctx).Info("stAsset outstanding supply:", supplyOfStTokens)

exchRate := balOfVirtualPoolOnHost.Quo(supplyOfStTokens.Amount.ToDec())
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than returning an exchange rate, should this just update a variable in the store? That way, we could put this call in the BeginBlocker or EndBlocker (or even in an epoch) and just update the exchange rate on some cadence

k.Logger(ctx).Error("Unable to unmarshal validators info for zone", "zone", zone.ChainId, "err", err)
return err
}
hostZone.TotalAllBalances = sdk.Dec(queryRes.Balances.AmountOf(hostZone.BaseDenom))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this update will have any effect on the store (if that's the intention), I think you need to update the variable then set it in the store.

Also not totally sure whether this variable is scoped to the cbTotalBalance function or if updates persist outside that scope

@riley-stride
Copy link
Contributor Author

Closing this as it's subsumed by TEST-50

riley-stride pushed a commit that referenced this pull request Sep 5, 2022
* Fix CI

* Remove on push due to double run

* Update naming

* Try adding an error

* For some reason commenting seems broken

* CI errors worked!
asalzmann pushed a commit that referenced this pull request Jan 25, 2024
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.

3 participants