Skip to content

Commit

Permalink
Epoch Logs Cleanup - Day Epoch Pt. 2 (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Dec 17, 2022
1 parent 6816961 commit d1938b9
Show file tree
Hide file tree
Showing 15 changed files with 223 additions and 172 deletions.
12 changes: 10 additions & 2 deletions x/epochs/keeper/abci.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package keeper

import (
"fmt"
"strconv"
"strings"
"time"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/Stride-Labs/stride/v4/utils"
"github.com/Stride-Labs/stride/v4/x/epochs/types"
)

Expand All @@ -26,10 +29,15 @@ func (k Keeper) BeginBlocker(ctx sdk.Context) {
switch {
case shouldInitialEpochStart:
epochInfo = startInitialEpoch(epochInfo)
logger.Info("starting epoch", "identifier", epochInfo.Identifier)
logger.Info(fmt.Sprintf("initial %s epoch", epochInfo.Identifier))
case shouldEpochStart:
epochInfo = endEpoch(epochInfo)
logger.Info("ending epoch", "identifier", epochInfo.Identifier)

// Capitalize the epoch identifier for the logs
epochAlias := strings.ToUpper(strings.ReplaceAll(epochInfo.Identifier, "_epoch", ""))
logger.Info(utils.LogHeader("%s EPOCH %d", epochAlias, epochInfo.CurrentEpoch))
logger.Info(utils.LogHeader("Epoch Start Time: %s", epochInfo.CurrentEpochStartTime))

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeEpochEnd,
Expand Down
8 changes: 4 additions & 4 deletions x/stakeibc/keeper/deposit_records.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (k Keeper) TransferExistingDepositsToHostZones(ctx sdk.Context, epochNumber

for _, depositRecord := range transferDepositRecords {
k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId,
"Processing deposit record %d: %d%s", depositRecord.Id, depositRecord.Amount, depositRecord.Denom))
"Processing deposit record %d: %v%s", depositRecord.Id, depositRecord.Amount, depositRecord.Denom))

// if a TRANSFER_QUEUE record has 0 balance and was created in the previous epoch, it's safe to remove since it will never be updated or used
if depositRecord.Amount.LTE(sdk.ZeroInt()) && depositRecord.DepositEpochNumber < epochNumber {
Expand All @@ -70,7 +70,7 @@ func (k Keeper) TransferExistingDepositsToHostZones(ctx sdk.Context, epochNumber
}
delegateAddress := delegateAccount.Address

k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId, "Transferring %d%s", depositRecord.Amount, hostZone.HostDenom))
k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId, "Transferring %v%s", depositRecord.Amount, hostZone.HostDenom))
transferCoin := sdk.NewCoin(hostZone.IbcDenom, depositRecord.Amount)

// timeout 30 min in the future
Expand Down Expand Up @@ -118,7 +118,7 @@ func (k Keeper) StakeExistingDepositsOnHostZones(ctx sdk.Context, epochNumber ui

for _, depositRecord := range stakeDepositRecords[:maxDepositRecordsToStake] {
k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId,
"Processing deposit record %d: %d%s", depositRecord.Id, depositRecord.Amount, depositRecord.Denom))
"Processing deposit record %d: %v%s", depositRecord.Id, depositRecord.Amount, depositRecord.Denom))

hostZone, hostZoneFound := k.GetHostZone(ctx, depositRecord.HostZoneId)
if !hostZoneFound {
Expand All @@ -132,7 +132,7 @@ func (k Keeper) StakeExistingDepositsOnHostZones(ctx sdk.Context, epochNumber ui
continue
}

k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId, "Staking %d%s", depositRecord.Amount, hostZone.HostDenom))
k.Logger(ctx).Info(utils.LogWithHostZone(depositRecord.HostZoneId, "Staking %v%s", depositRecord.Amount, hostZone.HostDenom))
stakeAmount := sdk.NewCoin(hostZone.HostDenom, depositRecord.Amount)

err := k.DelegateOnHost(ctx, hostZone, stakeAmount, depositRecord)
Expand Down
11 changes: 2 additions & 9 deletions x/stakeibc/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
)

func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInfo) {
k.Logger(ctx).Info(utils.LogHeader("EPOCH %d - %s", epochInfo.CurrentEpoch, epochInfo.CurrentEpochStartTime))

// Update the stakeibc epoch tracker
epochNumber, err := k.UpdateEpochTracker(ctx, epochInfo)
if err != nil {
Expand All @@ -24,8 +22,6 @@ func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInf

// Day Epoch - Process Unbondings
if epochInfo.Identifier == epochstypes.DAY_EPOCH {
k.Logger(ctx).Info(utils.LogHeader("DAY EPOCH %d", epochNumber))

// Initiate unbondings from any hostZone where it's appropriate
k.InitiateAllHostZoneUnbondings(ctx, epochNumber)
// Check previous epochs to see if unbondings finished, and sweep the tokens if so
Expand All @@ -38,8 +34,6 @@ func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochInfo epochstypes.EpochInf

// Stride Epoch - Process Deposits and Delegations
if epochInfo.Identifier == epochstypes.STRIDE_EPOCH {
k.Logger(ctx).Info(utils.LogHeader("STRIDE EPOCH %d", epochNumber))

// Get cadence intervals
redemptionRateInterval := k.GetParam(ctx, types.KeyRedemptionRateInterval)
depositInterval := k.GetParam(ctx, types.KeyDepositInterval)
Expand Down Expand Up @@ -165,12 +159,12 @@ func (k Keeper) UpdateRedemptionRates(ctx sdk.Context, depositRecords []recordst
}

k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId,
"Redemption Rate Components - Undelegated Balance: %d, Staked Balance: %d, Module Account Balance: %d, stToken Supply: %d",
"Redemption Rate Components - Undelegated Balance: %v, Staked Balance: %v, Module Account Balance: %v, stToken Supply: %v",
undelegatedBalance, stakedBalance, moduleAcctBalance, stSupply))

// Calculate the redemption rate
redemptionRate := (sdk.NewDecFromInt(undelegatedBalance).Add(sdk.NewDecFromInt(stakedBalance)).Add(sdk.NewDecFromInt(moduleAcctBalance))).Quo(sdk.NewDecFromInt(stSupply))
k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId, "New Redemption Rate: %d (vs Prev Rate: %d)", redemptionRate, hostZone.RedemptionRate))
k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId, "New Redemption Rate: %v (vs Prev Rate: %v)", redemptionRate, hostZone.RedemptionRate))

// Update the host zone
hostZone.LastRedemptionRate = hostZone.RedemptionRate
Expand Down Expand Up @@ -233,6 +227,5 @@ func (k Keeper) ReinvestRewards(ctx sdk.Context) {
k.Logger(ctx).Error(fmt.Sprintf("Error updating withdrawal balance for host zone %s: %s", hostZone.ConnectionId, err.Error()))
continue
}
k.Logger(ctx).Info(utils.LogWithHostZone(hostZone.ChainId, "Updated withdrawal balance"))
}
}
27 changes: 16 additions & 11 deletions x/stakeibc/keeper/host_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,28 +93,31 @@ func (k Keeper) GetAllHostZone(ctx sdk.Context) (list []types.HostZone) {
return
}

func (k Keeper) AddDelegationToValidator(ctx sdk.Context, hostZone types.HostZone, valAddr string, amt sdk.Int) (success bool) {
for _, val := range hostZone.GetValidators() {
if val.GetAddress() == valAddr {
k.Logger(ctx).Info(fmt.Sprintf("Validator %s, Current Delegation: %d, Delegation Change: %d", val.GetAddress(), val.DelegationAmt, amt))
if amt.GTE(sdk.ZeroInt()) {
val.DelegationAmt = val.DelegationAmt.Add(amt)
func (k Keeper) AddDelegationToValidator(ctx sdk.Context, hostZone types.HostZone, validatorAddress string, amount sdk.Int) (success bool) {
for _, validator := range hostZone.Validators {
if validator.Address == validatorAddress {
k.Logger(ctx).Info(fmt.Sprintf("Validator %s, Current Delegation: %v, Delegation Change: %v", validator.Address, validator.DelegationAmt, amount))
if amount.GTE(sdk.ZeroInt()) {
validator.DelegationAmt = validator.DelegationAmt.Add(amount)
return true
} else {
absAmt := amt.Abs()
if absAmt.GT(val.DelegationAmt) {
k.Logger(ctx).Error(fmt.Sprintf("Delegation amount %d is greater than validator %s delegation amount %d", absAmt, valAddr, val.DelegationAmt))
absAmt := amount.Abs()
if absAmt.GT(validator.DelegationAmt) {
k.Logger(ctx).Error(fmt.Sprintf("Delegation amount %v is greater than validator %s delegation amount %v", absAmt, validatorAddress, validator.DelegationAmt))
return false
}
val.DelegationAmt = val.DelegationAmt.Sub(absAmt)
validator.DelegationAmt = validator.DelegationAmt.Sub(absAmt)
return true
}
}
}
k.Logger(ctx).Error(fmt.Sprintf("Could not find validator %s on host zone %s", valAddr, hostZone.GetChainId()))
k.Logger(ctx).Error(fmt.Sprintf("Could not find validator %s on host zone %s", validatorAddress, hostZone.ChainId))
return false
}

// Appends a validator to host zone (if the host zone is not already at capacity)
// If the validator is added through governance, the weight is equal to the minimum weight across the set
// If the validator is added through an admin transactions, the weight is specified in the message
func (k Keeper) AddValidatorToHostZone(ctx sdk.Context, msg *types.MsgAddValidator, fromGovernance bool) error {
// Get the corresponding host zone
hostZone, found := k.GetHostZone(ctx, msg.HostZone)
Expand Down Expand Up @@ -171,6 +174,8 @@ func (k Keeper) AddValidatorToHostZone(ctx sdk.Context, msg *types.MsgAddValidat
return nil
}

// Removes a validator from a host zone
// The validator must be zero-weight and have no delegations in order to be removed
func (k Keeper) RemoveValidatorFromHostZone(ctx sdk.Context, chainId string, validatorAddress string) error {
hostZone, found := k.GetHostZone(ctx, chainId)
if !found {
Expand Down
2 changes: 1 addition & 1 deletion x/stakeibc/keeper/icacallbacks_delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func DelegateCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, ack

for _, splitDelegation := range delegateCallback.SplitDelegations {
validator := splitDelegation.Validator
k.Logger(ctx).Info(fmt.Sprintf("incrementing stakedBal %d on %s", splitDelegation.Amount, validator))
k.Logger(ctx).Info(fmt.Sprintf("incrementing stakedBal %v on %s", splitDelegation.Amount, validator))

zone.StakedBal = zone.StakedBal.Add(splitDelegation.Amount)
success := k.AddDelegationToValidator(ctx, zone, validator, splitDelegation.Amount)
Expand Down
16 changes: 8 additions & 8 deletions x/stakeibc/keeper/icacallbacks_undelegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,18 @@ func UndelegateCallback(k Keeper, ctx sdk.Context, packet channeltypes.Packet, a
func (k Keeper) UpdateDelegationBalances(ctx sdk.Context, zone types.HostZone, undelegateCallback types.UndelegateCallback) error {
// Undelegate from each validator and update host zone staked balance, if successful
for _, undelegation := range undelegateCallback.SplitDelegations {
k.Logger(ctx).Info(fmt.Sprintf("UndelegateCallback, Undelegation: %d, validator: %s", undelegation.Amount, undelegation.Validator))
k.Logger(ctx).Info(fmt.Sprintf("UndelegateCallback, Undelegation: %v, validator: %s", undelegation.Amount, undelegation.Validator))

undelegateVal := undelegation.Validator
success := k.AddDelegationToValidator(ctx, zone, undelegateVal, undelegation.Amount.Neg())
if !success {
return sdkerrors.Wrapf(types.ErrValidatorDelegationChg, "Failed to remove delegation to validator")
}

if undelegation.Amount.GT(zone.StakedBal) {
// handle incoming underflow
// Once we add a killswitch, we should also stop liquid staking on the zone here
return sdkerrors.Wrapf(types.ErrUndelegationAmount, "undelegation.Amount > zone.StakedBal, undelegation.Amount: %d, zone.StakedBal %d", undelegation.Amount, zone.StakedBal)
return sdkerrors.Wrapf(types.ErrUndelegationAmount, "undelegation.Amount > zone.StakedBal, undelegation.Amount: %v, zone.StakedBal %v", undelegation.Amount, zone.StakedBal)
} else {
zone.StakedBal = zone.StakedBal.Sub(undelegation.Amount)
}
Expand Down Expand Up @@ -154,16 +154,16 @@ func (k Keeper) GetLatestCompletionTime(ctx sdk.Context, txMsgData *sdk.TxMsgDat
return &latestCompletionTime, nil
}

// UpdateHostZoneUnbondings does two things:
// 1. Update the status and time of each hostZoneUnbonding on each epochUnbondingRecord
// 2. Return the number of stTokens that need to be burned
func (k Keeper) UpdateHostZoneUnbondings(
ctx sdk.Context,
latestCompletionTime time.Time,
zone types.HostZone,
undelegateCallback types.UndelegateCallback,
) (stTokenBurnAmount sdk.Int, err error) {
stTokenBurnAmount = sdk.ZeroInt()
// UpdateHostZoneUnbondings does two things:
// 1. Update the status and time of each hostZoneUnbonding on each epochUnbondingRecord
// 2. Return the number of stTokens that need to be burned
for _, epochNumber := range undelegateCallback.EpochUnbondingRecordIds {
epochUnbondingRecord, found := k.RecordsKeeper.GetEpochUnbondingRecord(ctx, epochNumber)
if !found {
Expand All @@ -187,7 +187,7 @@ func (k Keeper) UpdateHostZoneUnbondings(
hostZoneUnbonding.UnbondingTime = cast.ToUint64(latestCompletionTime.UnixNano())
updatedEpochUnbondingRecord, success := k.RecordsKeeper.AddHostZoneToEpochUnbondingRecord(ctx, epochUnbondingRecord.EpochNumber, zone.ChainId, hostZoneUnbonding)
if !success {
k.Logger(ctx).Error(fmt.Sprintf("Failed to set host zone epoch unbonding record: epochNumber %d, chainId %s, hostZoneUnbonding %v", epochUnbondingRecord.EpochNumber, zone.ChainId, hostZoneUnbonding))
k.Logger(ctx).Error(fmt.Sprintf("Failed to set host zone epoch unbonding record: epochNumber %d, chainId %s, hostZoneUnbonding %+v", epochUnbondingRecord.EpochNumber, zone.ChainId, hostZoneUnbonding))
return sdk.ZeroInt(), sdkerrors.Wrapf(types.ErrEpochNotFound, "couldn't set host zone epoch unbonding record. err: %s", err.Error())
}
k.RecordsKeeper.SetEpochUnbondingRecord(ctx, *updatedEpochUnbondingRecord)
Expand Down Expand Up @@ -217,7 +217,7 @@ func (k Keeper) BurnTokens(ctx sdk.Context, zone types.HostZone, stTokenBurnAmou
err = k.bankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(stCoin))
if err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Failed to burn stAssets upon successful unbonding %s", err.Error()))
return sdkerrors.Wrapf(types.ErrInsufficientFunds, "couldn't burn %d %s tokens in module account. err: %s", stTokenBurnAmount, stCoinDenom, err.Error())
return sdkerrors.Wrapf(types.ErrInsufficientFunds, "couldn't burn %v%s tokens in module account. err: %s", stTokenBurnAmount, stCoinDenom, err.Error())
}
k.Logger(ctx).Info(fmt.Sprintf("Total supply %s", k.bankKeeper.GetSupply(ctx, stCoinDenom)))
return nil
Expand Down
6 changes: 3 additions & 3 deletions x/stakeibc/keeper/icqcallbacks_delegator_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func DelegatorSharesCallback(k Keeper, ctx sdk.Context, args []byte, query icqty
// TODO: make sure conversion math precision matches the sdk's staking module's version (we did it slightly differently)
// note: truncateInt per https://github.com/cosmos/cosmos-sdk/blob/cb31043d35bad90c4daa923bb109f38fd092feda/x/staking/types/validator.go#L431
validatorTokens := queriedDelgation.Shares.Mul(validator.InternalExchangeRate.InternalTokensToSharesRate).TruncateInt()
k.Logger(ctx).Info(fmt.Sprintf("DelegationCallback: HostZone: %s, Validator: %s, Previous NumTokens: %d, Current NumTokens: %v",
k.Logger(ctx).Info(fmt.Sprintf("DelegationCallback: HostZone: %s, Validator: %s, Previous NumTokens: %v, Current NumTokens: %v",
hostZone.ChainId, validator.Address, validator.DelegationAmt, validatorTokens))

// Confirm the validator has actually been slashed
Expand All @@ -98,7 +98,7 @@ func DelegatorSharesCallback(k Keeper, ctx sdk.Context, args []byte, query icqty

// Get slash percentage
slashAmount := validator.DelegationAmt.Sub(validatorTokens)

weight, err := cast.ToInt64E(validator.Weight)
if err != nil {
errMsg := fmt.Sprintf("unable to convert validator weight to int64, err: %s", err.Error())
Expand All @@ -107,7 +107,7 @@ func DelegatorSharesCallback(k Keeper, ctx sdk.Context, args []byte, query icqty
}

slashPct := sdk.NewDecFromInt(slashAmount).Quo(sdk.NewDecFromInt(validator.DelegationAmt))
k.Logger(ctx).Info(fmt.Sprintf("ICQ'd Delegation Amoount Mismatch, HostZone: %s, Validator: %s, Delegator: %s, Records Tokens: %d, Tokens from ICQ %v, Slash Amount: %d, Slash Pct: %v!",
k.Logger(ctx).Info(fmt.Sprintf("ICQ'd Delegation Amount Mismatch, HostZone: %s, Validator: %s, Delegator: %s, Records Tokens: %v, Tokens from ICQ %v, Slash Amount: %v, Slash Pct: %v!",
hostZone.ChainId, validator.Address, queriedDelgation.DelegatorAddress, validator.DelegationAmt, validatorTokens, slashAmount, slashPct))

// Abort if the slash was greater than 10%
Expand Down
8 changes: 4 additions & 4 deletions x/stakeibc/keeper/icqcallbacks_withdrawal_balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq
}

// Confirm the balance is greater than zero
if withdrawalBalanceCoin.Amount.Int64() <= 0 {
if withdrawalBalanceCoin.Amount.LTE(sdk.ZeroInt()) {
k.Logger(ctx).Info(fmt.Sprintf("WithdrawalBalanceCallback: no balance to transfer for zone: %s, accAddr: %v, coin: %v",
hostZone.ChainId, hostZone.WithdrawalAccount.GetAddress(), withdrawalBalanceCoin.String()))
return nil
}

// Sweep the withdrawal account balance, to the commission and the delegation accounts
k.Logger(ctx).Info(fmt.Sprintf("ICA Bank Sending %d%s from withdrawalAddr to delegationAddr.",
withdrawalBalanceCoin.Amount.Int64(), withdrawalBalanceCoin.Denom))
k.Logger(ctx).Info(fmt.Sprintf("ICA Bank Sending %v%s from withdrawalAddr to delegationAddr.",
withdrawalBalanceCoin.Amount, withdrawalBalanceCoin.Denom))

withdrawalAccount := hostZone.GetWithdrawalAccount()
if withdrawalAccount == nil {
Expand Down Expand Up @@ -92,7 +92,7 @@ func WithdrawalBalanceCallback(k Keeper, ctx sdk.Context, args []byte, query icq

// TODO(TEST-112) safety check, balances should add to original amount
if (strideClaimFloored.Int64() + reinvestAmountCeil.Int64()) != withdrawalBalanceAmount.Int64() {
ctx.Logger().Error(fmt.Sprintf("Error with withdraw logic: %d, Fee portion: %d, reinvestPortion %d", withdrawalBalanceAmount.Int64(), strideClaimFloored.Int64(), reinvestAmountCeil.Int64()))
ctx.Logger().Error(fmt.Sprintf("Error with withdraw logic: %v, Fee portion: %v, reinvestPortion %v", withdrawalBalanceAmount, strideClaimFloored, reinvestAmountCeil))
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Failed to subdivide rewards to feeAccount and delegationAccount")
}
strideCoin := sdk.NewCoin(withdrawalBalanceCoin.Denom, strideClaimFloored)
Expand Down
8 changes: 4 additions & 4 deletions x/stakeibc/keeper/msg_server_redeem_stake.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (k msgServer) RedeemStake(goCtx context.Context, msg *types.MsgRedeemStake)
nativeAmount := sdk.NewDecFromInt(msg.Amount).Mul(hostZone.RedemptionRate).RoundInt()

if nativeAmount.GT(hostZone.StakedBal) {
return nil, sdkerrors.Wrapf(types.ErrInvalidAmount, "cannot unstake an amount g.t. staked balance on host zone: %d", msg.Amount)
return nil, sdkerrors.Wrapf(types.ErrInvalidAmount, "cannot unstake an amount g.t. staked balance on host zone: %v", msg.Amount)
}

// safety check: redemption rate must be within safety bounds
Expand All @@ -70,14 +70,14 @@ func (k msgServer) RedeemStake(goCtx context.Context, msg *types.MsgRedeemStake)
// safety checks on the coin
// - Redemption amount must be positive
if !nativeAmount.IsPositive() {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "amount must be greater than 0. found: %d", msg.Amount)
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "amount must be greater than 0. found: %v", msg.Amount)
}
// - Creator owns at least "amount" stAssets
balance := k.bankKeeper.GetBalance(ctx, sender, stDenom)
k.Logger(ctx).Info(fmt.Sprintf("Redemption issuer IBCDenom balance: %v%s", balance.Amount, balance.Denom))
k.Logger(ctx).Info(fmt.Sprintf("Redemption requested redemotion amount: %v%s", inCoin.Amount, inCoin.Denom))
if balance.Amount.LT(msg.Amount) {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "balance is lower than redemption amount. redemption amount: %d, balance %d: ", msg.Amount, balance.Amount)
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "balance is lower than redemption amount. redemption amount: %v, balance %v: ", msg.Amount, balance.Amount)
}
// UNBONDING RECORD KEEPING
userRedemptionRecord := recordstypes.UserRedemptionRecord{
Expand Down Expand Up @@ -115,7 +115,7 @@ func (k msgServer) RedeemStake(goCtx context.Context, msg *types.MsgRedeemStake)
err = k.bankKeeper.SendCoins(ctx, sender, bech32ZoneAddress, redeemCoin)
if err != nil {
k.Logger(ctx).Error("Failed to send sdk.NewCoins(inCoins) from account to module")
return nil, sdkerrors.Wrapf(types.ErrInsufficientFunds, "couldn't send %d derivative %s tokens to module account. err: %s", msg.Amount, hostZone.HostDenom, err.Error())
return nil, sdkerrors.Wrapf(types.ErrInsufficientFunds, "couldn't send %v derivative %s tokens to module account. err: %s", msg.Amount, hostZone.HostDenom, err.Error())
}

// record the number of stAssets that should be burned after unbonding
Expand Down
Loading

0 comments on commit d1938b9

Please sign in to comment.