├── .github ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ ├── go.yml │ ├── lint.yml │ └── test.yml ├── .gitignore ├── .golangci.yml ├── LICENSE ├── Makefile ├── README.md ├── adr ├── adr-001.md ├── adr-002.md └── adr-003.md ├── app ├── README.md ├── app.go ├── app_test.go ├── config.go ├── encoding.go ├── export.go ├── genesis.go ├── genesis_account.go ├── genesis_account_test.go ├── helpers │ └── test_helpers.go ├── params │ ├── doc.go │ ├── encoding.go │ ├── params.go │ ├── proto.go │ └── weights.go ├── sim_bench_test.go ├── sim_test.go ├── state.go ├── test_helpers.go ├── types.go ├── upgrades.go ├── utils.go └── utils_test.go ├── cmd └── liquidstakingd │ ├── cmd │ ├── cmd_test.go │ ├── genaccounts.go │ ├── genaccounts_test.go │ ├── root.go │ ├── testnet.go │ └── testnet_test.go │ └── main.go ├── contrib └── devtools │ ├── Makefile │ └── install-golangci-lint.sh ├── genesis.json ├── go.mod ├── go.sum ├── proto ├── buf.gen.gogo.yaml ├── buf.lock ├── buf.yaml ├── distribution │ └── v1beta1 │ │ ├── distribution.proto │ │ ├── genesis.proto │ │ ├── query.proto │ │ └── tx.proto └── staking │ └── v1beta1 │ ├── authz.proto │ ├── genesis.proto │ ├── query.proto │ ├── staking.proto │ └── tx.proto ├── scripts ├── Makefile └── protocgen.sh ├── start.sh ├── testutil └── network │ ├── doc.go │ ├── network.go │ ├── network_test.go │ └── util.go ├── third_party └── proto │ ├── cosmos │ ├── authz │ │ └── v1beta1 │ │ │ ├── authz.proto │ │ │ ├── event.proto │ │ │ ├── genesis.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ ├── bank │ │ └── v1beta1 │ │ │ ├── authz.proto │ │ │ ├── bank.proto │ │ │ ├── genesis.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ ├── base │ │ ├── abci │ │ │ └── v1beta1 │ │ │ │ └── abci.proto │ │ ├── kv │ │ │ └── v1beta1 │ │ │ │ └── kv.proto │ │ ├── node │ │ │ └── v1beta1 │ │ │ │ └── query.proto │ │ ├── query │ │ │ └── v1beta1 │ │ │ │ └── pagination.proto │ │ ├── reflection │ │ │ ├── v1beta1 │ │ │ │ └── reflection.proto │ │ │ └── v2alpha1 │ │ │ │ └── reflection.proto │ │ ├── snapshots │ │ │ └── v1beta1 │ │ │ │ └── snapshot.proto │ │ ├── store │ │ │ └── v1beta1 │ │ │ │ ├── commit_info.proto │ │ │ │ └── listening.proto │ │ ├── tendermint │ │ │ └── v1beta1 │ │ │ │ ├── query.proto │ │ │ │ └── types.proto │ │ └── v1beta1 │ │ │ └── coin.proto │ ├── capability │ │ └── v1beta1 │ │ │ ├── capability.proto │ │ │ └── genesis.proto │ ├── crisis │ │ └── v1beta1 │ │ │ ├── genesis.proto │ │ │ └── tx.proto │ ├── crypto │ │ ├── ed25519 │ │ │ └── keys.proto │ │ ├── hd │ │ │ └── v1 │ │ │ │ └── hd.proto │ │ ├── keyring │ │ │ └── v1 │ │ │ │ └── record.proto │ │ ├── multisig │ │ │ ├── keys.proto │ │ │ └── v1beta1 │ │ │ │ └── multisig.proto │ │ ├── secp256k1 │ │ │ └── keys.proto │ │ └── secp256r1 │ │ │ └── keys.proto │ ├── evidence │ │ └── v1beta1 │ │ │ ├── evidence.proto │ │ │ ├── genesis.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ ├── feegrant │ │ └── v1beta1 │ │ │ ├── feegrant.proto │ │ │ ├── genesis.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ ├── genutil │ │ └── v1beta1 │ │ │ └── genesis.proto │ ├── gov │ │ ├── v1 │ │ │ ├── genesis.proto │ │ │ ├── gov.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ │ └── v1beta1 │ │ │ ├── genesis.proto │ │ │ ├── gov.proto │ │ │ ├── query.proto │ │ │ └── tx.proto │ ├── group │ │ └── v1 │ │ │ ├── events.proto │ │ │ ├── genesis.proto │ │ │ ├── query.proto │ │ │ ├── tx.proto │ │ │ └── types.proto │ ├── mint │ │ └── v1beta1 │ │ │ ├── genesis.proto │ │ │ ├── mint.proto │ │ │ └── query.proto │ ├── msg │ │ └── v1 │ │ │ └── msg.proto │ ├── params │ │ └── v1beta1 │ │ │ ├── params.proto │ │ │ └── query.proto │ ├── slashing │ │ └── v1beta1 │ │ │ ├── genesis.proto │ │ │ ├── query.proto │ │ │ ├── slashing.proto │ │ │ └── tx.proto │ ├── tx │ │ ├── signing │ │ │ └── v1beta1 │ │ │ │ └── signing.proto │ │ └── v1beta1 │ │ │ ├── service.proto │ │ │ └── tx.proto │ ├── upgrade │ │ └── v1beta1 │ │ │ ├── query.proto │ │ │ ├── tx.proto │ │ │ └── upgrade.proto │ └── vesting │ │ └── v1beta1 │ │ ├── tx.proto │ │ └── vesting.proto │ ├── cosmos_proto │ └── cosmos.proto │ ├── gogoproto │ └── gogo.proto │ ├── google │ ├── api │ │ ├── annotations.proto │ │ ├── http.proto │ │ └── httpbody.proto │ └── protobuf │ │ └── any.proto │ └── tendermint │ ├── abci │ └── types.proto │ ├── crypto │ ├── keys.proto │ └── proof.proto │ ├── libs │ └── bits │ │ └── types.proto │ ├── p2p │ └── types.proto │ ├── types │ ├── block.proto │ ├── evidence.proto │ ├── params.proto │ ├── types.proto │ └── validator.proto │ └── version │ └── types.proto └── x ├── distribution ├── README.md ├── abci.go ├── client │ ├── cli │ │ ├── query.go │ │ ├── tx.go │ │ ├── tx_test.go │ │ └── utils.go │ ├── common │ │ ├── common.go │ │ └── common_test.go │ ├── proposal_handler.go │ └── testutil │ │ ├── cli_test.go │ │ ├── grpc_query_suite.go │ │ ├── helpers.go │ │ ├── suite.go │ │ └── withdraw_all_suite.go ├── doc.go ├── handler.go ├── handler_test.go ├── keeper │ ├── alias_functions.go │ ├── allocation.go │ ├── allocation_test.go │ ├── common_test.go │ ├── delegation.go │ ├── delegation_test.go │ ├── fee_pool.go │ ├── genesis.go │ ├── grpc_query.go │ ├── grpc_query_test.go │ ├── hooks.go │ ├── invariants.go │ ├── keeper.go │ ├── keeper_test.go │ ├── migrations.go │ ├── msg_server.go │ ├── params.go │ ├── proposal_handler.go │ ├── querier.go │ ├── querier_test.go │ ├── store.go │ └── validator.go ├── module.go ├── module_test.go ├── proposal_handler_test.go ├── simulation │ ├── decoder.go │ ├── decoder_test.go │ ├── genesis.go │ ├── genesis_test.go │ ├── operations.go │ ├── operations_test.go │ ├── params.go │ ├── params_test.go │ ├── proposals.go │ └── proposals_test.go ├── spec │ ├── 01_concepts.md │ ├── 02_state.md │ ├── 03_begin_block.md │ ├── 04_messages.md │ ├── 05_hooks.md │ ├── 06_events.md │ ├── 07_params.md │ ├── 08_client.md │ └── README.md └── types │ ├── codec.go │ ├── common_test.go │ ├── delegator.go │ ├── distribution.pb.go │ ├── errors.go │ ├── events.go │ ├── expected_keepers.go │ ├── fee_pool.go │ ├── fee_pool_test.go │ ├── genesis.go │ ├── genesis.pb.go │ ├── keys.go │ ├── msg.go │ ├── msg_test.go │ ├── params.go │ ├── params_internal_test.go │ ├── params_test.go │ ├── proposal.go │ ├── querier.go │ ├── query.go │ ├── query.pb.go │ ├── query.pb.gw.go │ ├── tx.pb.go │ └── validator.go ├── genutil ├── client │ ├── cli │ │ ├── collect.go │ │ ├── gentx.go │ │ ├── init.go │ │ ├── init_test.go │ │ ├── migrate.go │ │ └── validate_genesis.go │ └── testutil │ │ ├── cli_test.go │ │ ├── helpers.go │ │ ├── migrate.go │ │ └── suite.go ├── collect.go ├── collect_test.go ├── doc.go ├── genesis.go ├── gentx.go ├── gentx_test.go ├── migrations │ └── v046 │ │ └── migrate.go ├── module.go ├── types │ ├── expected_keepers.go │ ├── genesis.pb.go │ ├── genesis_state.go │ ├── genesis_state_test.go │ └── types.go ├── utils.go └── utils_test.go ├── slashing ├── README.md ├── abci.go ├── abci_test.go ├── app_test.go ├── client │ ├── cli │ │ ├── flags.go │ │ ├── query.go │ │ └── tx.go │ └── testutil │ │ ├── cli_test.go │ │ ├── grpc.go │ │ └── suite.go ├── init_test.go ├── keeper │ ├── common_test.go │ ├── genesis.go │ ├── genesis_test.go │ ├── grpc_query.go │ ├── grpc_query_test.go │ ├── hooks.go │ ├── infractions.go │ ├── keeper.go │ ├── keeper_test.go │ ├── migrations.go │ ├── msg_server.go │ ├── params.go │ ├── querier.go │ ├── querier_test.go │ ├── signing_info.go │ ├── signing_info_test.go │ └── unjail.go ├── module.go ├── simulation │ ├── decoder.go │ ├── decoder_test.go │ ├── genesis.go │ ├── genesis_test.go │ ├── operations.go │ ├── operations_test.go │ ├── params.go │ └── params_test.go ├── spec │ ├── 01_concepts.md │ ├── 02_state.md │ ├── 03_messages.md │ ├── 04_begin_block.md │ ├── 05_hooks.md │ ├── 06_events.md │ ├── 07_tombstone.md │ ├── 08_params.md │ ├── 09_client.md │ └── README.md ├── testslashing │ └── params.go └── types │ ├── codec.go │ ├── errors.go │ ├── events.go │ ├── expected_keepers.go │ ├── genesis.go │ ├── genesis.pb.go │ ├── keys.go │ ├── msg.go │ ├── msg_test.go │ ├── params.go │ ├── querier.go │ ├── query.pb.go │ ├── query.pb.gw.go │ ├── signing_info.go │ ├── slashing.pb.go │ └── tx.pb.go └── staking ├── README.md ├── abci.go ├── app_test.go ├── bench_test.go ├── client ├── cli │ ├── flags.go │ ├── query.go │ ├── tx.go │ ├── tx_test.go │ └── utils.go └── testutil │ ├── cli_test.go │ ├── grpc.go │ ├── suite.go │ └── test_helpers.go ├── common_test.go ├── genesis.go ├── genesis_test.go ├── handler.go ├── handler_test.go ├── keeper ├── alias_functions.go ├── common_test.go ├── delegation.go ├── delegation_test.go ├── genesis.go ├── genesis_test.go ├── grpc_query.go ├── grpc_query_test.go ├── historical_info.go ├── historical_info_test.go ├── hooks.go ├── invariants.go ├── keeper.go ├── keeper_test.go ├── liquid_stake.go ├── liquid_stake_test.go ├── migrations.go ├── msg_server.go ├── msg_server_test.go ├── params.go ├── pool.go ├── power_reduction.go ├── power_reduction_test.go ├── querier.go ├── querier_test.go ├── query_utils.go ├── slash.go ├── slash_test.go ├── test_common.go ├── tokenize_share_record.go ├── tokenize_share_record_test.go ├── val_state_change.go ├── validator.go ├── validator_bench_test.go └── validator_test.go ├── module.go ├── module_test.go ├── simulation ├── common_test.go ├── decoder.go ├── decoder_test.go ├── genesis.go ├── genesis_test.go ├── operations.go ├── operations_test.go ├── params.go └── params_test.go ├── spec ├── 01_state.md ├── 02_state_transitions.md ├── 03_messages.md ├── 04_begin_block.md ├── 05_end_block.md ├── 06_hooks.md ├── 07_events.md ├── 08_params.md ├── 09_client.md └── README.md ├── teststaking ├── helper.go ├── tm.go └── validator.go └── types ├── authz.go ├── authz.pb.go ├── authz_test.go ├── codec.go ├── commission.go ├── commission_test.go ├── data_test.go ├── delegation.go ├── delegation_test.go ├── errors.go ├── events.go ├── expected_keepers.go ├── exported.go ├── genesis.go ├── genesis.pb.go ├── historical_info.go ├── historical_info_test.go ├── hooks.go ├── keys.go ├── keys_test.go ├── msg.go ├── msg_test.go ├── params.go ├── params_test.go ├── pool.go ├── querier.go ├── query.pb.go ├── query.pb.gw.go ├── staking.pb.go ├── tokenize_share_record.go ├── tx.pb.go ├── validator.go └── validator_test.go /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | target-branch: "master" 8 | open-pull-requests-limit: 10 9 | labels: 10 | - dependencies 11 | 12 | - package-ecosystem: gomod 13 | directory: "/" 14 | schedule: 15 | interval: weekly 16 | target-branch: "master" 17 | open-pull-requests-limit: 10 18 | labels: 19 | - dependencies 20 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [ master ] 7 | 8 | jobs: 9 | analyze: 10 | name: Analyze 11 | runs-on: ubuntu-latest 12 | permissions: 13 | actions: read 14 | contents: read 15 | security-events: write 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4.1.1 20 | 21 | # Initializes the CodeQL tools for scanning. 22 | - name: Initialize CodeQL 23 | uses: github/codeql-action/init@v2 24 | with: 25 | languages: 'go' 26 | queries: crypto-com/cosmos-sdk-codeql@main,security-and-quality 27 | # If you wish to specify custom queries, you can do so here or in a config file. 28 | # By default, queries listed here will override any specified in a config file. 29 | # Prefix the list here with "+" to use these queries and those in the config file. 30 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 31 | 32 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 33 | # If this step fails, then you should remove it and run the build manually (see below) 34 | - name: Autobuild 35 | uses: github/codeql-action/autobuild@v2 36 | 37 | # ℹ️ Command-line programs to run using the OS shell. 38 | # 📚 https://git.io/JvXDl 39 | 40 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 41 | # and modify them (or add more) to build your code if your project 42 | # uses a compiled language 43 | 44 | #- run: | 45 | # make bootstrap 46 | # make release 47 | 48 | - name: Perform CodeQL Analysis 49 | uses: github/codeql-action/analyze@v2 -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a golang project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Go 5 | 6 | on: 7 | push: 8 | branches: [ "master" ] 9 | pull_request: 10 | branches: [ "master" ] 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4.1.1 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v4 21 | with: 22 | go-version: "1.20" 23 | 24 | - name: Build 25 | run: go build -v ./... 26 | 27 | - name: Test 28 | run: go test -v ./... 29 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | tags: 5 | - v* 6 | branches: 7 | - master 8 | - main 9 | pull_request: 10 | permissions: 11 | contents: read 12 | # Optional: allow read access to pull request. Use with `only-new-issues` option. 13 | # pull-requests: read 14 | jobs: 15 | golangci: 16 | name: lint 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/setup-go@v4 20 | with: 21 | go-version: "1.20" 22 | cache: false 23 | - uses: actions/checkout@v4.1.1 24 | - name: golangci-lint 25 | uses: golangci/golangci-lint-action@v3 26 | with: 27 | version: latest 28 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/mvdan/github-actions-golang 2 | # Runs tests on mac, windows, and linux, for go v1.19 and v1.20 3 | 4 | on: [push, pull_request] 5 | name: Test 6 | jobs: 7 | test: 8 | strategy: 9 | matrix: 10 | go-version: [1.20.x] 11 | os: [ubuntu-latest, macos-latest] 12 | runs-on: ${{ matrix.os }} 13 | steps: 14 | - uses: actions/checkout@v4.1.1 15 | - uses: actions/setup-go@v4 16 | with: 17 | go-version: ${{ matrix.go-version }} 18 | - run: go test ./... 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS 2 | .DS_Store 3 | *.swp 4 | *.swo 5 | *.swl 6 | *.swm 7 | *.swn 8 | *.dot 9 | .vscode 10 | .idea 11 | 12 | # Build 13 | vendor 14 | build 15 | tools/bin/* 16 | examples/build/* 17 | docs/_build 18 | docs/tutorial 19 | dist 20 | tools-stamp 21 | buf-stamp 22 | 23 | # Data - ideally these don't exist 24 | baseapp/data/* 25 | client/lcd/keys/* 26 | cmd/liquidstakingcli/statik/statik.go 27 | mytestnet 28 | 29 | # Testing 30 | coverage.txt 31 | profile.out 32 | 33 | # Vagrant 34 | .vagrant/ 35 | *.box 36 | *.log 37 | vagrant 38 | 39 | # IDE 40 | .idea/ 41 | *.iml 42 | 43 | # Graphviz 44 | dependency-graph.png 45 | 46 | # Latex 47 | *.aux 48 | *.out 49 | *.synctex.gz 50 | contract_tests/* 51 | 52 | home 53 | *.zip -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | tests: true 3 | timeout: 5m 4 | allow-parallel-runners: true 5 | 6 | linters: 7 | disable-all: true 8 | enable: 9 | - bodyclose 10 | - dogsled 11 | - errcheck 12 | - exportloopref 13 | - goconst 14 | - gocritic 15 | - gofumpt 16 | - gosec 17 | - gosimple 18 | - govet 19 | - ineffassign 20 | - misspell 21 | - nakedret 22 | - nolintlint 23 | - revive 24 | - staticcheck 25 | - stylecheck 26 | - typecheck 27 | - unconvert 28 | - unparam 29 | - unused 30 | 31 | # TODO: fix the errorsmod.Wrap deprecation warning and re-enable staticcheck 32 | # TODO: fix the use of deprecated gov style 33 | 34 | issues: 35 | exclude-rules: 36 | - text: "simtypes" 37 | linters: 38 | - staticcheck 39 | - text: "Use of weak random number generator" 40 | linters: 41 | - gosec 42 | - text: "ST1003:" 43 | linters: 44 | - stylecheck 45 | # FIXME: Disabled until golangci-lint updates stylecheck with this fix: 46 | # https://github.com/dominikh/go-tools/issues/389 47 | - text: "ST1016:" 48 | linters: 49 | - stylecheck 50 | - path: "migrations" 51 | text: "SA1019:" 52 | linters: 53 | - staticcheck 54 | 55 | max-issues-per-linter: 10000 56 | max-same-issues: 10000 57 | 58 | linters-settings: 59 | dogsled: 60 | max-blank-identifiers: 3 61 | maligned: 62 | # print struct with more effective memory layout or not, false by default 63 | suggest-new: true 64 | nolintlint: 65 | allow-unused: false 66 | allow-leading-space: true 67 | require-explanation: false 68 | require-specific: false 69 | -------------------------------------------------------------------------------- /app/encoding.go: -------------------------------------------------------------------------------- 1 | package simapp 2 | 3 | import ( 4 | simappparams "github.com/cosmos/cosmos-sdk/simapp/params" 5 | "github.com/cosmos/cosmos-sdk/std" 6 | ) 7 | 8 | // MakeTestEncodingConfig creates an EncodingConfig for testing. This function 9 | // should be used only in tests or when creating a new app instance (NewApp*()). 10 | // App user shouldn't create new codecs - use the app.AppCodec instead. 11 | // [DEPRECATED] 12 | func MakeTestEncodingConfig() simappparams.EncodingConfig { 13 | encodingConfig := simappparams.MakeTestEncodingConfig() 14 | std.RegisterLegacyAminoCodec(encodingConfig.Amino) 15 | std.RegisterInterfaces(encodingConfig.InterfaceRegistry) 16 | ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) 17 | ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) 18 | return encodingConfig 19 | } 20 | -------------------------------------------------------------------------------- /app/genesis.go: -------------------------------------------------------------------------------- 1 | package simapp 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | ) 8 | 9 | // GenesisState of the blockchain is represented here as a map of raw json 10 | // messages key'd by a identifier string. 11 | // The identifier is used to determine which module genesis information belongs 12 | // to so it may be appropriately routed during init chain. 13 | // Within this application default genesis information is retrieved from 14 | // the ModuleBasicManager which populates json from each BasicModule 15 | // object provided to it during init. 16 | type GenesisState map[string]json.RawMessage 17 | 18 | // NewDefaultGenesisState generates the default state for the application. 19 | func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { 20 | return ModuleBasics.DefaultGenesis(cdc) 21 | } 22 | -------------------------------------------------------------------------------- /app/genesis_account.go: -------------------------------------------------------------------------------- 1 | package simapp 2 | 3 | import ( 4 | "errors" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 8 | ) 9 | 10 | var _ authtypes.GenesisAccount = (*SimGenesisAccount)(nil) 11 | 12 | // SimGenesisAccount defines a type that implements the GenesisAccount interface 13 | // to be used for simulation accounts in the genesis state. 14 | type SimGenesisAccount struct { 15 | *authtypes.BaseAccount 16 | 17 | // vesting account fields 18 | OriginalVesting sdk.Coins `json:"original_vesting" yaml:"original_vesting"` // total vesting coins upon initialization 19 | DelegatedFree sdk.Coins `json:"delegated_free" yaml:"delegated_free"` // delegated vested coins at time of delegation 20 | DelegatedVesting sdk.Coins `json:"delegated_vesting" yaml:"delegated_vesting"` // delegated vesting coins at time of delegation 21 | StartTime int64 `json:"start_time" yaml:"start_time"` // vesting start time (UNIX Epoch time) 22 | EndTime int64 `json:"end_time" yaml:"end_time"` // vesting end time (UNIX Epoch time) 23 | 24 | // module account fields 25 | ModuleName string `json:"module_name" yaml:"module_name"` // name of the module account 26 | ModulePermissions []string `json:"module_permissions" yaml:"module_permissions"` // permissions of module account 27 | } 28 | 29 | // Validate checks for errors on the vesting and module account parameters 30 | func (sga SimGenesisAccount) Validate() error { 31 | if !sga.OriginalVesting.IsZero() { 32 | if sga.StartTime >= sga.EndTime { 33 | return errors.New("vesting start-time cannot be before end-time") 34 | } 35 | } 36 | 37 | if sga.ModuleName != "" { 38 | ma := authtypes.ModuleAccount{ 39 | BaseAccount: sga.BaseAccount, Name: sga.ModuleName, Permissions: sga.ModulePermissions, 40 | } 41 | if err := ma.Validate(); err != nil { 42 | return err 43 | } 44 | } 45 | 46 | return sga.BaseAccount.Validate() 47 | } 48 | -------------------------------------------------------------------------------- /app/helpers/test_helpers.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | 7 | "github.com/cosmos/cosmos-sdk/client" 8 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/cosmos/cosmos-sdk/types/simulation" 11 | "github.com/cosmos/cosmos-sdk/types/tx/signing" 12 | authsign "github.com/cosmos/cosmos-sdk/x/auth/signing" 13 | ) 14 | 15 | // SimAppChainID hardcoded chainID for simulation 16 | const ( 17 | DefaultGenTxGas = 1000000 18 | SimAppChainID = "simulation-app" 19 | ) 20 | 21 | // GenTx generates a signed mock transaction. 22 | func GenTx(gen client.TxConfig, msgs []sdk.Msg, feeAmt sdk.Coins, gas uint64, chainID string, accNums, accSeqs []uint64, priv ...cryptotypes.PrivKey) (sdk.Tx, error) { 23 | sigs := make([]signing.SignatureV2, len(priv)) 24 | 25 | // create a random length memo 26 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 27 | 28 | memo := simulation.RandStringOfLength(r, simulation.RandIntBetween(r, 0, 100)) 29 | 30 | signMode := gen.SignModeHandler().DefaultMode() 31 | 32 | // 1st round: set SignatureV2 with empty signatures, to set correct 33 | // signer infos. 34 | for i, p := range priv { 35 | sigs[i] = signing.SignatureV2{ 36 | PubKey: p.PubKey(), 37 | Data: &signing.SingleSignatureData{ 38 | SignMode: signMode, 39 | }, 40 | Sequence: accSeqs[i], 41 | } 42 | } 43 | 44 | tx := gen.NewTxBuilder() 45 | err := tx.SetMsgs(msgs...) 46 | if err != nil { 47 | return nil, err 48 | } 49 | err = tx.SetSignatures(sigs...) 50 | if err != nil { 51 | return nil, err 52 | } 53 | tx.SetMemo(memo) 54 | tx.SetFeeAmount(feeAmt) 55 | tx.SetGasLimit(gas) 56 | 57 | // 2nd round: once all signer infos are set, every signer can sign. 58 | for i, p := range priv { 59 | signerData := authsign.SignerData{ 60 | ChainID: chainID, 61 | AccountNumber: accNums[i], 62 | Sequence: accSeqs[i], 63 | } 64 | signBytes, err := gen.SignModeHandler().GetSignBytes(signMode, signerData, tx.GetTx()) 65 | if err != nil { 66 | panic(err) 67 | } 68 | sig, err := p.Sign(signBytes) 69 | if err != nil { 70 | panic(err) 71 | } 72 | sigs[i].Data.(*signing.SingleSignatureData).Signature = sig 73 | err = tx.SetSignatures(sigs...) 74 | if err != nil { 75 | panic(err) 76 | } 77 | } 78 | 79 | return tx.GetTx(), nil 80 | } 81 | -------------------------------------------------------------------------------- /app/params/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package params defines the simulation parameters in the simapp. 3 | 4 | It contains the default weights used for each transaction used on the module's 5 | simulation. These weights define the chance for a transaction to be simulated at 6 | any given operation. 7 | 8 | You can replace the default values for the weights by providing a params.json 9 | file with the weights defined for each of the transaction operations: 10 | 11 | { 12 | "op_weight_msg_send": 60, 13 | "op_weight_msg_delegate": 100, 14 | } 15 | 16 | In the example above, the `MsgSend` has 60% chance to be simulated, while the 17 | `MsgDelegate` will always be simulated. 18 | */ 19 | package params 20 | -------------------------------------------------------------------------------- /app/params/encoding.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/client" 5 | "github.com/cosmos/cosmos-sdk/codec" 6 | "github.com/cosmos/cosmos-sdk/codec/types" 7 | ) 8 | 9 | // EncodingConfig specifies the concrete encoding types to use for a given app. 10 | // This is provided for compatibility between protobuf and amino implementations. 11 | type EncodingConfig struct { 12 | InterfaceRegistry types.InterfaceRegistry 13 | Codec codec.Codec 14 | TxConfig client.TxConfig 15 | Amino *codec.LegacyAmino 16 | } 17 | -------------------------------------------------------------------------------- /app/params/params.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | // Simulation parameter constants 4 | const ( 5 | StakePerAccount = "stake_per_account" 6 | InitiallyBondedValidators = "initially_bonded_validators" 7 | ) 8 | -------------------------------------------------------------------------------- /app/params/proto.go: -------------------------------------------------------------------------------- 1 | //go:build !test_amino 2 | // +build !test_amino 3 | 4 | package params 5 | 6 | import ( 7 | "github.com/cosmos/cosmos-sdk/codec" 8 | "github.com/cosmos/cosmos-sdk/codec/types" 9 | "github.com/cosmos/cosmos-sdk/x/auth/tx" 10 | ) 11 | 12 | // MakeTestEncodingConfig creates an EncodingConfig for a non-amino based test configuration. 13 | // This function should be used only internally (in the SDK). 14 | // App user should'nt create new codecs - use the app.AppCodec instead. 15 | // [DEPRECATED] 16 | func MakeTestEncodingConfig() EncodingConfig { 17 | cdc := codec.NewLegacyAmino() 18 | interfaceRegistry := types.NewInterfaceRegistry() 19 | codec := codec.NewProtoCodec(interfaceRegistry) 20 | 21 | return EncodingConfig{ 22 | InterfaceRegistry: interfaceRegistry, 23 | Codec: codec, 24 | TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes), 25 | Amino: cdc, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/params/weights.go: -------------------------------------------------------------------------------- 1 | package params 2 | 3 | // Default simulation operation weights for messages and gov proposals 4 | const ( 5 | DefaultWeightMsgSend int = 100 6 | DefaultWeightMsgMultiSend int = 10 7 | DefaultWeightMsgSetWithdrawAddress int = 50 8 | DefaultWeightMsgWithdrawDelegationReward int = 50 9 | DefaultWeightMsgWithdrawValidatorCommission int = 50 10 | DefaultWeightMsgFundCommunityPool int = 50 11 | DefaultWeightMsgDeposit int = 100 12 | DefaultWeightMsgVote int = 67 13 | DefaultWeightMsgVoteWeighted int = 33 14 | DefaultWeightMsgUnjail int = 100 15 | DefaultWeightMsgCreateValidator int = 100 16 | DefaultWeightMsgEditValidator int = 5 17 | DefaultWeightMsgDelegate int = 100 18 | DefaultWeightMsgUndelegate int = 100 19 | DefaultWeightMsgBeginRedelegate int = 100 20 | 21 | DefaultWeightCommunitySpendProposal int = 5 22 | DefaultWeightTextProposal int = 5 23 | DefaultWeightParamChangeProposal int = 5 24 | 25 | // feegrant 26 | DefaultWeightGrantAllowance int = 100 27 | DefaultWeightRevokeAllowance int = 100 28 | ) 29 | -------------------------------------------------------------------------------- /app/types.go: -------------------------------------------------------------------------------- 1 | package simapp 2 | 3 | import ( 4 | abci "github.com/tendermint/tendermint/abci/types" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | "github.com/cosmos/cosmos-sdk/server/types" 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/cosmos/cosmos-sdk/types/module" 10 | ) 11 | 12 | // App implements the common methods for a Cosmos SDK-based application 13 | // specific blockchain. 14 | type App interface { 15 | // The assigned name of the app. 16 | Name() string 17 | 18 | // The application types codec. 19 | // NOTE: This shoult be sealed before being returned. 20 | LegacyAmino() *codec.LegacyAmino 21 | 22 | // Application updates every begin block. 23 | BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock 24 | 25 | // Application updates every end block. 26 | EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock 27 | 28 | // Application update at chain (i.e app) initialization. 29 | InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain 30 | 31 | // Loads the app at a given height. 32 | LoadHeight(height int64) error 33 | 34 | // Exports the state of the application for a genesis file. 35 | ExportAppStateAndValidators( 36 | forZeroHeight bool, jailAllowedAddrs []string, 37 | ) (types.ExportedApp, error) 38 | 39 | // All the registered module account addreses. 40 | ModuleAccountAddrs() map[string]bool 41 | 42 | // Helper for the simulation framework. 43 | SimulationManager() *module.SimulationManager 44 | } 45 | -------------------------------------------------------------------------------- /app/upgrades.go: -------------------------------------------------------------------------------- 1 | package simapp 2 | 3 | // import ( 4 | // storetypes "github.com/cosmos/cosmos-sdk/store/types" 5 | // sdk "github.com/cosmos/cosmos-sdk/types" 6 | // "github.com/cosmos/cosmos-sdk/types/module" 7 | // upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" 8 | // ) 9 | 10 | // // UpgradeName defines the on-chain upgrade name for the sample simap upgrade from v045 to v046. 11 | // // 12 | // // NOTE: This upgrade defines a reference implementation of what an upgrade could look like 13 | // // when an application is migrating from Cosmos SDK version v0.45.x to v0.46.x. 14 | // const UpgradeName = "v045-to-v046" 15 | 16 | // func (app SimApp) RegisterUpgradeHandlers() { 17 | // app.UpgradeKeeper.SetUpgradeHandler(UpgradeName, 18 | // func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { 19 | // return app.mm.RunMigrations(ctx, app.configurator, fromVM) 20 | // }) 21 | 22 | // upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() 23 | // if err != nil { 24 | // panic(err) 25 | // } 26 | 27 | // if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { 28 | // storeUpgrades := storetypes.StoreUpgrades{ 29 | // Added: []string{ 30 | // group.ModuleName, 31 | // nft.ModuleName, 32 | // }, 33 | // } 34 | 35 | // // configure store loader that checks if version == upgradeHeight and applies store upgrades 36 | // app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) 37 | // } 38 | // } 39 | -------------------------------------------------------------------------------- /app/utils_test.go: -------------------------------------------------------------------------------- 1 | package simapp 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | 9 | "github.com/cosmos/cosmos-sdk/codec" 10 | "github.com/cosmos/cosmos-sdk/std" 11 | sdk "github.com/cosmos/cosmos-sdk/types" 12 | "github.com/cosmos/cosmos-sdk/types/kv" 13 | "github.com/cosmos/cosmos-sdk/types/module" 14 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 15 | ) 16 | 17 | func makeCodec(bm module.BasicManager) *codec.LegacyAmino { 18 | cdc := codec.NewLegacyAmino() 19 | 20 | bm.RegisterLegacyAminoCodec(cdc) 21 | std.RegisterLegacyAminoCodec(cdc) 22 | 23 | return cdc 24 | } 25 | 26 | func TestGetSimulationLog(t *testing.T) { 27 | cdc := makeCodec(ModuleBasics) 28 | 29 | decoders := make(sdk.StoreDecoderRegistry) 30 | decoders[authtypes.StoreKey] = func(kvAs, kvBs kv.Pair) string { return "10" } 31 | 32 | tests := []struct { 33 | store string 34 | kvPairs []kv.Pair 35 | expectedLog string 36 | }{ 37 | { 38 | "Empty", 39 | []kv.Pair{{}}, 40 | "", 41 | }, 42 | { 43 | authtypes.StoreKey, 44 | []kv.Pair{{Key: authtypes.GlobalAccountNumberKey, Value: cdc.MustMarshal(uint64(10))}}, 45 | "10", 46 | }, 47 | { 48 | "OtherStore", 49 | []kv.Pair{{Key: []byte("key"), Value: []byte("value")}}, 50 | fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", []byte("key"), []byte("value"), []byte("key"), []byte("value")), 51 | }, 52 | } 53 | 54 | for _, tt := range tests { 55 | tt := tt 56 | t.Run(tt.store, func(t *testing.T) { 57 | require.Equal(t, tt.expectedLog, GetSimulationLog(tt.store, decoders, tt.kvPairs, tt.kvPairs), tt.store) 58 | }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /cmd/liquidstakingd/cmd/cmd_test.go: -------------------------------------------------------------------------------- 1 | package cmd_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | 9 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" 10 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 11 | "github.com/iqlusioninc/liquidity-staking-module/cmd/liquidstakingd/cmd" 12 | "github.com/iqlusioninc/liquidity-staking-module/x/genutil/client/cli" 13 | ) 14 | 15 | func TestInitCmd(t *testing.T) { 16 | rootCmd, _ := cmd.NewRootCmd() 17 | rootCmd.SetArgs([]string{ 18 | "init", // Test the init cmd 19 | "simapp-test", // Moniker 20 | fmt.Sprintf("--%s=%s", cli.FlagOverwrite, "true"), // Overwrite genesis.json, in case it already exists 21 | }) 22 | 23 | require.NoError(t, svrcmd.Execute(rootCmd, simapp.DefaultNodeHome)) 24 | } 25 | -------------------------------------------------------------------------------- /cmd/liquidstakingd/cmd/testnet_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/spf13/viper" 9 | "github.com/stretchr/testify/require" 10 | "github.com/tendermint/tendermint/libs/log" 11 | 12 | "github.com/cosmos/cosmos-sdk/client" 13 | "github.com/cosmos/cosmos-sdk/client/flags" 14 | "github.com/cosmos/cosmos-sdk/server" 15 | banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" 16 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 17 | genutiltest "github.com/iqlusioninc/liquidity-staking-module/x/genutil/client/testutil" 18 | genutiltypes "github.com/iqlusioninc/liquidity-staking-module/x/genutil/types" 19 | ) 20 | 21 | func Test_TestnetCmd(t *testing.T) { 22 | home := t.TempDir() 23 | encodingConfig := simapp.MakeTestEncodingConfig() 24 | logger := log.NewNopLogger() 25 | cfg, err := genutiltest.CreateDefaultTendermintConfig(home) 26 | require.NoError(t, err) 27 | 28 | err = genutiltest.ExecInitCmd(simapp.ModuleBasics, home, encodingConfig.Marshaler) 29 | require.NoError(t, err) 30 | 31 | serverCtx := server.NewContext(viper.New(), cfg, logger) 32 | clientCtx := client.Context{}. 33 | WithCodec(encodingConfig.Marshaler). 34 | WithHomeDir(home). 35 | WithTxConfig(encodingConfig.TxConfig) 36 | 37 | ctx := context.Background() 38 | ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) 39 | ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 40 | cmd := testnetInitFilesCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}) 41 | cmd.SetArgs([]string{fmt.Sprintf("--%s=test", flags.FlagKeyringBackend), fmt.Sprintf("--output-dir=%s", home)}) 42 | err = cmd.ExecuteContext(ctx) 43 | require.NoError(t, err) 44 | 45 | genFile := cfg.GenesisFile() 46 | appState, _, err := genutiltypes.GenesisStateFromGenFile(genFile) 47 | require.NoError(t, err) 48 | 49 | bankGenState := banktypes.GetGenesisStateFromAppState(encodingConfig.Marshaler, appState) 50 | require.NotEmpty(t, bankGenState.Supply.String()) 51 | } 52 | -------------------------------------------------------------------------------- /cmd/liquidstakingd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/cosmos/cosmos-sdk/server" 7 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" 8 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 9 | "github.com/iqlusioninc/liquidity-staking-module/cmd/liquidstakingd/cmd" 10 | ) 11 | 12 | func main() { 13 | rootCmd, _ := cmd.NewRootCmd() 14 | 15 | if err := svrcmd.Execute(rootCmd, simapp.DefaultNodeHome); err != nil { 16 | switch e := err.(type) { 17 | case server.ErrorCode: 18 | os.Exit(e.Code) 19 | 20 | default: 21 | os.Exit(1) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contrib/devtools/install-golangci-lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | installer="$(mktemp)" 6 | trap "rm -f ${installer}" EXIT 7 | 8 | GOBIN="${1}" 9 | CURL="$(which curl)" 10 | HASHSUM="${2}" 11 | 12 | f_sha256() { 13 | local l_file 14 | l_file=$1 15 | python -sBc "import hashlib;print(hashlib.sha256(open('$l_file','rb').read()).hexdigest())" 16 | } 17 | 18 | get_latest_release() { 19 | "${CURL}" --silent "https://api.github.com/repos/$1/releases/latest" | 20 | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' 21 | } 22 | 23 | VERSION="$(get_latest_release golangci/golangci-lint)" 24 | 25 | echo "Downloading golangci-lint ${VERSION} installer ..." >&2 26 | "${CURL}" -sfL "https://raw.githubusercontent.com/golangci/golangci-lint/${VERSION}/install.sh" >"${installer}" 27 | 28 | echo "Checking hashsum ..." >&2 29 | # [ "${HASHSUM}" = "$(f_sha256 ${installer})" ] 30 | chmod +x "${installer}" 31 | 32 | echo "Launching installer ..." >&2 33 | exec "${installer}" -d -b "${GOBIN}" "${VERSION}" 34 | -------------------------------------------------------------------------------- /proto/buf.gen.gogo.yaml: -------------------------------------------------------------------------------- 1 | version: v1 2 | plugins: 3 | - name: gocosmos 4 | out: .. 5 | opt: plugins=grpc,Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types,Mcosmos/orm/v1alpha1/orm.proto=github.com/cosmos/cosmos-sdk/api/cosmos/orm/v1alpha1 6 | - name: grpc-gateway 7 | out: .. 8 | opt: logtostderr=true,allow_colon_final_segments=true 9 | -------------------------------------------------------------------------------- /proto/buf.lock: -------------------------------------------------------------------------------- 1 | # Generated by buf. DO NOT EDIT. 2 | version: v1 3 | deps: 4 | - remote: buf.build 5 | owner: cosmos 6 | repository: cosmos-proto 7 | commit: 1935555c206d4afb9e94615dfd0fad31 8 | - remote: buf.build 9 | owner: cosmos 10 | repository: cosmos-sdk 11 | commit: 6cd9d51cd7964f1fab5fd5928256eb95 12 | - remote: buf.build 13 | owner: cosmos 14 | repository: gogo-proto 15 | commit: 6652e3443c3b4504bb3bf82e73a7e409 16 | - remote: buf.build 17 | owner: googleapis 18 | repository: googleapis 19 | commit: 8d7204855ec14631a499bd7393ce1970 20 | -------------------------------------------------------------------------------- /proto/buf.yaml: -------------------------------------------------------------------------------- 1 | # Generated by "buf config migrate-v1beta1". Edit as necessary, and 2 | # remove this comment when you're finished. 3 | # 4 | # This module represents the "proto" root found in 5 | # the previous configuration. 6 | version: v1 7 | name: buf.build/regen/regen-ledger 8 | deps: 9 | - buf.build/cosmos/cosmos-sdk 10 | - buf.build/cosmos/cosmos-proto 11 | - buf.build/cosmos/gogo-proto 12 | - buf.build/googleapis/googleapis 13 | breaking: 14 | use: 15 | - FILE 16 | lint: 17 | use: 18 | - DEFAULT 19 | - COMMENTS 20 | except: 21 | - SERVICE_SUFFIX 22 | - RPC_REQUEST_STANDARD_NAME 23 | -------------------------------------------------------------------------------- /proto/staking/v1beta1/authz.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package liquidstaking.staking.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos_proto/cosmos.proto"; 6 | import "cosmos/base/v1beta1/coin.proto"; 7 | 8 | option go_package = "github.com/iqlusioninc/liquidity-staking-module/x/staking/types"; 9 | 10 | // StakeAuthorization defines authorization for delegate/undelegate/redelegate. 11 | message StakeAuthorization { 12 | option (cosmos_proto.implements_interface) = "Authorization"; 13 | 14 | // max_tokens specifies the maximum amount of tokens can be delegate to a validator. If it is 15 | // empty, there is no spend limit and any amount of coins can be delegated. 16 | cosmos.base.v1beta1.Coin max_tokens = 1 [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coin"]; 17 | // validators is the oneof that represents either allow_list or deny_list 18 | oneof validators { 19 | // allow_list specifies list of validator addresses to whom grantee can delegate tokens on behalf of granter's 20 | // account. 21 | Validators allow_list = 2; 22 | // deny_list specifies list of validator addresses to whom grantee can not delegate tokens. 23 | Validators deny_list = 3; 24 | } 25 | // Validators defines list of validator addresses. 26 | message Validators { 27 | repeated string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 28 | } 29 | // authorization_type defines one of AuthorizationType. 30 | AuthorizationType authorization_type = 4; 31 | } 32 | 33 | // AuthorizationType defines the type of staking module authorization type 34 | enum AuthorizationType { 35 | // AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type 36 | AUTHORIZATION_TYPE_UNSPECIFIED = 0; 37 | // AUTHORIZATION_TYPE_DELEGATE defines an authorization type for Msg/Delegate 38 | AUTHORIZATION_TYPE_DELEGATE = 1; 39 | // AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for Msg/Undelegate 40 | AUTHORIZATION_TYPE_UNDELEGATE = 2; 41 | // AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for Msg/BeginRedelegate 42 | AUTHORIZATION_TYPE_REDELEGATE = 3; 43 | } 44 | -------------------------------------------------------------------------------- /scripts/protocgen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eo pipefail 4 | 5 | go get github.com/regen-network/cosmos-proto/protoc-gen-gocosmos 2>/dev/null 6 | 7 | echo "Generating gogo proto code" 8 | cd proto 9 | proto_dirs=$(find . -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) 10 | for dir in $proto_dirs; do 11 | for file in $(find "${dir}" -maxdepth 1 -name '*.proto'); do 12 | if grep "option go_package" $file &> /dev/null ; then 13 | buf generate --template buf.gen.gogo.yaml $file 14 | fi 15 | done 16 | done 17 | 18 | cd .. 19 | 20 | # move proto files to the right places 21 | cp -r github.com/iqlusioninc/liquidity-staking-module/* ./ 22 | rm -rf github.com 23 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | rm -rf ~/.simapp 2 | 3 | set -o errexit -o nounset 4 | 5 | liquidstakingd init --chain-id test test 6 | liquidstakingd keys add validator --keyring-backend="test" 7 | liquidstakingd add-genesis-account $(liquidstakingd keys show validator -a --keyring-backend="test") 100000000000000stake 8 | liquidstakingd gentx validator 100000000stake --keyring-backend="test" --chain-id test 9 | liquidstakingd collect-gentxs 10 | 11 | sed -i '' 's/"validator_bond_factor": "-1.000000000000000000"/"validator_bond_factor": "10.000000000000000000"/g' ~/.simapp/config/genesis.json 12 | 13 | liquidstakingd start 14 | # liquidstakingd start --home=home --mode=validator 15 | -------------------------------------------------------------------------------- /testutil/network/network_test.go: -------------------------------------------------------------------------------- 1 | //go:build norace 2 | // +build norace 3 | 4 | package network_test 5 | 6 | import ( 7 | "testing" 8 | "time" 9 | 10 | "github.com/stretchr/testify/suite" 11 | 12 | "github.com/iqlusioninc/liquidity-staking-module/testutil/network" 13 | ) 14 | 15 | type IntegrationTestSuite struct { 16 | suite.Suite 17 | 18 | network *network.Network 19 | } 20 | 21 | func (s *IntegrationTestSuite) SetupSuite() { 22 | s.T().Log("setting up integration test suite") 23 | 24 | var err error 25 | s.network, err = network.New(s.T(), s.T().TempDir(), network.DefaultConfig()) 26 | s.Require().NoError(err) 27 | 28 | h, err := s.network.WaitForHeight(1) 29 | s.Require().NoError(err, "stalled at height %d", h) 30 | } 31 | 32 | func (s *IntegrationTestSuite) TearDownSuite() { 33 | s.T().Log("tearing down integration test suite") 34 | s.network.Cleanup() 35 | } 36 | 37 | func (s *IntegrationTestSuite) TestNetwork_Liveness() { 38 | h, err := s.network.WaitForHeightWithTimeout(10, time.Minute) 39 | s.Require().NoError(err, "expected to reach 10 blocks; got %d", h) 40 | } 41 | 42 | func TestIntegrationTestSuite(t *testing.T) { 43 | suite.Run(t, new(IntegrationTestSuite)) 44 | } 45 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/authz/v1beta1/authz.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.43 2 | syntax = "proto3"; 3 | package cosmos.authz.v1beta1; 4 | 5 | import "cosmos_proto/cosmos.proto"; 6 | import "google/protobuf/timestamp.proto"; 7 | import "gogoproto/gogo.proto"; 8 | import "google/protobuf/any.proto"; 9 | 10 | option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; 11 | option (gogoproto.goproto_getters_all) = false; 12 | 13 | // GenericAuthorization gives the grantee unrestricted permissions to execute 14 | // the provided method on behalf of the granter's account. 15 | message GenericAuthorization { 16 | option (cosmos_proto.implements_interface) = "Authorization"; 17 | 18 | // Msg, identified by it's type URL, to grant unrestricted permissions to execute 19 | string msg = 1; 20 | } 21 | 22 | // Grant gives permissions to execute 23 | // the provide method with expiration time. 24 | message Grant { 25 | google.protobuf.Any authorization = 1 [(cosmos_proto.accepts_interface) = "Authorization"]; 26 | // time when the grant will expire and will be pruned. If null, then the grant 27 | // doesn't have a time expiration (other conditions in `authorization` 28 | // may apply to invalidate the grant) 29 | google.protobuf.Timestamp expiration = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = true]; 30 | } 31 | 32 | // GrantAuthorization extends a grant with both the addresses of the grantee and granter. 33 | // It is used in genesis.proto and query.proto 34 | message GrantAuthorization { 35 | string granter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 36 | string grantee = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 37 | 38 | google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"]; 39 | google.protobuf.Timestamp expiration = 4 [(gogoproto.stdtime) = true]; 40 | } 41 | 42 | // GrantQueueItem contains the list of TypeURL of a sdk.Msg. 43 | message GrantQueueItem { 44 | // msg_type_urls contains the list of TypeURL of a sdk.Msg. 45 | repeated string msg_type_urls = 1; 46 | } 47 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/authz/v1beta1/event.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.43 2 | syntax = "proto3"; 3 | package cosmos.authz.v1beta1; 4 | 5 | import "cosmos_proto/cosmos.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; 8 | 9 | // EventGrant is emitted on Msg/Grant 10 | message EventGrant { 11 | // Msg type URL for which an autorization is granted 12 | string msg_type_url = 2; 13 | // Granter account address 14 | string granter = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 15 | // Grantee account address 16 | string grantee = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 17 | } 18 | 19 | // EventRevoke is emitted on Msg/Revoke 20 | message EventRevoke { 21 | // Msg type URL for which an autorization is revoked 22 | string msg_type_url = 2; 23 | // Granter account address 24 | string granter = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 25 | // Grantee account address 26 | string grantee = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 27 | } 28 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/authz/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.43 2 | syntax = "proto3"; 3 | package cosmos.authz.v1beta1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | import "cosmos/authz/v1beta1/authz.proto"; 7 | 8 | option go_package = "github.com/cosmos/cosmos-sdk/x/authz"; 9 | 10 | // GenesisState defines the authz module's genesis state. 11 | message GenesisState { 12 | repeated GrantAuthorization authorization = 1 [(gogoproto.nullable) = false]; 13 | } 14 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/bank/v1beta1/authz.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.bank.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos_proto/cosmos.proto"; 6 | import "cosmos/base/v1beta1/coin.proto"; 7 | 8 | option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; 9 | 10 | // SendAuthorization allows the grantee to spend up to spend_limit coins from 11 | // the granter's account. 12 | // 13 | // Since: cosmos-sdk 0.43 14 | message SendAuthorization { 15 | option (cosmos_proto.implements_interface) = "Authorization"; 16 | 17 | repeated cosmos.base.v1beta1.Coin spend_limit = 1 18 | [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; 19 | } 20 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/bank/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.bank.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos/base/v1beta1/coin.proto"; 6 | import "cosmos/bank/v1beta1/bank.proto"; 7 | import "cosmos_proto/cosmos.proto"; 8 | 9 | option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; 10 | 11 | // GenesisState defines the bank module's genesis state. 12 | message GenesisState { 13 | // params defines all the paramaters of the module. 14 | Params params = 1 [(gogoproto.nullable) = false]; 15 | 16 | // balances is an array containing the balances of all the accounts. 17 | repeated Balance balances = 2 [(gogoproto.nullable) = false]; 18 | 19 | // supply represents the total supply. If it is left empty, then supply will be calculated based on the provided 20 | // balances. Otherwise, it will be used to validate that the sum of the balances equals this amount. 21 | repeated cosmos.base.v1beta1.Coin supply = 3 22 | [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; 23 | 24 | // denom_metadata defines the metadata of the differents coins. 25 | repeated Metadata denom_metadata = 4 [(gogoproto.nullable) = false]; 26 | } 27 | 28 | // Balance defines an account address and balance pair used in the bank module's 29 | // genesis state. 30 | message Balance { 31 | option (gogoproto.equal) = false; 32 | option (gogoproto.goproto_getters) = false; 33 | 34 | // address is the address of the balance holder. 35 | string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 36 | 37 | // coins defines the different coins this balance holds. 38 | repeated cosmos.base.v1beta1.Coin coins = 2 39 | [(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false]; 40 | } 41 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/bank/v1beta1/tx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.bank.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos/base/v1beta1/coin.proto"; 6 | import "cosmos/bank/v1beta1/bank.proto"; 7 | import "cosmos_proto/cosmos.proto"; 8 | import "cosmos/msg/v1/msg.proto"; 9 | 10 | option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types"; 11 | 12 | // Msg defines the bank Msg service. 13 | service Msg { 14 | // Send defines a method for sending coins from one account to another account. 15 | rpc Send(MsgSend) returns (MsgSendResponse); 16 | 17 | // MultiSend defines a method for sending coins from some accounts to other accounts. 18 | rpc MultiSend(MsgMultiSend) returns (MsgMultiSendResponse); 19 | } 20 | 21 | // MsgSend represents a message to send coins from one account to another. 22 | message MsgSend { 23 | option (cosmos.msg.v1.signer) = "from_address"; 24 | 25 | option (gogoproto.equal) = false; 26 | option (gogoproto.goproto_getters) = false; 27 | 28 | string from_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 29 | string to_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 30 | repeated cosmos.base.v1beta1.Coin amount = 3 31 | [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"]; 32 | } 33 | 34 | // MsgSendResponse defines the Msg/Send response type. 35 | message MsgSendResponse {} 36 | 37 | // MsgMultiSend represents an arbitrary multi-in, multi-out send message. 38 | message MsgMultiSend { 39 | option (cosmos.msg.v1.signer) = "inputs"; 40 | 41 | option (gogoproto.equal) = false; 42 | 43 | repeated Input inputs = 1 [(gogoproto.nullable) = false]; 44 | repeated Output outputs = 2 [(gogoproto.nullable) = false]; 45 | } 46 | 47 | // MsgMultiSendResponse defines the Msg/MultiSend response type. 48 | message MsgMultiSendResponse {} 49 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/kv/v1beta1/kv.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.kv.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/types/kv"; 7 | 8 | // Pairs defines a repeated slice of Pair objects. 9 | message Pairs { 10 | repeated Pair pairs = 1 [(gogoproto.nullable) = false]; 11 | } 12 | 13 | // Pair defines a key/value bytes tuple. 14 | message Pair { 15 | bytes key = 1; 16 | bytes value = 2; 17 | } 18 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/node/v1beta1/query.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.node.v1beta1; 3 | 4 | import "google/api/annotations.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/node"; 7 | 8 | // Service defines the gRPC querier service for node related queries. 9 | service Service { 10 | // Config queries for the operator configuration. 11 | rpc Config(ConfigRequest) returns (ConfigResponse) { 12 | option (google.api.http).get = "/cosmos/base/node/v1beta1/config"; 13 | } 14 | } 15 | 16 | // ConfigRequest defines the request structure for the Config gRPC query. 17 | message ConfigRequest {} 18 | 19 | // ConfigResponse defines the response structure for the Config gRPC query. 20 | message ConfigResponse { 21 | string minimum_gas_price = 1; 22 | } 23 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/query/v1beta1/pagination.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.query.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/types/query"; 5 | 6 | // PageRequest is to be embedded in gRPC request messages for efficient 7 | // pagination. Ex: 8 | // 9 | // message SomeRequest { 10 | // Foo some_parameter = 1; 11 | // PageRequest pagination = 2; 12 | // } 13 | message PageRequest { 14 | // key is a value returned in PageResponse.next_key to begin 15 | // querying the next page most efficiently. Only one of offset or key 16 | // should be set. 17 | bytes key = 1; 18 | 19 | // offset is a numeric offset that can be used when key is unavailable. 20 | // It is less efficient than using key. Only one of offset or key should 21 | // be set. 22 | uint64 offset = 2; 23 | 24 | // limit is the total number of results to be returned in the result page. 25 | // If left empty it will default to a value to be set by each app. 26 | uint64 limit = 3; 27 | 28 | // count_total is set to true to indicate that the result set should include 29 | // a count of the total number of items available for pagination in UIs. 30 | // count_total is only respected when offset is used. It is ignored when key 31 | // is set. 32 | bool count_total = 4; 33 | 34 | // reverse is set to true if results are to be returned in the descending order. 35 | // 36 | // Since: cosmos-sdk 0.43 37 | bool reverse = 5; 38 | } 39 | 40 | // PageResponse is to be embedded in gRPC response messages where the 41 | // corresponding request message has used PageRequest. 42 | // 43 | // message SomeResponse { 44 | // repeated Bar results = 1; 45 | // PageResponse page = 2; 46 | // } 47 | message PageResponse { 48 | // next_key is the key to be passed to PageRequest.key to 49 | // query the next page most efficiently. It will be empty if 50 | // there are no more results. 51 | bytes next_key = 1; 52 | 53 | // total is total number of results available if PageRequest.count_total 54 | // was set, its value is undefined otherwise 55 | uint64 total = 2; 56 | } 57 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/reflection/v1beta1/reflection.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.reflection.v1beta1; 3 | 4 | import "google/api/annotations.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/client/grpc/reflection"; 7 | 8 | // ReflectionService defines a service for interface reflection. 9 | service ReflectionService { 10 | // ListAllInterfaces lists all the interfaces registered in the interface 11 | // registry. 12 | rpc ListAllInterfaces(ListAllInterfacesRequest) returns (ListAllInterfacesResponse) { 13 | option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces"; 14 | }; 15 | 16 | // ListImplementations list all the concrete types that implement a given 17 | // interface. 18 | rpc ListImplementations(ListImplementationsRequest) returns (ListImplementationsResponse) { 19 | option (google.api.http).get = "/cosmos/base/reflection/v1beta1/interfaces/" 20 | "{interface_name}/implementations"; 21 | }; 22 | } 23 | 24 | // ListAllInterfacesRequest is the request type of the ListAllInterfaces RPC. 25 | message ListAllInterfacesRequest {} 26 | 27 | // ListAllInterfacesResponse is the response type of the ListAllInterfaces RPC. 28 | message ListAllInterfacesResponse { 29 | // interface_names is an array of all the registered interfaces. 30 | repeated string interface_names = 1; 31 | } 32 | 33 | // ListImplementationsRequest is the request type of the ListImplementations 34 | // RPC. 35 | message ListImplementationsRequest { 36 | // interface_name defines the interface to query the implementations for. 37 | string interface_name = 1; 38 | } 39 | 40 | // ListImplementationsResponse is the response type of the ListImplementations 41 | // RPC. 42 | message ListImplementationsResponse { 43 | repeated string implementation_message_names = 1; 44 | } 45 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/store/v1beta1/commit_info.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.store.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/store/types"; 7 | 8 | // CommitInfo defines commit information used by the multi-store when committing 9 | // a version/height. 10 | message CommitInfo { 11 | int64 version = 1; 12 | repeated StoreInfo store_infos = 2 [(gogoproto.nullable) = false]; 13 | } 14 | 15 | // StoreInfo defines store-specific commit information. It contains a reference 16 | // between a store name and the commit ID. 17 | message StoreInfo { 18 | string name = 1; 19 | CommitID commit_id = 2 [(gogoproto.nullable) = false]; 20 | } 21 | 22 | // CommitID defines the committment information when a specific store is 23 | // committed. 24 | message CommitID { 25 | option (gogoproto.goproto_stringer) = false; 26 | 27 | int64 version = 1; 28 | bytes hash = 2; 29 | } 30 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/store/v1beta1/listening.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.store.v1beta1; 3 | 4 | import "tendermint/abci/types.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/store/types"; 7 | 8 | // StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) 9 | // It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and 10 | // Deletes 11 | // 12 | // Since: cosmos-sdk 0.43 13 | message StoreKVPair { 14 | string store_key = 1; // the store key for the KVStore this pair originates from 15 | bool delete = 2; // true indicates a delete operation, false indicates a set operation 16 | bytes key = 3; 17 | bytes value = 4; 18 | } 19 | 20 | // BlockMetadata contains all the abci event data of a block 21 | // the file streamer dump them into files together with the state changes. 22 | message BlockMetadata { 23 | // DeliverTx encapulate deliver tx request and response. 24 | message DeliverTx { 25 | tendermint.abci.RequestDeliverTx request = 1; 26 | tendermint.abci.ResponseDeliverTx response = 2; 27 | } 28 | tendermint.abci.RequestBeginBlock request_begin_block = 1; 29 | tendermint.abci.ResponseBeginBlock response_begin_block = 2; 30 | repeated DeliverTx deliver_txs = 3; 31 | tendermint.abci.RequestEndBlock request_end_block = 4; 32 | tendermint.abci.ResponseEndBlock response_end_block = 5; 33 | tendermint.abci.ResponseCommit response_commit = 6; 34 | } 35 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/base/v1beta1/coin.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.base.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos_proto/cosmos.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/types"; 8 | option (gogoproto.goproto_stringer_all) = false; 9 | option (gogoproto.stringer_all) = false; 10 | 11 | // Coin defines a token with a denomination and an amount. 12 | // 13 | // NOTE: The amount field is an Int which implements the custom method 14 | // signatures required by gogoproto. 15 | message Coin { 16 | option (gogoproto.equal) = true; 17 | 18 | string denom = 1; 19 | string amount = 2 20 | [(cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; 21 | } 22 | 23 | // DecCoin defines a token with a denomination and a decimal amount. 24 | // 25 | // NOTE: The amount field is an Dec which implements the custom method 26 | // signatures required by gogoproto. 27 | message DecCoin { 28 | option (gogoproto.equal) = true; 29 | 30 | string denom = 1; 31 | string amount = 2 32 | [(cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; 33 | } 34 | 35 | // IntProto defines a Protobuf wrapper around an Int object. 36 | message IntProto { 37 | string int = 1 [(cosmos_proto.scalar) = "cosmos.Int", (gogoproto.customtype) = "Int", (gogoproto.nullable) = false]; 38 | } 39 | 40 | // DecProto defines a Protobuf wrapper around a Dec object. 41 | message DecProto { 42 | string dec = 1 [(cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "Dec", (gogoproto.nullable) = false]; 43 | } 44 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/capability/v1beta1/capability.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.capability.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | 8 | // Capability defines an implementation of an object capability. The index 9 | // provided to a Capability must be globally unique. 10 | message Capability { 11 | option (gogoproto.goproto_stringer) = false; 12 | 13 | uint64 index = 1; 14 | } 15 | 16 | // Owner defines a single capability owner. An owner is defined by the name of 17 | // capability and the module name. 18 | message Owner { 19 | option (gogoproto.goproto_stringer) = false; 20 | option (gogoproto.goproto_getters) = false; 21 | 22 | string module = 1; 23 | string name = 2; 24 | } 25 | 26 | // CapabilityOwners defines a set of owners of a single Capability. The set of 27 | // owners must be unique. 28 | message CapabilityOwners { 29 | repeated Owner owners = 1 [(gogoproto.nullable) = false]; 30 | } 31 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/capability/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.capability.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos/capability/v1beta1/capability.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/x/capability/types"; 8 | 9 | // GenesisOwners defines the capability owners with their corresponding index. 10 | message GenesisOwners { 11 | // index is the index of the capability owner. 12 | uint64 index = 1; 13 | 14 | // index_owners are the owners at the given index. 15 | CapabilityOwners index_owners = 2 [(gogoproto.nullable) = false]; 16 | } 17 | 18 | // GenesisState defines the capability module's genesis state. 19 | message GenesisState { 20 | // index is the capability global index. 21 | uint64 index = 1; 22 | 23 | // owners represents a map from index to owners of the capability index 24 | // index key is string to allow amino marshalling. 25 | repeated GenesisOwners owners = 2 [(gogoproto.nullable) = false]; 26 | } 27 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crisis/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.crisis.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "cosmos/base/v1beta1/coin.proto"; 8 | 9 | // GenesisState defines the crisis module's genesis state. 10 | message GenesisState { 11 | // constant_fee is the fee used to verify the invariant in the crisis 12 | // module. 13 | cosmos.base.v1beta1.Coin constant_fee = 3 [(gogoproto.nullable) = false]; 14 | } 15 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crisis/v1beta1/tx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.crisis.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/crisis/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "cosmos_proto/cosmos.proto"; 8 | import "cosmos/msg/v1/msg.proto"; 9 | 10 | // Msg defines the bank Msg service. 11 | service Msg { 12 | // VerifyInvariant defines a method to verify a particular invariance. 13 | rpc VerifyInvariant(MsgVerifyInvariant) returns (MsgVerifyInvariantResponse); 14 | } 15 | 16 | // MsgVerifyInvariant represents a message to verify a particular invariance. 17 | message MsgVerifyInvariant { 18 | option (cosmos.msg.v1.signer) = "sender"; 19 | 20 | option (gogoproto.equal) = false; 21 | option (gogoproto.goproto_getters) = false; 22 | 23 | string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 24 | string invariant_module_name = 2; 25 | string invariant_route = 3; 26 | } 27 | 28 | // MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type. 29 | message MsgVerifyInvariantResponse {} 30 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/ed25519/keys.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.crypto.ed25519; 3 | 4 | import "gogoproto/gogo.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"; 7 | 8 | // PubKey is an ed25519 public key for handling Tendermint keys in SDK. 9 | // It's needed for Any serialization and SDK compatibility. 10 | // It must not be used in a non Tendermint key context because it doesn't implement 11 | // ADR-28. Nevertheless, you will like to use ed25519 in app user level 12 | // then you must create a new proto message and follow ADR-28 for Address construction. 13 | message PubKey { 14 | option (gogoproto.goproto_stringer) = false; 15 | 16 | bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PublicKey"]; 17 | } 18 | 19 | // Deprecated: PrivKey defines a ed25519 private key. 20 | // NOTE: ed25519 keys must not be used in SDK apps except in a tendermint validator context. 21 | message PrivKey { 22 | bytes key = 1 [(gogoproto.casttype) = "crypto/ed25519.PrivateKey"]; 23 | } 24 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/hd/v1/hd.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.46 2 | syntax = "proto3"; 3 | package cosmos.crypto.hd.v1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/hd"; 8 | option (gogoproto.goproto_getters_all) = false; 9 | 10 | // BIP44Params is used as path field in ledger item in Record. 11 | message BIP44Params { 12 | option (gogoproto.goproto_stringer) = false; 13 | // purpose is a constant set to 44' (or 0x8000002C) following the BIP43 recommendation 14 | uint32 purpose = 1; 15 | // coin_type is a constant that improves privacy 16 | uint32 coin_type = 2; 17 | // account splits the key space into independent user identities 18 | uint32 account = 3; 19 | // change is a constant used for public derivation. Constant 0 is used for external chain and constant 1 for internal 20 | // chain. 21 | bool change = 4; 22 | // address_index is used as child index in BIP32 derivation 23 | uint32 address_index = 5; 24 | } 25 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/keyring/v1/record.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.46 2 | syntax = "proto3"; 3 | package cosmos.crypto.keyring.v1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | import "google/protobuf/any.proto"; 7 | import "cosmos/crypto/hd/v1/hd.proto"; 8 | 9 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/keyring"; 10 | option (gogoproto.goproto_getters_all) = false; 11 | 12 | // Record is used for representing a key in the keyring. 13 | message Record { 14 | // name represents a name of Record 15 | string name = 1; 16 | // pub_key represents a public key in any format 17 | google.protobuf.Any pub_key = 2; 18 | 19 | // Record contains one of the following items 20 | oneof item { 21 | // local stores the private key locally. 22 | Local local = 3; 23 | // ledger stores the information about a Ledger key. 24 | Ledger ledger = 4; 25 | // Multi does not store any other information. 26 | Multi multi = 5; 27 | // Offline does not store any other information. 28 | Offline offline = 6; 29 | } 30 | 31 | // Item is a keyring item stored in a keyring backend. 32 | // Local item 33 | message Local { 34 | google.protobuf.Any priv_key = 1; 35 | } 36 | 37 | // Ledger item 38 | message Ledger { 39 | hd.v1.BIP44Params path = 1; 40 | } 41 | 42 | // Multi item 43 | message Multi {} 44 | 45 | // Offline item 46 | message Offline {} 47 | } 48 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/multisig/keys.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.crypto.multisig; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "google/protobuf/any.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"; 8 | 9 | // LegacyAminoPubKey specifies a public key type 10 | // which nests multiple public keys and a threshold, 11 | // it uses legacy amino address rules. 12 | message LegacyAminoPubKey { 13 | option (gogoproto.goproto_getters) = false; 14 | 15 | uint32 threshold = 1; 16 | repeated google.protobuf.Any public_keys = 2 [(gogoproto.customname) = "PubKeys"]; 17 | } 18 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/multisig/v1beta1/multisig.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.crypto.multisig.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/types"; 7 | 8 | // MultiSignature wraps the signatures from a multisig.LegacyAminoPubKey. 9 | // See cosmos.tx.v1betata1.ModeInfo.Multi for how to specify which signers 10 | // signed and with which modes. 11 | message MultiSignature { 12 | option (gogoproto.goproto_unrecognized) = true; 13 | repeated bytes signatures = 1; 14 | } 15 | 16 | // CompactBitArray is an implementation of a space efficient bit array. 17 | // This is used to ensure that the encoded data takes up a minimal amount of 18 | // space after proto encoding. 19 | // This is not thread safe, and is not intended for concurrent usage. 20 | message CompactBitArray { 21 | option (gogoproto.goproto_stringer) = false; 22 | 23 | uint32 extra_bits_stored = 1; 24 | bytes elems = 2; 25 | } 26 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/secp256k1/keys.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.crypto.secp256k1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"; 7 | 8 | // PubKey defines a secp256k1 public key 9 | // Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte 10 | // if the y-coordinate is the lexicographically largest of the two associated with 11 | // the x-coordinate. Otherwise the first byte is a 0x03. 12 | // This prefix is followed with the x-coordinate. 13 | message PubKey { 14 | option (gogoproto.goproto_stringer) = false; 15 | 16 | bytes key = 1; 17 | } 18 | 19 | // PrivKey defines a secp256k1 private key. 20 | message PrivKey { 21 | bytes key = 1; 22 | } 23 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/crypto/secp256r1/keys.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.43 2 | syntax = "proto3"; 3 | package cosmos.crypto.secp256r1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1"; 8 | option (gogoproto.messagename_all) = true; 9 | option (gogoproto.goproto_stringer_all) = false; 10 | option (gogoproto.goproto_getters_all) = false; 11 | 12 | // PubKey defines a secp256r1 ECDSA public key. 13 | message PubKey { 14 | // Point on secp256r1 curve in a compressed representation as specified in section 15 | // 4.3.6 of ANSI X9.62: https://webstore.ansi.org/standards/ascx9/ansix9621998 16 | bytes key = 1 [(gogoproto.customtype) = "ecdsaPK"]; 17 | } 18 | 19 | // PrivKey defines a secp256r1 ECDSA private key. 20 | message PrivKey { 21 | // secret number serialized using big-endian encoding 22 | bytes secret = 1 [(gogoproto.customtype) = "ecdsaSK"]; 23 | } 24 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/evidence/v1beta1/evidence.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.evidence.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; 5 | option (gogoproto.equal_all) = true; 6 | 7 | import "gogoproto/gogo.proto"; 8 | import "google/protobuf/timestamp.proto"; 9 | import "cosmos_proto/cosmos.proto"; 10 | 11 | // Equivocation implements the Evidence interface and defines evidence of double 12 | // signing misbehavior. 13 | message Equivocation { 14 | option (gogoproto.goproto_stringer) = false; 15 | option (gogoproto.goproto_getters) = false; 16 | option (gogoproto.equal) = false; 17 | 18 | int64 height = 1; 19 | google.protobuf.Timestamp time = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; 20 | int64 power = 3; 21 | string consensus_address = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 22 | } -------------------------------------------------------------------------------- /third_party/proto/cosmos/evidence/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.evidence.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; 5 | 6 | import "google/protobuf/any.proto"; 7 | 8 | // GenesisState defines the evidence module's genesis state. 9 | message GenesisState { 10 | // evidence defines all the evidence at genesis. 11 | repeated google.protobuf.Any evidence = 1; 12 | } 13 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/evidence/v1beta1/query.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.evidence.v1beta1; 3 | 4 | import "cosmos/base/query/v1beta1/pagination.proto"; 5 | import "gogoproto/gogo.proto"; 6 | import "google/protobuf/any.proto"; 7 | import "google/api/annotations.proto"; 8 | 9 | option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; 10 | 11 | // Query defines the gRPC querier service. 12 | service Query { 13 | // Evidence queries evidence based on evidence hash. 14 | rpc Evidence(QueryEvidenceRequest) returns (QueryEvidenceResponse) { 15 | option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence/{evidence_hash}"; 16 | } 17 | 18 | // AllEvidence queries all evidence. 19 | rpc AllEvidence(QueryAllEvidenceRequest) returns (QueryAllEvidenceResponse) { 20 | option (google.api.http).get = "/cosmos/evidence/v1beta1/evidence"; 21 | } 22 | } 23 | 24 | // QueryEvidenceRequest is the request type for the Query/Evidence RPC method. 25 | message QueryEvidenceRequest { 26 | // evidence_hash defines the hash of the requested evidence. 27 | bytes evidence_hash = 1 [(gogoproto.casttype) = "github.com/tendermint/tendermint/libs/bytes.HexBytes"]; 28 | } 29 | 30 | // QueryEvidenceResponse is the response type for the Query/Evidence RPC method. 31 | message QueryEvidenceResponse { 32 | // evidence returns the requested evidence. 33 | google.protobuf.Any evidence = 1; 34 | } 35 | 36 | // QueryEvidenceRequest is the request type for the Query/AllEvidence RPC 37 | // method. 38 | message QueryAllEvidenceRequest { 39 | // pagination defines an optional pagination for the request. 40 | cosmos.base.query.v1beta1.PageRequest pagination = 1; 41 | } 42 | 43 | // QueryAllEvidenceResponse is the response type for the Query/AllEvidence RPC 44 | // method. 45 | message QueryAllEvidenceResponse { 46 | // evidence returns all evidences. 47 | repeated google.protobuf.Any evidence = 1; 48 | 49 | // pagination defines the pagination in the response. 50 | cosmos.base.query.v1beta1.PageResponse pagination = 2; 51 | } 52 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/evidence/v1beta1/tx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.evidence.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/evidence/types"; 5 | option (gogoproto.equal_all) = true; 6 | 7 | import "gogoproto/gogo.proto"; 8 | import "google/protobuf/any.proto"; 9 | import "cosmos_proto/cosmos.proto"; 10 | import "cosmos/msg/v1/msg.proto"; 11 | 12 | // Msg defines the evidence Msg service. 13 | service Msg { 14 | // SubmitEvidence submits an arbitrary Evidence of misbehavior such as equivocation or 15 | // counterfactual signing. 16 | rpc SubmitEvidence(MsgSubmitEvidence) returns (MsgSubmitEvidenceResponse); 17 | } 18 | 19 | // MsgSubmitEvidence represents a message that supports submitting arbitrary 20 | // Evidence of misbehavior such as equivocation or counterfactual signing. 21 | message MsgSubmitEvidence { 22 | option (cosmos.msg.v1.signer) = "submitter"; 23 | 24 | option (gogoproto.equal) = false; 25 | option (gogoproto.goproto_getters) = false; 26 | 27 | string submitter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 28 | google.protobuf.Any evidence = 2 [(cosmos_proto.accepts_interface) = "Evidence"]; 29 | } 30 | 31 | // MsgSubmitEvidenceResponse defines the Msg/SubmitEvidence response type. 32 | message MsgSubmitEvidenceResponse { 33 | // hash defines the hash of the evidence. 34 | bytes hash = 4; 35 | } 36 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/feegrant/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.43 2 | syntax = "proto3"; 3 | package cosmos.feegrant.v1beta1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | import "cosmos/feegrant/v1beta1/feegrant.proto"; 7 | 8 | option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; 9 | 10 | // GenesisState contains a set of fee allowances, persisted from the store 11 | message GenesisState { 12 | repeated Grant allowances = 1 [(gogoproto.nullable) = false]; 13 | } 14 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/feegrant/v1beta1/tx.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.43 2 | syntax = "proto3"; 3 | package cosmos.feegrant.v1beta1; 4 | 5 | import "google/protobuf/any.proto"; 6 | import "cosmos_proto/cosmos.proto"; 7 | import "cosmos/msg/v1/msg.proto"; 8 | 9 | option go_package = "github.com/cosmos/cosmos-sdk/x/feegrant"; 10 | 11 | // Msg defines the feegrant msg service. 12 | service Msg { 13 | 14 | // GrantAllowance grants fee allowance to the grantee on the granter's 15 | // account with the provided expiration time. 16 | rpc GrantAllowance(MsgGrantAllowance) returns (MsgGrantAllowanceResponse); 17 | 18 | // RevokeAllowance revokes any fee allowance of granter's account that 19 | // has been granted to the grantee. 20 | rpc RevokeAllowance(MsgRevokeAllowance) returns (MsgRevokeAllowanceResponse); 21 | } 22 | 23 | // MsgGrantAllowance adds permission for Grantee to spend up to Allowance 24 | // of fees from the account of Granter. 25 | message MsgGrantAllowance { 26 | option (cosmos.msg.v1.signer) = "granter"; 27 | 28 | // granter is the address of the user granting an allowance of their funds. 29 | string granter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 30 | 31 | // grantee is the address of the user being granted an allowance of another user's funds. 32 | string grantee = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 33 | 34 | // allowance can be any of basic, periodic, allowed fee allowance. 35 | google.protobuf.Any allowance = 3 [(cosmos_proto.accepts_interface) = "FeeAllowanceI"]; 36 | } 37 | 38 | // MsgGrantAllowanceResponse defines the Msg/GrantAllowanceResponse response type. 39 | message MsgGrantAllowanceResponse {} 40 | 41 | // MsgRevokeAllowance removes any existing Allowance from Granter to Grantee. 42 | message MsgRevokeAllowance { 43 | option (cosmos.msg.v1.signer) = "granter"; 44 | 45 | // granter is the address of the user granting an allowance of their funds. 46 | string granter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 47 | 48 | // grantee is the address of the user being granted an allowance of another user's funds. 49 | string grantee = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 50 | } 51 | 52 | // MsgRevokeAllowanceResponse defines the Msg/RevokeAllowanceResponse response type. 53 | message MsgRevokeAllowanceResponse {} 54 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/genutil/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.genutil.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/x/genutil/types"; 7 | 8 | // GenesisState defines the raw genesis transaction in JSON. 9 | message GenesisState { 10 | // gen_txs defines the genesis transactions. 11 | repeated bytes gen_txs = 1 [(gogoproto.casttype) = "encoding/json.RawMessage", (gogoproto.jsontag) = "gentxs"]; 12 | } 13 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/gov/v1/genesis.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.46 2 | syntax = "proto3"; 3 | 4 | package cosmos.gov.v1; 5 | 6 | import "cosmos/gov/v1/gov.proto"; 7 | 8 | option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types/v1"; 9 | 10 | // GenesisState defines the gov module's genesis state. 11 | message GenesisState { 12 | // starting_proposal_id is the ID of the starting proposal. 13 | uint64 starting_proposal_id = 1; 14 | // deposits defines all the deposits present at genesis. 15 | repeated Deposit deposits = 2; 16 | // votes defines all the votes present at genesis. 17 | repeated Vote votes = 3; 18 | // proposals defines all the proposals present at genesis. 19 | repeated Proposal proposals = 4; 20 | // params defines all the paramaters of related to deposit. 21 | DepositParams deposit_params = 5; 22 | // params defines all the paramaters of related to voting. 23 | VotingParams voting_params = 6; 24 | // params defines all the paramaters of related to tally. 25 | TallyParams tally_params = 7; 26 | } 27 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/gov/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package cosmos.gov.v1beta1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | import "cosmos/gov/v1beta1/gov.proto"; 7 | 8 | option go_package = "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"; 9 | 10 | // GenesisState defines the gov module's genesis state. 11 | message GenesisState { 12 | // starting_proposal_id is the ID of the starting proposal. 13 | uint64 starting_proposal_id = 1; 14 | // deposits defines all the deposits present at genesis. 15 | repeated Deposit deposits = 2 [(gogoproto.castrepeated) = "Deposits", (gogoproto.nullable) = false]; 16 | // votes defines all the votes present at genesis. 17 | repeated Vote votes = 3 [(gogoproto.castrepeated) = "Votes", (gogoproto.nullable) = false]; 18 | // proposals defines all the proposals present at genesis. 19 | repeated Proposal proposals = 4 [(gogoproto.castrepeated) = "Proposals", (gogoproto.nullable) = false]; 20 | // params defines all the paramaters of related to deposit. 21 | DepositParams deposit_params = 5 [(gogoproto.nullable) = false]; 22 | // params defines all the paramaters of related to voting. 23 | VotingParams voting_params = 6 [(gogoproto.nullable) = false]; 24 | // params defines all the paramaters of related to tally. 25 | TallyParams tally_params = 7 [(gogoproto.nullable) = false]; 26 | } 27 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/group/v1/genesis.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.46 2 | syntax = "proto3"; 3 | 4 | package cosmos.group.v1; 5 | 6 | option go_package = "github.com/cosmos/cosmos-sdk/x/group"; 7 | 8 | import "cosmos/group/v1/types.proto"; 9 | 10 | // GenesisState defines the group module's genesis state. 11 | message GenesisState { 12 | 13 | // group_seq is the group table orm.Sequence, 14 | // it is used to get the next group ID. 15 | uint64 group_seq = 1; 16 | 17 | // groups is the list of groups info. 18 | repeated GroupInfo groups = 2; 19 | 20 | // group_members is the list of groups members. 21 | repeated GroupMember group_members = 3; 22 | 23 | // group_policy_seq is the group policy table orm.Sequence, 24 | // it is used to generate the next group policy account address. 25 | uint64 group_policy_seq = 4; 26 | 27 | // group_policies is the list of group policies info. 28 | repeated GroupPolicyInfo group_policies = 5; 29 | 30 | // proposal_seq is the proposal table orm.Sequence, 31 | // it is used to get the next proposal ID. 32 | uint64 proposal_seq = 6; 33 | 34 | // proposals is the list of proposals. 35 | repeated Proposal proposals = 7; 36 | 37 | // votes is the list of votes. 38 | repeated Vote votes = 8; 39 | } -------------------------------------------------------------------------------- /third_party/proto/cosmos/mint/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.mint.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "cosmos/mint/v1beta1/mint.proto"; 6 | 7 | option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; 8 | 9 | // GenesisState defines the mint module's genesis state. 10 | message GenesisState { 11 | // minter is a space for holding current inflation information. 12 | Minter minter = 1 [(gogoproto.nullable) = false]; 13 | 14 | // params defines all the paramaters of the module. 15 | Params params = 2 [(gogoproto.nullable) = false]; 16 | } 17 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/mint/v1beta1/mint.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.mint.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/mint/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "cosmos_proto/cosmos.proto"; 8 | 9 | // Minter represents the minting state. 10 | message Minter { 11 | // current annual inflation rate 12 | string inflation = 1 [ 13 | (cosmos_proto.scalar) = "cosmos.Dec", 14 | (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", 15 | (gogoproto.nullable) = false 16 | ]; 17 | // current annual expected provisions 18 | string annual_provisions = 2 [ 19 | (cosmos_proto.scalar) = "cosmos.Dec", 20 | (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", 21 | (gogoproto.nullable) = false 22 | ]; 23 | } 24 | 25 | // Params holds parameters for the mint module. 26 | message Params { 27 | option (gogoproto.goproto_stringer) = false; 28 | 29 | // type of coin to mint 30 | string mint_denom = 1; 31 | // maximum annual change in inflation rate 32 | string inflation_rate_change = 2 [ 33 | (cosmos_proto.scalar) = "cosmos.Dec", 34 | (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", 35 | (gogoproto.nullable) = false 36 | ]; 37 | // maximum inflation rate 38 | string inflation_max = 3 [ 39 | (cosmos_proto.scalar) = "cosmos.Dec", 40 | (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", 41 | (gogoproto.nullable) = false 42 | ]; 43 | // minimum inflation rate 44 | string inflation_min = 4 [ 45 | (cosmos_proto.scalar) = "cosmos.Dec", 46 | (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", 47 | (gogoproto.nullable) = false 48 | ]; 49 | // goal of percent bonded atoms 50 | string goal_bonded = 5 [ 51 | (cosmos_proto.scalar) = "cosmos.Dec", 52 | (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", 53 | (gogoproto.nullable) = false 54 | ]; 55 | // expected blocks per year 56 | uint64 blocks_per_year = 6; 57 | } 58 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/msg/v1/msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package cosmos.msg.v1; 4 | 5 | import "google/protobuf/descriptor.proto"; 6 | 7 | // TODO(fdymylja): once we fully migrate to protov2 the go_package needs to be updated. 8 | // We need this right now because gogoproto codegen needs to import the extension. 9 | option go_package = "github.com/cosmos/cosmos-sdk/types/msgservice"; 10 | 11 | extend google.protobuf.MessageOptions { 12 | // signer must be used in cosmos messages in order 13 | // to signal to external clients which fields in a 14 | // given cosmos message must be filled with signer 15 | // information (address). 16 | // The field must be the protobuf name of the message 17 | // field extended with this MessageOption. 18 | // The field must either be of string kind, or of message 19 | // kind in case the signer information is contained within 20 | // a message inside the cosmos message. 21 | repeated string signer = 11110000; 22 | } -------------------------------------------------------------------------------- /third_party/proto/cosmos/params/v1beta1/params.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.params.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; 5 | option (gogoproto.equal_all) = true; 6 | 7 | import "gogoproto/gogo.proto"; 8 | import "cosmos_proto/cosmos.proto"; 9 | 10 | // ParameterChangeProposal defines a proposal to change one or more parameters. 11 | message ParameterChangeProposal { 12 | option (gogoproto.goproto_getters) = false; 13 | option (gogoproto.goproto_stringer) = false; 14 | option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; 15 | 16 | string title = 1; 17 | string description = 2; 18 | repeated ParamChange changes = 3 [(gogoproto.nullable) = false]; 19 | } 20 | 21 | // ParamChange defines an individual parameter change, for use in 22 | // ParameterChangeProposal. 23 | message ParamChange { 24 | option (gogoproto.goproto_stringer) = false; 25 | 26 | string subspace = 1; 27 | string key = 2; 28 | string value = 3; 29 | } 30 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/params/v1beta1/query.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.params.v1beta1; 3 | 4 | import "gogoproto/gogo.proto"; 5 | import "google/api/annotations.proto"; 6 | import "cosmos/params/v1beta1/params.proto"; 7 | 8 | option go_package = "github.com/cosmos/cosmos-sdk/x/params/types/proposal"; 9 | 10 | // Query defines the gRPC querier service. 11 | service Query { 12 | // Params queries a specific parameter of a module, given its subspace and 13 | // key. 14 | rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { 15 | option (google.api.http).get = "/cosmos/params/v1beta1/params"; 16 | } 17 | 18 | // Subspaces queries for all registered subspaces and all keys for a subspace. 19 | // 20 | // Since: cosmos-sdk 0.46 21 | rpc Subspaces(QuerySubspacesRequest) returns (QuerySubspacesResponse) { 22 | option (google.api.http).get = "/cosmos/params/v1beta1/subspaces"; 23 | } 24 | } 25 | 26 | // QueryParamsRequest is request type for the Query/Params RPC method. 27 | message QueryParamsRequest { 28 | // subspace defines the module to query the parameter for. 29 | string subspace = 1; 30 | 31 | // key defines the key of the parameter in the subspace. 32 | string key = 2; 33 | } 34 | 35 | // QueryParamsResponse is response type for the Query/Params RPC method. 36 | message QueryParamsResponse { 37 | // param defines the queried parameter. 38 | ParamChange param = 1 [(gogoproto.nullable) = false]; 39 | } 40 | 41 | // QuerySubspacesRequest defines a request type for querying for all registered 42 | // subspaces and all keys for a subspace. 43 | // 44 | // Since: cosmos-sdk 0.46 45 | message QuerySubspacesRequest {} 46 | 47 | // QuerySubspacesResponse defines the response types for querying for all 48 | // registered subspaces and all keys for a subspace. 49 | // 50 | // Since: cosmos-sdk 0.46 51 | message QuerySubspacesResponse { 52 | repeated Subspace subspaces = 1; 53 | } 54 | 55 | // Subspace defines a parameter subspace name and all the keys that exist for 56 | // the subspace. 57 | // 58 | // Since: cosmos-sdk 0.46 59 | message Subspace { 60 | string subspace = 1; 61 | repeated string keys = 2; 62 | } 63 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/slashing/v1beta1/genesis.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.slashing.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "cosmos/slashing/v1beta1/slashing.proto"; 8 | import "cosmos_proto/cosmos.proto"; 9 | 10 | // GenesisState defines the slashing module's genesis state. 11 | message GenesisState { 12 | // params defines all the paramaters of related to deposit. 13 | Params params = 1 [(gogoproto.nullable) = false]; 14 | 15 | // signing_infos represents a map between validator addresses and their 16 | // signing infos. 17 | repeated SigningInfo signing_infos = 2 [(gogoproto.nullable) = false]; 18 | 19 | // missed_blocks represents a map between validator addresses and their 20 | // missed blocks. 21 | repeated ValidatorMissedBlocks missed_blocks = 3 [(gogoproto.nullable) = false]; 22 | } 23 | 24 | // SigningInfo stores validator signing info of corresponding address. 25 | message SigningInfo { 26 | // address is the validator address. 27 | string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 28 | // validator_signing_info represents the signing info of this validator. 29 | ValidatorSigningInfo validator_signing_info = 2 [(gogoproto.nullable) = false]; 30 | } 31 | 32 | // ValidatorMissedBlocks contains array of missed blocks of corresponding 33 | // address. 34 | message ValidatorMissedBlocks { 35 | // address is the validator address. 36 | string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 37 | // missed_blocks is an array of missed blocks by the validator. 38 | repeated MissedBlock missed_blocks = 2 [(gogoproto.nullable) = false]; 39 | } 40 | 41 | // MissedBlock contains height and missed status as boolean. 42 | message MissedBlock { 43 | // index is the height at which the block was missed. 44 | int64 index = 1; 45 | // missed is the missed status. 46 | bool missed = 2; 47 | } 48 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/slashing/v1beta1/tx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmos.slashing.v1beta1; 3 | 4 | option go_package = "github.com/cosmos/cosmos-sdk/x/slashing/types"; 5 | option (gogoproto.equal_all) = true; 6 | 7 | import "gogoproto/gogo.proto"; 8 | import "cosmos_proto/cosmos.proto"; 9 | import "cosmos/msg/v1/msg.proto"; 10 | 11 | // Msg defines the slashing Msg service. 12 | service Msg { 13 | // Unjail defines a method for unjailing a jailed validator, thus returning 14 | // them into the bonded validator set, so they can begin receiving provisions 15 | // and rewards again. 16 | rpc Unjail(MsgUnjail) returns (MsgUnjailResponse); 17 | } 18 | 19 | // MsgUnjail defines the Msg/Unjail request type 20 | message MsgUnjail { 21 | option (cosmos.msg.v1.signer) = "validator_addr"; 22 | 23 | option (gogoproto.goproto_getters) = false; 24 | option (gogoproto.goproto_stringer) = true; 25 | 26 | string validator_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString", (gogoproto.jsontag) = "address"]; 27 | } 28 | 29 | // MsgUnjailResponse defines the Msg/Unjail response type 30 | message MsgUnjailResponse {} 31 | -------------------------------------------------------------------------------- /third_party/proto/cosmos/upgrade/v1beta1/tx.proto: -------------------------------------------------------------------------------- 1 | // Since: cosmos-sdk 0.46 2 | syntax = "proto3"; 3 | package cosmos.upgrade.v1beta1; 4 | 5 | import "gogoproto/gogo.proto"; 6 | import "cosmos_proto/cosmos.proto"; 7 | import "cosmos/upgrade/v1beta1/upgrade.proto"; 8 | import "cosmos/msg/v1/msg.proto"; 9 | 10 | option go_package = "github.com/cosmos/cosmos-sdk/x/upgrade/types"; 11 | 12 | // Msg defines the upgrade Msg service. 13 | service Msg { 14 | // SoftwareUpgrade is a governance operation for initiating a software upgrade. 15 | // 16 | // Since: cosmos-sdk 0.46 17 | rpc SoftwareUpgrade(MsgSoftwareUpgrade) returns (MsgSoftwareUpgradeResponse); 18 | // CancelUpgrade is a governance operation for cancelling a previously 19 | // approvid software upgrade. 20 | // 21 | // Since: cosmos-sdk 0.46 22 | rpc CancelUpgrade(MsgCancelUpgrade) returns (MsgCancelUpgradeResponse); 23 | } 24 | 25 | // MsgSoftwareUpgrade is the Msg/SoftwareUpgrade request type. 26 | // 27 | // Since: cosmos-sdk 0.46 28 | message MsgSoftwareUpgrade { 29 | option (cosmos.msg.v1.signer) = "authority"; 30 | 31 | // authority is the address of the governance account. 32 | string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 33 | 34 | // plan is the upgrade plan. 35 | Plan plan = 2 [(gogoproto.nullable) = false]; 36 | } 37 | 38 | // MsgSoftwareUpgradeResponse is the Msg/SoftwareUpgrade response type. 39 | // 40 | // Since: cosmos-sdk 0.46 41 | message MsgSoftwareUpgradeResponse {} 42 | 43 | // MsgCancelUpgrade is the Msg/CancelUpgrade request type. 44 | // 45 | // Since: cosmos-sdk 0.46 46 | message MsgCancelUpgrade { 47 | option (cosmos.msg.v1.signer) = "authority"; 48 | 49 | // authority is the address of the governance account. 50 | string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; 51 | } 52 | 53 | // MsgCancelUpgradeResponse is the Msg/CancelUpgrade response type. 54 | // 55 | // Since: cosmos-sdk 0.46 56 | message MsgCancelUpgradeResponse {} 57 | -------------------------------------------------------------------------------- /third_party/proto/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/crypto/keys.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.crypto; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | 8 | // PublicKey defines the keys available for use with Tendermint Validators 9 | message PublicKey { 10 | option (gogoproto.compare) = true; 11 | option (gogoproto.equal) = true; 12 | 13 | oneof sum { 14 | bytes ed25519 = 1; 15 | bytes secp256k1 = 2; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/crypto/proof.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.crypto; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/crypto"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | 8 | message Proof { 9 | int64 total = 1; 10 | int64 index = 2; 11 | bytes leaf_hash = 3; 12 | repeated bytes aunts = 4; 13 | } 14 | 15 | message ValueOp { 16 | // Encoded in ProofOp.Key. 17 | bytes key = 1; 18 | 19 | // To encode in ProofOp.Data 20 | Proof proof = 2; 21 | } 22 | 23 | message DominoOp { 24 | string key = 1; 25 | string input = 2; 26 | string output = 3; 27 | } 28 | 29 | // ProofOp defines an operation used for calculating Merkle root 30 | // The data could be arbitrary format, providing nessecary data 31 | // for example neighbouring node hash 32 | message ProofOp { 33 | string type = 1; 34 | bytes key = 2; 35 | bytes data = 3; 36 | } 37 | 38 | // ProofOps is Merkle proof defined by the list of ProofOps 39 | message ProofOps { 40 | repeated ProofOp ops = 1 [(gogoproto.nullable) = false]; 41 | } 42 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/libs/bits/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.libs.bits; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/libs/bits"; 5 | 6 | message BitArray { 7 | int64 bits = 1; 8 | repeated uint64 elems = 2; 9 | } 10 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/p2p/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.p2p; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | 8 | message NetAddress { 9 | string id = 1 [(gogoproto.customname) = "ID"]; 10 | string ip = 2 [(gogoproto.customname) = "IP"]; 11 | uint32 port = 3; 12 | } 13 | 14 | message ProtocolVersion { 15 | uint64 p2p = 1 [(gogoproto.customname) = "P2P"]; 16 | uint64 block = 2; 17 | uint64 app = 3; 18 | } 19 | 20 | message DefaultNodeInfo { 21 | ProtocolVersion protocol_version = 1 [(gogoproto.nullable) = false]; 22 | string default_node_id = 2 [(gogoproto.customname) = "DefaultNodeID"]; 23 | string listen_addr = 3; 24 | string network = 4; 25 | string version = 5; 26 | bytes channels = 6; 27 | string moniker = 7; 28 | DefaultNodeInfoOther other = 8 [(gogoproto.nullable) = false]; 29 | } 30 | 31 | message DefaultNodeInfoOther { 32 | string tx_index = 1; 33 | string rpc_address = 2 [(gogoproto.customname) = "RPCAddress"]; 34 | } 35 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/types/block.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.types; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "tendermint/types/types.proto"; 8 | import "tendermint/types/evidence.proto"; 9 | 10 | message Block { 11 | Header header = 1 [(gogoproto.nullable) = false]; 12 | Data data = 2 [(gogoproto.nullable) = false]; 13 | tendermint.types.EvidenceList evidence = 3 [(gogoproto.nullable) = false]; 14 | Commit last_commit = 4; 15 | } 16 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/types/evidence.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.types; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "google/protobuf/timestamp.proto"; 8 | import "tendermint/types/types.proto"; 9 | import "tendermint/types/validator.proto"; 10 | 11 | message Evidence { 12 | oneof sum { 13 | DuplicateVoteEvidence duplicate_vote_evidence = 1; 14 | LightClientAttackEvidence light_client_attack_evidence = 2; 15 | } 16 | } 17 | 18 | // DuplicateVoteEvidence contains evidence of a validator signed two conflicting votes. 19 | message DuplicateVoteEvidence { 20 | tendermint.types.Vote vote_a = 1; 21 | tendermint.types.Vote vote_b = 2; 22 | int64 total_voting_power = 3; 23 | int64 validator_power = 4; 24 | google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; 25 | } 26 | 27 | // LightClientAttackEvidence contains evidence of a set of validators attempting to mislead a light client. 28 | message LightClientAttackEvidence { 29 | tendermint.types.LightBlock conflicting_block = 1; 30 | int64 common_height = 2; 31 | repeated tendermint.types.Validator byzantine_validators = 3; 32 | int64 total_voting_power = 4; 33 | google.protobuf.Timestamp timestamp = 5 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; 34 | } 35 | 36 | message EvidenceList { 37 | repeated Evidence evidence = 1 [(gogoproto.nullable) = false]; 38 | } 39 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/types/validator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.types; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | import "tendermint/crypto/keys.proto"; 8 | 9 | message ValidatorSet { 10 | repeated Validator validators = 1; 11 | Validator proposer = 2; 12 | int64 total_voting_power = 3; 13 | } 14 | 15 | message Validator { 16 | bytes address = 1; 17 | tendermint.crypto.PublicKey pub_key = 2 [(gogoproto.nullable) = false]; 18 | int64 voting_power = 3; 19 | int64 proposer_priority = 4; 20 | } 21 | 22 | message SimpleValidator { 23 | tendermint.crypto.PublicKey pub_key = 1; 24 | int64 voting_power = 2; 25 | } 26 | -------------------------------------------------------------------------------- /third_party/proto/tendermint/version/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tendermint.version; 3 | 4 | option go_package = "github.com/tendermint/tendermint/proto/tendermint/version"; 5 | 6 | import "gogoproto/gogo.proto"; 7 | 8 | // App includes the protocol and software version for the application. 9 | // This information is included in ResponseInfo. The App.Protocol can be 10 | // updated in ResponseEndBlock. 11 | message App { 12 | uint64 protocol = 1; 13 | string software = 2; 14 | } 15 | 16 | // Consensus captures the consensus rules for processing a block in the blockchain, 17 | // including all blockchain data structures and the rules of the application's 18 | // state transition machine. 19 | message Consensus { 20 | option (gogoproto.equal) = true; 21 | 22 | uint64 block = 1; 23 | uint64 app = 2; 24 | } 25 | -------------------------------------------------------------------------------- /x/distribution/README.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Distribution 6 | 7 | * [Distribution](spec/README.md) - Fee distribution, and staking token provision distribution. 8 | -------------------------------------------------------------------------------- /x/distribution/abci.go: -------------------------------------------------------------------------------- 1 | package distribution 2 | 3 | import ( 4 | "time" 5 | 6 | abci "github.com/tendermint/tendermint/abci/types" 7 | 8 | "github.com/cosmos/cosmos-sdk/telemetry" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/keeper" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 12 | ) 13 | 14 | // BeginBlocker sets the proposer for determining distribution during endblock 15 | // and distribute rewards for the previous block 16 | func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) { 17 | defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) 18 | 19 | // determine the total power signing the block 20 | var previousTotalPower, sumPreviousPrecommitPower int64 21 | for _, voteInfo := range req.LastCommitInfo.GetVotes() { 22 | previousTotalPower += voteInfo.Validator.Power 23 | if voteInfo.SignedLastBlock { 24 | sumPreviousPrecommitPower += voteInfo.Validator.Power 25 | } 26 | } 27 | 28 | // TODO this is Tendermint-dependent 29 | // ref https://github.com/cosmos/cosmos-sdk/issues/3095 30 | if ctx.BlockHeight() > 1 { 31 | previousProposer := k.GetPreviousProposerConsAddr(ctx) 32 | k.AllocateTokens(ctx, sumPreviousPrecommitPower, previousTotalPower, previousProposer, req.LastCommitInfo.GetVotes()) 33 | } 34 | 35 | // record the proposer for when we payout on the next block 36 | consAddr := sdk.ConsAddress(req.Header.ProposerAddress) 37 | k.SetPreviousProposerConsAddr(ctx, consAddr) 38 | } 39 | -------------------------------------------------------------------------------- /x/distribution/client/cli/utils.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 8 | ) 9 | 10 | // ParseCommunityPoolSpendProposalWithDeposit reads and parses a CommunityPoolSpendProposalWithDeposit from a file. 11 | func ParseCommunityPoolSpendProposalWithDeposit(cdc codec.JSONCodec, proposalFile string) (types.CommunityPoolSpendProposalWithDeposit, error) { 12 | proposal := types.CommunityPoolSpendProposalWithDeposit{} 13 | 14 | contents, err := os.ReadFile(proposalFile) 15 | if err != nil { 16 | return proposal, err 17 | } 18 | 19 | if err = cdc.UnmarshalJSON(contents, &proposal); err != nil { 20 | return proposal, err 21 | } 22 | 23 | return proposal, nil 24 | } 25 | -------------------------------------------------------------------------------- /x/distribution/client/common/common_test.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec/legacy" 7 | 8 | "github.com/stretchr/testify/require" 9 | 10 | "github.com/cosmos/cosmos-sdk/client" 11 | ) 12 | 13 | func TestQueryDelegationRewardsAddrValidation(t *testing.T) { 14 | clientCtx := client.Context{}.WithLegacyAmino(legacy.Cdc) 15 | 16 | type args struct { 17 | delAddr string 18 | valAddr string 19 | } 20 | 21 | tests := []struct { 22 | name string 23 | args args 24 | want []byte 25 | wantErr bool 26 | }{ 27 | {"invalid delegator address", args{"invalid", ""}, nil, true}, 28 | {"empty delegator address", args{"", ""}, nil, true}, 29 | {"invalid validator address", args{"cosmos1zxcsu7l5qxs53lvp0fqgd09a9r2g6kqrk2cdpa", "invalid"}, nil, true}, 30 | {"empty validator address", args{"cosmos1zxcsu7l5qxs53lvp0fqgd09a9r2g6kqrk2cdpa", ""}, nil, true}, 31 | } 32 | 33 | for _, tt := range tests { 34 | tt := tt 35 | t.Run(tt.name, func(t *testing.T) { 36 | _, _, err := QueryDelegationRewards(clientCtx, tt.args.delAddr, tt.args.valAddr) 37 | require.True(t, err != nil, tt.wantErr) 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /x/distribution/client/proposal_handler.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/x/distribution/client/rest" 5 | govclient "github.com/cosmos/cosmos-sdk/x/gov/client" 6 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/client/cli" 7 | ) 8 | 9 | // ProposalHandler is the community spend proposal handler. 10 | var ( 11 | // ProposalHandler = govclient.NewProposalHandler(cli.GetCmdSubmitProposal) 12 | ProposalHandler = govclient.NewProposalHandler(cli.GetCmdSubmitProposal, rest.ProposalRESTHandler) 13 | ) 14 | -------------------------------------------------------------------------------- /x/distribution/client/testutil/cli_test.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/suite" 7 | ) 8 | 9 | func TestIntegrationTestSuite(t *testing.T) { 10 | suite.Run(t, new(IntegrationTestSuite)) 11 | } 12 | 13 | func TestGRPCQueryTestSuite(t *testing.T) { 14 | suite.Run(t, new(GRPCQueryTestSuite)) 15 | } 16 | 17 | func TestWithdrawAllSuite(t *testing.T) { 18 | suite.Run(t, new(WithdrawAllTestSuite)) 19 | } 20 | -------------------------------------------------------------------------------- /x/distribution/client/testutil/helpers.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | 8 | "github.com/cosmos/cosmos-sdk/client" 9 | distrcli "github.com/iqlusioninc/liquidity-staking-module/x/distribution/client/cli" 10 | ) 11 | 12 | func MsgWithdrawDelegatorRewardExec(clientCtx client.Context, valAddr fmt.Stringer, extraArgs ...string) ([]byte, error) { 13 | buf := new(bytes.Buffer) 14 | clientCtx = clientCtx.WithOutput(buf) 15 | 16 | ctx := context.Background() 17 | ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 18 | 19 | args := []string{valAddr.String()} 20 | args = append(args, extraArgs...) 21 | 22 | cmd := distrcli.NewWithdrawRewardsCmd() 23 | cmd.SetErr(buf) 24 | cmd.SetOut(buf) 25 | cmd.SetArgs(args) 26 | 27 | if err := cmd.ExecuteContext(ctx); err != nil { 28 | return nil, err 29 | } 30 | 31 | return buf.Bytes(), nil 32 | } 33 | -------------------------------------------------------------------------------- /x/distribution/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package distribution implements a Cosmos SDK module, that provides an implementation 3 | of the F1 fee distribution algorithm. It handles reward tracking, allocation, and 4 | distribution. Please refer to the specification under /spec for further information. 5 | */ 6 | package distribution 7 | -------------------------------------------------------------------------------- /x/distribution/handler_test.go: -------------------------------------------------------------------------------- 1 | package distribution_test 2 | 3 | import ( 4 | "testing" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 8 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution" 9 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 10 | "github.com/stretchr/testify/require" 11 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 12 | ) 13 | 14 | // test msg registration 15 | func TestWithdrawTokenizeShareRecordReward(t *testing.T) { 16 | app := simapp.Setup(t, false) 17 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 18 | 19 | h := distribution.NewHandler(app.DistrKeeper) 20 | delAddr1 = sdk.AccAddress(delPk1.Address()) 21 | 22 | res, err := h(ctx, &types.MsgWithdrawAllTokenizeShareRecordReward{ 23 | OwnerAddress: delAddr1.String(), 24 | }) 25 | require.NoError(t, err) 26 | require.NotNil(t, res) 27 | } 28 | -------------------------------------------------------------------------------- /x/distribution/keeper/alias_functions.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 6 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 7 | ) 8 | 9 | // get outstanding rewards 10 | func (k Keeper) GetValidatorOutstandingRewardsCoins(ctx sdk.Context, val sdk.ValAddress) sdk.DecCoins { 11 | return k.GetValidatorOutstandingRewards(ctx, val).Rewards 12 | } 13 | 14 | // get the community coins 15 | func (k Keeper) GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins { 16 | return k.GetFeePool(ctx).CommunityPool 17 | } 18 | 19 | // GetDistributionAccount returns the distribution ModuleAccount 20 | func (k Keeper) GetDistributionAccount(ctx sdk.Context) authtypes.ModuleAccountI { 21 | return k.authKeeper.GetModuleAccount(ctx, types.ModuleName) 22 | } 23 | -------------------------------------------------------------------------------- /x/distribution/keeper/common_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 6 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 7 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 8 | ) 9 | 10 | var ( 11 | PKS = simapp.CreateTestPubKeys(5) 12 | 13 | valConsPk1 = PKS[0] 14 | valConsPk2 = PKS[1] 15 | valConsPk3 = PKS[2] 16 | 17 | valConsAddr1 = sdk.ConsAddress(valConsPk1.Address()) 18 | valConsAddr2 = sdk.ConsAddress(valConsPk2.Address()) 19 | 20 | distrAcc = authtypes.NewEmptyModuleAccount(types.ModuleName) 21 | ) 22 | -------------------------------------------------------------------------------- /x/distribution/keeper/fee_pool.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | sdkdistr "github.com/cosmos/cosmos-sdk/x/distribution/types" 6 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 7 | ) 8 | 9 | // DistributeFromFeePool distributes funds from the distribution module account to 10 | // a receiver address while updating the community pool 11 | func (k Keeper) DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error { 12 | feePool := k.GetFeePool(ctx) 13 | 14 | // NOTE the community pool isn't a module account, however its coins 15 | // are held in the distribution module account. Thus the community pool 16 | // must be reduced separately from the SendCoinsFromModuleToAccount call 17 | newPool, negative := feePool.CommunityPool.SafeSub(sdk.NewDecCoinsFromCoins(amount...)) 18 | if negative { 19 | return sdkdistr.ErrBadDistribution 20 | } 21 | 22 | feePool.CommunityPool = newPool 23 | 24 | err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, receiveAddr, amount) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | k.SetFeePool(ctx, feePool) 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /x/distribution/keeper/migrations.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | -------------------------------------------------------------------------------- /x/distribution/keeper/params.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 6 | ) 7 | 8 | // GetParams returns the total set of distribution parameters. 9 | func (k Keeper) GetParams(clientCtx sdk.Context) (params types.Params) { 10 | k.paramSpace.GetParamSet(clientCtx, ¶ms) 11 | return params 12 | } 13 | 14 | // SetParams sets the distribution parameters to the param space. 15 | func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { 16 | k.paramSpace.SetParamSet(ctx, ¶ms) 17 | } 18 | 19 | // GetCommunityTax returns the current distribution community tax. 20 | func (k Keeper) GetCommunityTax(ctx sdk.Context) (percent sdk.Dec) { 21 | k.paramSpace.Get(ctx, types.ParamStoreKeyCommunityTax, &percent) 22 | return percent 23 | } 24 | 25 | // GetBaseProposerReward returns the current distribution base proposer rate. 26 | func (k Keeper) GetBaseProposerReward(ctx sdk.Context) (percent sdk.Dec) { 27 | k.paramSpace.Get(ctx, types.ParamStoreKeyBaseProposerReward, &percent) 28 | return percent 29 | } 30 | 31 | // GetBonusProposerReward returns the current distribution bonus proposer reward 32 | // rate. 33 | func (k Keeper) GetBonusProposerReward(ctx sdk.Context) (percent sdk.Dec) { 34 | k.paramSpace.Get(ctx, types.ParamStoreKeyBonusProposerReward, &percent) 35 | return percent 36 | } 37 | 38 | // GetWithdrawAddrEnabled returns the current distribution withdraw address 39 | // enabled parameter. 40 | func (k Keeper) GetWithdrawAddrEnabled(ctx sdk.Context) (enabled bool) { 41 | k.paramSpace.Get(ctx, types.ParamStoreKeyWithdrawAddrEnabled, &enabled) 42 | return enabled 43 | } 44 | -------------------------------------------------------------------------------- /x/distribution/keeper/proposal_handler.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | errorsmod "cosmossdk.io/errors" 5 | sdk "github.com/cosmos/cosmos-sdk/types" 6 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 7 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 8 | ) 9 | 10 | // HandleCommunityPoolSpendProposal is a handler for executing a passed community spend proposal 11 | func HandleCommunityPoolSpendProposal(ctx sdk.Context, k Keeper, p *types.CommunityPoolSpendProposal) error { 12 | recipient, addrErr := sdk.AccAddressFromBech32(p.Recipient) 13 | if addrErr != nil { 14 | return addrErr 15 | } 16 | 17 | if k.bankKeeper.BlockedAddr(recipient) { 18 | return errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive external funds", p.Recipient) 19 | } 20 | 21 | err := k.DistributeFromFeePool(ctx, p.Amount, recipient) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | logger := k.Logger(ctx) 27 | logger.Info("transferred from the community pool to recipient", "amount", p.Amount.String(), "recipient", p.Recipient) 28 | 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /x/distribution/module_test.go: -------------------------------------------------------------------------------- 1 | package distribution_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | abcitypes "github.com/tendermint/tendermint/abci/types" 8 | tmjson "github.com/tendermint/tendermint/libs/json" 9 | "github.com/tendermint/tendermint/libs/log" 10 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 11 | dbm "github.com/tendermint/tm-db" 12 | 13 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 14 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 15 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 16 | ) 17 | 18 | func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { 19 | db := dbm.NewMemDB() 20 | encCdc := simapp.MakeTestEncodingConfig() 21 | app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) 22 | 23 | genesisState := simapp.GenesisStateWithSingleValidator(t, app) 24 | stateBytes, err := tmjson.Marshal(genesisState) 25 | require.NoError(t, err) 26 | 27 | app.InitChain( 28 | abcitypes.RequestInitChain{ 29 | AppStateBytes: stateBytes, 30 | ChainId: "test-chain-id", 31 | }, 32 | ) 33 | 34 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 35 | acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName)) 36 | require.NotNil(t, acc) 37 | } 38 | -------------------------------------------------------------------------------- /x/distribution/simulation/params.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | // DONTCOVER 4 | 5 | import ( 6 | "fmt" 7 | "math/rand" 8 | 9 | "github.com/cosmos/cosmos-sdk/x/simulation" 10 | 11 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 12 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 13 | ) 14 | 15 | const ( 16 | keyCommunityTax = "communitytax" 17 | keyBaseProposerReward = "baseproposerreward" 18 | keyBonusProposerReward = "bonusproposerreward" 19 | ) 20 | 21 | // ParamChanges defines the parameters that can be modified by param change proposals 22 | // on the simulation 23 | func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { 24 | return []simtypes.ParamChange{ 25 | simulation.NewSimParamChange(types.ModuleName, keyCommunityTax, 26 | func(r *rand.Rand) string { 27 | return fmt.Sprintf("\"%s\"", GenCommunityTax(r)) 28 | }, 29 | ), 30 | simulation.NewSimParamChange(types.ModuleName, keyBaseProposerReward, 31 | func(r *rand.Rand) string { 32 | return fmt.Sprintf("\"%s\"", GenBaseProposerReward(r)) 33 | }, 34 | ), 35 | simulation.NewSimParamChange(types.ModuleName, keyBonusProposerReward, 36 | func(r *rand.Rand) string { 37 | return fmt.Sprintf("\"%s\"", GenBonusProposerReward(r)) 38 | }, 39 | ), 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /x/distribution/simulation/params_test.go: -------------------------------------------------------------------------------- 1 | package simulation_test 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | 9 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/simulation" 10 | ) 11 | 12 | func TestParamChanges(t *testing.T) { 13 | s := rand.NewSource(1) 14 | r := rand.New(s) 15 | 16 | expected := []struct { 17 | composedKey string 18 | key string 19 | simValue string 20 | subspace string 21 | }{ 22 | {"distribution/communitytax", "communitytax", "\"0.120000000000000000\"", "distribution"}, 23 | {"distribution/baseproposerreward", "baseproposerreward", "\"0.280000000000000000\"", "distribution"}, 24 | {"distribution/bonusproposerreward", "bonusproposerreward", "\"0.180000000000000000\"", "distribution"}, 25 | } 26 | 27 | paramChanges := simulation.ParamChanges(r) 28 | 29 | require.Len(t, paramChanges, 3) 30 | 31 | for i, p := range paramChanges { 32 | require.Equal(t, expected[i].composedKey, p.ComposedKey()) 33 | require.Equal(t, expected[i].key, p.Key()) 34 | require.Equal(t, expected[i].simValue, p.SimValue()(r)) 35 | require.Equal(t, expected[i].subspace, p.Subspace()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /x/distribution/simulation/proposals.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | import ( 4 | "math/rand" 5 | 6 | simappparams "github.com/cosmos/cosmos-sdk/simapp/params" 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 9 | "github.com/cosmos/cosmos-sdk/x/simulation" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/keeper" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 12 | ) 13 | 14 | // OpWeightSubmitCommunitySpendProposal app params key for community spend proposal 15 | const OpWeightSubmitCommunitySpendProposal = "op_weight_submit_community_spend_proposal" 16 | 17 | // ProposalContents defines the module weighted proposals' contents 18 | func ProposalContents(k keeper.Keeper) []simtypes.WeightedProposalContent { 19 | return []simtypes.WeightedProposalContent{ 20 | simulation.NewWeightedProposalContent( 21 | OpWeightSubmitCommunitySpendProposal, 22 | simappparams.DefaultWeightCommunitySpendProposal, 23 | SimulateCommunityPoolSpendProposalContent(k), 24 | ), 25 | } 26 | } 27 | 28 | // SimulateCommunityPoolSpendProposalContent generates random community-pool-spend proposal content 29 | func SimulateCommunityPoolSpendProposalContent(k keeper.Keeper) simtypes.ContentSimulatorFn { 30 | return func(r *rand.Rand, ctx sdk.Context, accs []simtypes.Account) simtypes.Content { 31 | simAccount, _ := simtypes.RandomAcc(r, accs) 32 | 33 | balance := k.GetFeePool(ctx).CommunityPool 34 | if balance.Empty() { 35 | return nil 36 | } 37 | 38 | denomIndex := r.Intn(len(balance)) 39 | amount, err := simtypes.RandPositiveInt(r, balance[denomIndex].Amount.TruncateInt()) 40 | if err != nil { 41 | return nil 42 | } 43 | 44 | return types.NewCommunityPoolSpendProposal( 45 | simtypes.RandStringOfLength(r, 10), 46 | simtypes.RandStringOfLength(r, 100), 47 | simAccount.Address, 48 | sdk.NewCoins(sdk.NewCoin(balance[denomIndex].Denom, amount)), 49 | ) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /x/distribution/simulation/proposals_test.go: -------------------------------------------------------------------------------- 1 | package simulation_test 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 9 | 10 | simappparams "github.com/cosmos/cosmos-sdk/simapp/params" 11 | sdk "github.com/cosmos/cosmos-sdk/types" 12 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 13 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 14 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/simulation" 15 | ) 16 | 17 | func TestProposalContents(t *testing.T) { 18 | app := simapp.Setup(t, false) 19 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 20 | 21 | // initialize parameters 22 | s := rand.NewSource(1) 23 | r := rand.New(s) 24 | 25 | accounts := simtypes.RandomAccounts(r, 3) 26 | 27 | // execute ProposalContents function 28 | weightedProposalContent := simulation.ProposalContents(app.DistrKeeper) 29 | require.Len(t, weightedProposalContent, 1) 30 | 31 | w0 := weightedProposalContent[0] 32 | 33 | // tests w0 interface: 34 | require.Equal(t, simulation.OpWeightSubmitCommunitySpendProposal, w0.AppParamsKey()) 35 | require.Equal(t, simappparams.DefaultWeightTextProposal, w0.DefaultWeight()) 36 | 37 | amount := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1)), sdk.NewCoin("atoken", sdk.NewInt(2))) 38 | 39 | feePool := app.DistrKeeper.GetFeePool(ctx) 40 | feePool.CommunityPool = sdk.NewDecCoinsFromCoins(amount...) 41 | app.DistrKeeper.SetFeePool(ctx, feePool) 42 | 43 | content := w0.ContentSimulatorFn()(r, ctx, accounts) 44 | 45 | require.Equal(t, "sTxPjfweXhSUkMhPjMaxKlMIJMOXcnQfyzeOcbWwNbeHVIkPZBSpYuLyYggwexjxusrBqDOTtGTOWeLrQKjLxzIivHSlcxgdXhhu", content.GetDescription()) 46 | require.Equal(t, "xKGLwQvuyN", content.GetTitle()) 47 | require.Equal(t, "distribution", content.ProposalRoute()) 48 | require.Equal(t, "CommunityPoolSpend", content.ProposalType()) 49 | } 50 | -------------------------------------------------------------------------------- /x/distribution/spec/02_state.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # State 6 | 7 | ## FeePool 8 | 9 | All globally tracked parameters for distribution are stored within 10 | `FeePool`. Rewards are collected and added to the reward pool and 11 | distributed to validators/delegators from here. 12 | 13 | Note that the reward pool holds decimal coins (`DecCoins`) to allow 14 | for fractions of coins to be received from operations like inflation. 15 | When coins are distributed from the pool they are truncated back to 16 | `sdk.Coins` which are non-decimal. 17 | 18 | - FeePool: `0x00 -> ProtocolBuffer(FeePool)` 19 | 20 | ```go 21 | // coins with decimal 22 | type DecCoins []DecCoin 23 | 24 | type DecCoin struct { 25 | Amount sdk.Dec 26 | Denom string 27 | } 28 | ``` 29 | 30 | +++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/distribution/v1beta1/distribution.proto#L94-L101 31 | 32 | ## Validator Distribution 33 | 34 | Validator distribution information for the relevant validator is updated each time: 35 | 36 | 1. delegation amount to a validator is updated, 37 | 2. a validator successfully proposes a block and receives a reward, 38 | 3. any delegator withdraws from a validator, or 39 | 4. the validator withdraws its commission. 40 | 41 | - ValidatorDistInfo: `0x02 | ValOperatorAddrLen (1 byte) | ValOperatorAddr -> ProtocolBuffer(validatorDistribution)` 42 | 43 | ```go 44 | type ValidatorDistInfo struct { 45 | OperatorAddress sdk.AccAddress 46 | SelfBondRewards sdk.DecCoins 47 | ValidatorCommission types.ValidatorAccumulatedCommission 48 | } 49 | ``` 50 | 51 | ## Delegation Distribution 52 | 53 | Each delegation distribution only needs to record the height at which it last 54 | withdrew fees. Because a delegation must withdraw fees each time it's 55 | properties change (aka bonded tokens etc.) its properties will remain constant 56 | and the delegator's _accumulation_ factor can be calculated passively knowing 57 | only the height of the last withdrawal and its current properties. 58 | 59 | - DelegationDistInfo: `0x02 | DelegatorAddrLen (1 byte) | DelegatorAddr | ValOperatorAddrLen (1 byte) | ValOperatorAddr -> ProtocolBuffer(delegatorDist)` 60 | 61 | ```go 62 | type DelegationDistInfo struct { 63 | WithdrawalHeight int64 // last time this delegation withdrew rewards 64 | } 65 | ``` 66 | -------------------------------------------------------------------------------- /x/distribution/spec/05_hooks.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Hooks 6 | 7 | Available hooks that can be called by and from this module. 8 | 9 | ## Create or modify delegation distribution 10 | 11 | - triggered-by: `staking.MsgDelegate`, `staking.MsgBeginRedelegate`, `staking.MsgUndelegate` 12 | 13 | ### Before 14 | 15 | - The delegation rewards are withdrawn to the withdraw address of the delegator. 16 | The rewards include the current period and exclude the starting period. 17 | - The validator period is incremented. 18 | The validator period is incremented because the validator's power and share distribution might have changed. 19 | - The reference count for the delegator's starting period is decremented. 20 | 21 | ### After 22 | 23 | The starting height of the delegation is set to the previous period. 24 | Because of the `Before`-hook, this period is the last period for which the delegator was rewarded. 25 | 26 | ## Validator created 27 | 28 | - triggered-by: `staking.MsgCreateValidator` 29 | 30 | When a validator is created, the following validator variables are initialized: 31 | 32 | - Historical rewards 33 | - Current accumulated rewards 34 | - Accumulated commission 35 | - Total outstanding rewards 36 | - Period 37 | 38 | By default, all values are set to a `0`, except period, which is set to `1`. 39 | 40 | ## Validator removed 41 | 42 | - triggered-by: `staking.RemoveValidator` 43 | 44 | Outstanding commission is sent to the validator's self-delegation withdrawal address. 45 | Remaining delegator rewards get sent to the community fee pool. 46 | 47 | Note: The validator gets removed only when it has no remaining delegations. 48 | At that time, all outstanding delegator rewards will have been withdrawn. 49 | Any remaining rewards are dust amounts. 50 | 51 | ## Validator is slashed 52 | 53 | - triggered-by: `staking.Slash` 54 | 55 | - The current validator period reference count is incremented. 56 | The reference count is incremented because the slash event has created a reference to it. 57 | - The validator period is incremented. 58 | - The slash event is stored for later use. 59 | The slash event will be referenced when calculating delegator rewards. 60 | -------------------------------------------------------------------------------- /x/distribution/spec/06_events.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Events 6 | 7 | The distribution module emits the following events: 8 | 9 | ## BeginBlocker 10 | 11 | | Type | Attribute Key | Attribute Value | 12 | |-----------------|---------------|--------------------| 13 | | proposer_reward | validator | {validatorAddress} | 14 | | proposer_reward | reward | {proposerReward} | 15 | | commission | amount | {commissionAmount} | 16 | | commission | validator | {validatorAddress} | 17 | | rewards | amount | {rewardAmount} | 18 | | rewards | validator | {validatorAddress} | 19 | 20 | ## Handlers 21 | 22 | ### MsgSetWithdrawAddress 23 | 24 | | Type | Attribute Key | Attribute Value | 25 | |----------------------|------------------|----------------------| 26 | | set_withdraw_address | withdraw_address | {withdrawAddress} | 27 | | message | module | distribution | 28 | | message | action | set_withdraw_address | 29 | | message | sender | {senderAddress} | 30 | 31 | ### MsgWithdrawDelegatorReward 32 | 33 | | Type | Attribute Key | Attribute Value | 34 | |---------|---------------|---------------------------| 35 | | withdraw_rewards | amount | {rewardAmount} | 36 | | withdraw_rewards | validator | {validatorAddress} | 37 | | message | module | distribution | 38 | | message | action | withdraw_delegator_reward | 39 | | message | sender | {senderAddress} | 40 | 41 | ### MsgWithdrawValidatorCommission 42 | 43 | | Type | Attribute Key | Attribute Value | 44 | |------------|---------------|-------------------------------| 45 | | withdraw_commission | amount | {commissionAmount} | 46 | | message | module | distribution | 47 | | message | action | withdraw_validator_commission | 48 | | message | sender | {senderAddress} | 49 | -------------------------------------------------------------------------------- /x/distribution/spec/07_params.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Parameters 6 | 7 | The distribution module contains the following parameters: 8 | 9 | | Key | Type | Example | 10 | | ------------------- | ------------ | -------------------------- | 11 | | communitytax | string (dec) | "0.020000000000000000" [0] | 12 | | baseproposerreward | string (dec) | "0.010000000000000000" [0] | 13 | | bonusproposerreward | string (dec) | "0.040000000000000000" [0] | 14 | | withdrawaddrenabled | bool | true | 15 | 16 | * [0] `communitytax`, `baseproposerreward` and `bonusproposerreward` must be 17 | positive and their sum cannot exceed 1.00. 18 | -------------------------------------------------------------------------------- /x/distribution/types/codec.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/codec" 5 | "github.com/cosmos/cosmos-sdk/codec/legacy" 6 | "github.com/cosmos/cosmos-sdk/codec/types" 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/cosmos/cosmos-sdk/types/msgservice" 9 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" 10 | ) 11 | 12 | // RegisterLegacyAminoCodec registers the necessary x/distribution interfaces and concrete types 13 | // on the provided LegacyAmino codec. These types are used for Amino JSON serialization. 14 | func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { 15 | // cdc.RegisterConcrete(&MsgWithdrawDelegatorReward{}, "cosmos-sdk/MsgWithdrawDelegationReward", nil) 16 | // cdc.RegisterConcrete(&MsgWithdrawValidatorCommission{}, "cosmos-sdk/MsgWithdrawValidatorCommission", nil) 17 | // cdc.RegisterConcrete(&MsgSetWithdrawAddress{}, "cosmos-sdk/MsgModifyWithdrawAddress", nil) 18 | // cdc.RegisterConcrete(&MsgFundCommunityPool{}, "cosmos-sdk/MsgFundCommunityPool", nil) 19 | // cdc.RegisterConcrete(&CommunityPoolSpendProposal{}, "cosmos-sdk/CommunityPoolSpendProposal", nil) 20 | cdc.RegisterConcrete(&MsgWithdrawTokenizeShareRecordReward{}, "cosmos-sdk/MsgWithdrawTokenizeShareRecordReward", nil) 21 | cdc.RegisterConcrete(&MsgWithdrawAllTokenizeShareRecordReward{}, "cosmos-sdk/MsgWithdrawAllTokenizeShareRecordReward", nil) 22 | } 23 | 24 | func RegisterInterfaces(registry types.InterfaceRegistry) { 25 | registry.RegisterImplementations( 26 | (*sdk.Msg)(nil), 27 | &MsgWithdrawDelegatorReward{}, 28 | &MsgWithdrawValidatorCommission{}, 29 | &MsgSetWithdrawAddress{}, 30 | &MsgFundCommunityPool{}, 31 | &MsgWithdrawTokenizeShareRecordReward{}, 32 | &MsgWithdrawAllTokenizeShareRecordReward{}, 33 | ) 34 | registry.RegisterImplementations( 35 | (*govtypes.Content)(nil), 36 | &CommunityPoolSpendProposal{}, 37 | ) 38 | 39 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) 40 | } 41 | 42 | func init() { 43 | RegisterLegacyAminoCodec(legacy.Cdc) 44 | } 45 | -------------------------------------------------------------------------------- /x/distribution/types/common_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 5 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | ) 8 | 9 | //nolint:deadcode,unused,varcheck 10 | var ( 11 | delPk1 = ed25519.GenPrivKey().PubKey() 12 | delPk2 = ed25519.GenPrivKey().PubKey() 13 | delPk3 = ed25519.GenPrivKey().PubKey() 14 | delAddr1 = sdk.AccAddress(delPk1.Address()) 15 | delAddr2 = sdk.AccAddress(delPk2.Address()) 16 | delAddr3 = sdk.AccAddress(delPk3.Address()) 17 | emptyDelAddr sdk.AccAddress 18 | 19 | valPk1 = ed25519.GenPrivKey().PubKey() 20 | valPk2 = ed25519.GenPrivKey().PubKey() 21 | valPk3 = ed25519.GenPrivKey().PubKey() 22 | valAddr1 = sdk.ValAddress(valPk1.Address()) 23 | valAddr2 = sdk.ValAddress(valPk2.Address()) 24 | valAddr3 = sdk.ValAddress(valPk3.Address()) 25 | emptyValAddr sdk.ValAddress 26 | 27 | emptyPubkey cryptotypes.PubKey 28 | ) 29 | -------------------------------------------------------------------------------- /x/distribution/types/delegator.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | // create a new DelegatorStartingInfo 8 | func NewDelegatorStartingInfo(previousPeriod uint64, stake sdk.Dec, height uint64) DelegatorStartingInfo { 9 | return DelegatorStartingInfo{ 10 | PreviousPeriod: previousPeriod, 11 | Stake: stake, 12 | Height: height, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /x/distribution/types/errors.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | errorsmod "cosmossdk.io/errors" 5 | ) 6 | 7 | // x/distribution module sentinel errors 8 | var ( 9 | // ErrEmptyDelegatorAddr = errorsmod.Register(ModuleName, 2, "delegator address is empty") 10 | // ErrEmptyWithdrawAddr = errorsmod.Register(ModuleName, 3, "withdraw address is empty") 11 | // ErrEmptyValidatorAddr = errorsmod.Register(ModuleName, 4, "validator address is empty") 12 | // ErrEmptyDelegationDistInfo = errorsmod.Register(ModuleName, 5, "no delegation distribution info") 13 | // ErrNoValidatorDistInfo = errorsmod.Register(ModuleName, 6, "no validator distribution info") 14 | // ErrNoValidatorCommission = errorsmod.Register(ModuleName, 7, "no validator commission to withdraw") 15 | // ErrSetWithdrawAddrDisabled = errorsmod.Register(ModuleName, 8, "set withdraw address disabled") 16 | // ErrBadDistribution = errorsmod.Register(ModuleName, 9, "community pool does not have sufficient coins to distribute") 17 | // ErrInvalidProposalAmount = errorsmod.Register(ModuleName, 10, "invalid community pool spend proposal amount") 18 | // ErrEmptyProposalRecipient = errorsmod.Register(ModuleName, 11, "invalid community pool spend proposal recipient") 19 | // ErrNoValidatorExists = errorsmod.Register(ModuleName, 12, "validator does not exist") 20 | // ErrNoDelegationExists = errorsmod.Register(ModuleName, 13, "delegation does not exist") 21 | ErrNotTokenizeShareRecordOwner = errorsmod.Register(ModuleName, 44, "not tokenize share record owner") 22 | ) 23 | -------------------------------------------------------------------------------- /x/distribution/types/events.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // distribution module event types 4 | const ( 5 | EventTypeSetWithdrawAddress = "set_withdraw_address" 6 | EventTypeRewards = "rewards" 7 | EventTypeCommission = "commission" 8 | EventTypeWithdrawRewards = "withdraw_rewards" 9 | EventTypeWithdrawCommission = "withdraw_commission" 10 | EventTypeWithdrawTokenizeShareReward = "withdraw_tokenize_share_reward" 11 | EventTypeProposerReward = "proposer_reward" 12 | 13 | AttributeKeyWithdrawAddress = "withdraw_address" 14 | AttributeKeyValidator = "validator" 15 | 16 | AttributeValueCategory = ModuleName 17 | ) 18 | -------------------------------------------------------------------------------- /x/distribution/types/fee_pool.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | ) 8 | 9 | // zero fee pool 10 | func InitialFeePool() FeePool { 11 | return FeePool{ 12 | CommunityPool: sdk.DecCoins{}, 13 | } 14 | } 15 | 16 | // ValidateGenesis validates the fee pool for a genesis state 17 | func (f FeePool) ValidateGenesis() error { 18 | if f.CommunityPool.IsAnyNegative() { 19 | return fmt.Errorf("negative CommunityPool in distribution fee pool, is %v", 20 | f.CommunityPool) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /x/distribution/types/fee_pool_test.go: -------------------------------------------------------------------------------- 1 | package types_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 10 | ) 11 | 12 | func TestValidateGenesis(t *testing.T) { 13 | fp := types.InitialFeePool() 14 | require.Nil(t, fp.ValidateGenesis()) 15 | 16 | fp2 := types.FeePool{CommunityPool: sdk.DecCoins{{Denom: "stake", Amount: sdk.NewDec(-1)}}} 17 | require.NotNil(t, fp2.ValidateGenesis()) 18 | } 19 | -------------------------------------------------------------------------------- /x/distribution/types/genesis.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | //nolint:interfacer 8 | func NewGenesisState( 9 | params Params, fp FeePool, dwis []DelegatorWithdrawInfo, pp sdk.ConsAddress, r []ValidatorOutstandingRewardsRecord, 10 | acc []ValidatorAccumulatedCommissionRecord, historical []ValidatorHistoricalRewardsRecord, 11 | cur []ValidatorCurrentRewardsRecord, dels []DelegatorStartingInfoRecord, slashes []ValidatorSlashEventRecord, 12 | ) *GenesisState { 13 | return &GenesisState{ 14 | Params: params, 15 | FeePool: fp, 16 | DelegatorWithdrawInfos: dwis, 17 | PreviousProposer: pp.String(), 18 | OutstandingRewards: r, 19 | ValidatorAccumulatedCommissions: acc, 20 | ValidatorHistoricalRewards: historical, 21 | ValidatorCurrentRewards: cur, 22 | DelegatorStartingInfos: dels, 23 | ValidatorSlashEvents: slashes, 24 | } 25 | } 26 | 27 | // get raw genesis raw message for testing 28 | func DefaultGenesisState() *GenesisState { 29 | return &GenesisState{ 30 | FeePool: InitialFeePool(), 31 | Params: DefaultParams(), 32 | DelegatorWithdrawInfos: []DelegatorWithdrawInfo{}, 33 | PreviousProposer: "", 34 | OutstandingRewards: []ValidatorOutstandingRewardsRecord{}, 35 | ValidatorAccumulatedCommissions: []ValidatorAccumulatedCommissionRecord{}, 36 | ValidatorHistoricalRewards: []ValidatorHistoricalRewardsRecord{}, 37 | ValidatorCurrentRewards: []ValidatorCurrentRewardsRecord{}, 38 | DelegatorStartingInfos: []DelegatorStartingInfoRecord{}, 39 | ValidatorSlashEvents: []ValidatorSlashEventRecord{}, 40 | } 41 | } 42 | 43 | // ValidateGenesis validates the genesis state of distribution genesis input 44 | func ValidateGenesis(gs *GenesisState) error { 45 | if err := gs.Params.ValidateBasic(); err != nil { 46 | return err 47 | } 48 | return gs.FeePool.ValidateGenesis() 49 | } 50 | -------------------------------------------------------------------------------- /x/distribution/types/params_internal_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | ) 10 | 11 | func Test_validateAuxFuncs(t *testing.T) { 12 | type args struct { 13 | i interface{} 14 | } 15 | tests := []struct { 16 | name string 17 | args args 18 | wantErr bool 19 | }{ 20 | {"wrong type", args{10.5}, true}, 21 | {"empty sdk.Dec", args{sdk.Dec{}}, true}, 22 | {"negative", args{sdk.NewDec(-1)}, true}, 23 | {"one dec", args{sdk.NewDec(1)}, false}, 24 | {"two dec", args{sdk.NewDec(2)}, true}, 25 | } 26 | for _, tt := range tests { 27 | tt := tt 28 | t.Run(tt.name, func(t *testing.T) { 29 | require.Equal(t, tt.wantErr, validateCommunityTax(tt.args.i) != nil) 30 | require.Equal(t, tt.wantErr, validateBaseProposerReward(tt.args.i) != nil) 31 | require.Equal(t, tt.wantErr, validateBonusProposerReward(tt.args.i) != nil) 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /x/distribution/types/params_test.go: -------------------------------------------------------------------------------- 1 | package types_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/iqlusioninc/liquidity-staking-module/x/distribution/types" 10 | ) 11 | 12 | func TestParams_ValidateBasic(t *testing.T) { 13 | toDec := sdk.MustNewDecFromStr 14 | 15 | type fields struct { 16 | CommunityTax sdk.Dec 17 | BaseProposerReward sdk.Dec 18 | BonusProposerReward sdk.Dec 19 | WithdrawAddrEnabled bool 20 | } 21 | tests := []struct { 22 | name string 23 | fields fields 24 | wantErr bool 25 | }{ 26 | {"success", fields{toDec("0.1"), toDec("0.5"), toDec("0.4"), false}, false}, 27 | {"negative community tax", fields{toDec("-0.1"), toDec("0.5"), toDec("0.4"), false}, true}, 28 | {"negative base proposer reward", fields{toDec("0.1"), toDec("-0.5"), toDec("0.4"), false}, true}, 29 | {"negative bonus proposer reward", fields{toDec("0.1"), toDec("0.5"), toDec("-0.4"), false}, true}, 30 | {"total sum greater than 1", fields{toDec("0.2"), toDec("0.5"), toDec("0.4"), false}, true}, 31 | } 32 | for _, tt := range tests { 33 | t.Run(tt.name, func(t *testing.T) { 34 | p := types.Params{ 35 | CommunityTax: tt.fields.CommunityTax, 36 | BaseProposerReward: tt.fields.BaseProposerReward, 37 | BonusProposerReward: tt.fields.BonusProposerReward, 38 | WithdrawAddrEnabled: tt.fields.WithdrawAddrEnabled, 39 | } 40 | if err := p.ValidateBasic(); (err != nil) != tt.wantErr { 41 | t.Errorf("ValidateBasic() error = %v, wantErr %v", err, tt.wantErr) 42 | } 43 | }) 44 | } 45 | } 46 | 47 | func TestDefaultParams(t *testing.T) { 48 | require.NoError(t, types.DefaultParams().ValidateBasic()) 49 | } 50 | -------------------------------------------------------------------------------- /x/distribution/types/query.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | ) 9 | 10 | // QueryDelegatorTotalRewardsResponse defines the properties of 11 | // QueryDelegatorTotalRewards query's response. 12 | type QueryDelegatorTotalRewardsResponse struct { 13 | Rewards []DelegationDelegatorReward `json:"rewards" yaml:"rewards"` 14 | Total sdk.DecCoins `json:"total" yaml:"total"` 15 | } 16 | 17 | // NewQueryDelegatorTotalRewardsResponse constructs a QueryDelegatorTotalRewardsResponse 18 | func NewQueryDelegatorTotalRewardsResponse(rewards []DelegationDelegatorReward, 19 | total sdk.DecCoins, 20 | ) QueryDelegatorTotalRewardsResponse { 21 | return QueryDelegatorTotalRewardsResponse{Rewards: rewards, Total: total} 22 | } 23 | 24 | func (res QueryDelegatorTotalRewardsResponse) String() string { 25 | out := "Delegator Total Rewards:\n" 26 | out += " Rewards:" 27 | for _, reward := range res.Rewards { 28 | out += fmt.Sprintf(` 29 | ValidatorAddress: %s 30 | Reward: %s`, reward.ValidatorAddress, reward.Reward) 31 | } 32 | out += fmt.Sprintf("\n Total: %s\n", res.Total) 33 | return strings.TrimSpace(out) 34 | } 35 | 36 | // NewDelegationDelegatorReward constructs a DelegationDelegatorReward. 37 | // 38 | //nolint:interfacer 39 | func NewDelegationDelegatorReward(valAddr sdk.ValAddress, 40 | reward sdk.DecCoins, 41 | ) DelegationDelegatorReward { 42 | return DelegationDelegatorReward{ValidatorAddress: valAddr.String(), Reward: reward} 43 | } 44 | -------------------------------------------------------------------------------- /x/distribution/types/validator.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | ) 9 | 10 | // create a new ValidatorHistoricalRewards 11 | func NewValidatorHistoricalRewards(cumulativeRewardRatio sdk.DecCoins, referenceCount uint32) ValidatorHistoricalRewards { 12 | return ValidatorHistoricalRewards{ 13 | CumulativeRewardRatio: cumulativeRewardRatio, 14 | ReferenceCount: referenceCount, 15 | } 16 | } 17 | 18 | // create a new ValidatorCurrentRewards 19 | func NewValidatorCurrentRewards(rewards sdk.DecCoins, period uint64) ValidatorCurrentRewards { 20 | return ValidatorCurrentRewards{ 21 | Rewards: rewards, 22 | Period: period, 23 | } 24 | } 25 | 26 | // return the initial accumulated commission (zero) 27 | func InitialValidatorAccumulatedCommission() ValidatorAccumulatedCommission { 28 | return ValidatorAccumulatedCommission{} 29 | } 30 | 31 | // create a new ValidatorSlashEvent 32 | func NewValidatorSlashEvent(validatorPeriod uint64, fraction sdk.Dec) ValidatorSlashEvent { 33 | return ValidatorSlashEvent{ 34 | ValidatorPeriod: validatorPeriod, 35 | Fraction: fraction, 36 | } 37 | } 38 | 39 | func (vs ValidatorSlashEvents) String() string { 40 | out := "Validator Slash Events:\n" 41 | for i, sl := range vs.ValidatorSlashEvents { 42 | out += fmt.Sprintf(` Slash %d: 43 | Period: %d 44 | Fraction: %s 45 | `, i, sl.ValidatorPeriod, sl.Fraction) 46 | } 47 | return strings.TrimSpace(out) 48 | } 49 | -------------------------------------------------------------------------------- /x/genutil/client/cli/migrate.go: -------------------------------------------------------------------------------- 1 | package cli 2 | -------------------------------------------------------------------------------- /x/genutil/client/testutil/cli_test.go: -------------------------------------------------------------------------------- 1 | //go:build norace 2 | // +build norace 3 | 4 | package testutil 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/cosmos/cosmos-sdk/testutil/network" 10 | 11 | "github.com/stretchr/testify/suite" 12 | ) 13 | 14 | func TestIntegrationTestSuite(t *testing.T) { 15 | cfg := network.DefaultConfig() 16 | cfg.NumValidators = 1 17 | suite.Run(t, NewIntegrationTestSuite(cfg)) 18 | } 19 | -------------------------------------------------------------------------------- /x/genutil/client/testutil/helpers.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/spf13/viper" 8 | tmcfg "github.com/tendermint/tendermint/config" 9 | "github.com/tendermint/tendermint/libs/cli" 10 | "github.com/tendermint/tendermint/libs/log" 11 | 12 | "github.com/cosmos/cosmos-sdk/client" 13 | "github.com/cosmos/cosmos-sdk/codec" 14 | "github.com/cosmos/cosmos-sdk/server" 15 | "github.com/cosmos/cosmos-sdk/testutil" 16 | "github.com/cosmos/cosmos-sdk/types/module" 17 | genutilcli "github.com/iqlusioninc/liquidity-staking-module/x/genutil/client/cli" 18 | ) 19 | 20 | func ExecInitCmd(testMbm module.BasicManager, home string, cdc codec.Codec) error { 21 | logger := log.NewNopLogger() 22 | cfg, err := CreateDefaultTendermintConfig(home) 23 | if err != nil { 24 | return err 25 | } 26 | 27 | cmd := genutilcli.InitCmd(testMbm, home) 28 | serverCtx := server.NewContext(viper.New(), cfg, logger) 29 | clientCtx := client.Context{}.WithCodec(cdc).WithHomeDir(home) 30 | 31 | _, out := testutil.ApplyMockIO(cmd) 32 | clientCtx = clientCtx.WithOutput(out) 33 | 34 | ctx := context.Background() 35 | ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) 36 | ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) 37 | 38 | cmd.SetArgs([]string{"appnode-test", fmt.Sprintf("--%s=%s", cli.HomeFlag, home)}) 39 | 40 | return cmd.ExecuteContext(ctx) 41 | } 42 | 43 | func CreateDefaultTendermintConfig(rootDir string) (*tmcfg.Config, error) { 44 | conf := tmcfg.DefaultConfig() 45 | conf.SetRoot(rootDir) 46 | tmcfg.EnsureRoot(rootDir) 47 | 48 | if err := conf.ValidateBasic(); err != nil { 49 | return nil, fmt.Errorf("error in config file: %v", err) 50 | } 51 | 52 | return conf, nil 53 | } 54 | -------------------------------------------------------------------------------- /x/genutil/client/testutil/migrate.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | -------------------------------------------------------------------------------- /x/genutil/collect_test.go: -------------------------------------------------------------------------------- 1 | package genutil_test 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | "path/filepath" 7 | "testing" 8 | 9 | "github.com/gogo/protobuf/proto" 10 | 11 | tmtypes "github.com/tendermint/tendermint/types" 12 | 13 | "github.com/cosmos/cosmos-sdk/codec" 14 | cdctypes "github.com/cosmos/cosmos-sdk/codec/types" 15 | "github.com/cosmos/cosmos-sdk/server" 16 | "github.com/cosmos/cosmos-sdk/types" 17 | bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported" 18 | "github.com/iqlusioninc/liquidity-staking-module/x/genutil" 19 | gtypes "github.com/iqlusioninc/liquidity-staking-module/x/genutil/types" 20 | ) 21 | 22 | type doNothingUnmarshalJSON struct { 23 | codec.JSONCodec 24 | } 25 | 26 | func (dnj *doNothingUnmarshalJSON) UnmarshalJSON(_ []byte, _ proto.Message) error { 27 | return nil 28 | } 29 | 30 | type doNothingIterator struct { 31 | gtypes.GenesisBalancesIterator 32 | } 33 | 34 | func (dni *doNothingIterator) IterateGenesisBalances(_ codec.JSONCodec, _ map[string]json.RawMessage, _ func(bankexported.GenesisBalance) bool) { 35 | } 36 | 37 | // Ensures that CollectTx correctly traverses directories and won't error out on encountering 38 | // a directory during traversal of the first level. See issue https://github.com/cosmos/cosmos-sdk/issues/6788. 39 | func TestCollectTxsHandlesDirectories(t *testing.T) { 40 | testDir, err := os.MkdirTemp(os.TempDir(), "testCollectTxs") 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | defer os.RemoveAll(testDir) 45 | 46 | // 1. We'll insert a directory as the first element before JSON file. 47 | subDirPath := filepath.Join(testDir, "_adir") 48 | if err := os.MkdirAll(subDirPath, 0o755); err != nil { 49 | t.Fatal(err) 50 | } 51 | 52 | txDecoder := types.TxDecoder(func(txBytes []byte) (types.Tx, error) { 53 | return nil, nil 54 | }) 55 | 56 | // 2. Ensure that we don't encounter any error traversing the directory. 57 | srvCtx := server.NewDefaultContext() 58 | _ = srvCtx 59 | cdc := codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) 60 | gdoc := tmtypes.GenesisDoc{AppState: []byte("{}")} 61 | balItr := new(doNothingIterator) 62 | 63 | dnc := &doNothingUnmarshalJSON{cdc} 64 | if _, _, err := genutil.CollectTxs(dnc, txDecoder, "foo", testDir, gdoc, balItr); err != nil { 65 | t.Fatal(err) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /x/genutil/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package genutil contains a variety of genesis utility functionality 3 | for usage within a blockchain application. Namely: 4 | - Genesis transactions related (gentx) 5 | - commands for collection and creation of gentxs 6 | - initchain processing of gentxs 7 | - Genesis file validation 8 | - Tendermint related initialization 9 | */ 10 | package genutil 11 | -------------------------------------------------------------------------------- /x/genutil/genesis.go: -------------------------------------------------------------------------------- 1 | package genutil 2 | 3 | import ( 4 | abci "github.com/tendermint/tendermint/abci/types" 5 | 6 | "github.com/cosmos/cosmos-sdk/client" 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/iqlusioninc/liquidity-staking-module/x/genutil/types" 9 | ) 10 | 11 | // InitGenesis - initialize accounts and deliver genesis transactions 12 | func InitGenesis( 13 | ctx sdk.Context, stakingKeeper types.StakingKeeper, 14 | deliverTx deliverTxfn, genesisState types.GenesisState, 15 | txEncodingConfig client.TxEncodingConfig, 16 | ) (validators []abci.ValidatorUpdate, err error) { 17 | if len(genesisState.GenTxs) > 0 { 18 | validators, err = DeliverGenTxs(ctx, genesisState.GenTxs, stakingKeeper, deliverTx, txEncodingConfig) 19 | } 20 | return 21 | } 22 | -------------------------------------------------------------------------------- /x/genutil/migrations/v046/migrate.go: -------------------------------------------------------------------------------- 1 | package v046 2 | -------------------------------------------------------------------------------- /x/genutil/types/expected_keepers.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | abci "github.com/tendermint/tendermint/abci/types" 7 | 8 | "github.com/cosmos/cosmos-sdk/codec" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | auth "github.com/cosmos/cosmos-sdk/x/auth/types" 11 | bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported" 12 | ) 13 | 14 | // StakingKeeper defines the expected staking keeper (noalias) 15 | type StakingKeeper interface { 16 | ApplyAndReturnValidatorSetUpdates(sdk.Context) (updates []abci.ValidatorUpdate, err error) 17 | } 18 | 19 | // AccountKeeper defines the expected account keeper (noalias) 20 | type AccountKeeper interface { 21 | NewAccount(sdk.Context, auth.AccountI) auth.AccountI 22 | SetAccount(sdk.Context, auth.AccountI) 23 | IterateAccounts(ctx sdk.Context, process func(auth.AccountI) (stop bool)) 24 | } 25 | 26 | // GenesisAccountsIterator defines the expected iterating genesis accounts object (noalias) 27 | type GenesisAccountsIterator interface { 28 | IterateGenesisAccounts( 29 | cdc *codec.LegacyAmino, 30 | appGenesis map[string]json.RawMessage, 31 | cb func(auth.AccountI) (stop bool), 32 | ) 33 | } 34 | 35 | // GenesisAccountsIterator defines the expected iterating genesis accounts object (noalias) 36 | type GenesisBalancesIterator interface { 37 | IterateGenesisBalances( 38 | cdc codec.JSONCodec, 39 | appGenesis map[string]json.RawMessage, 40 | cb func(bankexported.GenesisBalance) (stop bool), 41 | ) 42 | } 43 | -------------------------------------------------------------------------------- /x/genutil/types/types.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/cosmos/cosmos-sdk/client" 7 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 8 | ) 9 | 10 | // DONTCOVER 11 | 12 | type ( 13 | // AppMap map modules names with their json raw representation. 14 | AppMap map[string]json.RawMessage 15 | 16 | // MigrationCallback converts a genesis map from the previous version to the 17 | // targeted one. 18 | // 19 | // TODO: MigrationCallback should also return an error upon failure. 20 | MigrationCallback func(AppMap, client.Context) AppMap 21 | 22 | // MigrationMap defines a mapping from a version to a MigrationCallback. 23 | MigrationMap map[string]MigrationCallback 24 | ) 25 | 26 | // ModuleName is genutil 27 | const ModuleName = "genutil" 28 | 29 | // InitConfig common config options for init 30 | type InitConfig struct { 31 | ChainID string 32 | GenTxsDir string 33 | NodeID string 34 | ValPubKey cryptotypes.PubKey 35 | } 36 | 37 | // NewInitConfig creates a new InitConfig object 38 | func NewInitConfig(chainID, genTxsDir, nodeID string, valPubKey cryptotypes.PubKey) InitConfig { 39 | return InitConfig{ 40 | ChainID: chainID, 41 | GenTxsDir: genTxsDir, 42 | NodeID: nodeID, 43 | ValPubKey: valPubKey, 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /x/genutil/utils_test.go: -------------------------------------------------------------------------------- 1 | package genutil 2 | -------------------------------------------------------------------------------- /x/slashing/README.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Slashing 6 | 7 | * [Slashing](spec/README.md) - validator punishment mechanisms. 8 | -------------------------------------------------------------------------------- /x/slashing/abci.go: -------------------------------------------------------------------------------- 1 | package slashing 2 | 3 | import ( 4 | "time" 5 | 6 | abci "github.com/tendermint/tendermint/abci/types" 7 | 8 | "github.com/cosmos/cosmos-sdk/telemetry" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/keeper" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 12 | ) 13 | 14 | // BeginBlocker check for infraction evidence or downtime of validators 15 | // on every begin block 16 | func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) { 17 | defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) 18 | 19 | // Iterate over all the validators which *should* have signed this block 20 | // store whether or not they have actually signed it and slash/unbond any 21 | // which have missed too many blocks in a row (downtime slashing) 22 | for _, voteInfo := range req.LastCommitInfo.GetVotes() { 23 | k.HandleValidatorSignature(ctx, voteInfo.Validator.Address, voteInfo.Validator.Power, voteInfo.SignedLastBlock) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /x/slashing/client/cli/flags.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | const ( 4 | FlagAddressValidator = "validator" 5 | ) 6 | -------------------------------------------------------------------------------- /x/slashing/client/cli/tx.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | 6 | "github.com/cosmos/cosmos-sdk/client" 7 | "github.com/cosmos/cosmos-sdk/client/flags" 8 | "github.com/cosmos/cosmos-sdk/client/tx" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 11 | ) 12 | 13 | // NewTxCmd returns a root CLI command handler for all x/slashing transaction commands. 14 | func NewTxCmd() *cobra.Command { 15 | slashingTxCmd := &cobra.Command{ 16 | Use: types.ModuleName, 17 | Short: "Slashing transaction subcommands", 18 | DisableFlagParsing: true, 19 | SuggestionsMinimumDistance: 2, 20 | RunE: client.ValidateCmd, 21 | } 22 | 23 | slashingTxCmd.AddCommand(NewUnjailTxCmd()) 24 | return slashingTxCmd 25 | } 26 | 27 | func NewUnjailTxCmd() *cobra.Command { 28 | cmd := &cobra.Command{ 29 | Use: "unjail", 30 | Args: cobra.NoArgs, 31 | Short: "unjail validator previously jailed for downtime", 32 | Long: `unjail a jailed validator: 33 | 34 | $ tx slashing unjail --from mykey 35 | `, 36 | RunE: func(cmd *cobra.Command, args []string) error { 37 | clientCtx, err := client.GetClientTxContext(cmd) 38 | if err != nil { 39 | return err 40 | } 41 | valAddr := clientCtx.GetFromAddress() 42 | 43 | msg := types.NewMsgUnjail(sdk.ValAddress(valAddr)) 44 | 45 | return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 46 | }, 47 | } 48 | 49 | flags.AddTxFlagsToCmd(cmd) 50 | 51 | return cmd 52 | } 53 | -------------------------------------------------------------------------------- /x/slashing/client/testutil/cli_test.go: -------------------------------------------------------------------------------- 1 | //go:build norace 2 | // +build norace 3 | 4 | package testutil 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/iqlusioninc/liquidity-staking-module/testutil/network" 10 | 11 | "github.com/stretchr/testify/suite" 12 | ) 13 | 14 | func TestIntegrationTestSuite(t *testing.T) { 15 | cfg := network.DefaultConfig() 16 | cfg.NumValidators = 1 17 | suite.Run(t, NewIntegrationTestSuite(cfg)) 18 | } 19 | -------------------------------------------------------------------------------- /x/slashing/init_test.go: -------------------------------------------------------------------------------- 1 | package slashing_test 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | // The default power validators are initialized to have within tests 8 | var InitTokens = sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) 9 | -------------------------------------------------------------------------------- /x/slashing/keeper/common_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import sdk "github.com/cosmos/cosmos-sdk/types" 4 | 5 | // The default power validators are initialized to have within tests 6 | var InitTokens = sdk.TokensFromConsensusPower(200, sdk.DefaultPowerReduction) 7 | -------------------------------------------------------------------------------- /x/slashing/keeper/migrations.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | // Migrator is a struct for handling in-place store migrations. 8 | type Migrator struct { 9 | keeper Keeper 10 | } 11 | 12 | // NewMigrator returns a new Migrator. 13 | func NewMigrator(keeper Keeper) Migrator { 14 | return Migrator{keeper: keeper} 15 | } 16 | 17 | // Migrate1to2 migrates from version 1 to 2. 18 | func (m Migrator) Migrate1to2(_ sdk.Context) error { 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /x/slashing/keeper/msg_server.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "context" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 8 | ) 9 | 10 | type msgServer struct { 11 | Keeper 12 | } 13 | 14 | // NewMsgServerImpl returns an implementation of the slashing MsgServer interface 15 | // for the provided Keeper. 16 | func NewMsgServerImpl(keeper Keeper) types.MsgServer { 17 | return &msgServer{Keeper: keeper} 18 | } 19 | 20 | var _ types.MsgServer = msgServer{} 21 | 22 | // Unjail implements MsgServer.Unjail method. 23 | // Validators must submit a transaction to unjail itself after 24 | // having been jailed (and thus unbonded) for downtime 25 | func (k msgServer) Unjail(goCtx context.Context, msg *types.MsgUnjail) (*types.MsgUnjailResponse, error) { 26 | ctx := sdk.UnwrapSDKContext(goCtx) 27 | 28 | valAddr, valErr := sdk.ValAddressFromBech32(msg.ValidatorAddr) 29 | if valErr != nil { 30 | return nil, valErr 31 | } 32 | err := k.Keeper.Unjail(ctx, valAddr) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | ctx.EventManager().EmitEvent( 38 | sdk.NewEvent( 39 | sdk.EventTypeMessage, 40 | sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), 41 | sdk.NewAttribute(sdk.AttributeKeySender, msg.ValidatorAddr), 42 | ), 43 | ) 44 | 45 | return &types.MsgUnjailResponse{}, nil 46 | } 47 | -------------------------------------------------------------------------------- /x/slashing/keeper/params.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | "time" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 8 | ) 9 | 10 | // SignedBlocksWindow - sliding window for downtime slashing 11 | func (k Keeper) SignedBlocksWindow(ctx sdk.Context) (res int64) { 12 | k.paramspace.Get(ctx, types.KeySignedBlocksWindow, &res) 13 | return 14 | } 15 | 16 | // MinSignedPerWindow - minimum blocks signed per window 17 | func (k Keeper) MinSignedPerWindow(ctx sdk.Context) int64 { 18 | var minSignedPerWindow sdk.Dec 19 | k.paramspace.Get(ctx, types.KeyMinSignedPerWindow, &minSignedPerWindow) 20 | signedBlocksWindow := k.SignedBlocksWindow(ctx) 21 | 22 | // NOTE: RoundInt64 will never panic as minSignedPerWindow is 23 | // less than 1. 24 | return minSignedPerWindow.MulInt64(signedBlocksWindow).RoundInt64() 25 | } 26 | 27 | // DowntimeJailDuration - Downtime unbond duration 28 | func (k Keeper) DowntimeJailDuration(ctx sdk.Context) (res time.Duration) { 29 | k.paramspace.Get(ctx, types.KeyDowntimeJailDuration, &res) 30 | return 31 | } 32 | 33 | // SlashFractionDoubleSign - fraction of power slashed in case of double sign 34 | func (k Keeper) SlashFractionDoubleSign(ctx sdk.Context) (res sdk.Dec) { 35 | k.paramspace.Get(ctx, types.KeySlashFractionDoubleSign, &res) 36 | return 37 | } 38 | 39 | // SlashFractionDowntime - fraction of power slashed for downtime 40 | func (k Keeper) SlashFractionDowntime(ctx sdk.Context) (res sdk.Dec) { 41 | k.paramspace.Get(ctx, types.KeySlashFractionDowntime, &res) 42 | return 43 | } 44 | 45 | // GetParams returns the total set of slashing parameters. 46 | func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { 47 | k.paramspace.GetParamSet(ctx, ¶ms) 48 | return params 49 | } 50 | 51 | // SetParams sets the slashing parameters to the param space. 52 | func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { 53 | k.paramspace.SetParamSet(ctx, ¶ms) 54 | } 55 | -------------------------------------------------------------------------------- /x/slashing/keeper/querier_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | abci "github.com/tendermint/tendermint/abci/types" 9 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 10 | 11 | "github.com/cosmos/cosmos-sdk/codec" 12 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 13 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/keeper" 14 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/testslashing" 15 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 16 | ) 17 | 18 | func TestNewQuerier(t *testing.T) { 19 | app := simapp.Setup(t, false) 20 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 21 | app.SlashingKeeper.SetParams(ctx, testslashing.TestParams()) 22 | legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino()) 23 | querier := keeper.NewQuerier(app.SlashingKeeper, legacyQuerierCdc.LegacyAmino) 24 | 25 | query := abci.RequestQuery{ 26 | Path: "", 27 | Data: []byte{}, 28 | } 29 | 30 | _, err := querier(ctx, []string{types.QueryParameters}, query) 31 | require.NoError(t, err) 32 | } 33 | 34 | func TestQueryParams(t *testing.T) { 35 | cdc := codec.NewLegacyAmino() 36 | legacyQuerierCdc := codec.NewAminoCodec(cdc) 37 | app := simapp.Setup(t, false) 38 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 39 | app.SlashingKeeper.SetParams(ctx, testslashing.TestParams()) 40 | 41 | querier := keeper.NewQuerier(app.SlashingKeeper, legacyQuerierCdc.LegacyAmino) 42 | 43 | query := abci.RequestQuery{ 44 | Path: "", 45 | Data: []byte{}, 46 | } 47 | 48 | var params types.Params 49 | 50 | res, err := querier(ctx, []string{types.QueryParameters}, query) 51 | require.NoError(t, err) 52 | 53 | err = cdc.UnmarshalJSON(res, ¶ms) 54 | require.NoError(t, err) 55 | require.Equal(t, app.SlashingKeeper.GetParams(ctx), params) 56 | } 57 | -------------------------------------------------------------------------------- /x/slashing/keeper/unjail.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | sdkslashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" 6 | ) 7 | 8 | // Unjail calls the staking Unjail function to unjail a validator if the 9 | // jailed period has concluded 10 | func (k Keeper) Unjail(ctx sdk.Context, validatorAddr sdk.ValAddress) error { 11 | validator := k.sk.Validator(ctx, validatorAddr) 12 | if validator == nil { 13 | return sdkslashingtypes.ErrNoValidatorForAddress 14 | } 15 | 16 | // cannot be unjailed if no self-delegation exists 17 | selfDel := k.sk.Delegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) 18 | if selfDel == nil { 19 | return sdkslashingtypes.ErrMissingSelfDelegation 20 | } 21 | 22 | // cannot be unjailed if not jailed 23 | if !validator.IsJailed() { 24 | return sdkslashingtypes.ErrValidatorNotJailed 25 | } 26 | 27 | consAddr, err := validator.GetConsAddr() 28 | if err != nil { 29 | return err 30 | } 31 | // If the validator has a ValidatorSigningInfo object that signals that the 32 | // validator was bonded and so we must check that the validator is not tombstoned 33 | // and can be unjailed at the current block. 34 | // 35 | // A validator that is jailed but has no ValidatorSigningInfo object signals 36 | // that the validator was never bonded and must've been jailed due to falling 37 | // below their minimum self-delegation. The validator can unjail at any point 38 | // assuming they've now bonded above their minimum self-delegation. 39 | info, found := k.GetValidatorSigningInfo(ctx, consAddr) 40 | if found { 41 | // cannot be unjailed if tombstoned 42 | if info.Tombstoned { 43 | return sdkslashingtypes.ErrValidatorJailed 44 | } 45 | 46 | // cannot be unjailed until out of jail 47 | if ctx.BlockHeader().Time.Before(info.JailedUntil) { 48 | return sdkslashingtypes.ErrValidatorJailed 49 | } 50 | } 51 | 52 | k.sk.Unjail(ctx, consAddr) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /x/slashing/simulation/decoder.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | 7 | gogotypes "github.com/gogo/protobuf/types" 8 | 9 | "github.com/cosmos/cosmos-sdk/codec" 10 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 11 | "github.com/cosmos/cosmos-sdk/types/kv" 12 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 13 | ) 14 | 15 | // NewDecodeStore returns a decoder function closure that unmarshals the KVPair's 16 | // Value to the corresponding slashing type. 17 | func NewDecodeStore(cdc codec.BinaryCodec) func(kvA, kvB kv.Pair) string { 18 | return func(kvA, kvB kv.Pair) string { 19 | switch { 20 | case bytes.Equal(kvA.Key[:1], types.ValidatorSigningInfoKeyPrefix): 21 | var infoA, infoB types.ValidatorSigningInfo 22 | cdc.MustUnmarshal(kvA.Value, &infoA) 23 | cdc.MustUnmarshal(kvB.Value, &infoB) 24 | return fmt.Sprintf("%v\n%v", infoA, infoB) 25 | 26 | case bytes.Equal(kvA.Key[:1], types.ValidatorMissedBlockBitArrayKeyPrefix): 27 | var missedA, missedB gogotypes.BoolValue 28 | cdc.MustUnmarshal(kvA.Value, &missedA) 29 | cdc.MustUnmarshal(kvB.Value, &missedB) 30 | return fmt.Sprintf("missedA: %v\nmissedB: %v", missedA.Value, missedB.Value) 31 | 32 | case bytes.Equal(kvA.Key[:1], types.AddrPubkeyRelationKeyPrefix): 33 | var pubKeyA, pubKeyB cryptotypes.PubKey 34 | if err := cdc.UnmarshalInterface(kvA.Value, &pubKeyA); err != nil { 35 | panic(fmt.Sprint("Can't unmarshal kvA; ", err)) 36 | } 37 | if err := cdc.UnmarshalInterface(kvB.Value, &pubKeyB); err != nil { 38 | panic(fmt.Sprint("Can't unmarshal kvB; ", err)) 39 | } 40 | return fmt.Sprintf("PubKeyA: %s\nPubKeyB: %s", pubKeyA, pubKeyB) 41 | 42 | default: 43 | panic(fmt.Sprintf("invalid slashing key prefix %X", kvA.Key[:1])) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /x/slashing/simulation/decoder_test.go: -------------------------------------------------------------------------------- 1 | package simulation_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | gogotypes "github.com/gogo/protobuf/types" 9 | "github.com/stretchr/testify/require" 10 | 11 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 12 | sdk "github.com/cosmos/cosmos-sdk/types" 13 | "github.com/cosmos/cosmos-sdk/types/kv" 14 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 15 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/simulation" 16 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 17 | ) 18 | 19 | //nolint:deadcode,unused,varcheck 20 | var ( 21 | delPk1 = ed25519.GenPrivKey().PubKey() 22 | delAddr1 = sdk.AccAddress(delPk1.Address()) 23 | valAddr1 = sdk.ValAddress(delPk1.Address()) 24 | consAddr1 = sdk.ConsAddress(delPk1.Address().Bytes()) 25 | ) 26 | 27 | func TestDecodeStore(t *testing.T) { 28 | cdc := simapp.MakeTestEncodingConfig().Marshaler 29 | dec := simulation.NewDecodeStore(cdc) 30 | 31 | info := types.NewValidatorSigningInfo(consAddr1, 0, 1, time.Now().UTC(), false, 0) 32 | missed := gogotypes.BoolValue{Value: true} 33 | bz, err := cdc.MarshalInterface(delPk1) 34 | require.NoError(t, err) 35 | 36 | kvPairs := kv.Pairs{ 37 | Pairs: []kv.Pair{ 38 | {Key: types.ValidatorSigningInfoKey(consAddr1), Value: cdc.MustMarshal(&info)}, 39 | {Key: types.ValidatorMissedBlockBitArrayKey(consAddr1, 6), Value: cdc.MustMarshal(&missed)}, 40 | {Key: types.AddrPubkeyRelationKey(delAddr1), Value: bz}, 41 | {Key: []byte{0x99}, Value: []byte{0x99}}, // This test should panic 42 | }, 43 | } 44 | 45 | tests := []struct { 46 | name string 47 | expectedLog string 48 | panics bool 49 | }{ 50 | {"ValidatorSigningInfo", fmt.Sprintf("%v\n%v", info, info), false}, 51 | {"ValidatorMissedBlockBitArray", fmt.Sprintf("missedA: %v\nmissedB: %v", missed.Value, missed.Value), false}, 52 | {"AddrPubkeyRelation", fmt.Sprintf("PubKeyA: %s\nPubKeyB: %s", delPk1, delPk1), false}, 53 | {"other", "", true}, 54 | } 55 | for i, tt := range tests { 56 | i, tt := i, tt 57 | t.Run(tt.name, func(t *testing.T) { 58 | if tt.panics { 59 | require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) 60 | } else { 61 | require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name) 62 | } 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /x/slashing/simulation/params.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | // DONTCOVER 4 | 5 | import ( 6 | "fmt" 7 | "math/rand" 8 | 9 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 10 | "github.com/cosmos/cosmos-sdk/x/simulation" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 12 | ) 13 | 14 | const ( 15 | keySignedBlocksWindow = "SignedBlocksWindow" 16 | keyMinSignedPerWindow = "MinSignedPerWindow" 17 | keySlashFractionDowntime = "SlashFractionDowntime" 18 | ) 19 | 20 | // ParamChanges defines the parameters that can be modified by param change proposals 21 | // on the simulation 22 | func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { 23 | return []simtypes.ParamChange{ 24 | simulation.NewSimParamChange(types.ModuleName, keySignedBlocksWindow, 25 | func(r *rand.Rand) string { 26 | return fmt.Sprintf("\"%d\"", GenSignedBlocksWindow(r)) 27 | }, 28 | ), 29 | simulation.NewSimParamChange(types.ModuleName, keyMinSignedPerWindow, 30 | func(r *rand.Rand) string { 31 | return fmt.Sprintf("\"%s\"", GenMinSignedPerWindow(r)) 32 | }, 33 | ), 34 | simulation.NewSimParamChange(types.ModuleName, keySlashFractionDowntime, 35 | func(r *rand.Rand) string { 36 | return fmt.Sprintf("\"%s\"", GenSlashFractionDowntime(r)) 37 | }, 38 | ), 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /x/slashing/simulation/params_test.go: -------------------------------------------------------------------------------- 1 | package simulation_test 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | 9 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/simulation" 10 | ) 11 | 12 | func TestParamChanges(t *testing.T) { 13 | s := rand.NewSource(1) 14 | r := rand.New(s) 15 | 16 | expected := []struct { 17 | composedKey string 18 | key string 19 | simValue string 20 | subspace string 21 | }{ 22 | {"slashing/SignedBlocksWindow", "SignedBlocksWindow", "\"231\"", "slashing"}, 23 | {"slashing/MinSignedPerWindow", "MinSignedPerWindow", "\"0.700000000000000000\"", "slashing"}, 24 | {"slashing/SlashFractionDowntime", "SlashFractionDowntime", "\"0.020833333333333333\"", "slashing"}, 25 | } 26 | 27 | paramChanges := simulation.ParamChanges(r) 28 | 29 | require.Len(t, paramChanges, 3) 30 | 31 | for i, p := range paramChanges { 32 | require.Equal(t, expected[i].composedKey, p.ComposedKey()) 33 | require.Equal(t, expected[i].key, p.Key()) 34 | require.Equal(t, expected[i].simValue, p.SimValue()(r)) 35 | require.Equal(t, expected[i].subspace, p.Subspace()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /x/slashing/spec/03_messages.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Messages 6 | 7 | In this section we describe the processing of messages for the `slashing` module. 8 | 9 | ## Unjail 10 | 11 | If a validator was automatically unbonded due to downtime and wishes to come back online & 12 | possibly rejoin the bonded set, it must send `MsgUnjail`: 13 | 14 | ```protobuf 15 | // MsgUnjail is an sdk.Msg used for unjailing a jailed validator, thus returning 16 | // them into the bonded validator set, so they can begin receiving provisions 17 | // and rewards again. 18 | message MsgUnjail { 19 | string validator_addr = 1; 20 | } 21 | ``` 22 | 23 | Below is a pseudocode of the `MsgSrv/Unjail` RPC: 24 | 25 | ```go 26 | unjail(tx MsgUnjail) 27 | validator = getValidator(tx.ValidatorAddr) 28 | if validator == nil 29 | fail with "No validator found" 30 | 31 | if getSelfDelegation(validator) == 0 32 | fail with "validator must self delegate before unjailing" 33 | 34 | if !validator.Jailed 35 | fail with "Validator not jailed, cannot unjail" 36 | 37 | info = GetValidatorSigningInfo(operator) 38 | if info.Tombstoned 39 | fail with "Tombstoned validator cannot be unjailed" 40 | if block time < info.JailedUntil 41 | fail with "Validator still jailed, cannot unjail until period has expired" 42 | 43 | validator.Jailed = false 44 | setValidator(validator) 45 | 46 | return 47 | ``` 48 | 49 | If the validator has enough stake to be in the top `n = MaximumBondedValidators`, it will be automatically rebonded, 50 | and all delegators still delegated to the validator will be rebonded and begin to again collect 51 | provisions and rewards. 52 | -------------------------------------------------------------------------------- /x/slashing/spec/05_hooks.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Hooks 6 | 7 | This section contains a description of the module's `hooks`. Hooks are operations that are executed automatically when events are raised. 8 | 9 | ## Staking hooks 10 | 11 | The slashing module implements the `StakingHooks` defined in `x/staking` and are used as record-keeping of validators information. During the app initialization, these hooks should be registered in the staking module struct. 12 | 13 | The following hooks impact the slashing state: 14 | 15 | * `AfterValidatorBonded` creates a `ValidatorSigningInfo` instance as described in the following section. 16 | * `AfterValidatorCreated` stores a validator's consensus key. 17 | * `AfterValidatorRemoved` removes a validator's consensus key. 18 | 19 | ## Validator Bonded 20 | 21 | Upon successful first-time bonding of a new validator, we create a new `ValidatorSigningInfo` structure for the 22 | now-bonded validator, which `StartHeight` of the current block. 23 | 24 | ```go 25 | onValidatorBonded(address sdk.ValAddress) 26 | 27 | signingInfo, found = GetValidatorSigningInfo(address) 28 | if !found { 29 | signingInfo = ValidatorSigningInfo { 30 | StartHeight : CurrentHeight, 31 | IndexOffset : 0, 32 | JailedUntil : time.Unix(0, 0), 33 | Tombstone : false, 34 | MissedBloskCounter : 0 35 | } 36 | setValidatorSigningInfo(signingInfo) 37 | } 38 | 39 | return 40 | ``` 41 | -------------------------------------------------------------------------------- /x/slashing/spec/06_events.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Events 6 | 7 | The slashing module emits the following events: 8 | 9 | ## MsgServer 10 | 11 | ### MsgUnjail 12 | 13 | | Type | Attribute Key | Attribute Value | 14 | | ------- | ------------- | ------------------ | 15 | | message | module | slashing | 16 | | message | sender | {validatorAddress} | 17 | 18 | ## Keeper 19 | 20 | ## BeginBlocker: HandleValidatorSignature 21 | 22 | | Type | Attribute Key | Attribute Value | 23 | | ----- | ------------- | --------------------------- | 24 | | slash | address | {validatorConsensusAddress} | 25 | | slash | power | {validatorPower} | 26 | | slash | reason | {slashReason} | 27 | | slash | jailed [0] | {validatorConsensusAddress} | 28 | | slash | burned coins | {sdk.Int} | 29 | 30 | * [0] Only included if the validator is jailed. 31 | 32 | | Type | Attribute Key | Attribute Value | 33 | | -------- | ------------- | --------------------------- | 34 | | liveness | address | {validatorConsensusAddress} | 35 | | liveness | missed_blocks | {missedBlocksCounter} | 36 | | liveness | height | {blockHeight} | 37 | 38 | ### Slash 39 | 40 | * same as `"slash"` event from `HandleValidatorSignature`, but without the `jailed` attribute. 41 | 42 | ### Jail 43 | 44 | | Type | Attribute Key | Attribute Value | 45 | | ----- | ------------- | ------------------ | 46 | | slash | jailed | {validatorAddress} | 47 | -------------------------------------------------------------------------------- /x/slashing/spec/08_params.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Parameters 6 | 7 | The slashing module contains the following parameters: 8 | 9 | | Key | Type | Example | 10 | | ----------------------- | -------------- | ---------------------- | 11 | | SignedBlocksWindow | string (int64) | "100" | 12 | | MinSignedPerWindow | string (dec) | "0.500000000000000000" | 13 | | DowntimeJailDuration | string (ns) | "600000000000" | 14 | | SlashFractionDoubleSign | string (dec) | "0.050000000000000000" | 15 | | SlashFractionDowntime | string (dec) | "0.010000000000000000" | 16 | -------------------------------------------------------------------------------- /x/slashing/spec/README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | # `x/slashing` 9 | 10 | ## Abstract 11 | 12 | This section specifies the slashing module of the Cosmos SDK, which implements functionality 13 | first outlined in the [Cosmos Whitepaper](https://cosmos.network/about/whitepaper) in June 2016. 14 | 15 | The slashing module enables Cosmos SDK-based blockchains to disincentivize any attributable action 16 | by a protocol-recognized actor with value at stake by penalizing them ("slashing"). 17 | 18 | Penalties may include, but are not limited to: 19 | 20 | * Burning some amount of their stake 21 | * Removing their ability to vote on future blocks for a period of time. 22 | 23 | This module will be used by the Cosmos Hub, the first hub in the Cosmos ecosystem. 24 | 25 | ## Contents 26 | 27 | 1. **[Concepts](01_concepts.md)** 28 | * [States](01_concepts.md#states) 29 | * [Tombstone Caps](01_concepts.md#tombstone-caps) 30 | * [ASCII timelines](01_concepts.md#ascii-timelines) 31 | 2. **[State](02_state.md)** 32 | * [Signing Info](02_state.md#signing-info) 33 | 3. **[Messages](03_messages.md)** 34 | * [Unjail](03_messages.md#unjail) 35 | 4. **[Begin-Block](04_begin_block.md)** 36 | * [Evidence handling](04_begin_block.md#evidence-handling) 37 | * [Uptime tracking](04_begin_block.md#uptime-tracking) 38 | 5. **[05_hooks.md](05_hooks.md)** 39 | * [Hooks](05_hooks.md#hooks) 40 | 6. **[Events](06_events.md)** 41 | * [BeginBlocker](06_events.md#beginblocker) 42 | * [Handlers](06_events.md#handlers) 43 | 7. **[Staking Tombstone](07_tombstone.md)** 44 | * [Abstract](07_tombstone.md#abstract) 45 | 8. **[Parameters](08_params.md)** 46 | 9. **[Client](09_client.md)** 47 | * [CLI](09_client.md#cli) 48 | * [gRPC](09_client.md#grpc) 49 | * [REST](09_client.md#rest) 50 | -------------------------------------------------------------------------------- /x/slashing/testslashing/params.go: -------------------------------------------------------------------------------- 1 | package testslashing 2 | 3 | import ( 4 | "github.com/iqlusioninc/liquidity-staking-module/x/slashing/types" 5 | ) 6 | 7 | // TestParams construct default slashing params for tests. 8 | // Have to change these parameters for tests 9 | // lest the tests take forever 10 | func TestParams() types.Params { 11 | params := types.DefaultParams() 12 | params.SignedBlocksWindow = 1000 13 | params.DowntimeJailDuration = 60 * 60 14 | 15 | return params 16 | } 17 | -------------------------------------------------------------------------------- /x/slashing/types/codec.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/codec" 5 | "github.com/cosmos/cosmos-sdk/codec/legacy" 6 | "github.com/cosmos/cosmos-sdk/codec/types" 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/cosmos/cosmos-sdk/types/msgservice" 9 | ) 10 | 11 | // RegisterLegacyAminoCodec registers concrete types on LegacyAmino codec 12 | func RegisterLegacyAminoCodec(_ *codec.LegacyAmino) { 13 | // cdc.RegisterConcrete(&MsgUnjail{}, "cosmos-sdk/MsgUnjail", nil) 14 | } 15 | 16 | func RegisterInterfaces(registry types.InterfaceRegistry) { 17 | registry.RegisterImplementations((*sdk.Msg)(nil), 18 | &MsgUnjail{}, 19 | ) 20 | 21 | msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) 22 | } 23 | 24 | func init() { 25 | RegisterLegacyAminoCodec(legacy.Cdc) 26 | } 27 | -------------------------------------------------------------------------------- /x/slashing/types/errors.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // import ( 4 | // sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 5 | // ) 6 | 7 | // // x/slashing module sentinel errors 8 | // var ( 9 | // ErrNoValidatorForAddress = sdkerrors.Register(ModuleName, 2, "address is not associated with any known validator") 10 | // ErrBadValidatorAddr = sdkerrors.Register(ModuleName, 3, "validator does not exist for that address") 11 | // ErrValidatorJailed = sdkerrors.Register(ModuleName, 4, "validator still jailed; cannot be unjailed") 12 | // ErrValidatorNotJailed = sdkerrors.Register(ModuleName, 5, "validator not jailed; cannot be unjailed") 13 | // ErrMissingSelfDelegation = sdkerrors.Register(ModuleName, 6, "validator has no self-delegation; cannot be unjailed") 14 | // ErrSelfDelegationTooLowToUnjail = sdkerrors.Register(ModuleName, 7, "validator's self delegation less than minimum; cannot be unjailed") 15 | // ErrNoSigningInfoFound = sdkerrors.Register(ModuleName, 8, "no validator signing info found") 16 | // ) 17 | -------------------------------------------------------------------------------- /x/slashing/types/events.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // Slashing module event types 4 | const ( 5 | EventTypeSlash = "slash" 6 | EventTypeLiveness = "liveness" 7 | 8 | AttributeKeyAddress = "address" 9 | AttributeKeyHeight = "height" 10 | AttributeKeyPower = "power" 11 | AttributeKeyReason = "reason" 12 | AttributeKeyJailed = "jailed" 13 | AttributeKeyMissedBlocks = "missed_blocks" 14 | AttributeKeyBurnedCoins = "burned_coins" 15 | 16 | AttributeValueDoubleSign = "double_sign" 17 | AttributeValueMissingSignature = "missing_signature" 18 | AttributeValueCategory = ModuleName 19 | ) 20 | -------------------------------------------------------------------------------- /x/slashing/types/genesis.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | ) 9 | 10 | // NewGenesisState creates a new GenesisState object 11 | func NewGenesisState( 12 | params Params, signingInfos []SigningInfo, missedBlocks []ValidatorMissedBlocks, 13 | ) *GenesisState { 14 | return &GenesisState{ 15 | Params: params, 16 | SigningInfos: signingInfos, 17 | MissedBlocks: missedBlocks, 18 | } 19 | } 20 | 21 | // NewMissedBlock creates a new MissedBlock instance 22 | func NewMissedBlock(index int64, missed bool) MissedBlock { 23 | return MissedBlock{ 24 | Index: index, 25 | Missed: missed, 26 | } 27 | } 28 | 29 | // DefaultGenesisState - default GenesisState used by Cosmos Hub 30 | func DefaultGenesisState() *GenesisState { 31 | return &GenesisState{ 32 | Params: DefaultParams(), 33 | SigningInfos: []SigningInfo{}, 34 | MissedBlocks: []ValidatorMissedBlocks{}, 35 | } 36 | } 37 | 38 | // ValidateGenesis validates the slashing genesis parameters 39 | func ValidateGenesis(data GenesisState) error { 40 | downtime := data.Params.SlashFractionDowntime 41 | if downtime.IsNegative() || downtime.GT(sdk.OneDec()) { 42 | return fmt.Errorf("slashing fraction downtime should be less than or equal to one and greater than zero, is %s", downtime.String()) 43 | } 44 | 45 | dblSign := data.Params.SlashFractionDoubleSign 46 | if dblSign.IsNegative() || dblSign.GT(sdk.OneDec()) { 47 | return fmt.Errorf("slashing fraction double sign should be less than or equal to one and greater than zero, is %s", dblSign.String()) 48 | } 49 | 50 | minSign := data.Params.MinSignedPerWindow 51 | if minSign.IsNegative() || minSign.GT(sdk.OneDec()) { 52 | return fmt.Errorf("min signed per window should be less than or equal to one and greater than zero, is %s", minSign.String()) 53 | } 54 | 55 | downtimeJail := data.Params.DowntimeJailDuration 56 | if downtimeJail < 1*time.Minute { 57 | return fmt.Errorf("downtime unjail duration must be at least 1 minute, is %s", downtimeJail.String()) 58 | } 59 | 60 | signedWindow := data.Params.SignedBlocksWindow 61 | if signedWindow < 10 { 62 | return fmt.Errorf("signed blocks window must be at least 10, is %d", signedWindow) 63 | } 64 | 65 | return nil 66 | } 67 | -------------------------------------------------------------------------------- /x/slashing/types/msg.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "github.com/cosmos/cosmos-sdk/codec/legacy" 5 | sdk "github.com/cosmos/cosmos-sdk/types" 6 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" 7 | ) 8 | 9 | // slashing message types 10 | const ( 11 | TypeMsgUnjail = "unjail" 12 | ) 13 | 14 | // verify interface at compile time 15 | var _ sdk.Msg = &MsgUnjail{} 16 | 17 | // NewMsgUnjail creates a new MsgUnjail instance 18 | // 19 | //nolint:interfacer 20 | func NewMsgUnjail(validatorAddr sdk.ValAddress) *MsgUnjail { 21 | return &MsgUnjail{ 22 | ValidatorAddr: validatorAddr.String(), 23 | } 24 | } 25 | 26 | func (msg MsgUnjail) Route() string { return RouterKey } 27 | func (msg MsgUnjail) Type() string { return TypeMsgUnjail } 28 | func (msg MsgUnjail) GetSigners() []sdk.AccAddress { 29 | valAddr, _ := sdk.ValAddressFromBech32(msg.ValidatorAddr) 30 | return []sdk.AccAddress{sdk.AccAddress(valAddr)} 31 | } 32 | 33 | // GetSignBytes gets the bytes for the message signer to sign on 34 | func (msg MsgUnjail) GetSignBytes() []byte { 35 | bz := legacy.Cdc.MustMarshalJSON(&msg) 36 | return sdk.MustSortJSON(bz) 37 | } 38 | 39 | // ValidateBasic validity check for the AnteHandler 40 | func (msg MsgUnjail) ValidateBasic() error { 41 | if _, err := sdk.ValAddressFromBech32(msg.ValidatorAddr); err != nil { 42 | return sdkerrors.ErrInvalidAddress.Wrapf("validator input address: %s", err) 43 | } 44 | return nil 45 | } 46 | -------------------------------------------------------------------------------- /x/slashing/types/msg_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | sdkslashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" 10 | ) 11 | 12 | func TestMsgUnjailGetSignBytes(t *testing.T) { 13 | addr := sdk.AccAddress("abcd") 14 | msg := sdkslashingtypes.NewMsgUnjail(sdk.ValAddress(addr)) 15 | bytes := msg.GetSignBytes() 16 | require.Equal( 17 | t, 18 | `{"type":"cosmos-sdk/MsgUnjail","value":{"address":"cosmosvaloper1v93xxeqhg9nn6"}}`, 19 | string(bytes), 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /x/slashing/types/querier.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // DONTCOVER 4 | 5 | // Query endpoints supported by the slashing querier 6 | const ( 7 | QueryParameters = "parameters" 8 | QuerySigningInfo = "signingInfo" 9 | QuerySigningInfos = "signingInfos" 10 | ) 11 | 12 | // QuerySigningInfosParams defines the params for the following queries: 13 | // - 'custom/slashing/signingInfos' 14 | type QuerySigningInfosParams struct { 15 | Page, Limit int 16 | } 17 | 18 | // NewQuerySigningInfosParams creates a new QuerySigningInfosParams instance 19 | func NewQuerySigningInfosParams(page, limit int) QuerySigningInfosParams { 20 | return QuerySigningInfosParams{page, limit} 21 | } 22 | -------------------------------------------------------------------------------- /x/slashing/types/signing_info.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/cosmos/cosmos-sdk/codec" 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | ) 10 | 11 | // NewValidatorSigningInfo creates a new ValidatorSigningInfo instance 12 | // 13 | //nolint:interfacer 14 | func NewValidatorSigningInfo( 15 | condAddr sdk.ConsAddress, startHeight, indexOffset int64, 16 | jailedUntil time.Time, tombstoned bool, missedBlocksCounter int64, 17 | ) ValidatorSigningInfo { 18 | return ValidatorSigningInfo{ 19 | Address: condAddr.String(), 20 | StartHeight: startHeight, 21 | IndexOffset: indexOffset, 22 | JailedUntil: jailedUntil, 23 | Tombstoned: tombstoned, 24 | MissedBlocksCounter: missedBlocksCounter, 25 | } 26 | } 27 | 28 | // String implements the stringer interface for ValidatorSigningInfo 29 | func (i ValidatorSigningInfo) String() string { 30 | return fmt.Sprintf(`Validator Signing Info: 31 | Address: %s 32 | Start Height: %d 33 | Index Offset: %d 34 | Jailed Until: %v 35 | Tombstoned: %t 36 | Missed Blocks Counter: %d`, 37 | i.Address, i.StartHeight, i.IndexOffset, i.JailedUntil, 38 | i.Tombstoned, i.MissedBlocksCounter) 39 | } 40 | 41 | // unmarshal a validator signing info from a store value 42 | func UnmarshalValSigningInfo(cdc codec.Codec, value []byte) (signingInfo ValidatorSigningInfo, err error) { 43 | err = cdc.Unmarshal(value, &signingInfo) 44 | return signingInfo, err 45 | } 46 | -------------------------------------------------------------------------------- /x/staking/README.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Staking 6 | 7 | * [Staking](spec/README.md) - Proof-of-Stake layer for public blockchains. 8 | -------------------------------------------------------------------------------- /x/staking/abci.go: -------------------------------------------------------------------------------- 1 | package staking 2 | 3 | import ( 4 | "time" 5 | 6 | abci "github.com/tendermint/tendermint/abci/types" 7 | 8 | "github.com/cosmos/cosmos-sdk/telemetry" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/keeper" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 12 | ) 13 | 14 | // BeginBlocker will persist the current header and validator set as a historical entry 15 | // and prune the oldest entry based on the HistoricalEntries parameter 16 | func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { 17 | defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) 18 | 19 | k.TrackHistoricalInfo(ctx) 20 | k.RemoveExpiredTokenizeShareLocks(ctx, ctx.BlockTime()) 21 | } 22 | 23 | // Called every block, update validator set 24 | func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate { 25 | defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) 26 | 27 | return k.BlockValidatorUpdates(ctx) 28 | } 29 | -------------------------------------------------------------------------------- /x/staking/bench_test.go: -------------------------------------------------------------------------------- 1 | package staking_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/iqlusioninc/liquidity-staking-module/x/staking" 9 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/teststaking" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 11 | ) 12 | 13 | func BenchmarkValidateGenesis10Validators(b *testing.B) { 14 | benchmarkValidateGenesis(b, 10) 15 | } 16 | 17 | func BenchmarkValidateGenesis100Validators(b *testing.B) { 18 | benchmarkValidateGenesis(b, 100) 19 | } 20 | 21 | func BenchmarkValidateGenesis400Validators(b *testing.B) { 22 | benchmarkValidateGenesis(b, 400) 23 | } 24 | 25 | func benchmarkValidateGenesis(b *testing.B, n int) { 26 | b.ReportAllocs() 27 | 28 | validators := make([]types.Validator, 0, n) 29 | addressL, pubKeyL := makeRandomAddressesAndPublicKeys(n) 30 | for i := 0; i < n; i++ { 31 | addr, pubKey := addressL[i], pubKeyL[i] 32 | validator := teststaking.NewValidator(b, addr, pubKey) 33 | ni := int64(i + 1) 34 | validator.Tokens = sdk.NewInt(ni) 35 | validator.DelegatorShares = sdk.NewDec(ni) 36 | validators = append(validators, validator) 37 | } 38 | 39 | b.ResetTimer() 40 | for i := 0; i < b.N; i++ { 41 | genesisState := types.DefaultGenesisState() 42 | genesisState.Validators = validators 43 | if err := staking.ValidateGenesis(genesisState); err != nil { 44 | b.Fatal(err) 45 | } 46 | } 47 | } 48 | 49 | func makeRandomAddressesAndPublicKeys(n int) (accL []sdk.ValAddress, pkL []*ed25519.PubKey) { 50 | for i := 0; i < n; i++ { 51 | pk := ed25519.GenPrivKey().PubKey().(*ed25519.PubKey) 52 | pkL = append(pkL, pk) 53 | accL = append(accL, sdk.ValAddress(pk.Address())) 54 | } 55 | return accL, pkL 56 | } 57 | -------------------------------------------------------------------------------- /x/staking/client/cli/utils.go: -------------------------------------------------------------------------------- 1 | package cli 2 | 3 | import ( 4 | "errors" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 8 | ) 9 | 10 | func buildCommissionRates(rateStr, maxRateStr, maxChangeRateStr string) (commission types.CommissionRates, err error) { 11 | if rateStr == "" || maxRateStr == "" || maxChangeRateStr == "" { 12 | return commission, errors.New("must specify all validator commission parameters") 13 | } 14 | 15 | rate, err := sdk.NewDecFromStr(rateStr) 16 | if err != nil { 17 | return commission, err 18 | } 19 | 20 | maxRate, err := sdk.NewDecFromStr(maxRateStr) 21 | if err != nil { 22 | return commission, err 23 | } 24 | 25 | maxChangeRate, err := sdk.NewDecFromStr(maxChangeRateStr) 26 | if err != nil { 27 | return commission, err 28 | } 29 | 30 | commission = types.NewCommissionRates(rate, maxRate, maxChangeRate) 31 | 32 | return commission, nil 33 | } 34 | -------------------------------------------------------------------------------- /x/staking/client/testutil/cli_test.go: -------------------------------------------------------------------------------- 1 | //go:build norace 2 | // +build norace 3 | 4 | package testutil 5 | 6 | import ( 7 | "testing" 8 | 9 | "github.com/iqlusioninc/liquidity-staking-module/testutil/network" 10 | 11 | "github.com/stretchr/testify/suite" 12 | ) 13 | 14 | func TestIntegrationTestSuite(t *testing.T) { 15 | cfg := network.DefaultConfig() 16 | cfg.NumValidators = 2 17 | suite.Run(t, NewIntegrationTestSuite(cfg)) 18 | } 19 | -------------------------------------------------------------------------------- /x/staking/client/testutil/test_helpers.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/cosmos/cosmos-sdk/client" 7 | "github.com/cosmos/cosmos-sdk/client/flags" 8 | "github.com/cosmos/cosmos-sdk/testutil" 9 | clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" 10 | sdk "github.com/cosmos/cosmos-sdk/types" 11 | stakingcli "github.com/iqlusioninc/liquidity-staking-module/x/staking/client/cli" 12 | ) 13 | 14 | var commonArgs = []string{ 15 | fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), 16 | fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), 17 | fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()), 18 | } 19 | 20 | // MsgRedelegateExec creates a redelegate message. 21 | func MsgRedelegateExec(clientCtx client.Context, from, src, dst, amount fmt.Stringer, 22 | extraArgs ...string, 23 | ) (testutil.BufferWriter, error) { 24 | args := []string{ 25 | src.String(), 26 | dst.String(), 27 | amount.String(), 28 | fmt.Sprintf("--%s=%s", flags.FlagFrom, from.String()), 29 | fmt.Sprintf("--%s=%d", flags.FlagGas, 300000), 30 | } 31 | args = append(args, extraArgs...) 32 | 33 | args = append(args, commonArgs...) 34 | return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewRedelegateCmd(), args) 35 | } 36 | 37 | // MsgUnbondExec creates a unbond message. 38 | func MsgUnbondExec(clientCtx client.Context, from fmt.Stringer, valAddress, 39 | amount fmt.Stringer, extraArgs ...string, 40 | ) (testutil.BufferWriter, error) { 41 | args := []string{ 42 | valAddress.String(), 43 | amount.String(), 44 | fmt.Sprintf("--%s=%s", flags.FlagFrom, from.String()), 45 | } 46 | 47 | args = append(args, commonArgs...) 48 | args = append(args, extraArgs...) 49 | return clitestutil.ExecTestCLICmd(clientCtx, stakingcli.NewUnbondCmd(), args) 50 | } 51 | -------------------------------------------------------------------------------- /x/staking/common_test.go: -------------------------------------------------------------------------------- 1 | package staking_test 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 8 | 9 | "github.com/cosmos/cosmos-sdk/codec" 10 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 11 | "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" 12 | sdk "github.com/cosmos/cosmos-sdk/types" 13 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 14 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/keeper" 15 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 16 | ) 17 | 18 | func init() { 19 | sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) 20 | } 21 | 22 | //nolint:deadcode,unused,varcheck 23 | var ( 24 | priv1 = secp256k1.GenPrivKey() 25 | addr1 = sdk.AccAddress(priv1.PubKey().Address()) 26 | priv2 = secp256k1.GenPrivKey() 27 | addr2 = sdk.AccAddress(priv2.PubKey().Address()) 28 | 29 | valKey = ed25519.GenPrivKey() 30 | valAddr = sdk.AccAddress(valKey.PubKey().Address()) 31 | 32 | commissionRates = types.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) 33 | 34 | PKs = simapp.CreateTestPubKeys(500) 35 | ) 36 | 37 | // getBaseSimappWithCustomKeeper Returns a simapp with custom StakingKeeper 38 | // to avoid messing with the hooks. 39 | func getBaseSimappWithCustomKeeper(t *testing.T) (*codec.LegacyAmino, *simapp.SimApp, sdk.Context) { 40 | app := simapp.Setup(t, false) 41 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 42 | 43 | appCodec := app.AppCodec() 44 | 45 | app.StakingKeeper = keeper.NewKeeper( 46 | appCodec, 47 | app.GetKey(types.StoreKey), 48 | app.AccountKeeper, 49 | app.BankKeeper, 50 | app.GetSubspace(types.ModuleName), 51 | ) 52 | app.StakingKeeper.SetParams(ctx, types.DefaultParams()) 53 | 54 | return codec.NewLegacyAmino(), app, ctx 55 | } 56 | 57 | // generateAddresses generates numAddrs of normal AccAddrs and ValAddrs 58 | func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int, accAmount sdk.Int) ([]sdk.AccAddress, []sdk.ValAddress) { 59 | addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, accAmount) 60 | addrVals := simapp.ConvertAddrsToValAddrs(addrDels) 61 | 62 | return addrDels, addrVals 63 | } 64 | -------------------------------------------------------------------------------- /x/staking/genesis_test.go: -------------------------------------------------------------------------------- 1 | package staking_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | 8 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | sdkstaking "github.com/cosmos/cosmos-sdk/x/staking/types" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/staking" 12 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/teststaking" 13 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 14 | ) 15 | 16 | func TestValidateGenesis(t *testing.T) { 17 | genValidators1 := make([]types.Validator, 1, 5) 18 | pk := ed25519.GenPrivKey().PubKey() 19 | genValidators1[0] = teststaking.NewValidator(t, sdk.ValAddress(pk.Address()), pk) 20 | genValidators1[0].Tokens = sdk.OneInt() 21 | genValidators1[0].DelegatorShares = sdk.OneDec() 22 | 23 | tests := []struct { 24 | name string 25 | mutate func(*types.GenesisState) 26 | wantErr bool 27 | }{ 28 | {"default", func(*types.GenesisState) {}, false}, 29 | // validate genesis validators 30 | {"duplicate validator", func(data *types.GenesisState) { 31 | data.Validators = genValidators1 32 | data.Validators = append(data.Validators, genValidators1[0]) 33 | }, true}, 34 | {"no delegator shares", func(data *types.GenesisState) { 35 | data.Validators = genValidators1 36 | data.Validators[0].DelegatorShares = sdk.ZeroDec() 37 | }, true}, 38 | {"jailed and bonded validator", func(data *types.GenesisState) { 39 | data.Validators = genValidators1 40 | data.Validators[0].Jailed = true 41 | data.Validators[0].Status = sdkstaking.Bonded 42 | }, true}, 43 | } 44 | 45 | for _, tt := range tests { 46 | tt := tt 47 | t.Run(tt.name, func(t *testing.T) { 48 | genesisState := types.DefaultGenesisState() 49 | tt.mutate(genesisState) 50 | if tt.wantErr { 51 | assert.Error(t, staking.ValidateGenesis(genesisState)) 52 | } else { 53 | assert.NoError(t, staking.ValidateGenesis(genesisState)) 54 | } 55 | }) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /x/staking/keeper/migrations.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | -------------------------------------------------------------------------------- /x/staking/keeper/power_reduction.go: -------------------------------------------------------------------------------- 1 | package keeper 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | // TokensToConsensusPower - convert input tokens to potential consensus-engine power 8 | func (k Keeper) TokensToConsensusPower(ctx sdk.Context, tokens sdk.Int) int64 { 9 | return sdk.TokensToConsensusPower(tokens, k.PowerReduction(ctx)) 10 | } 11 | 12 | // TokensFromConsensusPower - convert input power to tokens 13 | func (k Keeper) TokensFromConsensusPower(ctx sdk.Context, power int64) sdk.Int { 14 | return sdk.TokensFromConsensusPower(power, k.PowerReduction(ctx)) 15 | } 16 | -------------------------------------------------------------------------------- /x/staking/keeper/power_reduction_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import ( 4 | sdk "github.com/cosmos/cosmos-sdk/types" 5 | ) 6 | 7 | func (suite *KeeperTestSuite) TestTokensToConsensusPower() { 8 | suite.Require().Equal(int64(0), suite.app.StakingKeeper.TokensToConsensusPower(suite.ctx, sdk.DefaultPowerReduction.Sub(sdk.NewInt(1)))) 9 | suite.Require().Equal(int64(1), suite.app.StakingKeeper.TokensToConsensusPower(suite.ctx, sdk.DefaultPowerReduction)) 10 | } 11 | 12 | func (suite *KeeperTestSuite) TestTokensFromConsensusPower() { 13 | suite.Require().Equal(sdk.NewInt(0), suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 0)) 14 | suite.Require().Equal(sdk.DefaultPowerReduction, suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 1)) 15 | } 16 | -------------------------------------------------------------------------------- /x/staking/keeper/test_common.go: -------------------------------------------------------------------------------- 1 | package keeper // noalias 2 | 3 | import ( 4 | "bytes" 5 | "math/rand" 6 | 7 | sdk "github.com/cosmos/cosmos-sdk/types" 8 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 9 | ) 10 | 11 | // does a certain by-power index record exist 12 | func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool { 13 | store := ctx.KVStore(keeper.storeKey) 14 | return store.Has(power) 15 | } 16 | 17 | // update validator for testing 18 | func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator, apply bool) types.Validator { 19 | keeper.SetValidator(ctx, validator) 20 | 21 | // Remove any existing power key for validator. 22 | store := ctx.KVStore(keeper.storeKey) 23 | deleted := false 24 | 25 | iterator := sdk.KVStorePrefixIterator(store, types.ValidatorsByPowerIndexKey) 26 | defer iterator.Close() 27 | 28 | for ; iterator.Valid(); iterator.Next() { 29 | valAddr := types.ParseValidatorPowerRankKey(iterator.Key()) 30 | if bytes.Equal(valAddr, validator.GetOperator()) { 31 | if deleted { 32 | panic("found duplicate power index key") 33 | } else { 34 | deleted = true 35 | } 36 | 37 | store.Delete(iterator.Key()) 38 | } 39 | } 40 | 41 | keeper.SetValidatorByPowerIndex(ctx, validator) 42 | 43 | if !apply { 44 | ctx, _ = ctx.CacheContext() 45 | } 46 | _, err := keeper.ApplyAndReturnValidatorSetUpdates(ctx) 47 | if err != nil { 48 | panic(err) 49 | } 50 | 51 | validator, found := keeper.GetLiquidValidator(ctx, validator.GetOperator()) 52 | if !found { 53 | panic("validator expected but not found") 54 | } 55 | 56 | return validator 57 | } 58 | 59 | // RandomValidator returns a random validator given access to the keeper and ctx 60 | func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) { 61 | vals := keeper.GetAllValidators(ctx) 62 | if len(vals) == 0 { 63 | return types.Validator{}, false 64 | } 65 | 66 | i := r.Intn(len(vals)) 67 | 68 | return vals[i], true 69 | } 70 | -------------------------------------------------------------------------------- /x/staking/keeper/validator_bench_test.go: -------------------------------------------------------------------------------- 1 | package keeper_test 2 | 3 | import "testing" 4 | 5 | func BenchmarkGetLiquidValidator(b *testing.B) { 6 | // 900 is the max number we are allowed to use in order to avoid simapp.CreateTestPubKeys 7 | // panic: encoding/hex: odd length hex string 8 | powersNumber := 900 9 | 10 | totalPower := int64(0) 11 | powers := make([]int64, powersNumber) 12 | for i := range powers { 13 | powers[i] = int64(i) 14 | totalPower += int64(i) 15 | } 16 | 17 | app, ctx, valAddrs, vals := initValidators(b, totalPower, len(powers), powers) 18 | 19 | for _, validator := range vals { 20 | app.StakingKeeper.SetValidator(ctx, validator) 21 | } 22 | 23 | b.ResetTimer() 24 | for n := 0; n < b.N; n++ { 25 | for _, addr := range valAddrs { 26 | _, _ = app.StakingKeeper.GetLiquidValidator(ctx, addr) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /x/staking/module_test.go: -------------------------------------------------------------------------------- 1 | package staking_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | abcitypes "github.com/tendermint/tendermint/abci/types" 8 | tmjson "github.com/tendermint/tendermint/libs/json" 9 | "github.com/tendermint/tendermint/libs/log" 10 | tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 11 | dbm "github.com/tendermint/tm-db" 12 | 13 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" 14 | simapp "github.com/iqlusioninc/liquidity-staking-module/app" 15 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 16 | ) 17 | 18 | func TestItCreatesModuleAccountOnInitBlock(t *testing.T) { 19 | db := dbm.NewMemDB() 20 | encCdc := simapp.MakeTestEncodingConfig() 21 | app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{}) 22 | 23 | genesisState := simapp.GenesisStateWithSingleValidator(t, app) 24 | stateBytes, err := tmjson.Marshal(genesisState) 25 | require.NoError(t, err) 26 | 27 | app.InitChain( 28 | abcitypes.RequestInitChain{ 29 | AppStateBytes: stateBytes, 30 | ChainId: "test-chain-id", 31 | }, 32 | ) 33 | 34 | ctx := app.BaseApp.NewContext(false, tmproto.Header{}) 35 | acc := app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.BondedPoolName)) 36 | require.NotNil(t, acc) 37 | 38 | acc = app.AccountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.NotBondedPoolName)) 39 | require.NotNil(t, acc) 40 | } 41 | -------------------------------------------------------------------------------- /x/staking/simulation/common_test.go: -------------------------------------------------------------------------------- 1 | package simulation_test 2 | 3 | import ( 4 | "math/big" 5 | 6 | sdk "github.com/cosmos/cosmos-sdk/types" 7 | ) 8 | 9 | func init() { 10 | sdk.DefaultPowerReduction = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) 11 | } 12 | -------------------------------------------------------------------------------- /x/staking/simulation/params.go: -------------------------------------------------------------------------------- 1 | package simulation 2 | 3 | // DONTCOVER 4 | 5 | import ( 6 | "fmt" 7 | "math/rand" 8 | 9 | simtypes "github.com/cosmos/cosmos-sdk/types/simulation" 10 | "github.com/cosmos/cosmos-sdk/x/simulation" 11 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 12 | ) 13 | 14 | // ParamChanges defines the parameters that can be modified by param change proposals 15 | // on the simulation 16 | func ParamChanges(_ *rand.Rand) []simtypes.ParamChange { 17 | return []simtypes.ParamChange{ 18 | simulation.NewSimParamChange(types.ModuleName, string(types.KeyMaxValidators), 19 | func(r *rand.Rand) string { 20 | return fmt.Sprintf("%d", genMaxValidators(r)) 21 | }, 22 | ), 23 | simulation.NewSimParamChange(types.ModuleName, string(types.KeyUnbondingTime), 24 | func(r *rand.Rand) string { 25 | return fmt.Sprintf("\"%d\"", genUnbondingTime(r)) 26 | }, 27 | ), 28 | simulation.NewSimParamChange(types.ModuleName, string(types.KeyHistoricalEntries), 29 | func(r *rand.Rand) string { 30 | return fmt.Sprintf("%d", getHistEntries(r)) 31 | }, 32 | ), 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /x/staking/simulation/params_test.go: -------------------------------------------------------------------------------- 1 | package simulation_test 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | 9 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/simulation" 10 | ) 11 | 12 | func TestParamChanges(t *testing.T) { 13 | s := rand.NewSource(1) 14 | r := rand.New(s) 15 | 16 | expected := []struct { 17 | composedKey string 18 | key string 19 | simValue string 20 | subspace string 21 | }{ 22 | {"staking/MaxValidators", "MaxValidators", "82", "staking"}, 23 | {"staking/UnbondingTime", "UnbondingTime", "\"275307000000000\"", "staking"}, 24 | {"staking/HistoricalEntries", "HistoricalEntries", "9149", "staking"}, 25 | } 26 | 27 | paramChanges := simulation.ParamChanges(r) 28 | 29 | require.Len(t, paramChanges, 3) 30 | 31 | for i, p := range paramChanges { 32 | require.Equal(t, expected[i].composedKey, p.ComposedKey()) 33 | require.Equal(t, expected[i].key, p.Key()) 34 | require.Equal(t, expected[i].simValue, p.SimValue()(r)) 35 | require.Equal(t, expected[i].subspace, p.Subspace()) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /x/staking/spec/04_begin_block.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Begin-Block 6 | 7 | Each abci begin block call, the historical info will get stored and pruned 8 | according to the `HistoricalEntries` parameter. 9 | 10 | ## Historical Info Tracking 11 | 12 | If the `HistoricalEntries` parameter is 0, then the `BeginBlock` performs a no-op. 13 | 14 | Otherwise, the latest historical info is stored under the key `historicalInfoKey|height`, while any entries older than `height - HistoricalEntries` is deleted. 15 | In most cases, this results in a single entry being pruned per block. 16 | However, if the parameter `HistoricalEntries` has changed to a lower value there will be multiple entries in the store that must be pruned. 17 | -------------------------------------------------------------------------------- /x/staking/spec/06_hooks.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Hooks 6 | 7 | Other modules may register operations to execute when a certain event has 8 | occurred within staking. These events can be registered to execute either 9 | right `Before` or `After` the staking event (as per the hook name). The 10 | following hooks can registered with staking: 11 | 12 | - `AfterValidatorCreated(Context, ValAddress)` 13 | - called when a validator is created 14 | - `BeforeValidatorModified(Context, ValAddress)` 15 | - called when a validator's state is changed 16 | - `AfterValidatorRemoved(Context, ConsAddress, ValAddress)` 17 | - called when a validator is deleted 18 | - `AfterValidatorBonded(Context, ConsAddress, ValAddress)` 19 | - called when a validator is bonded 20 | - `AfterValidatorBeginUnbonding(Context, ConsAddress, ValAddress)` 21 | - called when a validator begins unbonding 22 | - `BeforeDelegationCreated(Context, AccAddress, ValAddress)` 23 | - called when a delegation is created 24 | - `BeforeDelegationSharesModified(Context, AccAddress, ValAddress)` 25 | - called when a delegation's shares are modified 26 | - `BeforeDelegationRemoved(Context, AccAddress, ValAddress)` 27 | - called when a delegation is removed 28 | -------------------------------------------------------------------------------- /x/staking/spec/08_params.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Parameters 6 | 7 | The staking module contains the following parameters: 8 | 9 | | Key | Type | Example | 10 | | ------------------------- | ---------------- | ---------------------- | 11 | | UnbondingTime | string (time ns) | "259200000000000" | 12 | | MaxValidators | uint16 | 100 | 13 | | KeyMaxEntries | uint16 | 7 | 14 | | HistoricalEntries | uint16 | 3 | 15 | | BondDenom | string | "stake" | 16 | | MinCommissionRate | string | "0.000000000000000000" | 17 | | ValidatorBondFactor | string | "250.0000000000000000" | 18 | | GlobalLiquidStakingCap | string | "0.250000000000000000" | 19 | | ValidatorLiquidStakingCap | string | "0.500000000000000000" | 20 | | LiquidStakingCapsEnabled | bool | true | -------------------------------------------------------------------------------- /x/staking/teststaking/tm.go: -------------------------------------------------------------------------------- 1 | package teststaking 2 | 3 | import ( 4 | tmcrypto "github.com/tendermint/tendermint/crypto" 5 | tmtypes "github.com/tendermint/tendermint/types" 6 | 7 | cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 10 | ) 11 | 12 | // GetTmConsPubKey gets the validator's public key as a tmcrypto.PubKey. 13 | func GetTmConsPubKey(v types.Validator) (tmcrypto.PubKey, error) { 14 | pk, err := v.ConsPubKey() 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | return cryptocodec.ToTmPubKeyInterface(pk) 20 | } 21 | 22 | // ToTmValidator casts an SDK validator to a tendermint type Validator. 23 | func ToTmValidator(v types.Validator, r sdk.Int) (*tmtypes.Validator, error) { 24 | tmPk, err := GetTmConsPubKey(v) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | return tmtypes.NewValidator(tmPk, v.ConsensusPower(r)), nil 30 | } 31 | 32 | // ToTmValidators casts all validators to the corresponding tendermint type. 33 | func ToTmValidators(v types.Validators, r sdk.Int) ([]*tmtypes.Validator, error) { 34 | validators := make([]*tmtypes.Validator, len(v)) 35 | var err error 36 | for i, val := range v { 37 | validators[i], err = ToTmValidator(val, r) 38 | if err != nil { 39 | return nil, err 40 | } 41 | } 42 | 43 | return validators, nil 44 | } 45 | -------------------------------------------------------------------------------- /x/staking/teststaking/validator.go: -------------------------------------------------------------------------------- 1 | package teststaking 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 11 | ) 12 | 13 | // NewValidator is a testing helper method to create validators in tests 14 | func NewValidator(t testing.TB, operator sdk.ValAddress, pubKey cryptotypes.PubKey) types.Validator { 15 | v, err := types.NewValidator(operator, pubKey, types.Description{}) 16 | require.NoError(t, err) 17 | return v 18 | } 19 | -------------------------------------------------------------------------------- /x/staking/types/data_test.go: -------------------------------------------------------------------------------- 1 | package types_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types" 7 | "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" 8 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 9 | sdk "github.com/cosmos/cosmos-sdk/types" 10 | ) 11 | 12 | var ( 13 | pk1 = ed25519.GenPrivKey().PubKey() 14 | pk1Any *codectypes.Any 15 | pk2 = ed25519.GenPrivKey().PubKey() 16 | pk3 = ed25519.GenPrivKey().PubKey() 17 | valAddr1 = sdk.ValAddress(pk1.Address()) 18 | valAddr2 = sdk.ValAddress(pk2.Address()) 19 | valAddr3 = sdk.ValAddress(pk3.Address()) 20 | 21 | emptyAddr sdk.ValAddress 22 | emptyPubkey cryptotypes.PubKey 23 | ) 24 | 25 | func init() { 26 | var err error 27 | pk1Any, err = codectypes.NewAnyWithValue(pk1) 28 | if err != nil { 29 | panic(fmt.Sprintf("Can't pack pk1 %t as Any", pk1)) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /x/staking/types/events.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // staking module event types 4 | const ( 5 | EventTypeCompleteUnbonding = "complete_unbonding" 6 | EventTypeCompleteRedelegation = "complete_redelegation" 7 | EventTypeCreateValidator = "create_validator" 8 | EventTypeEditValidator = "edit_validator" 9 | EventTypeDelegate = "delegate" 10 | EventTypeUnbond = "unbond" 11 | EventTypeRedelegate = "redelegate" 12 | EventTypeTokenizeShares = "tokenize_shares" 13 | EventTypeRedeemShares = "redeem_shares" 14 | EventTypeTransferTokenizeShareRecord = "transfer_tokenize_share_record" 15 | EventTypeValidatorBondDelegation = "validator_bond_delegation" 16 | 17 | AttributeKeyValidator = "validator" 18 | AttributeKeyCommissionRate = "commission_rate" 19 | AttributeKeySrcValidator = "source_validator" 20 | AttributeKeyDstValidator = "destination_validator" 21 | AttributeKeyDelegator = "delegator" 22 | AttributeKeyCompletionTime = "completion_time" 23 | AttributeKeyNewShares = "new_shares" 24 | AttributeKeyShareOwner = "share_owner" 25 | AttributeKeyShareRecordID = "share_record_id" 26 | AttributeKeyAmount = "amount" 27 | AttributeValueCategory = ModuleName 28 | ) 29 | -------------------------------------------------------------------------------- /x/staking/types/genesis.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/cosmos/cosmos-sdk/codec" 7 | codectypes "github.com/cosmos/cosmos-sdk/codec/types" 8 | ) 9 | 10 | // NewGenesisState creates a new GenesisState instanc e 11 | func NewGenesisState(params Params, validators []Validator, delegations []Delegation) *GenesisState { 12 | return &GenesisState{ 13 | Params: params, 14 | Validators: validators, 15 | Delegations: delegations, 16 | } 17 | } 18 | 19 | // DefaultGenesisState gets the raw genesis raw message for testing 20 | func DefaultGenesisState() *GenesisState { 21 | return &GenesisState{ 22 | Params: DefaultParams(), 23 | } 24 | } 25 | 26 | // GetGenesisStateFromAppState returns x/staking GenesisState given raw application 27 | // genesis state. 28 | func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *GenesisState { 29 | var genesisState GenesisState 30 | 31 | if appState[ModuleName] != nil { 32 | cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) 33 | } 34 | 35 | return &genesisState 36 | } 37 | 38 | // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces 39 | func (g GenesisState) UnpackInterfaces(c codectypes.AnyUnpacker) error { 40 | for i := range g.Validators { 41 | if err := g.Validators[i].UnpackInterfaces(c); err != nil { 42 | return err 43 | } 44 | } 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /x/staking/types/params_test.go: -------------------------------------------------------------------------------- 1 | package types_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/iqlusioninc/liquidity-staking-module/x/staking/types" 10 | ) 11 | 12 | func TestParamsEqual(t *testing.T) { 13 | p1 := types.DefaultParams() 14 | p2 := types.DefaultParams() 15 | 16 | ok := p1.Equal(p2) 17 | require.True(t, ok) 18 | 19 | p2.UnbondingTime = 60 * 60 * 24 * 2 20 | p2.BondDenom = "soup" 21 | 22 | ok = p1.Equal(p2) 23 | require.False(t, ok) 24 | } 25 | 26 | func Test_validateParams(t *testing.T) { 27 | params := types.DefaultParams() 28 | 29 | // default params have no error 30 | require.NoError(t, params.Validate()) 31 | 32 | // validate mincommision 33 | params.MinCommissionRate = sdk.NewDec(-1) 34 | require.Error(t, params.Validate()) 35 | 36 | params.MinCommissionRate = sdk.NewDec(2) 37 | require.Error(t, params.Validate()) 38 | } 39 | -------------------------------------------------------------------------------- /x/staking/types/pool.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import sdk "github.com/cosmos/cosmos-sdk/types" 4 | 5 | // names used as root for pool module accounts: 6 | // 7 | // - NotBondedPool -> "not_bonded_tokens_pool" 8 | // 9 | // - BondedPool -> "bonded_tokens_pool" 10 | const ( 11 | NotBondedPoolName = "not_bonded_tokens_pool" 12 | BondedPoolName = "bonded_tokens_pool" 13 | ) 14 | 15 | // NewPool creates a new Pool instance used for queries 16 | func NewPool(notBonded, bonded sdk.Int) Pool { 17 | return Pool{ 18 | NotBondedTokens: notBonded, 19 | BondedTokens: bonded, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /x/staking/types/tokenize_share_record.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | fmt "fmt" 5 | "strconv" 6 | "strings" 7 | 8 | sdk "github.com/cosmos/cosmos-sdk/types" 9 | "github.com/cosmos/cosmos-sdk/types/address" 10 | ) 11 | 12 | func (r TokenizeShareRecord) GetModuleAddress() sdk.AccAddress { 13 | // NOTE: The module name is intentionally hard coded so that, if this 14 | // function were to move to a different module in future SDK version, 15 | // it would not break all the address lookups 16 | moduleName := "lsm" 17 | return address.Module(moduleName, []byte(r.ModuleAccount)) 18 | } 19 | 20 | func (r TokenizeShareRecord) GetShareTokenDenom() string { 21 | return fmt.Sprintf("%s/%s", strings.ToLower(r.Validator), strconv.Itoa(int(r.Id))) 22 | } 23 | --------------------------------------------------------------------------------