diff --git a/CHANGELOG.md b/CHANGELOG.md index 152ad7ae9a..331fac5d5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,6 +99,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Bump cometbft to v0.34.29 (from v0.34.28) [PR 1649](https://github.com/provenance-io/provenance/pull/1649). * Add genesis/init for Marker module send deny list addresses. [#1660](https://github.com/provenance-io/provenance/issues/1660) * Add automatic changelog entries for dependabot. [#1674](https://github.com/provenance-io/provenance/issues/1674) +* Add upgrade handler to set net asset values to markers [PR 1712](https://github.com/provenance-io/provenance/pull/1712). * Add publishing of docker arm64 container builds [#1634](https://github.com/provenance-io/provenance/issues/1634) * Ensure IBC marker has matching supply [#1706](https://github.com/provenance-io/provenance/issues/1706). diff --git a/app/navs_mainnet.go b/app/navs_mainnet.go index 98b58298d1..3e6bc51a4f 100644 --- a/app/navs_mainnet.go +++ b/app/navs_mainnet.go @@ -2,10 +2,14 @@ package app import ( "github.com/cosmos/cosmos-sdk/types" + markertypes "github.com/provenance-io/provenance/x/marker/types" ) -func GetDenomToNav() map[string]markertypes.NetAssetValue { +// GetPioMainnet1DenomToNav are net asset values for the pio-mainnet-1 taken at blockheight 13631650 +// Source: https://figure.tech/service-pricing-engine/external/api/v1/pricing/marker/new?time=2023-11-07T17:59:59.999722Z +// NOTE: These should not be ran against any other network but pio-mainnet-1 +func GetPioMainnet1DenomToNav() map[string]markertypes.NetAssetValue { return map[string]markertypes.NetAssetValue{ "pm.participation.agreement.1bcslgccejhm9v3higsx7c": markertypes.NewNetAssetValue(types.NewInt64Coin(markertypes.UsdDenom, 1037949704), 1), "pm.participation.agreement.1cag7ztnmm4rdbbtwdrodb": markertypes.NewNetAssetValue(types.NewInt64Coin(markertypes.UsdDenom, 788900239), 1), diff --git a/app/upgrades.go b/app/upgrades.go index 9254bac161..56739f8c95 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -23,7 +23,7 @@ import ( "github.com/provenance-io/provenance/x/exchange" "github.com/provenance-io/provenance/x/hold" ibchookstypes "github.com/provenance-io/provenance/x/ibchooks/types" - "github.com/provenance-io/provenance/x/marker/types" + markertypes "github.com/provenance-io/provenance/x/marker/types" msgfeetypes "github.com/provenance-io/provenance/x/msgfees/types" oracletypes "github.com/provenance-io/provenance/x/oracle/types" triggertypes "github.com/provenance-io/provenance/x/trigger/types" @@ -164,6 +164,9 @@ var upgrades = map[string]appUpgrade{ removeInactiveValidatorDelegations(ctx, app) setupICQ(ctx, app) updateMaxSupply(ctx, app) + + addMarkerNavs(ctx, app, GetPioMainnet1DenomToNav()) + setExchangeParams(ctx, app) updateIbcMarkerDenomMetadata(ctx, app) @@ -377,6 +380,22 @@ func updateMaxSupply(ctx sdk.Context, app *App) { ctx.Logger().Info("Done updating MaxSupply marker param") } +// addMarkerNavs adds navs to existing markers +func addMarkerNavs(ctx sdk.Context, app *App, denomToNav map[string]markertypes.NetAssetValue) { + ctx.Logger().Info("Adding marker net asset values") + for denom, nav := range denomToNav { + marker, err := app.MarkerKeeper.GetMarkerByDenom(ctx, denom) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("unable to get marker %v: %v", denom, err)) + continue + } + if err := app.MarkerKeeper.AddSetNetAssetValues(ctx, marker, []markertypes.NetAssetValue{nav}, "upgrade_handler"); err != nil { + ctx.Logger().Error(fmt.Sprintf("unable to set net asset value %v: %v", nav, err)) + } + } + ctx.Logger().Info("Done adding marker net asset values") +} + // setExchangeParams sets exchange module's params to the defaults. // TODO: Remove with the saffron handlers. func setExchangeParams(ctx sdk.Context, app *App) { @@ -396,7 +415,7 @@ func setExchangeParams(ctx sdk.Context, app *App) { // TODO: Remove with the saffron handlers. func updateIbcMarkerDenomMetadata(ctx sdk.Context, app *App) { ctx.Logger().Info("Updating ibc marker denom metadata") - app.MarkerKeeper.IterateMarkers(ctx, func(record types.MarkerAccountI) bool { + app.MarkerKeeper.IterateMarkers(ctx, func(record markertypes.MarkerAccountI) bool { if !strings.HasPrefix(record.GetDenom(), "ibc/") { return false } diff --git a/app/upgrades_test.go b/app/upgrades_test.go index 8628ce4471..88e34fc12e 100644 --- a/app/upgrades_test.go +++ b/app/upgrades_test.go @@ -25,6 +25,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/provenance-io/provenance/x/exchange" + markertypes "github.com/provenance-io/provenance/x/marker/types" msgfeetypes "github.com/provenance-io/provenance/x/msgfees/types" ) @@ -465,6 +466,8 @@ func (s *UpgradeTestSuite) TestSaffron() { "INF Done updating ICQ params", "INF Updating MaxSupply marker param", "INF Done updating MaxSupply marker param", + "INF Adding marker net asset values", + "INF Done adding marker net asset values", "INF Ensuring exchange module params are set.", "INF Updating ibc marker denom metadata", "INF Done updating ibc marker denom metadata", @@ -868,6 +871,77 @@ func (s *UpgradeTestSuite) TestSetAccountDataNameRecord() { s.AssertLogContents(logOutput, expInLog, nil, true, "setAccountDataNameRecord") } +func (s *UpgradeTestSuite) TestAddMarkerNavs() { + address1 := sdk.AccAddress("address1") + testcoin := markertypes.NewEmptyMarkerAccount("testcoin", + address1.String(), + []markertypes.AccessGrant{}) + testcoin.Supply = sdk.OneInt() + s.Require().NoError(s.app.MarkerKeeper.AddMarkerAccount(s.ctx, testcoin), "AddMarkerAccount() error") + + testcoinInList := markertypes.NewEmptyMarkerAccount("testcoininlist", + address1.String(), + []markertypes.AccessGrant{}) + testcoinInList.Supply = sdk.OneInt() + s.Require().NoError(s.app.MarkerKeeper.AddMarkerAccount(s.ctx, testcoinInList), "AddMarkerAccount() error") + + nosupplycoin := markertypes.NewEmptyMarkerAccount("nosupplycoin", + address1.String(), + []markertypes.AccessGrant{}) + s.Require().NoError(s.app.MarkerKeeper.AddMarkerAccount(s.ctx, nosupplycoin), "AddMarkerAccount() error") + + hasnavcoin := markertypes.NewEmptyMarkerAccount("hasnavcoin", + address1.String(), + []markertypes.AccessGrant{}) + hasnavcoin.Supply = sdk.NewInt(100) + s.Require().NoError(s.app.MarkerKeeper.AddMarkerAccount(s.ctx, hasnavcoin), "AddMarkerAccount() error") + presentnav := markertypes.NewNetAssetValue(sdk.NewInt64Coin(markertypes.UsdDenom, int64(55)), uint64(100)) + s.Require().NoError(s.app.MarkerKeeper.AddSetNetAssetValues(s.ctx, hasnavcoin, []markertypes.NetAssetValue{presentnav}, "test")) + + addMarkerNavs(s.ctx, s.app, map[string]markertypes.NetAssetValue{ + "testcoininlist": {Price: sdk.NewInt64Coin(markertypes.UsdDenom, int64(12345)), Volume: uint64(1)}, + }) + + tests := []struct { + name string + markerAddr sdk.AccAddress + expNav *markertypes.NetAssetValue + }{ + { + name: "already has nav", + markerAddr: hasnavcoin.GetAddress(), + expNav: &markertypes.NetAssetValue{Price: sdk.NewInt64Coin(markertypes.UsdDenom, int64(55)), Volume: uint64(100)}, + }, + { + name: "nav add fails for coin", + markerAddr: nosupplycoin.GetAddress(), + expNav: nil, + }, + { + name: "nav set from custom config", + markerAddr: testcoinInList.GetAddress(), + expNav: &markertypes.NetAssetValue{Price: sdk.NewInt64Coin(markertypes.UsdDenom, int64(12345)), Volume: uint64(1)}, + }, + } + for _, tc := range tests { + s.Run(tc.name, func() { + netAssetValues := []markertypes.NetAssetValue{} + err := s.app.MarkerKeeper.IterateNetAssetValues(s.ctx, tc.markerAddr, func(state markertypes.NetAssetValue) (stop bool) { + netAssetValues = append(netAssetValues, state) + return false + }) + s.Require().NoError(err, "IterateNetAssetValues err") + if tc.expNav != nil { + s.Assert().Len(netAssetValues, 1, "Should be 1 nav set for testcoin") + s.Assert().Equal(tc.expNav.Price, netAssetValues[0].Price, "Net asset value price should equal default upgraded price") + s.Assert().Equal(tc.expNav.Volume, netAssetValues[0].Volume, "Net asset value volume should equal 1") + } else { + s.Assert().Len(netAssetValues, 0, "Marker not expected to have nav") + } + }) + } +} + func (s *UpgradeTestSuite) TestSetExchangeParams() { startMsg := "INF Ensuring exchange module params are set." noopMsg := "INF Exchange module params are already defined." @@ -917,7 +991,6 @@ func (s *UpgradeTestSuite) TestSetExchangeParams() { expInLog: []string{startMsg, noopMsg, doneMsg}, }, } - for _, tc := range tests { s.Run(tc.name, func() { s.app.ExchangeKeeper.SetParams(s.ctx, tc.existingParams)