Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/web-ui/cosmjs-types-…
Browse files Browse the repository at this point in the history
…0.9.0
  • Loading branch information
faddat authored Jan 5, 2024
2 parents ecb7f5a + 622693c commit f1c5e67
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 143 deletions.
6 changes: 3 additions & 3 deletions web-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@chalabi/chain-registry": "1.25.2",
"@chalabi/quicksilverjs": "0.0.2",
"@cosmjs/amino": "0.32.2",
"@cosmjs/cosmwasm-stargate": "0.29.5",
"@cosmjs/cosmwasm-stargate": "0.32.2",
"@cosmjs/proto-signing": "0.28.0",
"@cosmjs/stargate": "0.32.2",
"@cosmos-kit/core": "^2.0.3",
Expand All @@ -33,12 +33,12 @@
"@osmonauts/lcd": "^1.0.3",
"@radix-ui/react-icons": "^1.3.0",
"@tanstack/react-query": "^4.29.12",
"@tanstack/react-query-devtools": "^4.35.0",
"@tanstack/react-query-devtools": "^5.17.1",
"@types/crypto-js": "^4.2.1",
"bech32": "^2.0.0",
"bun": "^1.0.3",
"bun-framework-next": "latest",
"chain-registry": "1.19.0",
"chain-registry": "1.25.0",
"chakra-react-select": "^4.7.6",
"cosmjs-types": "0.9.0",
"crypto-js": "^4.2.0",
Expand Down
6 changes: 5 additions & 1 deletion x/interchainstaking/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ func (*Keeper) PrepareDelegationMessagesForCoins(zone *types.Zone, allocations m
var msgs []sdk.Msg
for _, valoper := range utils.Keys(allocations) {
if allocations[valoper].IsPositive() {
msgs = append(msgs, &stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: sdk.NewCoin(zone.BaseDenom, allocations[valoper])})
if allocations[valoper].GTE(sdk.NewInt(1_000_000)) {
// don't delegate tiny amounts. TODO: make configurable per zone.
msgs = append(msgs, &stakingtypes.MsgDelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: sdk.NewCoin(zone.BaseDenom, allocations[valoper])})
}
}
}
return msgs
Expand All @@ -205,6 +208,7 @@ func (*Keeper) PrepareDelegationMessagesForShares(zone *types.Zone, coins sdk.Co
var msgs []sdk.Msg
for _, coin := range coins.Sort() {
if coin.IsPositive() {
// no min amount here.
msgs = append(msgs, &lsmstakingtypes.MsgRedeemTokensForShares{DelegatorAddress: zone.DelegationAddress.Address, Amount: coin})
}
}
Expand Down
2 changes: 1 addition & 1 deletion x/interchainstaking/keeper/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -929,7 +929,7 @@ func (suite *KeeperTestSuite) TestDelegationPlanLsmFixture() {
}

// ensure sum of allocations equals the original amount
suite.True(allocSum.Equal(amount[0].Amount))
suite.True(allocSum.LTE(amount[0].Amount))
}

// values below are data dumps taken from the live quicksilver-2 and cosmoshub-4 chains, to be used as fixtures.
Expand Down
19 changes: 11 additions & 8 deletions x/interchainstaking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,14 +725,17 @@ func (k *Keeper) Rebalance(ctx sdk.Context, zone *types.Zone, epochNumber int64)
rebalances := types.DetermineAllocationsForRebalancing(currentAllocations, currentLocked, currentSum, lockedSum, targetAllocations, maxCanAllocate, k.Logger(ctx)).RemoveDuplicates()
msgs := make([]sdk.Msg, 0)
for _, rebalance := range rebalances {
msgs = append(msgs, &stakingtypes.MsgBeginRedelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorSrcAddress: rebalance.Source, ValidatorDstAddress: rebalance.Target, Amount: sdk.NewCoin(zone.BaseDenom, rebalance.Amount)})
k.SetRedelegationRecord(ctx, types.RedelegationRecord{
ChainId: zone.ChainId,
EpochNumber: epochNumber,
Source: rebalance.Source,
Destination: rebalance.Target,
Amount: rebalance.Amount.Int64(),
})
if rebalance.Amount.GTE(sdk.NewInt(1_000_000)) {
// don't redelegate dust; TODO: config per zone
msgs = append(msgs, &stakingtypes.MsgBeginRedelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorSrcAddress: rebalance.Source, ValidatorDstAddress: rebalance.Target, Amount: sdk.NewCoin(zone.BaseDenom, rebalance.Amount)})
k.SetRedelegationRecord(ctx, types.RedelegationRecord{
ChainId: zone.ChainId,
EpochNumber: epochNumber,
Source: rebalance.Source,
Destination: rebalance.Target,
Amount: rebalance.Amount.Int64(),
})
}
}
if len(msgs) == 0 {
k.Logger(ctx).Debug("No rebalancing required")
Expand Down
10 changes: 2 additions & 8 deletions x/interchainstaking/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,8 @@ func (k msgServer) RequestRedemption(goCtx context.Context, msg *types.MsgReques
return nil, fmt.Errorf("unable to send coins to escrow account: %w", err)
}

if zone.LiquidityModule {
if err := k.processRedemptionForLsm(ctx, zone, sender, msg.DestinationAddress, nativeTokens, msg.Value, hashString); err != nil {
return nil, fmt.Errorf("unable to process redemption for LSM: %w", err)
}
} else {
if err := k.queueRedemption(ctx, zone, sender, msg.DestinationAddress, nativeTokens, msg.Value, hashString); err != nil {
return nil, fmt.Errorf("unable to queue redemption: %w", err)
}
if err := k.queueRedemption(ctx, zone, sender, msg.DestinationAddress, nativeTokens, msg.Value, hashString); err != nil {
return nil, fmt.Errorf("unable to queue redemption: %w", err)
}

ctx.EventManager().EmitEvents(sdk.Events{
Expand Down
98 changes: 49 additions & 49 deletions x/interchainstaking/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,55 +302,55 @@ func (suite *KeeperTestSuite) TestRequestRedemption() {
}
})

// run tests with LSM enabled.
tt.name += "_LSM_enabled"
suite.Run(tt.name, func() {
suite.SetupTest()
suite.setupTestZones()

ctx := suite.chainA.GetContext()

params := suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.GetParams(ctx)
params.UnbondingEnabled = true
suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetParams(ctx, params)

err := suite.GetQuicksilverApp(suite.chainA).BankKeeper.MintCoins(ctx, icstypes.ModuleName, sdk.NewCoins(sdk.NewCoin("uqatom", math.NewInt(10000000))))
suite.NoError(err)
err = suite.GetQuicksilverApp(suite.chainA).BankKeeper.SendCoinsFromModuleToAccount(ctx, icstypes.ModuleName, testAccount, sdk.NewCoins(sdk.NewCoin("uqatom", math.NewInt(10000000))))
suite.NoError(err)

// enable LSM
zone, found := suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID)
suite.True(found)
zone.LiquidityModule = true
zone.UnbondingEnabled = true
suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetZone(ctx, &zone)

validators := suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID)
for _, delegation := range func(zone icstypes.Zone) []icstypes.Delegation {
out := make([]icstypes.Delegation, 0)
for _, valoper := range validators {
out = append(out, icstypes.NewDelegation(zone.DelegationAddress.Address, valoper, sdk.NewCoin(zone.BaseDenom, sdk.NewInt(3000000))))
}
return out
}(zone) {
suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetDelegation(ctx, zone.ChainId, delegation)
}

tt.malleate()

msgSrv := icskeeper.NewMsgServerImpl(suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper)
res, err := msgSrv.RequestRedemption(sdk.WrapSDKContext(suite.chainA.GetContext()), &msg)

if tt.expectErrLsm != "" {
suite.Errorf(err, tt.expectErrLsm)
suite.Nil(res)
suite.T().Logf("Error: %v", err)
} else {
suite.NoError(err)
suite.NotNil(res)
}
})
// run tests with LSM enabled. - disabled until we decide to use LSM unbonding.
// tt.name += "_LSM_enabled"
// suite.Run(tt.name, func() {
// suite.SetupTest()
// suite.setupTestZones()

// ctx := suite.chainA.GetContext()

// params := suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.GetParams(ctx)
// params.UnbondingEnabled = true
// suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetParams(ctx, params)

// err := suite.GetQuicksilverApp(suite.chainA).BankKeeper.MintCoins(ctx, icstypes.ModuleName, sdk.NewCoins(sdk.NewCoin("uqatom", math.NewInt(10000000))))
// suite.NoError(err)
// err = suite.GetQuicksilverApp(suite.chainA).BankKeeper.SendCoinsFromModuleToAccount(ctx, icstypes.ModuleName, testAccount, sdk.NewCoins(sdk.NewCoin("uqatom", math.NewInt(10000000))))
// suite.NoError(err)

// // enable LSM
// zone, found := suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.GetZone(ctx, suite.chainB.ChainID)
// suite.True(found)
// zone.LiquidityModule = true
// zone.UnbondingEnabled = true
// suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetZone(ctx, &zone)

// validators := suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.GetValidatorAddresses(ctx, suite.chainB.ChainID)
// for _, delegation := range func(zone icstypes.Zone) []icstypes.Delegation {
// out := make([]icstypes.Delegation, 0)
// for _, valoper := range validators {
// out = append(out, icstypes.NewDelegation(zone.DelegationAddress.Address, valoper, sdk.NewCoin(zone.BaseDenom, sdk.NewInt(3000000))))
// }
// return out
// }(zone) {
// suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper.SetDelegation(ctx, zone.ChainId, delegation)
// }

// tt.malleate()

// msgSrv := icskeeper.NewMsgServerImpl(suite.GetQuicksilverApp(suite.chainA).InterchainstakingKeeper)
// res, err := msgSrv.RequestRedemption(sdk.WrapSDKContext(suite.chainA.GetContext()), &msg)

// if tt.expectErrLsm != "" {
// suite.Errorf(err, tt.expectErrLsm)
// suite.Nil(res)
// suite.T().Logf("Error: %v", err)
// } else {
// suite.NoError(err)
// suite.NotNil(res)
// }
// })

}
}
Expand Down
129 changes: 64 additions & 65 deletions x/interchainstaking/keeper/redemptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,73 @@ import (
"github.com/quicksilver-zone/quicksilver/utils"
epochstypes "github.com/quicksilver-zone/quicksilver/x/epochs/types"
"github.com/quicksilver-zone/quicksilver/x/interchainstaking/types"
lsmstakingtypes "github.com/quicksilver-zone/quicksilver/x/lsmtypes"
)

// processRedemptionForLsm will determine based on user intent, the tokens to return to the user, generate Redeem message and send them.
func (k *Keeper) processRedemptionForLsm(ctx sdk.Context, zone *types.Zone, sender sdk.AccAddress, destination string, nativeTokens math.Int, burnAmount sdk.Coin, hash string) error {
intent, found := k.GetDelegatorIntent(ctx, zone, sender.String(), false)
// msgs is slice of MsgTokenizeShares, so we can handle dust allocation later.
msgs := make([]*lsmstakingtypes.MsgTokenizeShares, 0)
var err error
intents := intent.Intents

if !found || len(intents) == 0 {
// if user has no intent set (this can happen if redeeming tokens that were obtained offchain), use global intent.
// Note: this can be improved; user will receive a bunch of tokens.
intents, err = k.GetAggregateIntentOrDefault(ctx, zone)
if err != nil {
return err
}
}
outstanding := nativeTokens
distribution := make(map[string]uint64, 0)

availablePerValidator, _, err := k.GetUnlockedTokensForZone(ctx, zone)
if err != nil {
return err
}
for _, intent := range intents.Sort() {
thisAmount := intent.Weight.MulInt(nativeTokens).TruncateInt()
if thisAmount.GT(availablePerValidator[intent.ValoperAddress]) {
return errors.New("unable to satisfy unbond request; delegations may be locked")
}
distribution[intent.ValoperAddress] = thisAmount.Uint64()
outstanding = outstanding.Sub(thisAmount)
}

distribution[intents[0].ValoperAddress] += outstanding.Uint64()

if distribution[intents[0].ValoperAddress] > availablePerValidator[intents[0].ValoperAddress].Uint64() {
return errors.New("unable to satisfy unbond request (2); delegations may be locked")
}

for _, valoper := range utils.Keys(distribution) {
msgs = append(msgs, &lsmstakingtypes.MsgTokenizeShares{
DelegatorAddress: zone.DelegationAddress.Address,
ValidatorAddress: valoper,
Amount: sdk.NewCoin(zone.BaseDenom, sdk.NewIntFromUint64(distribution[valoper])),
TokenizedShareOwner: destination,
})
}

sdkMsgs := make([]sdk.Msg, 0)
for _, msg := range msgs {
sdkMsgs = append(sdkMsgs, sdk.Msg(msg))
}
distributions := make([]*types.Distribution, 0)

for valoper, amount := range distribution {
newDistribution := types.Distribution{
Valoper: valoper,
Amount: amount,
}
distributions = append(distributions, &newDistribution)
}

k.AddWithdrawalRecord(ctx, zone.ChainId, sender.String(), distributions, destination, sdk.Coins{}, burnAmount, hash, types.WithdrawStatusTokenize, time.Unix(0, 0), k.EpochsKeeper.GetEpochInfo(ctx, epochstypes.EpochIdentifierEpoch).CurrentEpoch)

return k.SubmitTx(ctx, sdkMsgs, zone.DelegationAddress, hash, zone.MessagesPerTx)
}
// func (k *Keeper) processRedemptionForLsm(ctx sdk.Context, zone *types.Zone, sender sdk.AccAddress, destination string, nativeTokens math.Int, burnAmount sdk.Coin, hash string) error {
// intent, found := k.GetDelegatorIntent(ctx, zone, sender.String(), false)
// // msgs is slice of MsgTokenizeShares, so we can handle dust allocation later.
// msgs := make([]*lsmstakingtypes.MsgTokenizeShares, 0)
// var err error
// intents := intent.Intents

// if !found || len(intents) == 0 {
// // if user has no intent set (this can happen if redeeming tokens that were obtained offchain), use global intent.
// // Note: this can be improved; user will receive a bunch of tokens.
// intents, err = k.GetAggregateIntentOrDefault(ctx, zone)
// if err != nil {
// return err
// }
// }
// outstanding := nativeTokens
// distribution := make(map[string]uint64, 0)

// availablePerValidator, _, err := k.GetUnlockedTokensForZone(ctx, zone)
// if err != nil {
// return err
// }
// for _, intent := range intents.Sort() {
// thisAmount := intent.Weight.MulInt(nativeTokens).TruncateInt()
// if thisAmount.GT(availablePerValidator[intent.ValoperAddress]) {
// return errors.New("unable to satisfy unbond request; delegations may be locked")
// }
// distribution[intent.ValoperAddress] = thisAmount.Uint64()
// outstanding = outstanding.Sub(thisAmount)
// }

// distribution[intents[0].ValoperAddress] += outstanding.Uint64()

// if distribution[intents[0].ValoperAddress] > availablePerValidator[intents[0].ValoperAddress].Uint64() {
// return errors.New("unable to satisfy unbond request (2); delegations may be locked")
// }

// for _, valoper := range utils.Keys(distribution) {
// msgs = append(msgs, &lsmstakingtypes.MsgTokenizeShares{
// DelegatorAddress: zone.DelegationAddress.Address,
// ValidatorAddress: valoper,
// Amount: sdk.NewCoin(zone.BaseDenom, sdk.NewIntFromUint64(distribution[valoper])),
// TokenizedShareOwner: destination,
// })
// }

// sdkMsgs := make([]sdk.Msg, 0)
// for _, msg := range msgs {
// sdkMsgs = append(sdkMsgs, sdk.Msg(msg))
// }
// distributions := make([]*types.Distribution, 0)

// for valoper, amount := range distribution {
// newDistribution := types.Distribution{
// Valoper: valoper,
// Amount: amount,
// }
// distributions = append(distributions, &newDistribution)
// }

// k.AddWithdrawalRecord(ctx, zone.ChainId, sender.String(), distributions, destination, sdk.Coins{}, burnAmount, hash, types.WithdrawStatusTokenize, time.Unix(0, 0), k.EpochsKeeper.GetEpochInfo(ctx, epochstypes.EpochIdentifierEpoch).CurrentEpoch)

// return k.SubmitTx(ctx, sdkMsgs, zone.DelegationAddress, hash, zone.MessagesPerTx)
// }

// queueRedemption will determine based on zone intent, the tokens to unbond, and add a withdrawal record with status QUEUED.
func (k *Keeper) queueRedemption(
Expand Down
4 changes: 2 additions & 2 deletions x/interchainstaking/types/allocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func TestTargetAllocationsMoreValidators(t *testing.T) {
amount := sdk.Coins{sdk.NewCoin("token", sdk.NewInt(1000))}

expectedAllocations := map[string]sdkmath.Int{
"validator1": sdkmath.NewInt(241),
"validator1": sdkmath.NewInt(239),
"validator2": sdkmath.NewInt(195),
"validator3": sdkmath.NewInt(282),
"validator4": sdkmath.NewInt(282),
Expand Down Expand Up @@ -214,7 +214,7 @@ func TestCurrentAllocationsMoreValidators(t *testing.T) {
amount := sdk.Coins{sdk.NewCoin("token", sdk.NewInt(1000))}

expectedAllocations := map[string]sdkmath.Int{
"validator1": sdkmath.NewInt(453),
"validator1": sdkmath.NewInt(452),
"validator2": sdkmath.NewInt(547),
}

Expand Down
8 changes: 4 additions & 4 deletions x/interchainstaking/types/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ func DetermineAllocationsForDelegation(currentAllocations map[string]sdkmath.Int
return nil, errors.New("outSum overflow; cannot be greater than input amount")
}

dust := input.Sub(outSum)
if !dust.IsZero() {
outWeights[deltas[0].ValoperAddress] = outWeights[deltas[0].ValoperAddress].Add(dust)
}
// dust := input.Sub(outSum)
// if !dust.IsZero() {
// outWeights[deltas[0].ValoperAddress] = outWeights[deltas[0].ValoperAddress].Add(dust)
// }

return outWeights, nil
}
4 changes: 2 additions & 2 deletions x/interchainstaking/types/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func TestDetermineAllocationsForDelegation(t *testing.T) {
expected: map[string]sdkmath.Int{
vals[3]: sdk.NewInt(7),
vals[1]: sdk.NewInt(5),
vals[0]: sdk.NewInt(8),
vals[0]: sdk.NewInt(7),
},
},
{
Expand All @@ -172,7 +172,7 @@ func TestDetermineAllocationsForDelegation(t *testing.T) {
},
inAmount: sdk.NewCoins(sdk.NewCoin("uqck", sdk.NewInt(50))),
expected: map[string]sdkmath.Int{
vals[0]: sdk.NewInt(27),
vals[0]: sdk.NewInt(21),
vals[1]: sdk.NewInt(12),
vals[2]: sdk.NewInt(1),
vals[3]: sdk.NewInt(10),
Expand Down

0 comments on commit f1c5e67

Please sign in to comment.