Skip to content

Commit

Permalink
deps!: use cosmos-sdk v0.45.16-lsm-ics (#2643)
Browse files Browse the repository at this point in the history
* deps: use cosmos-sdk v0.45.16-lsm-ics

* deps&rebase: use cosmos-sdk v0.45.16-lsm-ics

* add local testing script

* fix: update test_helpers; use latest lsm/ics versions

* chore: bump iqlusion:cosmos-sdk to latest

* Jstr/lsm e2e tests (#2679)

* lsm e2e test work - wip

* Add validator bond functionality on lsm happy path

* add tokenize share check on lsm test & redeemShare utility function

* add bank send lsm tokens test

* Add test for transfer reward ownership, and redeem shares

* Add staking param query utility & LSM params update process on LSM e2e test

* Add IBC transfer test on LSM share tokens & Resolve e2e tests by updating gas configs and result checker

* resolve github action bot comments

* bring all e2e test items back to enabled

* Update tests/e2e/e2e_lsm_test.go

Co-authored-by: sampocs <[email protected]>

* resolve comments

* reenable tokenize share record module account balance check

---------

Co-authored-by: jstr1121 <[email protected]>
Co-authored-by: jstr1121 <[email protected]>
Co-authored-by: sampocs <[email protected]>

* Add lsm params to upgrade handler (#2686)

* set LSM params in upgrade handler

* added comments around constants

* test: add migrateUBDEntries to upgrade handler — required adding exported.go to sdk

* Revert "test: add migrateUBDEntries to upgrade handler — required adding exported.go to sdk"

This reverts commit 7bd9727.

---------

Co-authored-by: Riley Edmunds <[email protected]>

* chore: bump cosmos-sdk and ics to latest

* Fix staking & distribution e2e test with LSM (#2687)

* lsm e2e test work - wip

* Add validator bond functionality on lsm happy path

* add tokenize share check on lsm test & redeemShare utility function

* add bank send lsm tokens test

* Add test for transfer reward ownership, and redeem shares

* Add staking param query utility & LSM params update process on LSM e2e test

* Add IBC transfer test on LSM share tokens & Resolve e2e tests by updating gas configs and result checker

* resolve github action bot comments

* bring all e2e test items back to enabled

* Update tests/e2e/e2e_lsm_test.go

Co-authored-by: sampocs <[email protected]>

* resolve comments

* reenable tokenize share record module account balance check

* fix staking test affected by other test

---------

Co-authored-by: jstr1121 <[email protected]>
Co-authored-by: jstr1121 <[email protected]>

* chore: appease lint rules

* docs: Add LSM docs (#2683)

* docs: validator FAQ updated with LSM docs

* docs: validator faq - remove min self delegation references

* docs: delegator faq - add lsm docs

* docs: address Marius review comments on docs

* bump SDK to 0.45.16-ics-lsm-rc0 and ICS to 2.0.0-lsm-rc0

* add .changelog entries

* use sdk.Dec

* Update constants.go

---------

Co-authored-by: riley-stride <[email protected]>
Co-authored-by: jstr1121 <[email protected]>
Co-authored-by: jstr1121 <[email protected]>
Co-authored-by: sampocs <[email protected]>
Co-authored-by: Riley Edmunds <[email protected]>
Co-authored-by: Marius Poke <[email protected]>
Co-authored-by: Shawn <[email protected]>
  • Loading branch information
8 people authored Aug 16, 2023
1 parent 027e0cc commit 75f0714
Show file tree
Hide file tree
Showing 23 changed files with 621 additions and 44 deletions.
3 changes: 3 additions & 0 deletions .changelog/unreleased/api-breaking/2643-lsm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Add Liquid Staking Module (LSM) and initialize the LSM params:
ValidatorBondFactor, ValidatorLiquidStakingCap, GlobalLiquidStakingCap
([\#2643](https://github.com/cosmos/gaia/pull/2643))
3 changes: 3 additions & 0 deletions .changelog/unreleased/dependencies/2643-bump-ics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Bump [interchain-security](https://github.com/cosmos/interchain-security) to
[v2.0.0-lsm](https://github.com/cosmos/interchain-security/releases/tag/v2.0.0-lsm)
([\#2643](https://github.com/cosmos/gaia/pull/2643))
3 changes: 3 additions & 0 deletions .changelog/unreleased/dependencies/2643-bump-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to
[v0.45.16-ics-lsm](https://github.com/cosmos/ibc-go/releases/tag/v0.45.16-ics-lsm)
([\#2643](https://github.com/cosmos/gaia/pull/2643))
3 changes: 3 additions & 0 deletions .changelog/unreleased/features/2643-lsm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Add Liquid Staking Module (LSM) and initialize the LSM params:
ValidatorBondFactor, ValidatorLiquidStakingCap, GlobalLiquidStakingCap
([\#2643](https://github.com/cosmos/gaia/pull/2643))
3 changes: 3 additions & 0 deletions .changelog/unreleased/state-breaking/2643-lsm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Add Liquid Staking Module (LSM) and initialize the LSM params:
ValidatorBondFactor, ValidatorLiquidStakingCap, GlobalLiquidStakingCap
([\#2643](https://github.com/cosmos/gaia/pull/2643))
21 changes: 10 additions & 11 deletions app/helpers/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,16 @@ func genesisStateWithValSet(t *testing.T,
pkAny, err := codectypes.NewAnyWithValue(pk)
require.NoError(t, err)
validator := stakingtypes.Validator{
OperatorAddress: sdk.ValAddress(val.Address).String(),
ConsensusPubkey: pkAny,
Jailed: false,
Status: stakingtypes.Bonded,
Tokens: bondAmt,
DelegatorShares: sdk.OneDec(),
Description: stakingtypes.Description{},
UnbondingHeight: int64(0),
UnbondingTime: time.Unix(0, 0).UTC(),
Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
MinSelfDelegation: sdk.ZeroInt(),
OperatorAddress: sdk.ValAddress(val.Address).String(),
ConsensusPubkey: pkAny,
Jailed: false,
Status: stakingtypes.Bonded,
Tokens: bondAmt,
DelegatorShares: sdk.OneDec(),
Description: stakingtypes.Description{},
UnbondingHeight: int64(0),
UnbondingTime: time.Unix(0, 0).UTC(),
Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()),
}
validators = append(validators, validator)
delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), sdk.OneDec()))
Expand Down
15 changes: 15 additions & 0 deletions app/upgrades/v12/constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package v12

import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/gaia/v12/app/upgrades"
)

Expand All @@ -9,6 +11,19 @@ const (
UpgradeName = "v12"
)

var (
// The ValidatorBondFactor dictates the cap on the liquid shares
// for a validator - determined as a multiple to their validator bond
// (e.g. ValidatorBondShares = 1000, BondFactor = 250 -> LiquidSharesCap: 250,000)
ValidatorBondFactor = sdk.NewDec(250)
// GlobalLiquidStakingCap represents a cap on the portion of stake that
// comes from liquid staking providers for a specific validator
ValidatorLiquidStakingCap = sdk.MustNewDecFromStr("0.5") // 50%
// GlobalLiquidStakingCap represents the percentage cap on
// the portion of a chain's total stake can be liquid
GlobalLiquidStakingCap = sdk.MustNewDecFromStr("0.25") // 25%
)

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
Expand Down
8 changes: 8 additions & 0 deletions app/upgrades/v12/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ func CreateUpgradeHandler(
return vm, err
}

// Set liquid staking module parameters
params := keepers.StakingKeeper.GetParams(ctx)
params.ValidatorBondFactor = ValidatorBondFactor
params.ValidatorLiquidStakingCap = ValidatorLiquidStakingCap
params.GlobalLiquidStakingCap = GlobalLiquidStakingCap

keepers.StakingKeeper.SetParams(ctx, params)

ctx.Logger().Info("Upgrade complete")
return vm, err
}
Expand Down
1 change: 0 additions & 1 deletion cmd/gaiad/cmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ func InitTestnet(
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()),
sdk.OneInt(),
)
if err != nil {
return err
Expand Down
65 changes: 65 additions & 0 deletions contrib/scripts/local-gaia.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/bash
set -eux

# User balance of stake tokens
USER_COINS="100000000000stake"
# Amount of stake tokens staked
STAKE="100000000stake"
# Node IP address
NODE_IP="127.0.0.1"

# Home directory
HOME_DIR="/Users/msalopek"

# Validator moniker
MONIKER="coordinator"

# Validator directory
PROV_NODE_DIR=${HOME_DIR}/provider-${MONIKER}

# Coordinator key
PROV_KEY=${MONIKER}-key


# Clean start
pkill -f gaiad &> /dev/null || true
rm -rf ${PROV_NODE_DIR}

# Build file and node directory structure
gaiad init $MONIKER --chain-id provider --home ${PROV_NODE_DIR}
jq ".app_state.gov.voting_params.voting_period = \"20s\" | .app_state.staking.params.unbonding_time = \"86400s\"" \
${PROV_NODE_DIR}/config/genesis.json > \
${PROV_NODE_DIR}/edited_genesis.json && mv ${PROV_NODE_DIR}/edited_genesis.json ${PROV_NODE_DIR}/config/genesis.json

sleep 1

# Create account keypair
gaiad keys add $PROV_KEY --home ${PROV_NODE_DIR} --keyring-backend test --output json > ${PROV_NODE_DIR}/${PROV_KEY}.json 2>&1
sleep 1

# Add stake to user
PROV_ACCOUNT_ADDR=$(jq -r '.address' ${PROV_NODE_DIR}/${PROV_KEY}.json)
gaiad add-genesis-account $PROV_ACCOUNT_ADDR $USER_COINS --home ${PROV_NODE_DIR} --keyring-backend test
sleep 1


# Stake 1/1000 user's coins
gaiad gentx $PROV_KEY $STAKE --chain-id provider --home ${PROV_NODE_DIR} --keyring-backend test --moniker $MONIKER
sleep 1

gaiad collect-gentxs --home ${PROV_NODE_DIR} --gentx-dir ${PROV_NODE_DIR}/config/gentx/
sleep 1

sed -i -r "/node =/ s/= .*/= \"tcp:\/\/${NODE_IP}:26658\"/" ${PROV_NODE_DIR}/config/client.toml
sed -i -r 's/timeout_commit = "5s"/timeout_commit = "3s"/g' ${PROV_NODE_DIR}/config/config.toml
sed -i -r 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${PROV_NODE_DIR}/config/config.toml


# Start gaia
gaiad start \
--home ${PROV_NODE_DIR} \
--rpc.laddr tcp://${NODE_IP}:26658 \
--grpc.address ${NODE_IP}:9091 \
--address tcp://${NODE_IP}:26655 \
--p2p.laddr tcp://${NODE_IP}:26656 \
--grpc-web.enable=false &> ${PROV_NODE_DIR}/logs
29 changes: 28 additions & 1 deletion docs/delegators/delegator-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ In order to choose their validators, delegators have access to a range of inform
- **Initial commission rate**: The commission rate on revenue charged to any delegator by the validator (see below for more detail).
- **Commission max change rate:** The maximum daily increase of the validator's commission. This parameter cannot be changed by the validator operator.
- **Maximum commission:** The maximum commission rate this validator candidate can charge. This parameter cannot be changed by the validator operator.
- **Minimum self-bond amount**: Minimum amount of Atoms the validator candidate need to have bonded at all time. If the validator's self-bonded stake falls below this limit, their entire staking pool (i.e. all its delegators) will unbond. This parameter exists as a safeguard for delegators. Indeed, when a validator misbehaves, part of their total stake gets slashed. This included the validator's self-delegateds stake as well as their delegators' stake. Thus, a validator with a high amount of self-delegated Atoms has more skin-in-the-game than a validator with a low amount. The minimum self-bond amount parameter guarantees to delegators that a validator will never fall below a certain amount of self-bonded stake, thereby ensuring a minimum level of skin-in-the-game. This parameter can only be increased by the validator operator.
- **Validator self-bond amount**: A validator with a high amount of self-delegated Atoms has more skin-in-the-game than a validator with a low amount.

## Directives of delegators

Expand Down Expand Up @@ -61,6 +61,33 @@ Our validator's staking pool represents 10% of the total stake, which means the

Then, each delegator in the staking pool can claim their portion of the delegators' total revenue.

## Liquid Staking

The Liquid Staking module enacts a safety framework and associated governance-controlled parameters to regulate the adoption of liquid staking.

The LSM mitigates liquid staking risks by limiting the total amount of ATOM that can be liquid staked to a percentage of all staked ATOM. As an additional risk-mitigation feature, the LSM introduces a requirement that validators self-bond ATOM to be eligible for delegations from liquid staking providers or to be eligible to mint LSM tokens. This mechanism is called the “validator bond”, and is technically distinct from the current self-bond mechanism, but functions similarly.

At the same time, the LSM introduces the ability for staked ATOM to be instantly liquid staked, without having to wait for the unbonding period.

The LSM enables users to instantly liquid stake their staked ATOM, without having to wait the twenty-one day unbonding period. This is important, because a very large portion of the ATOM supply is currently staked. Liquid staking ATOM that is already staked incurs a switching cost in the form of three weeks’ forfeited staking rewards. The LSM eliminates this switching cost.

A user would be able to visit any liquid staking provider that has integrated with the LSM and click a button to convert her staked ATOM to liquid staked ATOM. It would be as easy as liquid staking unstaked ATOM.

Technically speaking, this is accomplished by using something called an “LSM share.” Using the liquid staking module, a user can tokenize their staked ATOM and turn it into LSM shares. LSM shares can be redeemed for underlying staked tokens and are transferable. After staked ATOM is tokenized it can be immediately transferred to a liquid staking provider in exchange for liquid staking tokens - without having to wait for the unbonding period.

### Toggling the ability to tokenize shares

Currently the liquid staking module facilitates the immediate conversion of staked assets into liquid staked tokens. Despite the many benefits that come with this capability, it does inadvertently negate a protective measure available via traditional staking, where an account can stake their tokens to render them illiquid in the event that their wallet is compromised (the attacker would first need to unbond, then transfer out the tokens).

Tokenization obviates this potential recovery measure, as an attacker could tokenize and immediately transfer staked tokens to another wallet. So, as an additional protective measure, the staking module permit accounts to selectively disable the tokenization of their stake with the `DisableTokenizeShares` message.

The `DisableTokenizeShares` message is exposed by the staking module and can be executed as follows:
```
gaiad tx staking disable-tokenize-shares --from mykey
```

When tokenization is disabled, a lock is placed on the account, effectively preventing the tokenization of any delegations. Re-enabling tokenization would initiate the removal of the lock, but the process is not immediate. The lock removal is queued, with the lock itself persisting throughout the unbonding period. Following the completion of the unbonding period, the lock would be completely removed, restoring the account's ablility to tokenize. For liquid staking protocols that enable the lock, this delay better positions the base layer to coordinate a recovery in the event of an exploit.

## Risks

Staking Atoms is not free of risk. First, staked Atoms are locked up, and retrieving them requires a 3 week waiting period called unbonding period. Additionally, if a validator misbehaves, a portion of their total stake can be slashed (i.e. destroyed). This includes the stake of their delegators.
Expand Down
Loading

0 comments on commit 75f0714

Please sign in to comment.