Skip to content

Commit

Permalink
staketia migration - staketia accounting (#1214)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Jun 7, 2024
1 parent cb0f7e7 commit aa25564
Show file tree
Hide file tree
Showing 19 changed files with 150 additions and 1,329 deletions.
41 changes: 3 additions & 38 deletions proto/stride/staketia/staketia.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,45 +35,8 @@ message HostZone {
string safe_address_on_stride = 11
[ (cosmos_proto.scalar) = "cosmos.AddressString" ];

// Previous redemption rate
string last_redemption_rate = 12 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// Current redemption rate
string redemption_rate = 13 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// Min outer redemption rate - adjusted by governance
string min_redemption_rate = 14 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// Max outer redemption rate - adjusted by governance
string max_redemption_rate = 15 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// Min inner redemption rate - adjusted by controller
string min_inner_redemption_rate = 16 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
// Max inner redemption rate - adjusted by controller
string max_inner_redemption_rate = 17 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];

// Total delegated balance on the host zone delegation account
string delegated_balance = 18 [
string remaining_delegated_balance = 18 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
Expand All @@ -82,6 +45,8 @@ message HostZone {
uint64 unbonding_period_seconds = 19;
// Indicates whether the host zone has been halted
bool halted = 20;

reserved 13;
}

// Status fields for a delegation record
Expand Down
11 changes: 1 addition & 10 deletions x/staketia/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,4 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

func (k Keeper) BeginBlocker(ctx sdk.Context) {
// Check invariants

// Check redemption rate is within safety bounds
if err := k.CheckRedemptionRateExceedsBounds(ctx); err != nil {
k.Logger(ctx).Error(err.Error())
// If not, halt the zone
k.HaltZone(ctx)
}
}
func (k Keeper) BeginBlocker(ctx sdk.Context) {}
2 changes: 1 addition & 1 deletion x/staketia/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (k Keeper) ConfirmDelegation(ctx sdk.Context, recordId uint64, txHash strin
k.ArchiveDelegationRecord(ctx, delegationRecord)

// increment delegation on Host Zone
hostZone.DelegatedBalance = hostZone.DelegatedBalance.Add(delegationRecord.NativeAmount)
hostZone.RemainingDelegatedBalance = hostZone.RemainingDelegatedBalance.Add(delegationRecord.NativeAmount)
k.SetHostZone(ctx, hostZone)

EmitSuccessfulConfirmDelegationEvent(ctx, recordId, delegationRecord.NativeAmount, txHash, sender)
Expand Down
6 changes: 3 additions & 3 deletions x/staketia/keeper/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (s *KeeperTestSuite) SetupDelegationRecords() {

// Set HostZone
hostZone := s.initializeHostZone()
hostZone.DelegatedBalance = InitialDelegation
hostZone.RemainingDelegatedBalance = InitialDelegation
s.App.StaketiaKeeper.SetHostZone(s.Ctx, hostZone)
}

Expand Down Expand Up @@ -196,7 +196,7 @@ func (s *KeeperTestSuite) VerifyDelegationRecords(verifyIdentical bool, archiveI
// if nothing should have changed, verify that host zone balance is unmodified
if verifyIdentical {
// verify hostZone delegated balance is same as initial delegation
s.Require().Equal(InitialDelegation.Int64(), hostZone.DelegatedBalance.Int64(), "hostZone delegated balance should not have changed")
s.Require().Equal(InitialDelegation.Int64(), hostZone.RemainingDelegatedBalance.Int64(), "hostZone delegated balance should not have changed")
}
}
}
Expand All @@ -220,7 +220,7 @@ func (s *KeeperTestSuite) TestConfirmDelegation_Successful() {

// verify hostZone delegated balance is same as initial delegation + 6000
hostZone := s.MustGetHostZone()
s.Require().Equal(InitialDelegation.Int64()+6000, hostZone.DelegatedBalance.Int64(), "hostZone delegated balance should have increased by 6000")
s.Require().Equal(InitialDelegation.Int64()+6000, hostZone.RemainingDelegatedBalance.Int64(), "hostZone delegated balance should have increased by 6000")
}

func (s *KeeperTestSuite) TestConfirmDelegation_DelegationZero() {
Expand Down
1 change: 0 additions & 1 deletion x/staketia/keeper/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ func EmitHaltZoneEvent(ctx sdk.Context, hostZone types.HostZone) {
sdk.NewEvent(
types.EventTypeHostZoneHalt,
sdk.NewAttribute(types.AttributeKeyHostZone, hostZone.ChainId),
sdk.NewAttribute(types.AttributeKeyRedemptionRate, hostZone.RedemptionRate.String()),
),
)
}
14 changes: 0 additions & 14 deletions x/staketia/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,6 @@ func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInf
// Every day, refresh the redemption rate and prepare delegations
// Every 4 days, prepare undelegations
if epochInfo.Identifier == epochstypes.DAY_EPOCH {
// Update the redemption rate
// If this fails, do not proceed to the delegation or undelegation step
// Note: This must be run first because it is used when refreshing the native token
// balance in prepare undelegation
if err := k.UpdateRedemptionRate(ctx); err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Unable update redemption rate: %s", err.Error()))
return
}

// Post the redemption rate to the oracle (if it doesn't exceed the bounds)
if err := k.PostRedemptionRateToOracles(ctx); err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Unable to post redemption rate to oracle: %s", err.Error()))
}

// Prepare delegations by transferring the deposited tokens to the host zone
if err := k.SafelyPrepareDelegation(ctx, epochNumber, epochInfo.Duration); err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Unable to prepare delegation for epoch %d: %s", epochNumber, err.Error()))
Expand Down
31 changes: 12 additions & 19 deletions x/staketia/keeper/host_zone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,17 @@ import (
// Helper function to create the singleton HostZone with attributes
func (s *KeeperTestSuite) initializeHostZone() types.HostZone {
hostZone := types.HostZone{
ChainId: "CELESTIA",
NativeTokenDenom: "utia",
NativeTokenIbcDenom: "ibc/utia",
TransferChannelId: "channel-05",
DelegationAddress: "tia0384a",
RewardAddress: "tia144f42e9",
DepositAddress: "stride8abb3e",
RedemptionAddress: "stride3400de1",
ClaimAddress: "stride00b1a83",
LastRedemptionRate: sdk.MustNewDecFromStr("1.0"),
RedemptionRate: sdk.MustNewDecFromStr("1.0"),
MinRedemptionRate: sdk.MustNewDecFromStr("0.95"),
MaxRedemptionRate: sdk.MustNewDecFromStr("1.10"),
MinInnerRedemptionRate: sdk.MustNewDecFromStr("0.97"),
MaxInnerRedemptionRate: sdk.MustNewDecFromStr("1.07"),
DelegatedBalance: sdk.NewInt(1_000_000),
Halted: false,
ChainId: "CELESTIA",
NativeTokenDenom: "utia",
NativeTokenIbcDenom: "ibc/utia",
TransferChannelId: "channel-05",
DelegationAddress: "tia0384a",
RewardAddress: "tia144f42e9",
DepositAddress: "stride8abb3e",
RedemptionAddress: "stride3400de1",
ClaimAddress: "stride00b1a83",
RemainingDelegatedBalance: sdk.NewInt(1_000_000),
Halted: false,
}
s.App.StaketiaKeeper.SetHostZone(s.Ctx, hostZone)
return hostZone
Expand All @@ -47,8 +41,7 @@ func (s *KeeperTestSuite) TestRemoveHostZone() {
func (s *KeeperTestSuite) TestSetHostZone() {
hostZone := s.initializeHostZone()

hostZone.RedemptionRate = hostZone.RedemptionRate.Add(sdk.MustNewDecFromStr("0.1"))
hostZone.DelegatedBalance = hostZone.DelegatedBalance.Add(sdk.NewInt(100_000))
hostZone.RemainingDelegatedBalance = hostZone.RemainingDelegatedBalance.Add(sdk.NewInt(100_000))
s.App.StaketiaKeeper.SetHostZone(s.Ctx, hostZone)

loadedHostZone := s.MustGetHostZone()
Expand Down
2 changes: 1 addition & 1 deletion x/staketia/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (k Keeper) HaltZone(ctx sdk.Context) {
stDenom := utils.StAssetDenomFromHostZoneDenom(hostZone.NativeTokenDenom)
k.ratelimitKeeper.AddDenomToBlacklist(ctx, stDenom)

k.Logger(ctx).Error(fmt.Sprintf("[INVARIANT BROKEN!!!] %s's RR is %s.", hostZone.GetChainId(), hostZone.RedemptionRate.String()))
k.Logger(ctx).Error(fmt.Sprintf("[INVARIANT BROKEN!!!] %s's RR is %s.", hostZone.GetChainId()))

EmitHaltZoneEvent(ctx, hostZone)
}
72 changes: 5 additions & 67 deletions x/staketia/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ import (
"context"
"errors"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/Stride-Labs/stride/v22/utils"

"github.com/Stride-Labs/stride/v22/x/staketia/types"
)

Expand Down Expand Up @@ -107,10 +104,10 @@ func (k msgServer) AdjustDelegatedBalance(goCtx context.Context, msg *types.MsgA
if err != nil {
return nil, err
}
hostZone.DelegatedBalance = hostZone.DelegatedBalance.Add(msg.DelegationOffset)
hostZone.RemainingDelegatedBalance = hostZone.RemainingDelegatedBalance.Add(msg.DelegationOffset)

// safety check that this will not cause the delegated balance to be negative
if hostZone.DelegatedBalance.IsNegative() {
if hostZone.RemainingDelegatedBalance.IsNegative() {
return nil, types.ErrNegativeNotAllowed.Wrapf("offset would cause the delegated balance to be negative")
}
k.SetHostZone(ctx, hostZone)
Expand All @@ -130,71 +127,14 @@ func (k msgServer) AdjustDelegatedBalance(goCtx context.Context, msg *types.MsgA

// Adjusts the inner redemption rate bounds on the host zone
func (k msgServer) UpdateInnerRedemptionRateBounds(goCtx context.Context, msg *types.MsgUpdateInnerRedemptionRateBounds) (*types.MsgUpdateInnerRedemptionRateBoundsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// gate this transaction to the BOUNDS address
if err := utils.ValidateAdminAddress(msg.Creator); err != nil {
return nil, types.ErrInvalidAdmin
}

// Fetch the zone
zone, err := k.GetHostZone(ctx)
if err != nil {
return nil, err
}

// Get the outer bounds
maxOuterBound := zone.MaxRedemptionRate
minOuterBound := zone.MinRedemptionRate

// Confirm the inner bounds are within the outer bounds
maxInnerBound := msg.MaxInnerRedemptionRate
minInnerBound := msg.MinInnerRedemptionRate
if maxInnerBound.GT(maxOuterBound) {
return nil, types.ErrInvalidRedemptionRateBounds
}
if minInnerBound.LT(minOuterBound) {
return nil, types.ErrInvalidRedemptionRateBounds
}

// Set the inner bounds on the host zone
zone.MinInnerRedemptionRate = minInnerBound
zone.MaxInnerRedemptionRate = maxInnerBound

// Update the host zone
k.SetHostZone(ctx, zone)

_ = sdk.UnwrapSDKContext(goCtx)
return &types.MsgUpdateInnerRedemptionRateBoundsResponse{}, nil
}

// Unhalts the host zone if redemption rates were exceeded
// BOUNDS: verified in ValidateBasic
func (k msgServer) ResumeHostZone(goCtx context.Context, msg *types.MsgResumeHostZone) (*types.MsgResumeHostZoneResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// gate this transaction to the BOUNDS address
if err := utils.ValidateAdminAddress(msg.Creator); err != nil {
return nil, types.ErrInvalidAdmin
}

// Note: of course we don't want to fail this if the zone is halted!
zone, err := k.GetHostZone(ctx)
if err != nil {
return nil, err
}

// Check the zone is halted
if !zone.Halted {
return nil, errorsmod.Wrapf(types.ErrHostZoneNotHalted, "zone is not halted")
}

stDenom := utils.StAssetDenomFromHostZoneDenom(zone.NativeTokenDenom)
k.ratelimitKeeper.RemoveDenomFromBlacklist(ctx, stDenom)

// Resume zone
zone.Halted = false
k.SetHostZone(ctx, zone)

_ = sdk.UnwrapSDKContext(goCtx)
return &types.MsgResumeHostZoneResponse{}, nil
}

Expand All @@ -207,9 +147,7 @@ func (k msgServer) RefreshRedemptionRate(goCtx context.Context, msgTriggerRedemp
return nil, err
}

err := k.UpdateRedemptionRate(ctx)

return &types.MsgRefreshRedemptionRateResponse{}, err
return &types.MsgRefreshRedemptionRateResponse{}, nil
}

// overwrite a delegation record
Expand Down
Loading

0 comments on commit aa25564

Please sign in to comment.