Skip to content

Commit

Permalink
send disable tokenization tx for delegation account on hub (#1045)
Browse files Browse the repository at this point in the history
Co-authored-by: sampocs <sam.pochyly@gmail.com>
  • Loading branch information
ethan-stride and sampocs authored Jan 11, 2024
1 parent e8f2d0a commit f65bae9
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 15 deletions.
33 changes: 33 additions & 0 deletions app/upgrades/v17/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package v17

import (
"fmt"
"time"

errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/cosmos/gogoproto/proto"
icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"

Expand All @@ -32,6 +34,9 @@ var (
RedemptionRateOuterMinAdjustment = sdk.MustNewDecFromStr("0.05")
RedemptionRateOuterMaxAdjustment = sdk.MustNewDecFromStr("0.10")

// Define the hub chainId for disabling tokenization
GaiaChainId = "cosmoshub-4"

// Osmosis will have a slighly larger buffer with the redemption rate
// since their yield is less predictable
OsmosisChainId = "osmosis-1"
Expand Down Expand Up @@ -111,6 +116,9 @@ func CreateUpgradeHandler(
return vm, errorsmod.Wrapf(err, "unable to add rate limits to Osmosis")
}

ctx.Logger().Info("Disabling tokenization on the hub...")
DisableTokenization(ctx, stakeibcKeeper, GaiaChainId)

Check failure on line 120 in app/upgrades/v17/upgrades.go

View workflow job for this annotation

GitHub Actions / golangci-lint

Error return value is not checked (errcheck)

ctx.Logger().Info("Executing Prop 225, SHD Liquidity")
if err := ExecuteProp225(ctx, bankKeeper); err != nil {
return vm, errorsmod.Wrapf(err, "unable to execute prop 225")
Expand Down Expand Up @@ -318,6 +326,31 @@ func AddRateLimitToOsmosis(ctx sdk.Context, k ratelimitkeeper.Keeper) error {
return nil
}

// Sends the ICA message which disables LSM style tokenization of shares from the delegation
// account for this chain as a security to prevent possibility of large/fast withdrawls
func DisableTokenization(ctx sdk.Context, k stakeibckeeper.Keeper, chainId string) error {
hostZone, found := k.GetHostZone(ctx, chainId)
if !found {
return errorsmod.Wrapf(stakeibctypes.ErrHostZoneNotFound, "Unable to find chainId %s to remove tokenization", chainId)
}

// Build the msg for the disable tokenization ICA tx
var msgs []proto.Message
msgs = append(msgs, &stakeibctypes.MsgDisableTokenizeShares{
DelegatorAddress: hostZone.DelegationIcaAddress,
})

// Send the ICA tx to disable tokenization
timeoutTimestamp := uint64(ctx.BlockTime().Add(24 * time.Hour).UnixNano())
delegationOwner := stakeibctypes.FormatHostZoneICAOwner(hostZone.ChainId, stakeibctypes.ICAAccountType_DELEGATION)
err := k.SubmitICATxWithoutCallback(ctx, hostZone.ConnectionId, delegationOwner, msgs, timeoutTimestamp)
if err != nil {
return errorsmod.Wrapf(err, "Failed to submit ICA tx to disable tokenization, Messages: %+v", msgs)
}

return nil
}

// Execute Prop 225, release STRD to stride1auhjs4zgp3ahvrpkspf088r2psz7wpyrypcnal
func ExecuteProp225(ctx sdk.Context, k bankkeeper.Keeper) error {
communityPoolGrowthAddress := sdk.MustAccAddressFromBech32(CommunityPoolGrowthAddress)
Expand Down
47 changes: 40 additions & 7 deletions app/upgrades/v17/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
ibctesting "github.com/cosmos/ibc-go/v7/testing"
"github.com/stretchr/testify/suite"

icqtypes "github.com/Stride-Labs/stride/v16/x/interchainquery/types"
Expand All @@ -20,7 +21,6 @@ import (
)

const (
GaiaChainId = "cosmoshub-4"
SommelierChainId = "sommelier-3"

Atom = "uatom"
Expand Down Expand Up @@ -69,11 +69,16 @@ func TestKeeperTestSuite(t *testing.T) {
func (s *UpgradeTestSuite) TestUpgrade() {
dummyUpgradeHeight := int64(5)

// Create the gaia delegation channel
owner := stakeibctypes.FormatHostZoneICAOwner(v17.GaiaChainId, stakeibctypes.ICAAccountType_DELEGATION)
channelId, portId := s.CreateICAChannel(owner)

// Setup store before upgrade
checkHostZonesAfterUpgrade := s.SetupHostZonesBeforeUpgrade()
checkRateLimitsAfterUpgrade := s.SetupRateLimitsBeforeUpgrade()
checkCommunityPoolTaxAfterUpgrade := s.SetupCommunityPoolTaxBeforeUpgrade()
checkQueriesAfterUpgrade := s.SetupQueriesBeforeUpgrade()
checkDisableTokenizationICASubmitted := s.SetupTestDisableTokenization(channelId, portId)
checkProp225AfterUpgrade := s.SetupProp225BeforeUpgrade()

// Submit upgrade and confirm handler succeeds
Expand All @@ -84,6 +89,7 @@ func (s *UpgradeTestSuite) TestUpgrade() {
checkRateLimitsAfterUpgrade()
checkCommunityPoolTaxAfterUpgrade()
checkQueriesAfterUpgrade()
checkDisableTokenizationICASubmitted()
checkProp225AfterUpgrade()
}

Expand Down Expand Up @@ -126,9 +132,9 @@ func (s *UpgradeTestSuite) checkCommunityPoolICAAccountsRegistered(chainId strin
func (s *UpgradeTestSuite) SetupHostZonesBeforeUpgrade() func() {
hostZones := []stakeibctypes.HostZone{
{
ChainId: GaiaChainId,
ChainId: v17.GaiaChainId,
HostDenom: Atom,
ConnectionId: "connection-1",
ConnectionId: ibctesting.FirstConnectionID, // must be connection-0 since an ICA will be submitted
Validators: []*stakeibctypes.Validator{
{Address: "val1", SlashQueryInProgress: false},
{Address: "val2", SlashQueryInProgress: true},
Expand Down Expand Up @@ -169,14 +175,14 @@ func (s *UpgradeTestSuite) SetupHostZonesBeforeUpgrade() func() {
// Return callback to check store after upgrade
return func() {
// Check that the module and ICA accounts were registered
s.checkCommunityPoolModuleAccountsRegistered(GaiaChainId)
s.checkCommunityPoolModuleAccountsRegistered(v17.GaiaChainId)
s.checkCommunityPoolModuleAccountsRegistered(v17.OsmosisChainId)

s.checkCommunityPoolICAAccountsRegistered(GaiaChainId)
s.checkCommunityPoolICAAccountsRegistered(v17.GaiaChainId)
s.checkCommunityPoolICAAccountsRegistered(v17.OsmosisChainId)

// Check that the redemption rate bounds were set
gaiaHostZone, found := s.App.StakeibcKeeper.GetHostZone(s.Ctx, GaiaChainId)
gaiaHostZone, found := s.App.StakeibcKeeper.GetHostZone(s.Ctx, v17.GaiaChainId)
s.Require().True(found)

s.Require().Equal(sdk.MustNewDecFromStr("1.045"), gaiaHostZone.MinRedemptionRate, "gaia min outer") // 1.1 - 5% = 1.045
Expand Down Expand Up @@ -274,7 +280,7 @@ func (s *UpgradeTestSuite) SetupRateLimitsBeforeUpgrade() func() {
stAtomToGaiaRateLimit, found := s.App.RatelimitKeeper.GetRateLimit(s.Ctx, StAtom, gaiaChannelId)
s.Require().True(found)

atomThreshold := v17.UpdatedRateLimits[GaiaChainId]
atomThreshold := v17.UpdatedRateLimits[v17.GaiaChainId]
s.Require().Equal(atomThreshold, stAtomToGaiaRateLimit.Quota.MaxPercentSend, "statom -> gaia max percent send")
s.Require().Equal(atomThreshold, stAtomToGaiaRateLimit.Quota.MaxPercentRecv, "statom -> gaia max percent recv")
s.Require().Equal(initialFlow, stAtomToGaiaRateLimit.Flow.Outflow, "statom -> gaia outflow")
Expand Down Expand Up @@ -344,6 +350,17 @@ func (s *UpgradeTestSuite) SetupQueriesBeforeUpgrade() func() {
}
}

func (s *UpgradeTestSuite) SetupTestDisableTokenization(channelId, portId string) func() {
// Get the current sequence number (to check that it incremented)
startSequence := s.MustGetNextSequenceNumber(portId, channelId)

// Return callback to that the ICA was submitted
return func() {
endSequence := s.MustGetNextSequenceNumber(portId, channelId)
s.Require().Equal(startSequence+1, endSequence, "sequence number should have incremented from disabling detokenization")
}
}

func (s *UpgradeTestSuite) SetupProp225BeforeUpgrade() func() {
// Grab the community pool growth address and balance
communityPoolGrowthAddress := sdk.MustAccAddressFromBech32(v17.CommunityPoolGrowthAddress)
Expand Down Expand Up @@ -725,3 +742,19 @@ func (s *UpgradeTestSuite) TestAddRateLimitToOsmosis() {
err = v17.AddRateLimitToOsmosis(s.Ctx, s.App.RatelimitKeeper)
s.Require().ErrorContains(err, "channel value is zero")
}

func (s *UpgradeTestSuite) TestDisableTokenization() {
// Create the host zone and delegation channel
owner := stakeibctypes.FormatHostZoneICAOwner(v17.GaiaChainId, stakeibctypes.ICAAccountType_DELEGATION)
channelId, portId := s.CreateICAChannel(owner)

s.App.StakeibcKeeper.SetHostZone(s.Ctx, stakeibctypes.HostZone{
ChainId: v17.GaiaChainId,
ConnectionId: ibctesting.FirstConnectionID,
})

// Call the disable function and confirm the sequence number incremented (indicating an ICA was submitted)
s.CheckICATxSubmitted(portId, channelId, func() error {
return v17.DisableTokenization(s.Ctx, s.App.StakeibcKeeper, v17.GaiaChainId)
})
}
9 changes: 9 additions & 0 deletions proto/cosmos/staking/v1beta1/lsm_tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,12 @@ message MsgRedeemTokensForShares {
message MsgRedeemTokensForSharesResponse {
cosmos.base.v1beta1.Coin amount = 1 [ (gogoproto.nullable) = false ];
}

// MsgDisableTokenizeShares prevents LSM tokenization of shares for address
message MsgDisableTokenizeShares {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;

string delegator_address = 1
[ (gogoproto.moretags) = "yaml:\"delegator_address\"" ];
}
Loading

0 comments on commit f65bae9

Please sign in to comment.