Skip to content

Commit

Permalink
loosened outer redemption rate bounds for all host zones (#1280)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Aug 30, 2024
1 parent 91be901 commit 00b9f40
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
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)
}
}
}

0 comments on commit 00b9f40

Please sign in to comment.