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

loosened outer redemption rate bounds for all host zones #1280

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions app/upgrades/v24/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ import (

var (
UpgradeName = "v24"

// Redemption rate bounds updated to give ~3 months of slack on outer bounds
RedemptionRateOuterMinAdjustment = sdk.MustNewDecFromStr("0.05")
RedemptionRateOuterMaxAdjustment = sdk.MustNewDecFromStr("0.10")

// Osmosis will have a slighly larger buffer with the redemption rate
// since their yield is less predictable
OsmosisChainId = "osmosis-1"
OsmosisRedemptionRateBuffer = sdk.MustNewDecFromStr("0.02")
)

// CreateUpgradeHandler creates an SDK upgrade handler for v23
Expand All @@ -31,6 +40,7 @@ func CreateUpgradeHandler(
MigrateHostZones(ctx, stakeibcKeeper)
MigrateDepositRecords(ctx, recordsKeeper)
MigrateEpochUnbondingRecords(ctx, recordsKeeper)
UpdateRedemptionRateBounds(ctx, stakeibcKeeper)

ctx.Logger().Info("Running module migrations...")
return mm.RunMigrations(ctx, configurator, vm)
Expand Down Expand Up @@ -117,3 +127,27 @@ func MigrateEpochUnbondingRecords(ctx sdk.Context, k recordskeeper.Keeper) {
k.SetEpochUnbondingRecord(ctx, epochUnbondingRecord)
}
}

// Updates the outer redemption rate bounds
func UpdateRedemptionRateBounds(ctx sdk.Context, k stakeibckeeper.Keeper) {
ctx.Logger().Info("Updating redemption rate bounds...")

for _, hostZone := range k.GetAllHostZone(ctx) {
// Give osmosis a bit more slack since OSMO stakers collect real yield
outerAdjustment := RedemptionRateOuterMaxAdjustment
if hostZone.ChainId == OsmosisChainId {
outerAdjustment = outerAdjustment.Add(OsmosisRedemptionRateBuffer)
}

outerMinDelta := hostZone.RedemptionRate.Mul(RedemptionRateOuterMinAdjustment)
outerMaxDelta := hostZone.RedemptionRate.Mul(outerAdjustment)

outerMin := hostZone.RedemptionRate.Sub(outerMinDelta)
outerMax := hostZone.RedemptionRate.Add(outerMaxDelta)

hostZone.MinRedemptionRate = outerMin
hostZone.MaxRedemptionRate = outerMax

k.SetHostZone(ctx, hostZone)
}
}
61 changes: 59 additions & 2 deletions app/upgrades/v24/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ package v24_test
import (
"testing"

"github.com/stretchr/testify/suite"

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"

"github.com/Stride-Labs/stride/v24/app/apptesting"
v24 "github.com/Stride-Labs/stride/v24/app/upgrades/v24"
recordstypes "github.com/Stride-Labs/stride/v24/x/records/types"
stakeibctypes "github.com/Stride-Labs/stride/v24/x/stakeibc/types"
)

type UpdateRedemptionRateBounds struct {
ChainId string
CurrentRedemptionRate sdk.Dec
ExpectedMinOuterRedemptionRate sdk.Dec
ExpectedMaxOuterRedemptionRate sdk.Dec
}

type UpgradeTestSuite struct {
apptesting.AppTestHelper
}
Expand Down Expand Up @@ -59,6 +66,8 @@ func (s *UpgradeTestSuite) TestUpgrade() {
},
})

checkRedemptionRatesAfterUpgrade := s.SetupTestUpdateRedemptionRateBounds()

// Run the upgrade
s.ConfirmUpgradeSucceededs(v24.UpgradeName, upgradeHeight)

Expand All @@ -79,6 +88,8 @@ func (s *UpgradeTestSuite) TestUpgrade() {
s.Require().Equal(stTokens.Int64(), hostZoneUnbonding.StTokensToBurn.Int64(), "sttokens to burn")
s.Require().Equal(nativeTokens.Int64(), hostZoneUnbonding.NativeTokensToUnbond.Int64(), "native to unbond")
s.Require().Zero(hostZoneUnbonding.ClaimableNativeTokens.Int64(), "claimable tokens")

checkRedemptionRatesAfterUpgrade()
}

func (s *UpgradeTestSuite) TestMigrateHostZones() {
Expand Down Expand Up @@ -256,3 +267,49 @@ func (s *UpgradeTestSuite) TestMigrateEpochUnbondingRecords() {
"%s undelegation txs in progress", tc.chainId)
}
}

func (s *UpgradeTestSuite) SetupTestUpdateRedemptionRateBounds() func() {
// Define test cases consisting of an initial redemption rate and expected bounds
testCases := []UpdateRedemptionRateBounds{
{
ChainId: "chain-0",
CurrentRedemptionRate: sdk.MustNewDecFromStr("1.0"),
ExpectedMinOuterRedemptionRate: sdk.MustNewDecFromStr("0.95"), // 1 - 5% = 0.95
ExpectedMaxOuterRedemptionRate: sdk.MustNewDecFromStr("1.10"), // 1 + 10% = 1.1
},
{
ChainId: "chain-1",
CurrentRedemptionRate: sdk.MustNewDecFromStr("1.1"),
ExpectedMinOuterRedemptionRate: sdk.MustNewDecFromStr("1.045"), // 1.1 - 5% = 1.045
ExpectedMaxOuterRedemptionRate: sdk.MustNewDecFromStr("1.210"), // 1.1 + 10% = 1.21
},
{
// Max outer for osmo uses 12% instead of 10%
ChainId: v24.OsmosisChainId,
CurrentRedemptionRate: sdk.MustNewDecFromStr("1.25"),
ExpectedMinOuterRedemptionRate: sdk.MustNewDecFromStr("1.1875"), // 1.25 - 5% = 1.1875
ExpectedMaxOuterRedemptionRate: sdk.MustNewDecFromStr("1.4000"), // 1.25 + 12% = 1.400
},
}

// Create a host zone for each test case
for _, tc := range testCases {
hostZone := stakeibctypes.HostZone{
ChainId: tc.ChainId,
RedemptionRate: tc.CurrentRedemptionRate,
}
s.App.StakeibcKeeper.SetHostZone(s.Ctx, hostZone)
}

// Return callback to check store after upgrade
return func() {
// Confirm they were all updated
for _, tc := range testCases {
hostZone, found := s.App.StakeibcKeeper.GetHostZone(s.Ctx, tc.ChainId)
s.Require().True(found)

s.Require().Equal(tc.ExpectedMinOuterRedemptionRate, hostZone.MinRedemptionRate, "%s - min outer", tc.ChainId)
s.Require().Equal(tc.ExpectedMaxOuterRedemptionRate, hostZone.MaxRedemptionRate, "%s - max outer", tc.ChainId)
}
}
}
Loading