-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Liquid Staking module #114
Open
zsystm
wants to merge
42
commits into
Canto-Network:main
Choose a base branch
from
b-harvest:liquidstaking-module
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
implement skeleton for liquidstaking module
* most state transitions of core states (chunk, insurance, etc…) must occur in EndBlocker at Epoch. * withdraw insurance and liquid unstake are queued until epoch. * implement hooks for tracking changes of delegation object * this is for tracking delegation rewards so we can distriibute it to reward module and insurance fee pool * fix bugs
* implement genesis logic * implement epoch logic * add helpful tracking fields for NetAmountState * delete hooks * to simplify core logics related with delegation, we use custom tracking obj (e.g. UnpairingForUnstakingChunkInfo) * instead we should make sure for our epoch of liquidtstaking module must be same with unbonding period of staking module * when liquid unstaking is started at previous epoch and current epoch is reached, we can unstake it right away if unbonding period is just same with epoch period. it is good for capital efficiency and we can manage states as clean and easy. * apply atomic sending coins using InputOutputCoins of bank keeper.
* remove un-used keys and methods * remove PendingLiquidUnstake and use UnpairingForUnstakingChunkInfo and chunk status to indicate the status of chunk * update comment * fix grammar
also includes * refactor logics * add state queries * refactor test codes * add helpful prints to debug easily (while development period)
* re-size chunk from 500M to 250K * apply dynamic fee rate
also includes * update swagger * add some queries * implement claim discounted reward msg * security patch * added tc for dynamic fee
HandleUnprocessedQueuedLiquidUnstakes step is added to abci. during testing we found that, without this logic some unstaking request remains forever. also includes * refactor slashing ante handler * add util function to easily create tx * update swagger * update init test script * update cli and setup integration testing * add testing for genesis and grpc query * conservative invariants * add invariants tcs * add tcs for edge cases * add events * diet net amount state * setup simulation basic (wip) * add and update spec
* add test files and tcs to raise code coverage
same depth but different path can't be served
penalty from src validator happened during re-delegation period must be covered by unpairing insurance.
…and etc fix core logics * if duty-free insurance is un-paired and it has enough collateral and have valid validator, then it becomes pairing insurance. (it is in spec, but missed) * when finishing unstaking, unpairing insurance's balance can be smaller than penalty. in that situation, unpairing ins must send it's all balance instead of penalty amt itself(cannot pay it because lack of balance). * when handling paired chunk which is in re-pairing situation, must consider tombstone case(evidence height < epoch(re-pairing) height) update core logics * when finishing unstaking, unstaker will get whole chunk amount tokens if unpairing insurance can cover the penalty. * if penalty occurred during re-delegation period is bigger than src insurance, then dst insurance should avoid covering that penalty instead because it is not dst's duty. * add edge cases handling logics. error & panic * clarify panic and error situations with additional sanity checks. added * Staking param also checked in param change ante handler. * integration testing * cli docs. refactor * unify name convention * short variable name for readability * no return err during iteration (most iterations must success. that means if there are error during iteration, it should be panic. so no need to return err). simulation * implement sim operations
test: add workflow for ci/cd #5
* add maximum cap for insurance fee rate insurance fee rate + validator's fee rate must be smaller than 50%. * chore: fix typo
* fix: seperate antehandler for simulation * fix: simulation errors (cherry picked from commit 6961967) * fix: simulation workflow * fix: update sims.yml, add GOPATH on makefile --------- Co-authored-by: dongsam <[email protected]>
* wip: simplify penalty logic when insurance is under 5.75% of chunk size, then un-delegate it. now we can make sure that during unbonding or re-delegation period, there must be no case where un-pairing insurance cannot cover penalty. remainings: * fix broken tests * remove re-delegation info's deletable and amt field * add tcs for new logics. * handle decimal penalty and fix broken tests when calc penaltyAmt, must check shares value based on amt. * update re-delegation info Those fields are introduced to cover the situation where unpairing ins at previous epoch cannot cover the penalty during re-delegation period. But now we check paired ins with IsEnoughToCoverSlash so we don't need PenaltyAmt and Deletable anymore. Because that scenario will not happen. * apply feedbacks * panic when validator is invalid (this must not happen) * remove empty branch * fix wrong calc in IsEnoughToCoverSlash feedbacks: * #9 (comment) * #9 (comment) * add unit test for CalcCeiledPenalty * remove un-reached checking logic and un-necessary comments by adding IsEnoughToCoverSlash function, the edge cases we were previously worried about are gone. (unpairing ins at previous epoch cannot cover the penalty during re-delegation period). so comments and checking logics for that edge should be deleted as now. * update spec related with this pr updated spec related with this pr remove tc created during test locally change function name of mustDelegate mustDelegatePenaltyAmt is more readable and meaningful * Update lintk in x/liquidstaking/spec/02_state.md Co-authored-by: dongsam <[email protected]> * Update link in x/liquidstaking/spec/02_state.md Co-authored-by: dongsam <[email protected]> --------- Co-authored-by: dongsam <[email protected]>
* add api docs and fix duplicate restful path * complete api and cli docs * chore: fix link * apply feedback * unify format * reduce huge response * unify surfic
* sync state.md with latest implementation * update state transition diagrams * sync state transitions, messages and fix some logics DoCancelProvideInsurance when cancel provide insurance, we should return all of its spendable coins from both derived address and fee pool address. DoWithdrawInsurance we can accept request only paired or unpaired insurances, not unpairing insurance. it because unpairing insurance is already in state transition situation at epoch, so its weird to queue the request for that insurance. * sync latest spec with latest code and fix some core logics fix core logics before: * there can be bug because chunk's status is changed to unpairing but, current paired chunk's status is still Paired and chunk have paired insurance id even if it is unpairing chunk. after: if paired insurance of paired chunk have invalid insurance, then unpairing it and add it to out insurances to hande just like other unpairing chunks. add missing invariant checks * newly added RedelegationInfosInvariant was not included chore * refactor variables name in invariants.go * use lsm's own event key types, not other module's. * add module name to each event * add detailed comments for net amount and param change ante handlers also updated swagger docs and statik * add missed swagger yaml * add description for 5.75% * remove ConservativeNetAmount and update calc method of TotalLiquidTokens * if there were slashing (token value of chunk's del < chunk size), then we consider insurance balance now. * remove NativeTokenToLiquidStakeToken, just use MintRate. it is more easy to understand. * update remaining reward calc method * chore: update name of tc * update spec * optimize operations * optimize redundant calls * add todo * update and fix spec * add description about utilization ratio * definition of NetAmount is changed. we consider insurance coverage now. * add missing item to a formula of NetAmount: sum of all unbonding balance of chunks (insurance coverage included) * MaximumDiscountRate is defined as governance parameter * chore: fix grammar * update formula for calculating discount rate * add missing diagrams and security cap description * wip: update and refactor net amount state part TODO: fix broken tests * fix broken tcs and refactor some functions * remove netAmountBeforeModuleFee from net amount state * remove un-used function * add NetAmountBeforeModuleFee at spec * chore: fix variable name * refactor: calc functions / add: dynamic fee tcs those functions are moved to type level functions * add custom stringer for Params * add tc for CalcUtilizationRatio / chore: fix number expression * remove redundant func and logic
* sync state.md with latest implementation * update state transition diagrams * sync state transitions, messages and fix some logics DoCancelProvideInsurance when cancel provide insurance, we should return all of its spendable coins from both derived address and fee pool address. DoWithdrawInsurance we can accept request only paired or unpaired insurances, not unpairing insurance. it because unpairing insurance is already in state transition situation at epoch, so its weird to queue the request for that insurance. * sync latest spec with latest code and fix some core logics fix core logics before: * there can be bug because chunk's status is changed to unpairing but, current paired chunk's status is still Paired and chunk have paired insurance id even if it is unpairing chunk. after: if paired insurance of paired chunk have invalid insurance, then unpairing it and add it to out insurances to hande just like other unpairing chunks. add missing invariant checks * newly added RedelegationInfosInvariant was not included chore * refactor variables name in invariants.go * use lsm's own event key types, not other module's. * add module name to each event * wip: refactor simulation codes todo: need to run it in local * fix and update app.go * wip: implementing proposal simulations TODO: Solve cycle problem * solve import cycle and make it work TODO: deal with staking module's initial stake part * fix simulations * update reduction * resolve errors after merge * fix epoch and wrong deduction reduce advance epoch weight * update invariant and refactor some codes del shares can be less than 250K (e.g. slashing during re-delegation period, not yet reached epoch) * remove un-used check and add more context to panic message now chunk invariants does not check its delegation shares. it can be changed by slashing during re-delegation. * fix: re-delegation matured logic decision must be based on current block time. if current block time >= info.CompletionTime, then it is matured. if not, it is un-matured. * wip: fix some isseus and trouble shooting for seed 1623992154303935393 disabled mimicking begin block logic of distribution module at epoch * fix: simulation cancel provide insurance target insurance must be pairing * fix negative penaltyAmt * sim: change power reduction * fix: not updated validator problem and power reduction must use validator retrieved from latest state. * exclude epochs key EpochInfo.CurrentEpochStartHeight is set to the block height at the time of init genesis. This state is changeable when export and import, so exclude it. * fix: missing ReDelegationInfo at genesis import and export * chore: fix wrong variable name * fix: restOutIns can have paired chunk when ins directs Unbonding validator, then this situation can happen. In this situation, we just unpair and undelegate it. * temp: disable lsm param change * fix dynamic fee rate as default * fix: out insurance's status must not be updated this is related with recent patch. outIns is already unpairing for unpairing_for_withdrawa, so we must not update it. chore: removed un-used method. * fix: out insurance status out insurance can be PAIRED status (ranked out but no replacement). if it is not unpairing or unpairing for withdrawal we must change its status to unpairing because unbonding will be started. * fix: simop liquid unstake when decide unstakable chunk, we should consider whether it is already queued or not. * optimize gas consumption (add InsuranceState) and update sim optimize gas consumption * added new internal state InsuranceState * when calc NetAmount we don't need insurance states. so separate that state which will be used when query. update sim * apply default genesis * don't allow param change * enable inflation module temp: apply sdk.DefaultPowerReduction when calc epoch provision. this will be changed at next PR * add missing files * use b-harvest cosmos-sdk patched for canto-lsm simulation testing * clarify tc more understandable and readable tc * add missing proto file (separate insurance related field as InsuranceState) * remove un-used weights * refactor: just assign base keeper to BankKeeper right away * add missing proto file * remove epoch infos keys epoch module's state can be changed when initGenesis. * roll-back change and add NetAmountStateEssentials all core logics using NetAmount before now use NetAmountEssentials. NetAmount is used just for querying. * add missing files * apply ethermint reduction for this, applied custom ibc-go and cosmos-sdk to updated initialStake as sdk.Int * update spec related to NetAmountStateEssentials * fix syntax error(should use sdk.Int)
# Conflicts: # .github/workflows/build.yml # .github/workflows/sims.yml # .github/workflows/test.yml # Makefile # app/ante/handler_options.go # app/ante/vesting.go # app/app.go # app/sim_test.go # app/state.go # app/test_helpers.go # client/docs/config.json # client/docs/statik/statik.go # client/docs/swagger-ui/swagger.yaml # cmd/cantod/genaccounts.go # ibc/testing/app.go # proto/canto/csr/v1/query.proto # proto/canto/fees/v1/fees.proto # proto/canto/fees/v1/genesis.proto # proto/canto/fees/v1/query.proto # proto/canto/fees/v1/tx.proto # proto/canto/onboarding/v1/query.proto # proto/canto/recovery/v1/genesis.proto # proto/canto/vesting/v1/query.proto # proto/canto/vesting/v1/tx.proto # proto/canto/vesting/v1/vesting.proto # x/fees/client/cli/query.go # x/fees/client/cli/tx.go # x/fees/genesis.go # x/fees/handler.go # x/fees/keeper/fees.go # x/fees/keeper/fees_test.go # x/fees/keeper/grpc_query.go # x/fees/keeper/grpc_query_test.go # x/fees/keeper/integration_test.go # x/fees/keeper/keeper.go # x/fees/keeper/keeper_test.go # x/fees/keeper/msg_server.go # x/fees/keeper/msg_server_test.go # x/fees/keeper/params.go # x/fees/keeper/params_test.go # x/fees/module.go # x/onboarding/client/cli/query.go # x/onboarding/genesis.go # x/onboarding/genesis_test.go # x/onboarding/ibc_middleware.go # x/onboarding/keeper/grpc_query.go # x/onboarding/keeper/grpc_query_test.go # x/onboarding/keeper/keeper.go # x/onboarding/keeper/keeper_test.go # x/onboarding/keeper/params.go # x/onboarding/keeper/utils_test.go # x/onboarding/module.go # x/recovery/keeper/ibc_callbacks.go # x/recovery/keeper/ibc_callbacks_integration_suite_test.go # x/recovery/keeper/ibc_callbacks_integration_test.go # x/recovery/keeper/ibc_callbacks_test.go # x/vesting/client/cli/query.go # x/vesting/client/cli/tx.go # x/vesting/handler.go # x/vesting/keeper/grpc_query.go # x/vesting/keeper/grpc_query_test.go # x/vesting/keeper/integration_test.go # x/vesting/keeper/keeper.go # x/vesting/keeper/keeper_test.go # x/vesting/keeper/msg_server.go # x/vesting/keeper/msg_server_test.go # x/vesting/module.go # x/vesting/types/clawback_vesting_account_test.go
lstoken can be used as maxToken which is not registered as params. with no-op, we can proceed sim tests.
* disable minus fee rate * chore: remove un-used errors and bump cosmos-sdk * fix duplicate error code * update simop if calculated fee rate is negative, then apply zeroFeeRate
* tmp: add logger to analyze gas consumption logs gas consumption at fileLogger * disable minus fee rate * chore: remove un-used errors and bump cosmos-sdk * fix duplicate error code * update simop if calculated fee rate is negative, then apply zeroFeeRate * limit minting if it exceeds mainnet total supply * update: initialize at least one validator in AppStateRandomizedFn * apply Canto mainnet supply based on mainnet supply, rich account get fund when initialize genesis on simulation testing. each operation which needs token should get fund from rich account. * update CalcNetAmountStateEssentials: return multiple data structures this is for optimizing gas consumption when QueueLiquidUnstake instead of Iterate chunks separately, iterate it once when calc net amount state essentials. * refund gas used by cachedCtx * remove logger and print lines for debugging * remove un-necessary lines * chore: change variable name * reduce computation GetValidator().String is a redundant computation. We can just use ValidatorAddress field.
* add v8 upgrade handler and link issue related with go.mod * Fix comment Co-authored-by: dongsam <[email protected]> --------- Co-authored-by: dongsam <[email protected]>
* fix un-used variables and unify code usages DoLiquidStake must returns total new shares and total ls token mint amount because user can liquid stake multiple chunks. use sdk.Int instead of int64 when calc chunksToLiquidUnstake. sanity patch to avoid overflow. * add sanity checks * use SpendableCoins instead of GetBalance
* WIP: spec update * WIP: spec update applying comments * WIP: spec update
* set liquid bond denom at upgrade and msg_server * add tc for liquidBondDenom at upgrade * fix: set epoch duration same with staking unbonding time --------- Co-authored-by: dongsam <[email protected]>
* add abci spec * docs: updating abci spec * fix typo * update contents and figure * remove begin block and block mds * updated related contents * re-order docs * update diagram more detail description for covering penalty --------- Co-authored-by: poorphd <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
secure liquidstaking module on Canto
Brief summary (please read above links for details)
This PR is ready to be reviewed and audited but some additional commits can be pushed (not a big change)
cc. @dongsam @poorphd
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...