Skip to content

Commit

Permalink
Merge pull request #56 from Stride-Labs/TEST-102
Browse files Browse the repository at this point in the history
TEST-102: redemptionRate working!
  • Loading branch information
riley-stride authored Jun 27, 2022
2 parents 5b159a6 + 6304fb0 commit 7548950
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 154 deletions.
2 changes: 2 additions & 0 deletions proto/stakeibc/host_zone.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ message HostZone {
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
//TODO(TEST-101) int to dec
int64 stakedBal = 13;
}
2 changes: 1 addition & 1 deletion proto/stakeibc/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ message Params {
uint64 rewards_interval = 1;
uint64 delegate_interval = 6;
uint64 deposit_interval = 2;
uint64 exchange_rate_interval = 3;
uint64 redemption_rate_interval = 3;

uint64 stride_commission = 4;
// zone_com_address stores which addresses to
Expand Down
89 changes: 80 additions & 9 deletions x/stakeibc/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochN
}
epochTracker := types.EpochTracker{
EpochIdentifier: epochIdentifier,
EpochNumber: uint64(epochNumber),
EpochNumber: uint64(epochNumber),
}
// deposit records *must* exist for this epoch
k.SetEpochTracker(ctx, epochTracker)
Expand All @@ -52,12 +52,20 @@ func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochN
k.SetWithdrawalAddress(ctx)

depositRecords := k.RecordsKeeper.GetAllDepositRecord(ctx)

// Update the redemption rate
redemptionRateInterval := int64(k.GetParam(ctx, types.KeyDepositInterval))
if epochNumber%redemptionRateInterval == 0 {
k.Logger(ctx).Info("Triggeting update redemption rate")
k.UpdateRedemptionRates(ctx, depositRecords)
}

depositInterval := int64(k.GetParam(ctx, types.KeyDepositInterval))
if epochNumber%depositInterval == 0 {
// process previous deposit records
k.TransferExistingDepositsToHostZones(ctx, epochNumber, depositRecords)
}

// NOTE: the stake ICA timeout *must* be l.t. the staking epoch length, otherwise
// we could send a stake ICA call (which could succeed), without deleting the record.
// This could happen if the ack doesn't return by the next epoch. We would then send
Expand Down Expand Up @@ -114,14 +122,14 @@ func (h Hooks) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumbe
// -------------------- helper functions --------------------
func (k Keeper) CreateDepositRecordsForEpoch(ctx sdk.Context, epochNumber int64) {
// Create one new deposit record / host zone for the next epoch
createDepositRecords := func(ctx sdk.Context, index int64, zoneInfo types.HostZone) (error) {
createDepositRecords := func(ctx sdk.Context, index int64, zoneInfo types.HostZone) error {
// create a deposit record / host zone
depositRecord := recordstypes.DepositRecord{
Id: 0,
Amount: 0,
Denom: zoneInfo.HostDenom,
HostZoneId: zoneInfo.ChainId,
Status: recordstypes.DepositRecord_TRANSFER,
Id: 0,
Amount: 0,
Denom: zoneInfo.HostDenom,
HostZoneId: zoneInfo.ChainId,
Status: recordstypes.DepositRecord_TRANSFER,
EpochNumber: uint64(epochNumber),
}
k.RecordsKeeper.AppendDepositRecord(ctx, depositRecord)
Expand All @@ -132,7 +140,7 @@ func (k Keeper) CreateDepositRecordsForEpoch(ctx sdk.Context, epochNumber int64)
}

func (k Keeper) SetWithdrawalAddress(ctx sdk.Context) {
setWithdrawalAddresses := func(ctx sdk.Context, index int64, zoneInfo types.HostZone) (error) {
setWithdrawalAddresses := func(ctx sdk.Context, index int64, zoneInfo types.HostZone) error {
k.Logger(ctx).Info(fmt.Sprintf("\tsetting withdrawal addresses on host zones"))
err := k.SetWithdrawalAddressOnHost(ctx, zoneInfo)
if err != nil {
Expand Down Expand Up @@ -238,3 +246,66 @@ func (k Keeper) TransferExistingDepositsToHostZones(ctx sdk.Context, epochNumber
k.RecordsKeeper.RemoveDepositRecord(ctx, recordId)
}
}

func (k Keeper) UpdateRedemptionRates(ctx sdk.Context, depositRecords []recordstypes.DepositRecord) {
// Calc redemptionRate for each host zone
UpdateRedemptionRate := func(ctx sdk.Context, index int64, zoneInfo types.HostZone) error {

undelegatedBalance, error := k.GetUndelegatedBalance(ctx, zoneInfo, depositRecords)
if error != nil {
return error
}
stakedBalance := zoneInfo.StakedBal
modeuleAcctBalance, error := k.GetModuleAccountBalance(ctx, zoneInfo, depositRecords)
if error != nil {
return error
}
stSupply := k.bankKeeper.GetSupply(ctx, types.StAssetDenomFromHostZoneDenom(zoneInfo.HostDenom)).Amount.Int64()
if stSupply == 0 {
return fmt.Errorf("stSupply is 0")
}

// calc redemptionRate = (UB+SB+MA)/stSupply
redemptionRate := (sdk.NewDec(undelegatedBalance).Add(sdk.NewDec(stakedBalance)).Add(sdk.NewDec(modeuleAcctBalance))).Quo(sdk.NewDec(stSupply))
k.Logger(ctx).Info(fmt.Sprintf("[REDEMPTION-RATE] New Rate is %d (vs prev %d)", redemptionRate, zoneInfo.LastRedemptionRate))

// set redemptionRate attribute for the hostZone (and update last RedemptionRate)
zoneInfo.LastRedemptionRate = zoneInfo.RedemptionRate
zoneInfo.RedemptionRate = redemptionRate
k.SetHostZone(ctx, zoneInfo)

return nil
}
// Iterate the zones and apply icaReinvest
k.IterateHostZones(ctx, UpdateRedemptionRate)
}

func (k Keeper) GetUndelegatedBalance(ctx sdk.Context, hostZone types.HostZone, depositRecords []recordstypes.DepositRecord) (int64, error) {
// filter to only the deposit records for the host zone with status STAKE
UndelegatedDepositRecords := utils.FilterDepositRecords(depositRecords, func(record recordstypes.DepositRecord) (condition bool) {
return record.Status == recordstypes.DepositRecord_STAKE && record.HostZoneId == hostZone.ChainId
})

// sum the amounts of the deposit records
var totalAmount int64
for _, depositRecord := range UndelegatedDepositRecords {
totalAmount += depositRecord.Amount
}

return totalAmount, nil
}

func (k Keeper) GetModuleAccountBalance(ctx sdk.Context, hostZone types.HostZone, depositRecords []recordstypes.DepositRecord) (int64, error) {
// filter to only the deposit records for the host zone with status DELEGATION
ModuleAccountRecords := utils.FilterDepositRecords(depositRecords, func(record recordstypes.DepositRecord) (condition bool) {
return record.Status == recordstypes.DepositRecord_TRANSFER && record.HostZoneId == hostZone.ChainId
})

// sum the amounts of the deposit records
var totalAmount int64
for _, depositRecord := range ModuleAccountRecords {
totalAmount += depositRecord.Amount
}

return totalAmount, nil
}
29 changes: 16 additions & 13 deletions x/stakeibc/keeper/ibc_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ func (k Keeper) HandleAcknowledgement(ctx sdk.Context, modulePacket channeltypes
return err
}



txMsgData := &sdk.TxMsgData{}
err = proto.Unmarshal(ack.Result, txMsgData)
if err != nil {
Expand Down Expand Up @@ -135,7 +133,6 @@ func (k Keeper) HandleAcknowledgement(ctx sdk.Context, modulePacket channeltypes
return nil
}


func (k *Keeper) HandleSend(ctx sdk.Context, msg sdk.Msg) error {
k.Logger(ctx).Info("Received MsgSend acknowledgement")
// first, type assertion. we should have banktypes.MsgSend
Expand Down Expand Up @@ -168,24 +165,22 @@ func (k *Keeper) HandleSend(ctx sdk.Context, msg sdk.Msg) error {
epochNumber := strideEpochTracker.EpochNumber
// create a new record so that rewards are reinvested
record := recordstypes.DepositRecord{
Id: 0,
Amount: amount,
Denom: hostZoneDenom,
HostZoneId: zone.ChainId,
Status: recordstypes.DepositRecord_STAKE,
Source: recordstypes.DepositRecord_WITHDRAWAL_ICA,
Id: 0,
Amount: amount,
Denom: hostZoneDenom,
HostZoneId: zone.ChainId,
Status: recordstypes.DepositRecord_STAKE,
Source: recordstypes.DepositRecord_WITHDRAWAL_ICA,
EpochNumber: uint64(epochNumber),
}
k.RecordsKeeper.AppendDepositRecord(ctx, record)
k.RecordsKeeper.AppendDepositRecord(ctx, record)
} else {
return nil
}


return nil
}


func (k *Keeper) HandleDelegate(ctx sdk.Context, msg sdk.Msg) error {
k.Logger(ctx).Info("Received MsgDelegate acknowledgement")
// first, type assertion. we should have stakingtypes.MsgDelegate
Expand All @@ -206,11 +201,19 @@ func (k *Keeper) HandleDelegate(ctx sdk.Context, msg sdk.Msg) error {
return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "No deposit record found for zone: %s, amount: %s", zone.ChainId, amount)
}

// TODO(TEST-112) more safety checks here
// increment the stakedBal on the hostZome
if amount < 0 {
return sdkerrors.Wrapf(sdkerrors.ErrLogic, "Balance to stake was negative: %d", amount)
} else {
zone.StakedBal += amount
k.SetHostZone(ctx, *zone)
}

k.RecordsKeeper.RemoveDepositRecord(ctx, record.Id)
return nil
}


// TODO(TEST-28): Burn stAssets if RedeemStake succeeds
func (k Keeper) HandleUndelegate(ctx sdk.Context, msg sdk.Msg) error {
k.Logger(ctx).Info("Received MsgUndelegate acknowledgement")
Expand Down
101 changes: 69 additions & 32 deletions x/stakeibc/types/host_zone.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7548950

Please sign in to comment.