diff --git a/.github/workflows/all_checks_osmosis.yml b/.github/workflows/all_checks_osmosis.yml new file mode 100644 index 000000000..02d860e5b --- /dev/null +++ b/.github/workflows/all_checks_osmosis.yml @@ -0,0 +1,91 @@ +name: Test Tube (osmosis) + +on: + workflow_call: + inputs: + unittest: + required: false + default: false + type: boolean + proptest: + required: false + default: false + type: boolean + store_deps: + required: false + default: false + type: boolean + workflow_dispatch: + +env: + RUSTC_WRAPPER: cachepot + CARGO_TARGET_DIR: ~/target + +jobs: + test-tube: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + - name: Cleanup runner + run: sudo rm -rf /usr/local/share/boost && sudo rm -rf /usr/share/dotnet && sudo rm -rf /usr/local/lib/android && sudo rm -rf /opt/ghc && sudo rm -rf /opt/hostedtoolcache/CodeQL && sudo docker system prune --all --force + - name: Restore dependencies + id: restore-cache + uses: actions/cache/restore@v4 + with: + path: | + ~/.cache/cachepot + ~/.cargo + ~/go + ~/target + key: ${{ runner.os }}-cache-osmosis-${{ github.sha }} + restore-keys: ${{ runner.os }}-cache-osmosis + - name: Update PATH + run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH + - name: Install cachepot + run: test -e $HOME/.cargo/bin/cachepot && echo "cachepot found -- skipping install" || cargo install --git https://github.com/paritytech/cachepot + env: + RUSTC_WRAPPER: "" + - name: Rust lint + run: cargo clippy --features test-tube --all-targets -- -D warnings + working-directory: smart-contracts/osmosis + - name: Unit tests + run: cargo unit-test + working-directory: smart-contracts/osmosis + - name: Build merkle-incentives + run: cargo test-tube-build + working-directory: smart-contracts/osmosis/contracts/merkle-incentives + - name: Test merkle-incentives + run: cargo test-tube + working-directory: smart-contracts/osmosis/contracts/merkle-incentives + - name: Build dex-router-osmosis + run: cargo test-tube-build + working-directory: smart-contracts/osmosis/contracts/dex-router-osmosis + - name: Test dex-router-osmosis + run: cargo test-tube + working-directory: smart-contracts/osmosis/contracts/dex-router-osmosis + - name: Build cl-vault + run: cargo test-tube-build + working-directory: smart-contracts/osmosis/contracts/cl-vault + - name: Test cl-vault + run: cargo test-tube + working-directory: smart-contracts/osmosis/contracts/cl-vault + - if: inputs.proptest + name: Run prop-test + run: cargo prop-test + env: + PROPTEST_CASES: 10 + working-directory: smart-contracts/osmosis/contracts/cl-vault + - name: Store dependencies + if: inputs.store_deps && !(steps.restore-cache.outputs.cache-hit == 'false') + uses: actions/cache/save@v4 + with: + path: | + ~/.cache/cachepot + ~/.cargo + ~/go + ~/target + key: ${{ runner.os }}-cache-osmosis-${{ github.sha }} + diff --git a/.github/workflows/cargo_build_cache.yml b/.github/workflows/cargo_build_cache.yml index eb3804b68..1d1b107cc 100644 --- a/.github/workflows/cargo_build_cache.yml +++ b/.github/workflows/cargo_build_cache.yml @@ -1,13 +1,14 @@ name: Store cargo build cache on: - push: - branches: - - main - paths: - - 'smart-contracts/**.rs' - - 'smart-contracts/**.toml' - workflow_dispatch: + workflow_call: + inputs: + workspace: + required: true + type: string + +env: + CARGO_TARGET_DIR: ~/target jobs: store-build-cache: @@ -17,15 +18,29 @@ jobs: uses: actions/checkout@v3 - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Restore dependencies + uses: actions/cache/restore@v4 + with: + path: | + ~/.cache/cachepot + ~/.cargo + ~/go + ~/target + key: ${{ runner.os }}-cargo-${{ inputs.workspace }}-${{github.sha}} + restore-keys: ${{ runner.os }}-cargo-${{ inputs.workspace }} + - name: Install cachepot + run: test -e ~/.cargo/bin/cachepot && echo "cachepot found -- skipping install" || cargo install --git https://github.com/paritytech/cachepot - name: Rust check - run: cargo check - working-directory: smart-contracts + run: cargo check --all-targets --features test-tube + working-directory: smart-contracts/${{ inputs.workspace }} + env: + RUSTC_WRAPPER: cachepot - name: Store dependencies uses: actions/cache/save@v4 with: path: | + ~/.cache/cachepot ~/.cargo ~/go - **/target - key: ${{ runner.os }}-cargo-$GITHUB_SHA - restore-keys: ${{ runner.os }}-cargo + ~/target + key: ${{ runner.os }}-cargo-${{ inputs.workspace }}-${{github.sha}} diff --git a/.github/workflows/cargo_build_cache_quasar.yml b/.github/workflows/cargo_build_cache_quasar.yml new file mode 100644 index 000000000..7c56a5a35 --- /dev/null +++ b/.github/workflows/cargo_build_cache_quasar.yml @@ -0,0 +1,16 @@ +name: Store cargo build cache (quasar) + +on: + push: + branches: + - main + paths: + - 'smart-contracts/quasar/**.rs' + - 'smart-contracts/quasar/**.toml' + workflow_dispatch: + +jobs: + quasar-build-cache: + uses: ./.github/workflows/cargo_build_cache.yml + with: + workspace: quasar diff --git a/.github/workflows/cl_vault.yml b/.github/workflows/cl_vault.yml deleted file mode 100644 index a980f156b..000000000 --- a/.github/workflows/cl_vault.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: CL Vault - -on: - pull_request: - branches: - - main - paths: - - 'smart-contracts/contracts/cl-vault/Cargo.toml' - - 'smart-contracts/contracts/cl-vault/**.rs' - - 'smart-contracts/contracts/dex-router-osmosis/Cargo.toml' - - 'smart-contracts/contracts/dex-router-osmosis/**.rs' - - '.github/workflows/**.yml' - push: - branches: - - main - paths: - - 'smart-contracts/contracts/cl-vault/Cargo.toml' - - 'smart-contracts/contracts/cl-vault/**.rs' - - 'smart-contracts/contracts/dex-router-osmosis/Cargo.toml' - - 'smart-contracts/contracts/dex-router-osmosis/**.rs' - - '.github/workflows/**.yml' - workflow_dispatch: - -jobs: - unit-test: - uses: ./.github/workflows/rust_basic.yml - with: - target: 'contracts/cl-vault' - test-tube: - uses: ./.github/workflows/rust_test_tube.yml - with: - contract: 'cl-vault' - dex_router_osmosis: true diff --git a/.github/workflows/cl_vault_osmosis.yml b/.github/workflows/cl_vault_osmosis.yml new file mode 100644 index 000000000..7e584f402 --- /dev/null +++ b/.github/workflows/cl_vault_osmosis.yml @@ -0,0 +1,31 @@ +name: CL Vault (osmosis) + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/cl-vault/Cargo.toml' + - 'smart-contracts/osmosis/contracts/cl-vault/**.rs' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/**.rs' + - '.github/workflows/cl_vault_osmosis.yml' + - '.github/workflows/rust_basic.yml' + push: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/cl-vault/Cargo.toml' + - 'smart-contracts/osmosis/contracts/cl-vault/**.rs' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/**.rs' + - '.github/workflows/cl_vault_osmosis.yml' + - '.github/workflows/rust_basic.yml' + workflow_dispatch: + +jobs: + unit-test: + uses: ./.github/workflows/rust_basic.yml + with: + target: contracts/cl-vault + workspace: osmosis diff --git a/.github/workflows/dex_router_osmosis.yml b/.github/workflows/dex_router_osmosis.yml index 56853d878..563403854 100644 --- a/.github/workflows/dex_router_osmosis.yml +++ b/.github/workflows/dex_router_osmosis.yml @@ -5,24 +5,23 @@ on: branches: - main paths: - - 'smart-contracts/contracts/dex-router-osmosis/Cargo.toml' - - 'smart-contracts/contracts/dex-router-osmosis/**.rs' - - '.github/workflows/**.yml' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/dex_router_osmosis.yml' push: branches: - main paths: - - 'smart-contracts/contracts/dex-router-osmosis/Cargo.toml' - - 'smart-contracts/contracts/dex-router-osmosis/**.rs' - - '.github/workflows/**.yml' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/dex-router-osmosis/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/dex_router_osmosis.yml' workflow_dispatch: jobs: unit-test: uses: ./.github/workflows/rust_basic.yml with: - target: 'contracts/dex-router-osmosis' - test-tube: - uses: ./.github/workflows/rust_test_tube.yml - with: - contract: 'dex-router-osmosis' + target: contracts/dex-router-osmosis + workspace: osmosis diff --git a/.github/workflows/lst_adapter_osmosis.yml b/.github/workflows/lst_adapter_osmosis.yml index 3cbf47031..fd264be7c 100644 --- a/.github/workflows/lst_adapter_osmosis.yml +++ b/.github/workflows/lst_adapter_osmosis.yml @@ -5,16 +5,16 @@ on: branches: - main paths: - - 'smart-contracts/contracts/lst-adapter-osmosis/Cargo.toml' - - 'smart-contracts/contracts/lst-adapter-osmosis/**.rs' + - 'smart-contracts/osmosis/contracts/lst-adapter-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/lst-adapter-osmosis/**.rs' - '.github/workflows/rust_basic.yml' - '.github/workflows/lst_adapter_osmosis.yml' push: branches: - main paths: - - 'smart-contracts/contracts/lst-adapter-osmosis/Cargo.toml' - - 'smart-contracts/contracts/lst-adapter-osmosis/**.rs' + - 'smart-contracts/osmosis/contracts/lst-adapter-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/lst-adapter-osmosis/**.rs' - '.github/workflows/rust_basic.yml' - '.github/workflows/lst_adapter_osmosis.yml' workflow_dispatch: @@ -23,4 +23,5 @@ jobs: unit-test: uses: ./.github/workflows/rust_basic.yml with: - target: 'contracts/lst-adapter-osmosis' + target: contracts/lst-adapter-osmosis + workspace: osmosis diff --git a/.github/workflows/lst_dex_adapter_osmosis.yml b/.github/workflows/lst_dex_adapter_osmosis.yml index ab158a1b7..3b8bb2756 100644 --- a/.github/workflows/lst_dex_adapter_osmosis.yml +++ b/.github/workflows/lst_dex_adapter_osmosis.yml @@ -5,16 +5,16 @@ on: branches: - main paths: - - 'smart-contracts/contracts/lst-dex-adapter-osmosis/Cargo.toml' - - 'smart-contracts/contracts/lst-dex-adapter-osmosis/**.rs' + - 'smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/**.rs' - '.github/workflows/rust_basic.yml' - '.github/workflows/lst_dex_adapter_osmosis.yml' push: branches: - main paths: - - 'smart-contracts/contracts/lst-dex-adapter-osmosis/Cargo.toml' - - 'smart-contracts/contracts/lst-dex-adapter-osmosis/**.rs' + - 'smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/Cargo.toml' + - 'smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/**.rs' - '.github/workflows/rust_basic.yml' - '.github/workflows/lst_dex_adapter_osmosis.yml' workflow_dispatch: @@ -23,4 +23,5 @@ jobs: unit-test: uses: ./.github/workflows/rust_basic.yml with: - target: 'contracts/lst-dex-adapter-osmosis' + target: contracts/lst-dex-adapter-osmosis + workspace: osmosis diff --git a/.github/workflows/merkle_incentives.yml b/.github/workflows/merkle_incentives.yml deleted file mode 100644 index 5eec5bbe7..000000000 --- a/.github/workflows/merkle_incentives.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Merkle Incentives - -on: - pull_request: - branches: - - main - paths: - - 'smart-contracts/contracts/merkle-incentives/Cargo.toml' - - 'smart-contracts/contracts/merkle-incentives/**.rs' - - '.github/workflows/rust_basic.yml' - - '.github/workflows/rust_test_tube.yml' - - '.github/workflows/merkle_incentives.yml' - push: - branches: - - main - paths: - - 'smart-contracts/contracts/merkle-incentives/Cargo.toml' - - 'smart-contracts/contracts/merkle-incentives/**.rs' - - '.github/workflows/rust_basic.yml' - - '.github/workflows/rust_test_tube.yml' - - '.github/workflows/merkle_incentives.yml' - workflow_dispatch: - -jobs: - unit-test: - uses: ./.github/workflows/rust_basic.yml - with: - target: 'contracts/merkle-incentives' - test-tube: - uses: ./.github/workflows/rust_test_tube.yml - with: - contract: 'merkle-incentives' diff --git a/.github/workflows/merkle_incentives_osmosis.yml b/.github/workflows/merkle_incentives_osmosis.yml new file mode 100644 index 000000000..0d66b7c18 --- /dev/null +++ b/.github/workflows/merkle_incentives_osmosis.yml @@ -0,0 +1,27 @@ +name: Merkle Incentives (osmosis) + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/merkle-incentives/Cargo.toml' + - 'smart-contracts/osmosis/contracts/merkle-incentives/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/merkle_incentives_osmosis.yml' + push: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/merkle-incentives/Cargo.toml' + - 'smart-contracts/osmosis/contracts/merkle-incentives/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/merkle_incentives_osmosis.yml' + workflow_dispatch: + +jobs: + unit-test: + uses: ./.github/workflows/rust_basic.yml + with: + target: contracts/merkle-incentives + workspace: osmosis diff --git a/.github/workflows/proto_build.yml b/.github/workflows/proto_build.yml new file mode 100644 index 000000000..29255ff15 --- /dev/null +++ b/.github/workflows/proto_build.yml @@ -0,0 +1,28 @@ +name: proto build + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/quasar/proto-build/Cargo.toml' + - 'smart-contracts/quasar/proto-build/**.rs' + - '.github/workflows/proto_build.yml' + - '.github/workflows/rust_basic.yml' + push: + branches: + - main + paths: + - 'smart-contracts/quasar/proto-build/Cargo.toml' + - 'smart-contracts/quasar/proto-build/**.rs' + - '.github/workflows/proto_build.yml' + - '.github/workflows/rust_basic.yml' + workflow_dispatch: + +jobs: + unit-test: + uses: ./.github/workflows/rust_basic.yml + with: + target: proto-build + workspace: quasar + unit_tests: false diff --git a/.github/workflows/quasar_types.yml b/.github/workflows/quasar_types.yml deleted file mode 100644 index 4f38f327f..000000000 --- a/.github/workflows/quasar_types.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Quasar Types - -on: - pull_request: - branches: - - main - paths: - - 'smart-contracts/packages/quasar-types/**' - - '.github/workflows/**.yml' - push: - branches: - - main - paths: - - 'smart-contracts/packages/quasar-types/**' - - '.github/workflows/**.yml' - workflow_dispatch: - -jobs: - unit-test: - uses: ./.github/workflows/rust_basic.yml - with: - target: 'packages/quasar-types' diff --git a/.github/workflows/quasar_types_osmosis.yml b/.github/workflows/quasar_types_osmosis.yml new file mode 100644 index 000000000..f72b5fcf5 --- /dev/null +++ b/.github/workflows/quasar_types_osmosis.yml @@ -0,0 +1,27 @@ +name: Quasar Types (osmosis) + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/osmosis/packages/quasar-types/Cargo.toml' + - 'smart-contracts/osmosis/packages/quasar-types/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/quasar_types_osmosis.yml' + push: + branches: + - main + paths: + - 'smart-contracts/osmosis/packages/quasar-types/Cargo.toml' + - 'smart-contracts/osmosis/packages/quasar-types/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/quasar_types_osmosis.yml' + workflow_dispatch: + +jobs: + unit-test: + uses: ./.github/workflows/rust_basic.yml + with: + target: packages/quasar-types + workspace: osmosis diff --git a/.github/workflows/range_middleware.yml b/.github/workflows/range_middleware.yml deleted file mode 100644 index d88fd2855..000000000 --- a/.github/workflows/range_middleware.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Range Middleware - -on: - pull_request: - branches: - - main - paths: - - 'smart-contracts/contracts/range-middleware/Cargo.toml' - - 'smart-contracts/contracts/range-middleware/**.rs' - - '.github/workflows/rust_basic.yml' - - '.github/workflows/range_middleware.yml' - push: - branches: - - main - paths: - - 'smart-contracts/contracts/range-middleware/Cargo.toml' - - 'smart-contracts/contracts/range-middleware/**.rs' - - '.github/workflows/rust_basic.yml' - - '.github/workflows/range_middleware.yml' - workflow_dispatch: - -jobs: - unit-test: - uses: ./.github/workflows/rust_basic.yml - with: - target: 'contracts/range-middleware' diff --git a/.github/workflows/range_middleware_osmosis.yml b/.github/workflows/range_middleware_osmosis.yml new file mode 100644 index 000000000..8484d677e --- /dev/null +++ b/.github/workflows/range_middleware_osmosis.yml @@ -0,0 +1,27 @@ +name: Range Middleware (osmosis) + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/range-middleware/Cargo.toml' + - 'smart-contracts/osmosis/contracts/range-middleware/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/range_middleware_osmosis.yml' + push: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/range-middleware/Cargo.toml' + - 'smart-contracts/osmosis/contracts/range-middleware/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/range_middleware_osmosis.yml' + workflow_dispatch: + +jobs: + unit-test: + uses: ./.github/workflows/rust_basic.yml + with: + target: contracts/range-middleware + workspace: osmosis diff --git a/.github/workflows/rust_basic.yml b/.github/workflows/rust_basic.yml index 3ccf22cc5..b1fc2fd4d 100644 --- a/.github/workflows/rust_basic.yml +++ b/.github/workflows/rust_basic.yml @@ -3,9 +3,16 @@ name: Unit Test (rust) on: workflow_call: inputs: + workspace: + required: true + type: string target: required: true type: string + unit_tests: + required: false + default: true + type: boolean jobs: checks: @@ -15,21 +22,13 @@ jobs: uses: actions/checkout@v3 - name: Install Rust uses: dtolnay/rust-toolchain@stable - - name: Restore dependencies - uses: actions/cache/restore@v4 - with: - path: | - ~/.cargo - ~/go - **/target - key: ${{ runner.os }}-cargo-$GITHUB_SHA - restore-keys: ${{ runner.os }}-cargo - name: Rust lint - run: RUSTFLAGS="-Dwarnings" cargo clippy --workspace -- -D warnings --A deprecated - working-directory: smart-contracts/${{ inputs.target }} + run: cargo clippy --all-targets -- -D warnings + working-directory: smart-contracts/${{ inputs.workspace }} - name: Rust format check run: cargo fmt --all -- --check - working-directory: smart-contracts/${{ inputs.target }} - - name: Run unit-tests + working-directory: smart-contracts/${{ inputs.workspace }}/${{ inputs.target }} + - if: inputs.unit_tests + name: Run unit-tests run: cargo unit-test - working-directory: smart-contracts/${{ inputs.target }} + working-directory: smart-contracts/${{ inputs.workspace }}/${{ inputs.target }} diff --git a/.github/workflows/rust_test_tube.yml b/.github/workflows/rust_test_tube.yml deleted file mode 100644 index dc4a6cf0c..000000000 --- a/.github/workflows/rust_test_tube.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Test Tube - -on: - workflow_call: - inputs: - contract: - required: true - type: string - dex_router_osmosis: - required: false - default: false - type: boolean - -jobs: - test-tube: - runs-on: ubuntu-latest - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - - name: Restore dependencies - uses: actions/cache/restore@v4 - with: - path: | - ~/.cargo - ~/go - **/target - key: ${{ runner.os }}-cargo-$GITHUB_SHA - restore-keys: ${{ runner.os }}-cargo - - name: Build ${{ inputs.contract }} - run: cargo test-tube-build - working-directory: smart-contracts/contracts/${{ inputs.contract }} - - name: Build dex-router-osmosis - if: ${{inputs.dex_router_osmosis}} - run: cargo test-tube-build - working-directory: smart-contracts/contracts/dex-router-osmosis - - name: Run test-tube tests - run: cargo test-tube - env: - PROPTEST_CASES: 10 - working-directory: smart-contracts/contracts/${{ inputs.contract }} - - name: Clear temporary test-tube files - if: always() - run: rm -rf .osmosis-test-tube-temp-* - working-directory: /tmp diff --git a/.github/workflows/test_tube.yml b/.github/workflows/test_tube.yml new file mode 100644 index 000000000..b94245b19 --- /dev/null +++ b/.github/workflows/test_tube.yml @@ -0,0 +1,32 @@ +name: Test Tube (osmosis) + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/osmosis/**/Cargo.toml' + - 'smart-contracts/osmosis/**.rs' + - '.github/workflows/test_tube.yml' + - '.github/workflows/all_checks_osmosis.yml' + push: + branches: + - main + paths: + - 'smart-contracts/osmosis/**/Cargo.toml' + - 'smart-contracts/osmosis/**.rs' + - '.github/workflows/test_tube.yml' + - '.github/workflows/all_checks_osmosis.yml' + workflow_dispatch: + +jobs: + post-merge: + uses: ./.github/workflows/all_checks_osmosis.yml + if: github.event_name == 'push' + with: + unittest: true + proptest: true + store_deps: true + pre-commit: + uses: ./.github/workflows/all_checks_osmosis.yml + if: github.event_name == 'pull_request' diff --git a/.github/workflows/token_burner.yml b/.github/workflows/token_burner.yml deleted file mode 100644 index c60dfe301..000000000 --- a/.github/workflows/token_burner.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Token Burner - -on: - pull_request: - branches: - - main - paths: - - 'smart-contracts/contracts/token-burner/Cargo.toml' - - 'smart-contracts/contracts/token-burner/**.rs' - - '.github/workflows/rust_basic.yml' - - '.github/workflows/token_burner.yml' - push: - branches: - - main - paths: - - 'smart-contracts/contracts/token-burner/Cargo.toml' - - 'smart-contracts/contracts/token-burner/**.rs' - - '.github/workflows/rust_basic.yml' - - '.github/workflows/token_burner.yml' - workflow_dispatch: - -jobs: - unit-test: - uses: ./.github/workflows/rust_basic.yml - with: - target: 'contracts/token-burner' diff --git a/.github/workflows/token_burner_osmosis.yml b/.github/workflows/token_burner_osmosis.yml new file mode 100644 index 000000000..b18ed7966 --- /dev/null +++ b/.github/workflows/token_burner_osmosis.yml @@ -0,0 +1,27 @@ +name: Token Burner (osmosis) + +on: + pull_request: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/token-burner/Cargo.toml' + - 'smart-contracts/osmosis/contracts/token-burner/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/token_burner_osmosis.yml' + push: + branches: + - main + paths: + - 'smart-contracts/osmosis/contracts/token-burner/Cargo.toml' + - 'smart-contracts/osmosis/contracts/token-burner/**.rs' + - '.github/workflows/rust_basic.yml' + - '.github/workflows/token_burner_osmosis.yml' + workflow_dispatch: + +jobs: + unit-test: + uses: ./.github/workflows/rust_basic.yml + with: + target: contracts/token-burner + workspace: osmosis diff --git a/.gitignore b/.gitignore index 0857abaef..6d54347cd 100644 --- a/.gitignore +++ b/.gitignore @@ -21,10 +21,12 @@ vue/ local_testnet_run-*nodes/ *.out coverage.txt +**/Cargo.lock containers_homes/ # Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) **/.cargo-ok **/*.rs.bk +.devcontainer/ diff --git a/DEV_GUIDELINES.md b/DEV_GUIDELINES.md index 2e600b5da..88a5956a3 100644 --- a/DEV_GUIDELINES.md +++ b/DEV_GUIDELINES.md @@ -13,4 +13,9 @@ tbd ## Ready for review -tbd \ No newline at end of file +tbd + +## Unplanned work +In order to balance tracking of our progress and speed of development we use the following rules for unplanned works that gets identified during a sprint: +* fix takes less than 1h and you address it immediately: no ticket required +* fix takes more than 1h or you don't address it immediately: create a ticket diff --git a/README.md b/README.md index cb4fcde74..41854079b 100644 --- a/README.md +++ b/README.md @@ -64,8 +64,34 @@ In order to run test-tube the following dependencies are required: * go1.22 ([see here](https://go.dev/doc/install)) * libwasmvm ([see here](https://github.com/CosmWasm/wasmvm) -- !Instructions don't cover installation, copy the files to your desired install location or add the subfolder `wasmvm/internal/api` to your library paths) -## Pre-commit hook +## Git hooks +To automatically use both the pre-commit hook and the post-merge hook, you can adjust the hook path of git: `git config core.hooksPath ${PWD}/scripts/git`. + +#### Pre-commit hook Enable the pre-commit hook by copying the entrypoint to the hooks folder: `cp scripts/pre-commit .git/hooks`. It forwards to `scripts/git/pre-commit`, which contains the actual implementation. -If you are concerned about automatically picking up changes in a bash script from the repository you may install the pre-commit hook via: `cp scripts/git/pre-commit .git/hooks` \ No newline at end of file +If you are concerned about automatically picking up changes in a bash script from the repository you may install the pre-commit hook via: `cp scripts/git/pre-commit .git/hooks` + +#### Post-merge hook +The post-merge hook automatically removes branches that have been removed on the remote. +WARNING: Only use this if you are disciplined with your usage of git. + +## IDE Configuration +Rust-analyzer does not pick up optional dependencies (even when specified as required-dependencies for a target). Moreover, it can get confused it it finds too many workspaces. + +#### vscode +The following template enables rust-analyzer for test-tube tests and adds the workspace paths. + +Template for `./.vscode/settings.json`: +``` +{ + "rust-analyzer.linkedProjects": [ + "/smart-contracts/osmosis/Cargo.toml", + "/smart-contracts/quasar/Cargo.toml", + ], + "rust-analyzer.cargo.features": [ + "test-tube" + ] +} +``` diff --git a/scripts/git/post-merge b/scripts/git/post-merge old mode 100644 new mode 100755 diff --git a/scripts/git/pre-commit b/scripts/git/pre-commit old mode 100644 new mode 100755 index 4e9a9b52f..67ff68a0e --- a/scripts/git/pre-commit +++ b/scripts/git/pre-commit @@ -3,8 +3,9 @@ set -e REPO_ROOT=$(git rev-parse --show-toplevel) +DIFF_FILTER=ACMR -CHANGES=$(git diff --name-only origin/main) +CHANGES=$(git diff --name-only origin/main --cached --diff-filter=$DIFF_FILTER) if [ -z "$CHANGES" ] @@ -13,34 +14,88 @@ then exit 1 fi -update_schemas_and_formatting() { - local contract=$1 - if [[ $CHANGES == *contracts/${contract}* ]] +update_schemas() { + local workspace=$1 + local contract=$2 + if [[ $CHANGES == *${workspace}/contracts/${contract}/* ]] then echo "Changes in ${contract} contract" - cd ${REPO_ROOT}/smart-contracts/contracts/${contract} + cd ${REPO_ROOT}/smart-contracts/${workspace}/contracts/${contract} # generate schemas cargo schema - NEW_CHANGES=$(git diff --name-only origin/main) - if [[ $NEW_CHANGES == *schema/* ]] + NEW_CHANGES=$(git diff --name-only origin/main --diff-filter=$DIFF_FILTER) + if [[ $NEW_CHANGES == *${workspace}/contracts/${contract}/schema* ]] then git add schema else echo "No schema changes for ${contract}." fi + fi +} +check_lint() { + if [[ $CHANGES == *smart-contracts/osmosis* ]] + then + cd ${REPO_ROOT}/smart-contracts/osmosis + cargo clippy --workspace -- -D warnings + cd - + fi + if [[ $CHANGES == *smart-contracts/quasar* ]] + then + cd ${REPO_ROOT}/smart-contracts/quasar + cargo clippy --workspace -- -D warnings + cd - + fi +} + +fix_formatting() { + local target=$1 + if [[ $CHANGES == *${target}* ]] + then + echo "Changes in ${target}" + cd ${REPO_ROOT}/smart-contracts/${target} # fix formatting cargo fmt --all cd ${REPO_ROOT} - NEW_CHANGES=$(git diff --name-only origin/main --diff-filter=A) + NEW_CHANGES=$(git diff --name-only origin/main --cached --diff-filter=$DIFF_FILTER) git add $NEW_CHANGES fi } -update_schemas_and_formatting lst-dex-adapter-osmosis -update_schemas_and_formatting dex-router-osmosis -update_schemas_and_formatting token-burner -update_schemas_and_formatting cl-vault -update_schemas_and_formatting merkle-incentives -update_schemas_and_formatting range-middleware +check_lint() { + local target=$1 + if [[ $CHANGES == *${target}* ]] + then + echo "Changes in ${target}" + cd ${REPO_ROOT}/smart-contracts/${target} + cargo clippy --all-targets -- -D warnings + cd - + fi +} + +update_schemas osmosis lst-dex-adapter-osmosis +update_schemas osmosis lst-adapter-osmosis +update_schemas osmosis dex-router-osmosis +update_schemas osmosis token-burner +update_schemas osmosis cl-vault +update_schemas osmosis merkle-incentives +update_schemas osmosis range-middleware +fix_formatting osmosis/contracts/lst-dex-adapter-osmosis +fix_formatting osmosis/contracts/lst-adapter-osmosis +fix_formatting osmosis/contracts/dex-router-osmosis +fix_formatting osmosis/contracts/token-burner +fix_formatting osmosis/contracts/cl-vault +fix_formatting osmosis/contracts/merkle-incentives +fix_formatting osmosis/contracts/range-middleware +fix_formatting osmosis/packages/quasar-types +fix_formatting quasar/proto-build +check_lint osmosis/contracts/lst-dex-adapter-osmosis +check_lint osmosis/contracts/lst-adapter-osmosis +check_lint osmosis/contracts/dex-router-osmosis +check_lint osmosis/contracts/token-burner +check_lint osmosis/contracts/cl-vault +check_lint osmosis/contracts/merkle-incentives +check_lint osmosis/contracts/range-middleware +check_lint osmosis/packages/quasar-types +check_lint quasar/proto-build diff --git a/smart-contracts/.cargo/config b/smart-contracts/.cargo/config deleted file mode 100644 index fcfdb2f1a..000000000 --- a/smart-contracts/.cargo/config +++ /dev/null @@ -1,8 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -schema = "run --example schema" -lint = "clippy -- -D warnings" -lint-fix = "clippy --fix -- -D warnings" -unit-test = "test --lib" -test-vault = "test --lib -p basic-vault" -clip = "clippy -- --D warnings --A deprecated" \ No newline at end of file diff --git a/smart-contracts/Cargo.lock b/smart-contracts/Cargo.lock deleted file mode 100644 index d0bdec7f8..000000000 --- a/smart-contracts/Cargo.lock +++ /dev/null @@ -1,6499 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "abstract-account-factory" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449aba6ba1d653dff5e26302832413baa2bebe659352967575667b8acc1e16f8" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "protobuf", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-account-factory" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "protobuf", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-adapter" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-ibc-client 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-ibc-host 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-interface 0.22.1", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-adapter" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd5bff625f8f1566c35102f771ce8be9a2c94e18ad46269b8d7b6d197885c83d" -dependencies = [ - "abstract-ibc-client 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-ibc-host 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-interface 0.22.5", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "abstract-testing", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-adapter-utils" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74250fbd8f6bd7ddc059bc5a6ef44a2d2f85ca47d29a9c08dcb45cd563fdf59" -dependencies = [ - "cosmwasm-std", - "cw-asset", - "cw20 1.1.2", -] - -[[package]] -name = "abstract-adapter-utils" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "cosmwasm-std", - "cw-asset", - "cw20 1.1.2", -] - -[[package]] -name = "abstract-ans-host" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04ac3230e3496d8bb6889294f4c1f6cd73e9e7fe6c97f78adbcd9863f2aaa91d" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-ans-host" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-app" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81abe76c3be79546b6ab87d1b1bb060cf2586ab1adba445157bfca7d6971d4b8" -dependencies = [ - "abstract-ibc-host 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-interface 0.22.5", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "abstract-testing", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-astroport-adapter" -version = "2.10.0" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-dex-standard", - "abstract-sdk 0.22.2", - "abstract-staking-standard", - "cosmwasm-std", - "lazy_static", -] - -[[package]] -name = "abstract-astrovault-adapter" -version = "0.2.0" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-dex-standard", - "abstract-sdk 0.22.2", - "abstract-staking-standard", - "cosmwasm-std", - "lazy_static", -] - -[[package]] -name = "abstract-client" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8a7f2efb08869039bfcc3cfc3d537d2574b208858647c005b90b2399fba2503" -dependencies = [ - "abstract-cw-plus-interface", - "abstract-cw20", - "abstract-cw20-base", - "abstract-interface 0.22.5", - "abstract-std 0.22.2", - "cosmwasm-std", - "cw-asset", - "cw-orch 0.22.2", - "cw-ownable", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw-multi-test" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c77f8d4bac08f74fbc4fce8943cb2d35e742682b6cae8cb65555d6cd3830feb" -dependencies = [ - "anyhow", - "bech32 0.11.0", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw20-ics20", - "derivative", - "hex", - "itertools 0.12.1", - "log", - "prost 0.12.6", - "schemars", - "serde", - "serde_json", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "abstract-cw-orch-polytone" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9607f7cf2a40564906b0ed092c750843dbf66a5ff298a40df9558823cc088f32" -dependencies = [ - "abstract-polytone-note 2.0.0", - "abstract-polytone-proxy", - "abstract-polytone-voice", - "cosmwasm-std", - "cw-orch 0.22.2", -] - -[[package]] -name = "abstract-cw-plus-interface" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7441425a805439500492977107d154af02b1702aa044945775c245d0b3469968" -dependencies = [ - "abstract-cw1", - "abstract-cw1-subkeys", - "abstract-cw1-whitelist", - "abstract-cw20-base", - "abstract-cw20-ics20", - "abstract-cw3-fixed-multisig", - "abstract-cw3-flex-multisig", - "abstract-cw4-group", - "abstract-cw4-stake", - "cosmwasm-std", - "cw-orch 0.22.2", -] - -[[package]] -name = "abstract-cw1" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0895c076ab6a5165133a453f983ec9ccc9b6c41de256b6eb74e523eb555b3ebb" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "abstract-cw1-subkeys" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab08cdd6008afa38a52427943bf4aef9541bde78cc9c14849a53ad2608a1161e" -dependencies = [ - "abstract-cw1", - "abstract-cw1-whitelist", - "abstract-cw2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw1-whitelist" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171a0b5b3694627cf0fa554500d72431169d4013fffd14650d2b7d660230a205" -dependencies = [ - "abstract-cw1", - "abstract-cw2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw2" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945af4c176b4539be2a74c06aa166287ba964ab58aec98c644addd812431f141" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw20" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d5e4b8084c3a2b3e42502e6c4fe3ed985dc72e86eb612bcc527f4a0443fa42" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "abstract-cw20-base" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d300dec7d602e00841c5ab6fe598d4d290bab32e489c6885c607633c4f3fe67" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw20-ics20" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027678ddb0e62b4aba5f0167d2b0a3ec0182e1e32c47759be7e30b56775598ee" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw3" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c080cc760333d1d3477857aeac19aa7e6e661f1e58d04a7a78212913d49bf517" -dependencies = [ - "abstract-cw20", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw3-fixed-multisig" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1882e05bef33bd1c6b25e735eda8a23332a78c4df0b24a18ca56a8ca8ed6f222" -dependencies = [ - "abstract-cw2", - "abstract-cw3", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw3-flex-multisig" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92379f3e7c467f081312d6953eb8d300456efa352c9f7c5ef095ad99083d92db" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "abstract-cw3", - "abstract-cw3-fixed-multisig", - "abstract-cw4", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw4" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aacb0124dce37ee6f2b5636684285bcbaa65a1678980f95ea76366ab74a8912" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "serde", -] - -[[package]] -name = "abstract-cw4-group" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0af5ef484ba1d48fee8485452c81ac3465ba16a5941db90bda4dd6b58b50a9a6" -dependencies = [ - "abstract-cw2", - "abstract-cw4", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-cw4-stake" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1eb9985e8b752396a2c5d8fde8ebf65ea81070a95f167a3d31af0746f8e4b4e" -dependencies = [ - "abstract-cw2", - "abstract-cw20", - "abstract-cw4", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-dex-adapter" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-adapter 0.22.4", - "abstract-adapter-utils 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-astroport-adapter", - "abstract-astrovault-adapter", - "abstract-client", - "abstract-cw20", - "abstract-dex-standard", - "abstract-kujira-adapter", - "abstract-osmosis-adapter", - "abstract-wyndex-adapter", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw20 0.10.3", - "schemars", - "serde_json", - "thiserror", - "wasmswap", -] - -[[package]] -name = "abstract-dex-standard" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ac6054b628e9a25f516319d2e99697c81385f4db642382e20a8b0d18c385ea" -dependencies = [ - "abstract-adapter 0.22.4", - "abstract-adapter-utils 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw20 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-ibc-client" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3576a483bf0668624335eb7674da419bec75db1dda2ecd9b14da7ca47d8bdd8c" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-polytone", - "abstract-polytone-note 1.0.5", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-std", - "cw-ownable", - "cw-paginate", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-ibc-client" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-polytone", - "abstract-polytone-note 1.0.5", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-std", - "cw-ownable", - "cw-paginate", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-ibc-host" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f06fef7c5d6a348000959d4014f23db05684e23ee3c3a0322085656e016b5fd" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-ownable", - "cw-paginate", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-ibc-host" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-orch 0.22.2", - "cw-ownable", - "cw-paginate", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-interface" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-account-factory 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-ans-host 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-ibc-client 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-ibc-host 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-manager 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-module-factory 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-polytone", - "abstract-proxy 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-std 0.22.1", - "abstract-version-control 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-address-like", - "cw-asset", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "log", - "rust-embed", - "schemars", - "semver", - "serde", - "serde_json", - "speculoos", - "thiserror", -] - -[[package]] -name = "abstract-interface" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b56fe8d45d3b70bf0d263af402ffc6d767193c85085268a6ee14e78c90ee026" -dependencies = [ - "abstract-account-factory 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-ans-host 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-ibc-client 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-ibc-host 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-manager 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-module-factory 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-polytone", - "abstract-proxy 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-std 0.22.2", - "abstract-version-control 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-address-like", - "cw-asset", - "cw-controllers", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "log", - "rust-embed", - "schemars", - "semver", - "serde", - "serde_json", - "speculoos", - "thiserror", -] - -[[package]] -name = "abstract-kujira-adapter" -version = "0.3.0" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-dex-standard", - "abstract-money-market-standard", - "abstract-sdk 0.22.2", - "abstract-staking-standard", - "cosmwasm-std", - "prost 0.12.6", -] - -[[package]] -name = "abstract-macros" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60500f642b2d0641790a7daee9113103628d947218c7dd48b6a9a364ff102771" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "abstract-macros" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "abstract-manager" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa44c08fb79e56be341daa1e1df1fded49b23aefa75c24ccec09ed5437eb743" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-manager" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-module-factory" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ed7bf3d0efb347db7587381c676d239ddb3c5b1f0143d0f4aaeea8c392b19f" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "protobuf", - "semver", - "serde-cw-value", - "thiserror", -] - -[[package]] -name = "abstract-module-factory" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "protobuf", - "semver", - "serde-cw-value", - "thiserror", -] - -[[package]] -name = "abstract-money-market-standard" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-adapter 0.22.1", - "abstract-adapter-utils 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw20 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-osmosis-adapter" -version = "0.17.0" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-dex-standard", - "abstract-sdk 0.22.2", - "abstract-staking-standard", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", -] - -[[package]] -name = "abstract-polytone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05676a6c6c65c8d5d776140c47d4f3a96144bbf1bc5452c1e485d259f7c10cfc" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "abstract-polytone-note" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a454b2e0e4b8ce4bd38ec91af23638371f4d32bbe277531147e49e77cd500906" -dependencies = [ - "abstract-polytone", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "thiserror", -] - -[[package]] -name = "abstract-polytone-note" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b8e658ed796cc9c0fe3b837ae430c168a53aa7852db78fdaef07c99542f77e" -dependencies = [ - "abstract-polytone", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "thiserror", -] - -[[package]] -name = "abstract-polytone-proxy" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ce4a8ce93e50ab42e952d6848c45000cf0efe41f39d37f8fd55205086dc845" -dependencies = [ - "abstract-polytone", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "thiserror", -] - -[[package]] -name = "abstract-polytone-voice" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf7140953864e14b73d572921699df09f2ad75cb86136abce6dc4a3d9ab8b9" -dependencies = [ - "abstract-polytone", - "abstract-polytone-proxy", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "abstract-proxy" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e510b5ddc0b2492b00be37a1e6236b07a9b86156e507c55efc8d17286fdf46b" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-proxy" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-sdk" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-polytone", - "abstract-std 0.22.1", - "cosmwasm-std", - "cw-asset", - "cw-clearable", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-sdk" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f2d597571c6d09b66be3d4365752cff257fa973a4915c9775c5e46111a7c446" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-polytone", - "abstract-std 0.22.2", - "abstract-testing", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-clearable", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-staking-standard" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43950444fa17fb110808f7e04d144cff0194f69ba52ea6b704d5e609e60761ff" -dependencies = [ - "abstract-adapter 0.22.4", - "abstract-adapter-utils 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-orch 0.22.2", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw20 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-std" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-polytone", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-address-like", - "cw-asset", - "cw-clearable", - "cw-controllers", - "cw-orch 0.22.2", - "cw-ownable", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "function_name", - "schemars", - "semver", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "abstract-std" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d871df3db2ef86eb0edd24db0e8a8680794b36abad38a96eda365caba3d283" -dependencies = [ - "abstract-polytone", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-address-like", - "cw-asset", - "cw-clearable", - "cw-controllers", - "cw-orch 0.22.2", - "cw-ownable", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "function_name", - "schemars", - "semver", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "abstract-testing" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e6704bb0f55971edfade5ec6c12f648d31e3c8dc3d73a88624c17a7ac61aa7" -dependencies = [ - "abstract-std 0.22.2", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-ownable", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "derive_builder", - "schemars", - "semver", - "serde", - "serde_json", - "speculoos", -] - -[[package]] -name = "abstract-version-control" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c084c81186b9fa2f70ceae49bfedf9e56363f22abcab5fb8dd21dfe95b03af3b" -dependencies = [ - "abstract-macros 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "cosmwasm-schema 2.0.4", - "cosmwasm-std", - "cw-ownable", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-version-control" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-macros 0.22.1 (git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1)", - "abstract-sdk 0.22.1", - "abstract-std 0.22.1", - "cosmwasm-schema 2.0.4", - "cosmwasm-std", - "cw-ownable", - "cw-semver", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "serde", - "thiserror", -] - -[[package]] -name = "abstract-wyndex-adapter" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-cw20", - "abstract-dex-standard", - "abstract-sdk 0.22.2", - "abstract-staking-standard", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-utils", - "wyndex 1.1.2 (git+https://github.com/wynddao/wynddex?tag=v1.1.2)", - "wyndex-stake 1.1.2 (git+https://github.com/wynddao/wynddex?tag=v1.1.2)", -] - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[package]] -name = "apollo-cw-asset" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "423502406a307052f6877030f48b5fb4e9fb338fc5e7c8ca1064210def52876b" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw20 1.1.2", - "schemars", - "serde", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "async-stream" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "async-trait" -version = "0.1.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bech32" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" - -[[package]] -name = "bindgen" -version = "0.69.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" -dependencies = [ - "bitflags 2.4.2", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.48", - "which", -] - -[[package]] -name = "bip32" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" -dependencies = [ - "bs58", - "hmac", - "k256", - "rand_core 0.6.4", - "ripemd", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - -[[package]] -name = "bitcoin" -version = "0.30.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462" -dependencies = [ - "bech32 0.9.1", - "bitcoin-private", - "bitcoin_hashes", - "hex_lit", - "secp256k1", -] - -[[package]] -name = "bitcoin-private" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" - -[[package]] -name = "bitcoin_hashes" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" -dependencies = [ - "bitcoin-private", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" - -[[package]] -name = "borsh" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.48", - "syn_derive", -] - -[[package]] -name = "bs58" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" -dependencies = [ - "sha2 0.10.8", -] - -[[package]] -name = "bstr" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chrono" -version = "0.4.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets 0.52.0", -] - -[[package]] -name = "cl-vault" -version = "0.3.0" -dependencies = [ - "apollo-cw-asset", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw-vault-multi-standard", - "cw2 1.1.2", - "dex-router-osmosis", - "num_enum", - "osmosis-std", - "osmosis-std-derive", - "osmosis-test-tube", - "proptest", - "prost 0.12.6", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim 0.11.1", -] - -[[package]] -name = "clap_derive" -version = "4.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "clap_lex" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const_format" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "cosmos-sdk-proto" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" -dependencies = [ - "prost 0.12.6", - "prost-types 0.12.3", - "tendermint-proto 0.34.0", - "tonic 0.10.2", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e23f6ab56d5f031cde05b8b82a5fefd3a1a223595c79e32317a97189e612bc" -dependencies = [ - "prost 0.12.6", - "prost-types 0.12.3", - "tendermint-proto 0.35.0", -] - -[[package]] -name = "cosmrs" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.20.0", - "ecdsa", - "eyre", - "k256", - "rand_core 0.6.4", - "serde", - "serde_json", - "signature", - "subtle-encoding", - "tendermint 0.34.0", - "tendermint-rpc", - "thiserror", - "tokio", -] - -[[package]] -name = "cosmwasm-crypto" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd50718a2b6830ce9eb5d465de5a018a12e71729d66b70807ce97e6dd14f931d" -dependencies = [ - "digest 0.10.7", - "ecdsa", - "ed25519-zebra", - "k256", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "242e98e7a231c122e08f300d9db3262d1007b51758a8732cd6210b3e9faa4f3a" -dependencies = [ - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8467874827d384c131955ff6f4d47d02e72a956a08eb3c0ff24f8c903a5517b4" -dependencies = [ - "cosmwasm-schema-derive 1.5.4", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "101d0739564bd34cba9b84bf73665f0822487ae3b29b2dd59930608ed3aafd43" -dependencies = [ - "cosmwasm-schema-derive 2.0.4", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6db85d98ac80922aef465e564d5b21fa9cfac5058cb62df7f116c3682337393" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4be75f60158478da2c5d319ed59295bca1687ad50c18215a0485aa91a995ea" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cosmwasm-std" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" -dependencies = [ - "base64 0.21.7", - "bech32 0.9.1", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm 0.5.2", - "sha2 0.10.8", - "static_assertions", - "thiserror", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - -[[package]] -name = "cw-address-like" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451a4691083a88a3c0630a8a88799e9d4cd6679b7ce8ff22b8da2873ff31d380" -dependencies = [ - "cosmwasm-std", -] - -[[package]] -name = "cw-asset" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c999a12f8cd8736f6f86e9a4ede5905530cb23cfdef946b9da1c506ad1b70799" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-address-like", - "cw-storage-plus 1.2.0", - "cw20 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-clearable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e118941d0a55599b788ae502f728b88c9a4c6894a81dbf552828db4c8e2e2e2" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", -] - -[[package]] -name = "cw-controllers" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc33b1d65c102d72f46548c64dca423c337e528d6747d0c595316aa65f887b" -dependencies = [ - "anyhow", - "bech32 0.11.0", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "derivative", - "itertools 0.13.0", - "prost 0.12.6", - "schemars", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-orch" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1ddc937c28c59ccf2765fa05ddc0437644d3b283408a7cc64f7b371b0b9309" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cw-orch-contract-derive", - "cw-orch-core", - "cw-orch-fns-derive 0.19.1", - "cw-orch-mock", - "cw-orch-traits", - "cw-utils", - "hex", - "log", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-orch" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c76d9dd1c2632359f964e3531e5d0833d9022ae9fb216ce9aaaf36070d8bdf" -dependencies = [ - "anyhow", - "cosmrs", - "cosmwasm-std", - "cw-orch-contract-derive", - "cw-orch-core", - "cw-orch-daemon", - "cw-orch-fns-derive 0.21.1", - "cw-orch-mock", - "cw-orch-networks", - "cw-orch-traits", - "cw-utils", - "hex", - "log", - "schemars", - "serde", - "thiserror", - "tokio", -] - -[[package]] -name = "cw-orch-contract-derive" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc8ba75692fc7bd30e91c78fad2dc208a738e4e6ea26b232f9352c320e35543" -dependencies = [ - "convert_case", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "cw-orch-core" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60b3a78e06f38cc7d23127489f356b357d795df8c62090bc66c759f875cbc5f" -dependencies = [ - "abstract-cw-multi-test", - "anyhow", - "cosmos-sdk-proto 0.21.1", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "dirs", - "log", - "serde", - "serde_json", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "cw-orch-daemon" -version = "0.23.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5ddf3e3d51a72acdca54aaa89a3828bb26b720648b3c10bd9ec5cefc7c49c" -dependencies = [ - "anyhow", - "async-recursion", - "base16", - "base64 0.21.7", - "bitcoin", - "chrono", - "cosmrs", - "cosmwasm-std", - "cw-orch-core", - "cw-orch-networks", - "cw-orch-traits", - "dirs", - "ed25519-dalek", - "eyre", - "file-lock", - "flate2", - "hex", - "hkd32", - "lazy_static", - "log", - "once_cell", - "prost 0.12.6", - "prost-types 0.12.3", - "rand_core 0.6.4", - "regex", - "reqwest", - "ring", - "ripemd", - "schemars", - "serde", - "serde_json", - "sha2 0.10.8", - "thiserror", - "tokio", - "tonic 0.10.2", -] - -[[package]] -name = "cw-orch-fns-derive" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9acb7a15bfacc52abdf312a9fffb139883c1effb6ea7e645cd39580a8527463" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-orch-fns-derive" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85c3dea0893dd742c33ede8b4becdfb19b458e86e006ecf9a09ed66331d0c85" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-orch-interchain" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fcf7defbb524e4db4fafd920732de1a7a9ef467b28116223b1e153971e5955" -dependencies = [ - "cosmwasm-std", - "cw-orch-interchain-core", - "cw-orch-interchain-mock", - "cw1", - "cw1-whitelist", - "speculoos", -] - -[[package]] -name = "cw-orch-interchain-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac27dd32926b7f529ed0905e7d5c610126d5eddd8381afd5918831b21c900d" -dependencies = [ - "base64 0.21.7", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch-core", - "cw-orch-mock", - "futures", - "ibc-relayer-types", - "log", - "polytone", - "prost 0.12.6", - "serde_json", - "thiserror", - "tokio", - "tonic 0.10.2", -] - -[[package]] -name = "cw-orch-interchain-mock" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2042d10d65038139d8c2f0a1010ae050b67a43da9b6ee4f4fc2936b2d998b36" -dependencies = [ - "anyhow", - "cosmrs", - "cosmwasm-std", - "cw-orch-core", - "cw-orch-interchain-core", - "cw-orch-mock", - "cw-utils", - "ibc-relayer-types", - "log", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cw-orch-mock" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae9536620b86ee78c2729fd8449538feb4f6257a9809c72c5f9e461e720cf3b" -dependencies = [ - "abstract-cw-multi-test", - "cosmwasm-std", - "cw-orch-core", - "cw-utils", - "log", - "serde", - "sha2 0.10.8", -] - -[[package]] -name = "cw-orch-networks" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8867122381950dc06eab95544e94b62660a74743dc1586d9eeb653a40c4c2beb" -dependencies = [ - "cw-orch-core", - "serde", -] - -[[package]] -name = "cw-orch-traits" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5959ce29e9d8a52594b47933a0a2736ea94dd9bf5e29b220cbdbe2b097f07c3a" -dependencies = [ - "cw-orch-core", - "prost 0.12.6", - "prost-types 0.12.3", -] - -[[package]] -name = "cw-ownable" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-address-like", - "cw-ownable-derive", - "cw-storage-plus 1.2.0", - "cw-utils", - "thiserror", -] - -[[package]] -name = "cw-ownable-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d3bf2e0f341bb6cc100d7d441d31cf713fbd3ce0c511f91e79f14b40a889af" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw-paginate" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add278617f6251be1a35c781eb0fbffd44f899d8bb4dc5a9e420273a90684c4e" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "serde", -] - -[[package]] -name = "cw-placeholder" -version = "1.1.2" -source = "git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "thiserror", -] - -[[package]] -name = "cw-semver" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45fe7f7983e2e37363f440e68ae6e686d1e3f5c611ab5bb692410d88baffd3f6" -dependencies = [ - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b8b840947313c1a1cccf056836cd79a60b4526bdcd6582995be37dc97be4ae" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d7ee1963302b0ac2a9d42fe0faec826209c17452bfd36fbfd9d002a88929261" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw2 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw-vault-multi-standard" -version = "0.3.0" -source = "git+https://github.com/quasar-finance/cw-vault-standard?branch=master#2da85996ead32d50d58eecc8f1d5d245bab0383c" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "cw0" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae676b6cced78a3d38ad4b01ab4ed66fc78ac191c3c0d6bfd5372cb2efd473b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw1" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1605722190afd93bfea6384b88224d1cfe50ebf70d2e10641535da79fa70e83" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw1-whitelist" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bb3e9dc87f4ff26547f4e27e0ba3c82034372f21b2f55527fb52b542637d8d" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw1", - "cw2 1.1.2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7002e6f9c1a1ef3915dca704a6306ba00c39495efd928551d6077c734f9a3d8" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.10.3", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d81d7c359d6c1fba3aa83dad7ec6f999e512571380ae62f81257c3db569743" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.11.1", - "schemars", - "serde", -] - -[[package]] -name = "cw2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc9d54b9b365801beb101a5c0375dceaa5a285bfc14438a7b6007f9d362142" -dependencies = [ - "cosmwasm-std", - "cw0", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "cw20-base" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5df0a946a4a58dd4fdb158ff1595c55774beeef76d09f108b547bce572dcf" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus 0.10.3", - "cw0", - "cw2 0.10.3", - "cw20 0.10.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-base" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ad79e86ea3707229bf78df94e08732e8f713207b4a77b2699755596725e7d9" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "cw20-ics20" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76221201da08fed611c857ea3aa21c031a4a7dc771a8b1750559ca987335dc02" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "schemars", - "semver", - "serde", - "thiserror", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "der" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_macro" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" -dependencies = [ - "derive_builder_core", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "dex-router-osmosis" -version = "0.0.1" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "mars-owner", - "osmosis-std", - "osmosis-test-tube", - "prost 0.12.6", - "quasar-types", - "thiserror", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dyn-clone" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "serde", - "signature", -] - -[[package]] -name = "ed25519-consensus" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" -dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek 4.1.3", - "ed25519", - "serde", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek 3.2.0", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" -dependencies = [ - "serde", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "eyre" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "file-lock" -version = "2.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "040b48f80a749da50292d0f47a1e2d5bf1d772f52836c07f64bfccc62ba6e664" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "flate2" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "anyhow", - "eyre", - "paste", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "function_name" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1ab577a896d09940b5fe12ec5ae71f9d8211fff62c919c03a3750a9901e98a7" -dependencies = [ - "function_name-proc-macro", -] - -[[package]] -name = "function_name-proc-macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673464e1e314dd67a0fd9544abc99e8eb28d0c7e3b69b033bcff9b2d00b87333" - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "globset" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" -dependencies = [ - "aho-corasick", - "bstr", - "log", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 2.1.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex_lit" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" - -[[package]] -name = "hkd32" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e013a4f0b8772418eee1fc462e74017aba13c364a7b61bd3df1ddcbfe47b065" -dependencies = [ - "hmac", - "once_cell", - "pbkdf2", - "rand_core 0.6.4", - "sha2 0.10.8", - "subtle-encoding", - "zeroize", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "home" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ibc-proto" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c352715b36685c2543556a77091fb16af5d26257d5ce9c28e6756c1ccd71aa" -dependencies = [ - "base64 0.21.7", - "bytes", - "flex-error", - "ics23", - "prost 0.11.9", - "serde", - "subtle-encoding", - "tendermint-proto 0.32.2", - "tonic 0.9.2", -] - -[[package]] -name = "ibc-relayer-types" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fa9269c050d20b36a9e61955a5526345df1508f396f7f3a9acb4c03cdb572f3" -dependencies = [ - "bytes", - "derive_more", - "dyn-clone", - "erased-serde", - "flex-error", - "ibc-proto", - "ics23", - "itertools 0.10.5", - "num-rational", - "primitive-types", - "prost 0.11.9", - "regex", - "serde", - "serde_derive", - "serde_json", - "subtle-encoding", - "tendermint 0.32.2", - "tendermint-light-client-verifier", - "tendermint-proto 0.32.2", - "time", - "uint", -] - -[[package]] -name = "ica-oracle" -version = "1.0.0" -source = "git+https://github.com/Stride-Labs/ica-oracle?tag=v1.0.0#2fdf76f3ba4fad6a20a6d10d77c0511f2439b6c3" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "hex", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "ics23" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442d4bab37956e76f739c864f246c825d87c0bb7f9afa65660c57833c91bf6d4" -dependencies = [ - "anyhow", - "bytes", - "hex", - "informalsystems-pbjson", - "prost 0.11.9", - "ripemd", - "serde", - "sha2 0.10.8", - "sha3", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" -dependencies = [ - "equivalent", - "hashbrown 0.14.3", -] - -[[package]] -name = "informalsystems-pbjson" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eecd90f87bea412eac91c6ef94f6b1e390128290898cbe14f2b926787ae1fb" -dependencies = [ - "base64 0.13.1", - "serde", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "k256" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.8", - "signature", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" - -[[package]] -name = "libloading" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" -dependencies = [ - "cfg-if", - "windows-targets 0.52.0", -] - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.4.2", - "libc", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "lst-adapter-osmosis" -version = "0.0.1" -dependencies = [ - "abstract-app", - "abstract-client", - "abstract-cw-orch-polytone", - "abstract-interface 0.22.5", - "abstract-polytone", - "abstract-sdk 0.22.2", - "abstract-std 0.22.2", - "const_format", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-orch 0.23.0", - "cw-orch-interchain", - "cw-storage-plus 1.2.0", - "ibc-relayer-types", - "ica-oracle", - "mars-owner", - "osmosis-std", - "prost 0.12.6", - "quasar-types", - "serde_json", - "thiserror", -] - -[[package]] -name = "lst-dex-adapter-osmosis" -version = "0.0.1" -dependencies = [ - "abstract-app", - "abstract-client", - "abstract-dex-adapter", - "abstract-interface 0.22.5", - "clap", - "const_format", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-orch 0.23.0", - "cw-storage-plus 1.2.0", - "dotenv", - "env_logger", - "lst-adapter-osmosis", - "quasar-types", - "thiserror", - "wyndex-bundle", -] - -[[package]] -name = "mars-owner" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46e0b2f81a8a98036b46730fbe33a337e98e87cb3d34553b45a5ae87c5828c" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "schemars", - "thiserror", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "merkle-incentives" -version = "0.1.0" -dependencies = [ - "base64 0.22.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "osmosis-test-tube", - "rs_merkle", - "schemars", - "serde", - "serde-json-wasm 1.0.1", - "thiserror", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags 2.4.2", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "osmosis-std" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca66dca7e8c9b11b995cd41a44c038134ccca4469894d663d8a9452d6e716241" -dependencies = [ - "chrono", - "cosmwasm-std", - "osmosis-std-derive", - "prost 0.12.6", - "prost-types 0.12.3", - "schemars", - "serde", - "serde-cw-value", -] - -[[package]] -name = "osmosis-std-derive" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ebdfd1bc8ed04db596e110c6baa9b174b04f6ed1ec22c666ddc5cb3fa91bd7" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "prost-types 0.11.9", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "osmosis-test-tube" -version = "25.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb35dcc9adc1b39e23dfae07c9f04a60187fde57a52b7762434ea6548581a1a" -dependencies = [ - "base64 0.21.7", - "bindgen", - "cosmrs", - "cosmwasm-std", - "osmosis-std", - "prost 0.12.6", - "serde", - "serde_json", - "test-tube", - "thiserror", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.0", -] - -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "peg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "polytone" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f16d20da9144fdf0658e785fc9108b86cecee517335ff531745029dd56088" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "thiserror", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "prettyplease" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" -dependencies = [ - "proc-macro2", - "syn 2.0.48", -] - -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-serde", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proptest" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" -dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.4.2", - "lazy_static", - "num-traits", - "rand", - "rand_chacha", - "rand_xorshift", - "regex-syntax", - "rusty-fork", - "tempfile", - "unarray", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes", - "prost-derive 0.12.6", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "prost-derive" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" -dependencies = [ - "anyhow", - "itertools 0.12.1", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", -] - -[[package]] -name = "prost-types" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" -dependencies = [ - "prost 0.12.6", -] - -[[package]] -name = "protobuf" -version = "2.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" -dependencies = [ - "bytes", -] - -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "quasar-types" -version = "0.1.0" -dependencies = [ - "cosmos-sdk-proto 0.21.1", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw20 1.1.2", - "derive_more", - "osmosis-std", - "osmosis-std-derive", - "prost 0.12.6", - "rust_decimal", - "schemars", - "serde", - "serde-json-wasm 1.0.1", - "serde_json", - "serde_test", - "thiserror", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "range-middleware" -version = "0.3.0" -dependencies = [ - "cl-vault", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-multi-test", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "dex-router-osmosis", - "osmosis-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" -dependencies = [ - "bitflags 2.4.2", -] - -[[package]] -name = "redox_users" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rend" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" -dependencies = [ - "cc", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.48.0", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "rkyv" -version = "0.7.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" -dependencies = [ - "bitvec", - "bytecheck", - "bytes", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid 1.9.1", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rs_merkle" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b241d2e59b74ef9e98d94c78c47623d04c8392abaf82014dfd372a16041128f" -dependencies = [ - "sha2 0.10.8", -] - -[[package]] -name = "rust-embed" -version = "8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" -dependencies = [ - "rust-embed-impl", - "rust-embed-utils", - "walkdir", -] - -[[package]] -name = "rust-embed-impl" -version = "8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4" -dependencies = [ - "proc-macro2", - "quote", - "rust-embed-utils", - "syn 2.0.48", - "walkdir", -] - -[[package]] -name = "rust-embed-utils" -version = "8.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32" -dependencies = [ - "globset", - "sha2 0.10.8", - "walkdir", -] - -[[package]] -name = "rust_decimal" -version = "1.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" -dependencies = [ - "arrayvec", - "borsh", - "bytes", - "num-traits", - "rand", - "rkyv", - "serde", - "serde_json", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" -dependencies = [ - "bitflags 2.4.2", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.21.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - -[[package]] -name = "ryu" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.48", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "secp256k1" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" -dependencies = [ - "bitcoin_hashes", - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-cw-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" -dependencies = [ - "serde", -] - -[[package]] -name = "serde-json-wasm" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "serde_json" -version = "1.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "serde_test" -version = "1.0.176" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "speculoos" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65881c9270d6157f30a09233305da51bed97eef9192d0ea21e57b1c8f05c3620" -dependencies = [ - "num", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "tendermint" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" -dependencies = [ - "bytes", - "digest 0.10.7", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.8", - "signature", - "subtle", - "subtle-encoding", - "tendermint-proto 0.32.2", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789" -dependencies = [ - "bytes", - "digest 0.10.7", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "k256", - "num-traits", - "once_cell", - "prost 0.12.6", - "prost-types 0.12.3", - "ripemd", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.8", - "signature", - "subtle", - "subtle-encoding", - "tendermint-proto 0.34.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-config" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a25dbe8b953e80f3d61789fbdb83bf9ad6c0ef16df5ca6546f49912542cc137" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.34.0", - "toml", - "url", -] - -[[package]] -name = "tendermint-light-client-verifier" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9875dce5c1b08201152eb0860f8fb1dce96c53e37532c310ffc4956d20f90def" -dependencies = [ - "derive_more", - "flex-error", - "serde", - "tendermint 0.32.2", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cec054567d16d85e8c3f6a3139963d1a66d9d3051ed545d31562550e9bcc3d" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.12.6", - "prost-types 0.12.3", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff525d5540a9fc535c38dc0d92a98da3ee36fcdfbda99cecb9f3cce5cd4d41d7" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.4.2", - "num-traits", - "prost 0.12.6", - "prost-types 0.12.3", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-rpc" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbf0a4753b46a190f367337e0163d0b552a2674a6bac54e74f9f2cdcde2969b" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "peg", - "pin-project", - "reqwest", - "semver", - "serde", - "serde_bytes", - "serde_json", - "subtle", - "subtle-encoding", - "tendermint 0.34.0", - "tendermint-config", - "tendermint-proto 0.34.0", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid 0.8.2", - "walkdir", -] - -[[package]] -name = "test-tube" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804bb9bda992b6cda6f883e7973cb999d4da90d21257fb918d6a693407148681" -dependencies = [ - "base64 0.21.7", - "cosmrs", - "cosmwasm-std", - "osmosis-std", - "prost 0.12.6", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "time" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" -dependencies = [ - "libc", - "num_threads", - "time-macros", -] - -[[package]] -name = "time-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "token-burner" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "itertools 0.12.1", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "tokio" -version = "1.35.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" - -[[package]] -name = "toml_edit" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" -dependencies = [ - "indexmap 2.1.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tonic" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.12.6", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "tokio", - "tokio-rustls", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" - -[[package]] -name = "uuid" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - -[[package]] -name = "walkdir" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.48", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "wasmswap" -version = "1.2.0" -source = "git+https://github.com/Wasmswap/wasmswap-contracts?tag=v1.2.0#cbca1f2bd8088b2ac6784c47a4509227a227c755" -dependencies = [ - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.10.3", - "cw0", - "cw2 0.11.1", - "cw20 0.10.3", - "cw20-base 0.10.3", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" - -[[package]] -name = "winnow" -version = "0.5.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "wynd-utils" -version = "1.4.0" -source = "git+https://github.com/cosmorama/wynddao.git?tag=v1.4.0#5e85ebde304b2a65146beaf9d3098f8e2a2a223e" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "wyndex" -version = "1.1.2" -source = "git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw20 1.1.2", - "cw20-base 1.1.2", - "itertools 0.10.5", - "thiserror", - "uint", -] - -[[package]] -name = "wyndex" -version = "1.1.2" -source = "git+https://github.com/wynddao/wynddex?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw20 1.1.2", - "cw20-base 1.1.2", - "itertools 0.10.5", - "thiserror", - "uint", -] - -[[package]] -name = "wyndex-bundle" -version = "0.22.1" -source = "git+https://github.com/AbstractSDK/abstract.git?tag=v0.22.1#b3763085017976e4e2ba43c64bad76378fdf3df0" -dependencies = [ - "abstract-cw-plus-interface", - "abstract-cw20", - "abstract-cw20-base", - "abstract-interface 0.22.5", - "abstract-std 0.22.2", - "anyhow", - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-asset", - "cw-controllers", - "cw-orch 0.22.2", - "wyndex 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", - "wyndex-factory", - "wyndex-multi-hop", - "wyndex-pair", - "wyndex-stake 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", -] - -[[package]] -name = "wyndex-factory" -version = "1.1.2" -source = "git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-placeholder", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "itertools 0.10.5", - "thiserror", - "wyndex 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", - "wyndex-stake 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", -] - -[[package]] -name = "wyndex-multi-hop" -version = "1.1.2" -source = "git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "cw20 1.1.2", - "thiserror", - "wyndex 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", -] - -[[package]] -name = "wyndex-pair" -version = "1.1.2" -source = "git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "cw20-base 1.1.2", - "wyndex 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", - "wyndex-stake 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", -] - -[[package]] -name = "wyndex-stake" -version = "1.1.2" -source = "git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "serde", - "thiserror", - "wynd-utils", - "wyndex 1.1.2 (git+https://github.com/cosmorama/wynddex.git?tag=v1.1.2)", -] - -[[package]] -name = "wyndex-stake" -version = "1.1.2" -source = "git+https://github.com/wynddao/wynddex?tag=v1.1.2#acca3311673d9d7c990a88d910f4a03a9acf25fd" -dependencies = [ - "cosmwasm-schema 1.5.4", - "cosmwasm-std", - "cw-controllers", - "cw-storage-plus 1.2.0", - "cw-utils", - "cw2 1.1.2", - "cw20 1.1.2", - "serde", - "thiserror", - "wynd-utils", - "wyndex 1.1.2 (git+https://github.com/wynddao/wynddex?tag=v1.1.2)", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zeroize" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] diff --git a/smart-contracts/contracts/airdrop/.gitignore b/smart-contracts/contracts/airdrop/.gitignore deleted file mode 100644 index 360bb05b1..000000000 --- a/smart-contracts/contracts/airdrop/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ts -schema diff --git a/smart-contracts/contracts/airdrop/Cargo.toml b/smart-contracts/contracts/airdrop/Cargo.toml deleted file mode 100644 index 91a101ee4..000000000 --- a/smart-contracts/contracts/airdrop/Cargo.toml +++ /dev/null @@ -1,32 +0,0 @@ -[package] -name = "airdrop" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde ={ workspace = true } -thiserror ={ workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cw20-base = { workspace = true } -cw-asset = { workspace = true } -num_enum = { workspace = true } -itertools = { workspace = true } \ No newline at end of file diff --git a/smart-contracts/contracts/airdrop/examples/schema.rs b/smart-contracts/contracts/airdrop/examples/schema.rs deleted file mode 100644 index 0f41c1516..000000000 --- a/smart-contracts/contracts/airdrop/examples/schema.rs +++ /dev/null @@ -1,10 +0,0 @@ -use airdrop::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use cosmwasm_schema::write_api; - -fn main() { - write_api! { - instantiate: InstantiateMsg, - query: QueryMsg, - execute: ExecuteMsg, - } -} diff --git a/smart-contracts/contracts/airdrop/src/admin.rs b/smart-contracts/contracts/airdrop/src/admin.rs deleted file mode 100644 index 48b586c64..000000000 --- a/smart-contracts/contracts/airdrop/src/admin.rs +++ /dev/null @@ -1,459 +0,0 @@ -use std::string::String; - -use cosmwasm_std::{Attribute, DepsMut, Env, Event, Response, Uint128}; -use cw_asset::Asset; - -use crate::helpers::{ - check_amounts_and_airdrop_size, get_total_in_user_info, validate_amount, validate_update_config, -}; -use crate::msg::User; -use crate::state::{AirdropConfig, UserInfo, AIRDROP_CONFIG, USER_INFO}; -use crate::AirdropErrors; - -/// Updates the airdrop configuration of the contract. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `env` - The current contract execution environment. -/// * `config` - The new airdrop configuration to be set. -/// -/// # Errors -/// -/// Returns an error if the airdrop has already ended or if the new configuration is invalid. -/// -/// # Returns -/// -/// Returns a response indicating the success of the update operation and includes -/// relevant attributes in the event. -pub fn execute_update_airdrop_config( - deps: DepsMut, - env: Env, - config: AirdropConfig, -) -> Result { - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - if current_airdrop_config.is_airdrop_active(env.block.height) { - return Err(AirdropErrors::InvalidChangeInAirdropConfig {}); - } - - // Check if an airdrop has been executed on the contract and if the update is allowed - if current_airdrop_config.end_height != 0 - && env.block.height > current_airdrop_config.end_height - { - return Err(AirdropErrors::InvalidChangeInAirdropConfig {}); - } - - validate_update_config(config.clone(), deps.storage, deps.querier, env)?; - AIRDROP_CONFIG.save(deps.storage, &config)?; - - // Return a default response to indicate success with an "update_airdrop_config" event - Ok(Response::new().add_event( - Event::new("update_airdrop_config") - .add_attribute( - "description".to_string(), - config.airdrop_description.to_string(), - ) - .add_attribute( - "airdrop_amount".to_string(), - config.airdrop_amount.to_string(), - ) - .add_attribute( - "airdrop_asset".to_string(), - config.airdrop_asset.to_string(), - ) - .add_attribute("claimed".to_string(), config.total_claimed.to_string()) - .add_attribute("start_height".to_string(), config.start_height.to_string()) - .add_attribute("end_height".to_string(), config.end_height.to_string()), - )) -} - -/// Adds new users and their respective amounts to the airdrop configuration. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `users` - A vector of user addresses to be added. -/// * `amounts` - A vector of amounts to be allocated to each user. -/// -/// # Errors -/// -/// Returns an error if the airdrop window is not open, the number of users and amounts provided do not match, -/// or if any of the provided users already have existing claims or allocations. -/// -/// # Returns -/// -/// Returns a response indicating the success of the addition operation and includes relevant attributes -/// in the event. -pub fn execute_add_users(deps: DepsMut, users: Vec) -> Result { - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - // Check if the current airdrop window is not open (start_height or end_height not zero) - if current_airdrop_config.start_height != 0 || current_airdrop_config.end_height != 0 { - return Err(AirdropErrors::InvalidChangeUserInfo {}); - } - - let mut attributes: Vec = Vec::new(); - - // Loop through the provided users and amounts - for user in users { - // Validate the user's address - deps.api.addr_validate(&user.address)?; - - // Validate that the amount is not zero - validate_amount(user.clone())?; - - // Attempt to load user_info from storage - let maybe_user_info = USER_INFO.may_load(deps.storage, user.address.clone())?; - - // Check if the user_info exists (is not empty) - if let Some(user_info) = maybe_user_info { - // User info exists, perform your checks here - if user_info.get_claimable_amount() != Uint128::zero() || user_info.get_claimed_flag() { - // Handle the case where user_info exists - return Err(AirdropErrors::AlreadyExists { user: user.address }); - } - } else { - // User info does not exist, create a new entry - let new_user_info = UserInfo { - claimable_amount: user.amount, - claimed_flag: false, - }; - USER_INFO.save(deps.storage, user.address.to_string(), &new_user_info)?; - - // Add user and amount to attributes for the event - attributes.push(Attribute { - key: "address".to_string(), - value: user.address.to_string(), - }); - attributes.push(Attribute { - key: "amount".to_string(), - value: user.amount.to_string(), - }); - } - } - - // config is invalid of total claimable assigned to users is greater than amount assigned to the airdrop - check_amounts_and_airdrop_size( - get_total_in_user_info(deps.storage), - current_airdrop_config.airdrop_amount, - )?; - - // Return a default response if all checks pass with an "airdrop_add_users" event - Ok(Response::new().add_event(Event::new("airdrop_add_users").add_attributes(attributes))) -} - -/// Sets or updates the allocation of claimable amounts for a list of users in the airdrop configuration. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `users` - A vector of user addresses to set or update allocations for. -/// * `amounts` - A vector of amounts to be allocated to each user. -/// -/// # Errors -/// -/// Returns an error if the airdrop window is not open (start_height or end_height not zero), -/// the number of users and amounts provided do not match, or if any of the provided users have claimed their allocations. -/// -/// # Returns -/// -/// Returns a response indicating the success of the set/update operation and includes relevant attributes -/// in the event. -pub fn execute_set_users(deps: DepsMut, users: Vec) -> Result { - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - // Check if the current airdrop window is not open (start_height or end_height not zero) - if current_airdrop_config.start_height != 0 || current_airdrop_config.end_height != 0 { - return Err(AirdropErrors::InvalidChangeUserInfo {}); - } - - let mut attributes: Vec = Vec::new(); - - for user in users { - // Validate the user's address - deps.api.addr_validate(&user.address)?; - - // Validate that the amount is not zero - validate_amount(user.clone())?; - - // Load the user's current information from storage - let user_info = USER_INFO.load(deps.storage, user.address.to_string())?; - - // Check if the user has not claimed - if !user_info.get_claimed_flag() { - // Update all the users with the given info - let new_user_info = UserInfo { - claimable_amount: user.amount, - claimed_flag: false, - }; - USER_INFO.save(deps.storage, user.address.to_string(), &new_user_info)?; - - // Add user and amount to attributes for the event - attributes.push(Attribute { - key: "address".to_string(), - value: user.address.to_string(), - }); - attributes.push(Attribute { - key: "amount".to_string(), - value: user.amount.to_string(), - }) - } - } - - // config is invalid of total claimable assigned to users is greater than amount assigned to the airdrop - check_amounts_and_airdrop_size( - get_total_in_user_info(deps.storage), - current_airdrop_config.airdrop_amount, - )?; - - // Return a default response if all checks pass with an "airdrop_set_users" event - Ok(Response::new().add_event(Event::new("airdrop_set_users").add_attributes(attributes))) -} - -/// Removes specified users from the airdrop configuration if they have not claimed their allocations. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `users` - A vector of user addresses to remove from the airdrop configuration. -/// -/// # Errors -/// -/// Returns an error if the airdrop window is not open (start_height or end_height not zero). -/// -/// # Returns -/// -/// Returns a response indicating the success of the removal operation and includes relevant attributes -/// in the event for each removed user. -pub fn execute_remove_users(deps: DepsMut, users: Vec) -> Result { - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - // Check if the current airdrop window is not open (start_height or end_height not zero) - if current_airdrop_config.start_height != 0 || current_airdrop_config.end_height != 0 { - return Err(AirdropErrors::InvalidChangeUserInfo {}); - } - - // Initialize vectors to store removed users and attributes for the event - let mut removed_users: Vec = Vec::new(); - let mut attributes: Vec = Vec::new(); - - // Iterate through the list of users to be removed - for user in users.iter() { - // Validate the user's address - deps.api.addr_validate(user)?; - - // Load the user_info entry from storage - let user_info = USER_INFO.load(deps.storage, user.to_string())?; - - // Check if the claimed flag is false, indicating that the user has not claimed - if !user_info.get_claimed_flag() { - // Add the user's address to the list of removed users - removed_users.push(user.to_string()); - - // Remove the user's entry from the USER_INFO map - USER_INFO.remove(deps.storage, user.to_string()); - - // Add user address as an attribute for the event - attributes.push(Attribute { - key: "address".to_string(), - value: user.to_string(), - }); - } - } - - // Return a default response if all checks pass with an "airdrop_remove_users" event - Ok(Response::new().add_event(Event::new("airdrop_remove_users").add_attributes(attributes))) -} - -/// Withdraws airdrop funds to the specified address after the airdrop window has ended. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage, external data, and assets. -/// * `env` - Environment information including the current block height. -/// * `withdraw_address` - The address to which the airdrop funds will be withdrawn. -/// -/// # Errors -/// -/// Returns an error if the current block height is not within the airdrop window or the window is open-ended. -/// Also returns an error if the withdrawal address is invalid. -/// -/// # Returns -/// -/// Returns a response indicating the success of the withdrawal and includes attributes in the response for tracking. -pub fn execute_withdraw_funds( - deps: DepsMut, - env: Env, - withdraw_address: String, -) -> Result { - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - // Check if the current block height is within the airdrop window or the window is open-ended - if env.block.height < current_airdrop_config.end_height - || current_airdrop_config.end_height == 0 - || current_airdrop_config.start_height == 0 - { - return Err(AirdropErrors::InvalidWithdraw {}); - } - - // Validate the withdrawal address - deps.api.addr_validate(&withdraw_address)?; - - // Load the current airdrop configuration again to ensure consistency - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - // Query the contract's balance of the airdrop asset - let contract_balance = current_airdrop_config - .airdrop_asset - .query_balance(&deps.querier, &env.contract.address)?; - - // Transfer the airdrop asset to the withdrawal address - let withdraw = Asset::new(current_airdrop_config.airdrop_asset, contract_balance) - .transfer_msg(&withdraw_address)?; - - // Return a response and add the withdraw transfer message - Ok(Response::new().add_message(withdraw).add_attributes(vec![ - ("action", "withdraw"), - ("address", env.contract.address.as_ref()), - ("amount", &contract_balance.to_string()), - ])) -} - -// Import necessary modules for testing -#[cfg(test)] -mod tests { - // Import the necessary items for testing - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{Addr, Coin}; - use cw_asset::AssetInfo; - - use crate::contract::instantiate; - use crate::msg::InstantiateMsg; - - // Define a helper function to create a mock contract configuration - fn mock_config_1() -> AirdropConfig { - AirdropConfig { - airdrop_title: "Test Title".to_string(), - airdrop_description: "Test Airdrop".to_string(), - airdrop_amount: Uint128::new(1000000), // Adjust this value as needed - airdrop_asset: AssetInfo::Native("uqsr".parse().unwrap()), - total_claimed: Uint128::new(0), - start_height: 12346, // Adjust this value as needed - end_height: 14567, // Adjust this value as needed - } - } - - // Define a helper function to create a mock contract configuration - fn mock_config_2() -> AirdropConfig { - AirdropConfig { - airdrop_title: "Test Title".to_string(), - airdrop_description: "Test Airdrop".to_string(), - airdrop_amount: Uint128::new(1000000), // Adjust this value as needed - airdrop_asset: AssetInfo::Native("uqsr".parse().unwrap()), - total_claimed: Uint128::new(0), - start_height: 0, // Adjust this value as needed - end_height: 0, // Adjust this value as needed - } - } - - // Define a test case for updating the airdrop configuration - #[test] - fn test_execute_update_airdrop_config() { - // Create mock dependencies, environment, and config - let mut deps = mock_dependencies(); - let env = mock_env(); - let info = mock_info("admin", &[Coin::new(100000000, "uqsr")]); - let config = mock_config_1(); - - // Execute the instantiate function to set up the initial state (if needed) - let instantiate_msg_1 = InstantiateMsg { - config: config.clone(), - }; - instantiate(deps.as_mut(), env.clone(), info.clone(), instantiate_msg_1).unwrap_err(); - - // instantiate with a correct config - let instantiate_msg_2 = InstantiateMsg { - config: mock_config_2(), - }; - instantiate(deps.as_mut(), env.clone(), info.clone(), instantiate_msg_2).unwrap(); - - // try to update config with wrong conditions - execute_update_airdrop_config(deps.as_mut(), env.clone(), config.clone()).unwrap_err(); - - // add users to the airdrop - let users: Vec = vec![ - User { - address: "user1".to_string(), - amount: Uint128::new(330000), - }, - User { - address: "user2".to_string(), - amount: Uint128::new(330000), - }, - User { - address: "user3".to_string(), - amount: Uint128::new(330000), - }, - ]; - let add_users_response = execute_add_users(deps.as_mut(), users).unwrap(); - assert_eq!(add_users_response.events[0].attributes.len(), 6); - - // set a user so that the total is higher than airdrop size - let users1: Vec = vec![User { - address: "user1".to_string(), - amount: Uint128::new(630000), - }]; - execute_set_users(deps.as_mut(), users1).unwrap_err(); - - // set users with new values and the amount should be less than the airdrop size - let users2: Vec = vec![ - User { - address: "user1".to_string(), - amount: Uint128::new(230000), - }, - User { - address: "user2".to_string(), - amount: Uint128::new(430000), - }, - ]; - let set_users_response = execute_set_users(deps.as_mut(), users2).unwrap(); - assert_eq!(set_users_response.events[0].attributes.len(), 4); - - // remove user1 which should be successful - let users3: Vec = vec!["user1".to_string()]; - let set_users_response = execute_remove_users(deps.as_mut(), users3).unwrap(); - assert_eq!(set_users_response.events[0].attributes.len(), 1); - - // remove user4 which should result into an error - let users4: Vec = vec!["user4".to_string()]; - execute_remove_users(deps.as_mut(), users4).unwrap_err(); - - // add the user1 again - let users5: Vec = vec![User { - address: "user1".to_string(), - amount: Uint128::new(230000), - }]; - - let set_users_response = execute_add_users(deps.as_mut(), users5).unwrap(); - assert_eq!(set_users_response.events[0].attributes.len(), 2); - - // update the airdrop config with - let new_balance: Vec = vec![Coin { - denom: "uqsr".to_string(), - amount: Uint128::new(1000000), - }]; - let address = Addr::unchecked("cosmos2contract"); - deps.querier.update_balance(address, new_balance); - let execute_response = - execute_update_airdrop_config(deps.as_mut(), env.clone(), config.clone()).unwrap(); - - // Ensure that the response is successful - assert_eq!(execute_response.events[0].attributes.len(), 6); // Check for expected attributes - - // Verify that the new configuration is stored - let stored_config = AIRDROP_CONFIG.load(deps.as_ref().storage); - assert_eq!(stored_config.unwrap(), config); - } -} diff --git a/smart-contracts/contracts/airdrop/src/contract.rs b/smart-contracts/contracts/airdrop/src/contract.rs deleted file mode 100644 index 0961eb2b7..000000000 --- a/smart-contracts/contracts/airdrop/src/contract.rs +++ /dev/null @@ -1,168 +0,0 @@ -use cosmwasm_std::{ - entry_point, to_json_binary, Binary, Deps, DepsMut, Env, Event, MessageInfo, Response, - StdResult, Uint128, -}; -use cw2::set_contract_version; -use cw20_base::msg::MigrateMsg; - -use crate::admin::{ - execute_add_users, execute_remove_users, execute_set_users, execute_update_airdrop_config, - execute_withdraw_funds, -}; -use crate::error::AirdropErrors; -use crate::helpers::is_contract_admin; -use crate::msg::{AdminExecuteMsg, ExecuteMsg, InstantiateMsg, QueryMsg}; -use crate::query::{ - query_airdrop_readiness, query_config, query_contract_state, query_user, query_users_stats, -}; -use crate::state::AIRDROP_CONFIG; -use crate::users::execute_claim; - -// version info for migration info -const CONTRACT_NAME: &str = "quasar_airdrop"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -/// Instantiates the airdrop contract with the provided configuration. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `_env` - Environment information, not used in this function. -/// * `_info` - Message sender's information, not used in this function. -/// * `msg` - Instantiate message containing the airdrop configuration. -/// -/// # Errors -/// -/// Returns an error if the airdrop configuration is invalid, specifically if start height, -/// end height, and total claimed are not set to zero. -/// -/// # Returns -/// -/// Returns a response indicating the success of contract instantiation and includes attributes -/// describing the airdrop configuration. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - // Set the contract version in storage - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Check if the contract should not be instantiated due to an invalid airdrop window - if msg.config.start_height != 0 - || msg.config.end_height != 0 - || msg.config.total_claimed != Uint128::zero() - { - return Err(AirdropErrors::InvalidAirdropWindow {}); - } - - // Save the new airdrop configuration to storage - AIRDROP_CONFIG.save(deps.storage, &msg.config)?; - - // Return a response indicating successful contract instantiation with attributes - Ok(Response::new().add_event( - Event::new("instantiate_airdrop_contract") - .add_attribute( - "description".to_string(), - msg.config.airdrop_description.to_string(), - ) - .add_attribute( - "airdrop_amount".to_string(), - msg.config.airdrop_amount.to_string(), - ) - .add_attribute( - "airdrop_asset".to_string(), - msg.config.airdrop_asset.to_string(), - ) - .add_attribute("claimed".to_string(), msg.config.total_claimed.to_string()) - .add_attribute( - "start_height".to_string(), - msg.config.start_height.to_string(), - ) - .add_attribute("end_height".to_string(), msg.config.end_height.to_string()), - )) -} - -/// Executes contract operations based on the received message. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `env` - Environment information. -/// * `info` - Message sender's information. -/// * `msg` - Execute message to determine the operation. -/// -/// # Returns -/// -/// Returns a response based on the executed operation or an error if the operation fails. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Admin(admin_msg) => { - // Check if the sender is a contract admin - is_contract_admin(&deps.querier, &env, &info.sender)?; - - match admin_msg { - AdminExecuteMsg::UpdateAirdropConfig(airdrop_config) => { - // Call the function to update the airdrop configuration - execute_update_airdrop_config(deps, env, airdrop_config) - } - AdminExecuteMsg::AddUsers { users } => { - // Call the function to add users and their amounts - execute_add_users(deps, users) - } - AdminExecuteMsg::RemoveUsers(users) => execute_remove_users(deps, users), - AdminExecuteMsg::WithdrawFunds(withdraw_address) => { - execute_withdraw_funds(deps, env, withdraw_address) - } - AdminExecuteMsg::SetUsers { users } => execute_set_users(deps, users), - } - } - ExecuteMsg::ClaimAirdrop() => execute_claim(deps, env, info.sender), - } -} - -/// Queries contract state based on the received query message. -/// -/// # Arguments -/// -/// * `deps` - Dependencies to access storage and external data. -/// * `env` - Environment information. -/// * `msg` - Query message to determine the requested information. -/// -/// # Returns -/// -/// Returns a binary response containing the queried information or an error if the query fails. -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::AirdropConfigQuery {} => to_json_binary(&query_config(deps)?), - QueryMsg::UserInfoQuery { user } => to_json_binary(&query_user(deps, user)?), - QueryMsg::ContractStateQuery {} => to_json_binary(&query_contract_state(deps)?), - QueryMsg::SanityCheckQuery {} => to_json_binary(&query_airdrop_readiness(deps, env)?), - QueryMsg::UsersStatsQuery {} => to_json_binary(&query_users_stats(deps)?), - } -} - -/// Migrates the contract to a new version (not implemented). -/// -/// # Arguments -/// -/// * `_deps` - Dependencies to access storage and external data, not used in this function. -/// * `_env` - Environment information, not used in this function. -/// * `_msg` - Migrate message, not used in this function. -/// -/// # Returns -/// -/// Returns a response indicating a successful migration (not implemented). -#[entry_point] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - Ok(Response::new().add_attribute("migrate", "successful")) -} diff --git a/smart-contracts/contracts/airdrop/src/error.rs b/smart-contracts/contracts/airdrop/src/error.rs deleted file mode 100644 index d7757c1f9..000000000 --- a/smart-contracts/contracts/airdrop/src/error.rs +++ /dev/null @@ -1,60 +0,0 @@ -use cosmwasm_std::{StdError, Uint128}; -use cw_asset::AssetError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum AirdropErrors { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Asset(#[from] AssetError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Invalid airdrop window")] - InvalidAirdropWindow {}, - - #[error("Airdrop config cannot be changed once airdrop is active")] - InvalidChangeInConfig {}, - - #[error("User info cannot be changed once airdrop is active")] - InvalidChangeUserInfo {}, - - #[error("Withdraw is in an invalid window")] - InvalidWithdraw {}, - - #[error("Claim is in an invalid window")] - InvalidClaim {}, - - #[error("Already claimed")] - AlreadyClaimed {}, - - #[error("Already exists : {user:?}")] - AlreadyExists { user: String }, - - #[error("Invalid change in airdrop config")] - InvalidChangeInAirdropConfig {}, - - #[error("Insufficient funds in contract account. Balance: {balance:?}")] - InsufficientFundsInContractAccount { balance: Uint128 }, - - #[error("Total amount in the given user amounts {total_in_user_info:?} is greater than {current_airdrop_amount:?}")] - UserAmountIsGreaterThanTotal { - total_in_user_info: Uint128, - current_airdrop_amount: Uint128, - }, - - #[error("Failed due to config has less amount than the amount allowed to the users to claim")] - ConfigAmountLessThanTotalClaimable {}, - - #[error("Failed as total claimed is non zero")] - NonZeroClaimedAmount {}, - - #[error("Given number of users do not match the given number of amounts which results into a mismatch")] - UnequalLengths {}, - - #[error("Amount for address {address:?} is zero")] - ZeroAmount { address: String }, -} diff --git a/smart-contracts/contracts/airdrop/src/helpers.rs b/smart-contracts/contracts/airdrop/src/helpers.rs deleted file mode 100644 index 7ac09cc23..000000000 --- a/smart-contracts/contracts/airdrop/src/helpers.rs +++ /dev/null @@ -1,242 +0,0 @@ -use cosmwasm_std::{Addr, Env, Order, QuerierWrapper, Response, Storage, Uint128}; - -use crate::error::AirdropErrors; -use crate::msg::User; -use crate::state::{AirdropConfig, AIRDROP_CONFIG, USER_INFO}; - -/// Checks if the sender is the contract admin. Returns an error if not authorized. -/// -/// # Arguments -/// -/// * `querier` - QuerierWrapper to query contract admin information. -/// * `env` - Environment information. -/// * `sus_admin` - Address of the sender. -/// -/// # Returns -/// -/// Returns `Ok(())` if the sender is authorized as the contract admin, otherwise returns an Unauthorized error. -pub fn is_contract_admin( - querier: &QuerierWrapper, - env: &Env, - sus_admin: &Addr, -) -> Result<(), AirdropErrors> { - // Get the contract admin address from the contract's information - let contract_admin = querier - .query_wasm_contract_info(&env.contract.address)? - .admin; - - // Check if the contract admin address exists - if let Some(contract_admin) = contract_admin { - // Compare the contract admin address with the provided sus_admin address - if contract_admin != *sus_admin { - // If they don't match, return an Unauthorized error - return Err(AirdropErrors::Unauthorized {}); - } - } else { - // If the contract admin address doesn't exist, return an Unauthorized error - return Err(AirdropErrors::Unauthorized {}); - } - - // If all checks pass, return Ok() to indicate success - Ok(()) -} - -/// Checks if the total claimable amount exceeds the airdrop amount. -/// -/// # Arguments -/// -/// * `total_in_user_info` - Total claimable amount from all users. -/// * `current_airdrop_amount` - Current airdrop amount in the contract. -/// -/// # Returns -/// -/// Returns a default response if the total claimable amount does not exceed the airdrop amount, -/// otherwise returns an error indicating insufficient funds. -pub fn check_amounts_and_airdrop_size( - total_in_user_info: Uint128, - current_airdrop_amount: Uint128, -) -> Result { - // Check if the total claimable amount exceeds the airdrop amount - if total_in_user_info > current_airdrop_amount { - return Err(AirdropErrors::UserAmountIsGreaterThanTotal { - total_in_user_info, - current_airdrop_amount, - }); - } - Ok(Response::default()) -} - -/// Validates that an amount is not zero. -/// -/// # Arguments -/// -/// * `amount` - Amount to validate. -/// * `index` - Index of the amount in a list (used for error message). -/// -/// # Returns -/// -/// Returns a default response if the amount is not zero, otherwise returns an error indicating a zero amount. -pub fn validate_amount(user: User) -> Result { - // Check if the amount is not zero - if user.amount == Uint128::zero() { - return Err(AirdropErrors::ZeroAmount { - address: user.address, - }); - } - Ok(Response::default()) -} - -/// Validates and checks the airdrop configuration update. -/// -/// # Arguments -/// -/// * `config` - New airdrop configuration to validate. -/// * `storage` - Storage to access contract state. -/// * `querier` - QuerierWrapper to query contract state. -/// * `env` - Environment information. -/// -/// # Returns -/// -/// Returns a default response if the configuration update is valid, otherwise returns an error -/// indicating the reason for the validation failure. -pub fn validate_update_config( - config: AirdropConfig, - storage: &dyn Storage, - querier: QuerierWrapper, - env: Env, -) -> Result { - // Check if the start height and end height are not zero, - // indicating a valid airdrop window - if config.total_claimed == Uint128::zero() { - if config.start_height != 0 || config.end_height != 0 { - // Check if the current block height is less than the start height - // and if the start height is less than the end height - if env.block.height < config.start_height && config.start_height < config.end_height { - // Check if the airdrop amount is sufficient to supply all users - if config.airdrop_amount >= get_total_in_user_info(storage) { - // Get the contract's bank balance - let current_airdrop_config = AIRDROP_CONFIG.load(storage)?; - let contract_balance = current_airdrop_config - .airdrop_asset - .query_balance(&querier, &env.contract.address)?; - - // Check if the contract has enough funds for the airdrop - if contract_balance < config.airdrop_amount { - return Err(AirdropErrors::InsufficientFundsInContractAccount { - balance: contract_balance, - }); - } - } else { - return Err(AirdropErrors::ConfigAmountLessThanTotalClaimable {}); - } - } else { - return Err(AirdropErrors::InvalidAirdropWindow {}); - } - } - } else { - return Err(AirdropErrors::NonZeroClaimedAmount {}); - } - Ok(Response::default()) -} - -/// Calculates the total claimable amount from all users. -/// -/// # Arguments -/// -/// * `storage` - Storage to access user information. -/// -/// # Returns -/// -/// Returns the total claimable amount from all users. -pub fn get_total_in_user_info(storage: &dyn Storage) -> Uint128 { - let mut total_claimable_amount = Uint128::zero(); - - for res in USER_INFO.range(storage, None, None, Order::Ascending) { - let claimed = res.as_ref().unwrap().1.get_claimed_flag(); - if !claimed { - total_claimable_amount += res.unwrap().1.get_claimable_amount() - } - } - - // Return the total claimable amount - total_claimable_amount -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::testing::mock_dependencies; - - use crate::state::UserInfo; - - use super::*; - - #[test] - fn test_get_total_in_user_info() { - // Create a mock context and storage - let mut deps = mock_dependencies(); - - // Initialize the USER_INFO map in the mock storage with sample data - USER_INFO - .save( - &mut deps.storage, - "user1".parse().unwrap(), - &UserInfo { - claimable_amount: Uint128::new(100), - claimed_flag: false, - }, - ) - .unwrap(); - USER_INFO - .save( - &mut deps.storage, - "user2".parse().unwrap(), - &UserInfo { - claimable_amount: Uint128::new(200), - claimed_flag: false, - }, - ) - .unwrap(); - - // Call the function to be tested - let total_claimable_amount = get_total_in_user_info(deps.as_mut().storage); - - // Check the result against the expected total claimable amount - assert_eq!(total_claimable_amount, Uint128::new(300)); - } - - #[test] - fn test_validate_amount() { - let err = validate_amount(User { - address: "test".to_string(), - amount: Uint128::new(0), - }) - .unwrap_err(); - assert_eq!( - AirdropErrors::ZeroAmount { - address: "test".to_string() - }, - err - ); - let _resp = validate_amount(User { - address: "test".to_string(), - amount: Uint128::new(10), - }) - .unwrap(); - } - - // #[test] - // fn test_is_contract_admin() { - // let mut deps = mock_dependencies(); - // let env = mock_env(); - // let info = mock_info("admin", &[Coin::new(100000000, "uqsr")]); - // - // - // let qx: MockQuerier = MockQuerier::new(&[]); - // let q = QuerierWrapper::new(&qx); - // - // - // - // let a= is_contract_admin(&q, &env, &Addr::unchecked("admin")); - // println!("{:?}", a); - // } -} diff --git a/smart-contracts/contracts/airdrop/src/lib.rs b/smart-contracts/contracts/airdrop/src/lib.rs deleted file mode 100644 index b0c16682e..000000000 --- a/smart-contracts/contracts/airdrop/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod admin; -pub mod contract; -pub mod helpers; -pub mod msg; -pub mod query; -pub mod state; -pub mod users; - -mod error; -pub use crate::error::AirdropErrors; diff --git a/smart-contracts/contracts/airdrop/src/msg.rs b/smart-contracts/contracts/airdrop/src/msg.rs deleted file mode 100644 index a7d1b5b80..000000000 --- a/smart-contracts/contracts/airdrop/src/msg.rs +++ /dev/null @@ -1,90 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Uint128; - -use crate::state::{AirdropConfig, UserInfo}; - -#[cw_serde] -pub struct InstantiateMsg { - pub config: AirdropConfig, -} - -#[cw_serde] -pub enum ExecuteMsg { - /// admin contains all the messages that can be executed by admin permission only - Admin(AdminExecuteMsg), - - /// claim airdrop is for the users to execute a specific airdrop id - ClaimAirdrop(), -} - -#[cw_serde] -pub enum AdminExecuteMsg { - /// updates airdrop config given by the admin - UpdateAirdropConfig(AirdropConfig), - - /// add users to the airdrop with the given amounts - AddUsers { users: Vec }, - - /// updates the existing users with the given address and amounts - SetUsers { users: Vec }, - - /// remove a list of users from an airdrop - RemoveUsers(Vec), - - /// sends back the remaining funds to the quasar funding address - WithdrawFunds(String), -} - -#[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - /// airdrop config shows the current config set on the contract - #[returns(ConfigResponse)] - AirdropConfigQuery {}, - - #[returns(UserInfoResponse)] - UserInfoQuery { user: String }, - - #[returns(ContractStateResponse)] - ContractStateQuery {}, - - #[returns(SanityCheckResponse)] - SanityCheckQuery {}, - - #[returns(UsersStatsResponse)] - UsersStatsQuery {}, -} - -#[cw_serde] -pub struct ConfigResponse { - pub airdrop_config: AirdropConfig, -} - -#[cw_serde] -pub struct UserInfoResponse { - pub user_info: UserInfo, -} - -#[cw_serde] -pub struct ContractStateResponse { - pub airdrop_config: AirdropConfig, - pub user_info: Vec<(String, UserInfo)>, -} - -#[cw_serde] -pub struct SanityCheckResponse { - pub response: bool, -} - -#[cw_serde] -pub struct UsersStatsResponse { - pub claimed_users_count: u64, - pub unclaimed_users_count: u64, - pub total_users_count: u64, -} - -#[cw_serde] -pub struct User { - pub address: String, - pub amount: Uint128, -} diff --git a/smart-contracts/contracts/airdrop/src/query.rs b/smart-contracts/contracts/airdrop/src/query.rs deleted file mode 100644 index da22477da..000000000 --- a/smart-contracts/contracts/airdrop/src/query.rs +++ /dev/null @@ -1,131 +0,0 @@ -use std::string::String; - -use crate::helpers::get_total_in_user_info; -use cosmwasm_std::{Deps, Env, Order, StdResult}; - -use crate::msg::{ - ConfigResponse, ContractStateResponse, SanityCheckResponse, UserInfoResponse, - UsersStatsResponse, -}; -use crate::state::{UserInfo, AIRDROP_CONFIG, USER_INFO}; - -/// Queries and returns the current airdrop configuration. -/// -/// # Arguments -/// -/// * `deps` - Deps is a struct providing access to the contract's dependencies like storage. -/// -/// # Returns -/// -/// Returns a `ConfigResponse` containing the current airdrop configuration. -pub fn query_config(deps: Deps) -> StdResult { - let config = AIRDROP_CONFIG.load(deps.storage)?; - Ok(ConfigResponse { - airdrop_config: config, - }) -} - -/// Queries and returns the information of a specific user. -/// -/// # Arguments -/// -/// * `deps` - Deps is a struct providing access to the contract's dependencies like storage. -/// * `user` - The address of the user for which to retrieve information. -/// -/// # Returns -/// -/// Returns a `UserInfoResponse` containing the user's information. -pub fn query_user(deps: Deps, user: String) -> StdResult { - let user_addr = deps.api.addr_validate(&user)?; - let user_info = USER_INFO.load(deps.storage, user_addr.to_string())?; - Ok(UserInfoResponse { user_info }) -} - -/// Queries and returns the entire contract state, including airdrop configuration and user information. -/// -/// # Arguments -/// -/// * `deps` - Deps is a struct providing access to the contract's dependencies like storage. -/// -/// # Returns -/// -/// Returns a `ContractStateResponse` containing the airdrop configuration and user information. -pub fn query_contract_state(deps: Deps) -> StdResult { - let config = AIRDROP_CONFIG.load(deps.storage)?; - let mut user_infos: Vec<(String, UserInfo)> = Vec::new(); - for res in USER_INFO.range(deps.storage, None, None, Order::Ascending) { - let unwrapped_res = res.unwrap(); - user_infos.push((unwrapped_res.0, unwrapped_res.1)) - } - Ok(ContractStateResponse { - airdrop_config: config, - user_info: user_infos, - }) -} - -/// Performs a sanity check to verify if there are sufficient funds for airdrop payments. -/// -/// # Arguments -/// -/// * `deps` - Deps is a struct providing access to the contract's dependencies like storage and querier. -/// * `env` - Environment information. -/// -/// # Returns -/// -/// Returns a `SanityCheckResponse` indicating whether there are sufficient funds for airdrop payments. -pub fn query_airdrop_readiness(deps: Deps, env: Env) -> StdResult { - // Check if the airdrop amount is sufficient to supply all users - let airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - if airdrop_config.airdrop_amount >= get_total_in_user_info(deps.storage) { - // Get the contract's bank balance - let contract_balance = airdrop_config - .airdrop_asset - .query_balance(&deps.querier, env.contract.address) - .unwrap(); - - // Check if the contract has enough funds for the airdrop - if contract_balance < airdrop_config.airdrop_amount { - return Ok(SanityCheckResponse { response: false }); - } - } else { - return Ok(SanityCheckResponse { response: false }); - } - Ok(SanityCheckResponse { response: true }) -} - -/// Query user statistics including the number of claimed and unclaimed users. -/// -/// # Arguments -/// -/// - `deps`: A reference to the dependencies needed for the query. -/// -/// # Returns -/// -/// A result containing a `UsersStatsResponse`, which includes the counts of -/// claimed and unclaimed users, and the total number of users. -/// -/// # Errors -/// -/// This function returns a `StdResult` that can hold a `CosmosSDK` error. -/// -pub fn query_users_stats(deps: Deps) -> StdResult { - // Initialize counters for claimed and total users. - let mut claimed_users_count = 0u64; - let mut total_users_count = 0u64; - - // Iterate through user info and count claimed and total users. - for res in USER_INFO.range(deps.storage, None, None, Order::Ascending) { - let claimed = res.as_ref().unwrap().1.get_claimed_flag(); - if claimed { - claimed_users_count += 1; - } - total_users_count += 1; - } - - // Create and return the UsersStatsResponse. - Ok(UsersStatsResponse { - claimed_users_count, - unclaimed_users_count: total_users_count - claimed_users_count, - total_users_count, - }) -} diff --git a/smart-contracts/contracts/airdrop/src/state.rs b/smart-contracts/contracts/airdrop/src/state.rs deleted file mode 100644 index def711562..000000000 --- a/smart-contracts/contracts/airdrop/src/state.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::string::String; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::Uint128; -use cw_asset::AssetInfo; -use cw_storage_plus::{Item, Map}; - -pub const AIRDROP_CONFIG: Item = Item::new("airdrop_config"); -pub const USER_INFO: Map = Map::new("user_info"); - -//---------------------------------------------------------------------------------------- -// Storage types -//---------------------------------------------------------------------------------------- - -#[cw_serde] -pub struct AirdropConfig { - pub airdrop_title: String, - /// every airdrop contains a description of it - pub airdrop_description: String, - /// token amount to be airdropped - pub airdrop_amount: Uint128, - /// token denom to be airdropped - pub airdrop_asset: AssetInfo, - /// total claimed amount, zero initially - pub total_claimed: Uint128, - /// starting time from which users can claim airdrop - pub start_height: u64, - /// end time after which users cannot claim airdrop - pub end_height: u64, -} - -#[cw_serde] -pub struct UserInfo { - /// total airdrop tokens claimable by the user - pub claimable_amount: Uint128, - /// boolean value indicating if the user has withdrawn the remaining tokens - pub claimed_flag: bool, -} - -impl AirdropConfig { - pub fn get_start_height(&self) -> u64 { - self.start_height - } - pub fn get_end_heights(&self) -> u64 { - self.start_height - } - pub fn get_config(self) -> AirdropConfig { - self - } - pub fn is_airdrop_active(&self, current_height: u64) -> bool { - if self.start_height <= current_height && self.end_height >= current_height { - return true; - } - false - } -} - -impl UserInfo { - pub fn get_claimable_amount(&self) -> Uint128 { - self.claimable_amount - } - pub fn get_claimed_flag(&self) -> bool { - self.claimed_flag - } -} - -impl Default for UserInfo { - fn default() -> Self { - UserInfo { - claimable_amount: Uint128::zero(), - claimed_flag: false, - } - } -} diff --git a/smart-contracts/contracts/airdrop/src/users.rs b/smart-contracts/contracts/airdrop/src/users.rs deleted file mode 100644 index 2172c18d5..000000000 --- a/smart-contracts/contracts/airdrop/src/users.rs +++ /dev/null @@ -1,63 +0,0 @@ -use cosmwasm_std::{Addr, DepsMut, Env, Response}; -use cw_asset::Asset; - -use crate::state::{AIRDROP_CONFIG, USER_INFO}; -use crate::AirdropErrors; - -// Define a function to process airdrop claims for a user -pub fn execute_claim(deps: DepsMut, env: Env, user: Addr) -> Result { - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - - // Check if the airdrop window is open and the user is eligible to claim - if current_airdrop_config.start_height == 0 - || current_airdrop_config.end_height == 0 - || env.block.height > current_airdrop_config.end_height - || env.block.height < current_airdrop_config.start_height - { - return Err(AirdropErrors::InvalidClaim {}); - } - - // Load the user's airdrop information from storage - let mut user_info = USER_INFO.load(deps.storage, user.to_string())?; - - // Check if the user has already claimed the airdrop - if user_info.get_claimed_flag() { - return Err(AirdropErrors::AlreadyClaimed {}); - } - - // Get the admin address of the contract - let current_airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - let contract_balance = current_airdrop_config - .airdrop_asset - .query_balance(&deps.querier, &env.contract.address)?; - - // Check if the user's claimable amount exceeds the contract's balance - if user_info.get_claimable_amount() > contract_balance { - return Err(AirdropErrors::InsufficientFundsInContractAccount { - balance: contract_balance, - }); - } - - // Transfer the airdrop asset to the withdrawal address - let claim = Asset::new( - current_airdrop_config.airdrop_asset, - user_info.claimable_amount, - ) - .transfer_msg(user.clone())?; - - // Mark the user as claimed - user_info.claimed_flag = true; - USER_INFO.save(deps.storage, user.to_string(), &user_info)?; - - // Update the airdrop configuration by increasing the total claimed amount - let mut airdrop_config = AIRDROP_CONFIG.load(deps.storage)?; - airdrop_config.total_claimed += user_info.claimable_amount; - AIRDROP_CONFIG.save(deps.storage, &airdrop_config)?; - - // Return a default response if all checks pass - Ok(Response::new().add_message(claim).add_attributes(vec![ - ("action", "claim"), - ("user", user.as_ref()), - ("amount", &user_info.claimable_amount.to_string()), - ])) -} diff --git a/smart-contracts/contracts/basic-vault/.cargo/config b/smart-contracts/contracts/basic-vault/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/smart-contracts/contracts/basic-vault/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/smart-contracts/contracts/basic-vault/.gitignore b/smart-contracts/contracts/basic-vault/.gitignore deleted file mode 100644 index 360bb05b1..000000000 --- a/smart-contracts/contracts/basic-vault/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ts -schema diff --git a/smart-contracts/contracts/basic-vault/CHANGELOG.md b/smart-contracts/contracts/basic-vault/CHANGELOG.md deleted file mode 100644 index 466ae582b..000000000 --- a/smart-contracts/contracts/basic-vault/CHANGELOG.md +++ /dev/null @@ -1,20 +0,0 @@ -# CHANGELOG - -## V0.1.1 -### Initial version -### Dependencies -### API breaking -### State breaking -### Improvements -### Features -### Bugfixes -- Update user index for rewards contract on cw20 TransferFrom and SendFrom - -## V0.1.0 - \ No newline at end of file diff --git a/smart-contracts/contracts/basic-vault/Cargo.toml b/smart-contracts/contracts/basic-vault/Cargo.toml deleted file mode 100644 index 2ea4bcef9..000000000 --- a/smart-contracts/contracts/basic-vault/Cargo.toml +++ /dev/null @@ -1,47 +0,0 @@ -[package] -authors = ["N ", "Laurens Kubat "] -description = "a basic vault implementation to " -documentation = "https://docs.quasar.fi/" -edition = "2018" -homepage = "https://quasar.fi" -license = "Apache-2.0" -name = "basic-vault" -repository = "https://github.com/quasar-finance/quasar" -version = "0.1.1" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -thiserror = { workspace = true } -cosmwasm-schema = { workspace = true } -cosmwasm-std = { workspace = true } -cw-storage-plus = { workspace = true } -osmosis-std = { workspace = true } -cw-controllers = { workspace = true } -cw-utils = { workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cw20-base = { workspace = true } -serde-json-wasm = { workspace = true } -cw-asset = { workspace = true } -cw20-staking = { workspace = true } - -# Quasar contracts and packages -lp-strategy = {path = "../lp-strategy", features = ["library"], default-features = false} -vault-rewards = {path = "../vault-rewards", features = ["library"], default-features = false} -quasar-types = {path = "../../packages/quasar-types"} - -[dev-dependencies] -cw-multi-test = { workspace = true } -prost = { workspace = true } - -anyhow = "1" -derivative = "2" diff --git a/smart-contracts/contracts/basic-vault/NOTICE b/smart-contracts/contracts/basic-vault/NOTICE deleted file mode 100644 index 55148b76b..000000000 --- a/smart-contracts/contracts/basic-vault/NOTICE +++ /dev/null @@ -1,15 +0,0 @@ -CW20-Staking: Staking Derivatives as a CW20 token -Copyright 2020-21 Ethan Frey -Copyright 2021-22 Confio GmbH - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/smart-contracts/contracts/basic-vault/README.md b/smart-contracts/contracts/basic-vault/README.md deleted file mode 100644 index 9a23707dc..000000000 --- a/smart-contracts/contracts/basic-vault/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Staking Derivatives - -This is a sample contract that releases a minimal form of staking derivatives. -This is to be used for integration tests and as a foundation for other to build -more complex logic upon. - -## Functionality - -On one side, this acts as a CW20 token, holding a list of -balances for multiple addresses, and exposing queries and transfers (no -allowances and "transfer from" to focus the logic on the staking stuff). -However, it has no initial balance. Instead, it mints and burns them based on -delegations. - -For such a "bonding curve" we expose two additional message types. A "bond" -message sends native staking tokens to the contract to be bonded to a validator -and credits the user with the appropriate amount of derivative tokens. Likewise -you can burn some of your derivative tokens, and the contract will unbond the -proportional amount of stake to the user's account (after typical 21-day -unbonding period). - -To show an example of charging for such a service, we allow the contract owner -to take a small exit tax, thus maybe 98% of the tokens will be unbonded and sent -to the original account, and 2% of the tokens are not unbonded, but rather -transferred to the owners account. (The ownership can also be transferred). diff --git a/smart-contracts/contracts/basic-vault/examples/schema.rs b/smart-contracts/contracts/basic-vault/examples/schema.rs deleted file mode 100644 index f98d5bbfe..000000000 --- a/smart-contracts/contracts/basic-vault/examples/schema.rs +++ /dev/null @@ -1,10 +0,0 @@ -use basic_vault::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use cosmwasm_schema::write_api; - -fn main() { - write_api! { - instantiate: InstantiateMsg, - query: QueryMsg, - execute: ExecuteMsg, - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/basic-vault.json b/smart-contracts/contracts/basic-vault/schema/basic-vault.json deleted file mode 100644 index be93922f6..000000000 --- a/smart-contracts/contracts/basic-vault/schema/basic-vault.json +++ /dev/null @@ -1,1765 +0,0 @@ -{ - "contract_name": "basic-vault", - "contract_version": "0.14.2", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "decimals", - "min_withdrawal", - "name", - "primitives", - "reward_distribution_schedules", - "reward_token", - "symbol", - "thesis", - "total_cap", - "vault_rewards_code_id" - ], - "properties": { - "decimals": { - "description": "decimal places of the derivative token (for UI)", - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "min_withdrawal": { - "description": "This is the minimum amount we will pull out to reinvest, as well as a minimum that can be unbonded (to avoid needless staking tx)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "name": { - "description": "name of the derivative token", - "type": "string" - }, - "primitives": { - "type": "array", - "items": { - "$ref": "#/definitions/PrimitiveConfig" - } - }, - "reward_distribution_schedules": { - "type": "array", - "items": { - "$ref": "#/definitions/DistributionSchedule" - } - }, - "reward_token": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - }, - "symbol": { - "description": "symbol / ticker of the derivative token", - "type": "string" - }, - "thesis": { - "description": "description of the derivative token", - "type": "string" - }, - "total_cap": { - "$ref": "#/definitions/Uint128" - }, - "vault_rewards_code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "DistributionSchedule": { - "type": "object", - "required": [ - "amount", - "end", - "start" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "end": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "InstantiateMsg": { - "type": "object", - "required": [ - "base_denom", - "expected_connection", - "local_denom", - "lock_period", - "pool_denom", - "pool_id", - "quote_denom", - "return_source_channel", - "transfer_channel" - ], - "properties": { - "base_denom": { - "type": "string" - }, - "expected_connection": { - "type": "string" - }, - "local_denom": { - "type": "string" - }, - "lock_period": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_denom": { - "type": "string" - }, - "pool_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "quote_denom": { - "type": "string" - }, - "return_source_channel": { - "type": "string" - }, - "transfer_channel": { - "type": "string" - } - }, - "additionalProperties": false - }, - "PrimitiveConfig": { - "type": "object", - "required": [ - "address", - "init", - "weight" - ], - "properties": { - "address": { - "type": "string" - }, - "init": { - "$ref": "#/definitions/PrimitiveInitMsg" - }, - "weight": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "PrimitiveInitMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "l_p" - ], - "properties": { - "l_p": { - "$ref": "#/definitions/InstantiateMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Bond will bond all staking tokens sent with the message and release derivative tokens recipient will receive the minted vault tokens", - "type": "object", - "required": [ - "bond" - ], - "properties": { - "bond": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Unbond will \"burn\" the given amount of derivative tokens and send the unbonded staking tokens to the message sender (after exit tax is deducted)", - "type": "object", - "required": [ - "unbond" - ], - "properties": { - "unbond": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the chain-defined waiting period (eg. 3 weeks)", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "bond_response" - ], - "properties": { - "bond_response": { - "$ref": "#/definitions/BondResponse" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "start_unbond_response" - ], - "properties": { - "start_unbond_response": { - "$ref": "#/definitions/StartUnbondResponse" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "unbond_response" - ], - "properties": { - "unbond_response": { - "$ref": "#/definitions/UnbondResponse" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "clear_cache" - ], - "properties": { - "clear_cache": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "BondResponse": { - "description": "BondResponse is the response of a the primitive once the funds are succesfully bonded", - "type": "object", - "required": [ - "bond_id", - "share_amount" - ], - "properties": { - "bond_id": { - "type": "string" - }, - "share_amount": { - "description": "the amount of tokens that were bonded", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "StartUnbondResponse": { - "description": "UnbondResponse is the response of a primitive once shares succesfully start unbonding", - "type": "object", - "required": [ - "unbond_id", - "unlock_time" - ], - "properties": { - "unbond_id": { - "type": "string" - }, - "unlock_time": { - "$ref": "#/definitions/Timestamp" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "UnbondResponse": { - "type": "object", - "required": [ - "unbond_id" - ], - "properties": { - "unbond_id": { - "type": "string" - } - } - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Claims shows the number of tokens this address can access when they are done unbonding", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_cap" - ], - "properties": { - "get_cap": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Investment shows metadata on the staking info of the contract", - "type": "object", - "required": [ - "investment" - ], - "properties": { - "investment": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "DepositRatio shows the ratio of tokens that should be sent for a deposit given list of available tokens", - "type": "object", - "required": [ - "deposit_ratio" - ], - "properties": { - "deposit_ratio": { - "type": "object", - "required": [ - "funds" - ], - "properties": { - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "PendingBonds shows the bonds that are currently in the process of being deposited for a user", - "type": "object", - "required": [ - "pending_bonds" - ], - "properties": { - "pending_bonds": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "GetTvlInfo gets all info necessary for", - "type": "object", - "required": [ - "get_tvl_info" - ], - "properties": { - "get_tvl_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Get all unbonding claims of a user", - "type": "object", - "required": [ - "pending_unbonds" - ], - "properties": { - "pending_unbonds": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "GetDebug shows us debug string info", - "type": "object", - "required": [ - "get_debug" - ], - "properties": { - "get_debug": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns the current balance of the given address, 0 if unset.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns metadata on the contract - name, decimals, supply, etc.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Additional token metadata, includes regular token info too", - "type": "object", - "required": [ - "additional_token_info" - ], - "properties": { - "additional_token_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "additional_token_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VaultTokenInfoResponse", - "type": "object", - "required": [ - "creation_time", - "decimals", - "name", - "symbol", - "thesis", - "total_supply" - ], - "properties": { - "creation_time": { - "$ref": "#/definitions/Timestamp" - }, - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "thesis": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "allowance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "claims": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ClaimsResponse", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "array", - "items": { - "$ref": "#/definitions/Claim" - } - } - }, - "additionalProperties": false, - "definitions": { - "Claim": { - "type": "object", - "required": [ - "amount", - "release_at" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "release_at": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "deposit_ratio": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DepositRatioResponse", - "type": "object", - "required": [ - "primitive_funding_amounts", - "remainder" - ], - "properties": { - "primitive_funding_amounts": { - "description": "the ratio of tokens that should be sent for a deposit given list of available tokens", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "remainder": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "get_cap": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetCapResponse", - "type": "object", - "required": [ - "cap" - ], - "properties": { - "cap": { - "$ref": "#/definitions/Cap" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Cap": { - "type": "object", - "required": [ - "cap_admin", - "current", - "total" - ], - "properties": { - "cap_admin": { - "$ref": "#/definitions/Addr" - }, - "current": { - "$ref": "#/definitions/Uint128" - }, - "total": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "get_debug": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetDebugResponse", - "type": "object", - "required": [ - "debug" - ], - "properties": { - "debug": { - "description": "the debug string", - "type": "string" - } - }, - "additionalProperties": false - }, - "get_tvl_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TvlInfoResponse", - "type": "object", - "required": [ - "primitives" - ], - "properties": { - "primitives": { - "type": "array", - "items": { - "$ref": "#/definitions/PrimitiveInfo" - } - } - }, - "additionalProperties": false, - "definitions": { - "LpCache": { - "type": "object", - "required": [ - "d_unlocked_shares", - "locked_shares", - "w_unlocked_shares" - ], - "properties": { - "d_unlocked_shares": { - "$ref": "#/definitions/Uint128" - }, - "locked_shares": { - "$ref": "#/definitions/Uint128" - }, - "w_unlocked_shares": { - "$ref": "#/definitions/Uint128" - } - } - }, - "PrimitiveInfo": { - "type": "object", - "required": [ - "base_denom", - "ica_address", - "lp_denom", - "lp_shares", - "quote_denom" - ], - "properties": { - "base_denom": { - "type": "string" - }, - "ica_address": { - "type": "string" - }, - "lp_denom": { - "type": "string" - }, - "lp_shares": { - "$ref": "#/definitions/LpCache" - }, - "quote_denom": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "investment": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InvestmentResponse", - "type": "object", - "required": [ - "info" - ], - "properties": { - "info": { - "$ref": "#/definitions/InvestmentInfo" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "InstantiateMsg": { - "type": "object", - "required": [ - "base_denom", - "expected_connection", - "local_denom", - "lock_period", - "pool_denom", - "pool_id", - "quote_denom", - "return_source_channel", - "transfer_channel" - ], - "properties": { - "base_denom": { - "type": "string" - }, - "expected_connection": { - "type": "string" - }, - "local_denom": { - "type": "string" - }, - "lock_period": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_denom": { - "type": "string" - }, - "pool_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "quote_denom": { - "type": "string" - }, - "return_source_channel": { - "type": "string" - }, - "transfer_channel": { - "type": "string" - } - }, - "additionalProperties": false - }, - "InvestmentInfo": { - "description": "Investment info is fixed at instantiation, and is used to control the function of the contract", - "type": "object", - "required": [ - "min_withdrawal", - "owner", - "primitives" - ], - "properties": { - "min_withdrawal": { - "description": "This is the minimum amount we will pull out to reinvest, as well as a minimum that can be unbonded (to avoid needless staking tx)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "owner": { - "description": "Owner created the contract and takes a cut", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - }, - "primitives": { - "description": "this is the array of primitives that this vault will subscribe to", - "type": "array", - "items": { - "$ref": "#/definitions/PrimitiveConfig" - } - } - }, - "additionalProperties": false - }, - "PrimitiveConfig": { - "type": "object", - "required": [ - "address", - "init", - "weight" - ], - "properties": { - "address": { - "type": "string" - }, - "init": { - "$ref": "#/definitions/PrimitiveInitMsg" - }, - "weight": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "PrimitiveInitMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "l_p" - ], - "properties": { - "l_p": { - "$ref": "#/definitions/InstantiateMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "pending_bonds": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PendingBondsResponse", - "type": "object", - "required": [ - "pending_bond_ids", - "pending_bonds" - ], - "properties": { - "pending_bond_ids": { - "description": "the bond ids that are registered as pending for a user", - "type": "array", - "items": { - "type": "string" - } - }, - "pending_bonds": { - "description": "the bonds that are currently in the process of being deposited for a user", - "type": "array", - "items": { - "$ref": "#/definitions/BondingStub" - } - } - }, - "additionalProperties": false, - "definitions": { - "BondResponse": { - "description": "BondResponse is the response of a the primitive once the funds are succesfully bonded", - "type": "object", - "required": [ - "bond_id", - "share_amount" - ], - "properties": { - "bond_id": { - "type": "string" - }, - "share_amount": { - "description": "the amount of tokens that were bonded", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - } - }, - "BondingStub": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - }, - "bond_response": { - "anyOf": [ - { - "$ref": "#/definitions/BondResponse" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "pending_unbonds": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PendingUnbondsResponse", - "type": "object", - "required": [ - "pending_unbond_ids", - "pending_unbonds" - ], - "properties": { - "pending_unbond_ids": { - "description": "the bond ids that are registered as pending for a user", - "type": "array", - "items": { - "type": "string" - } - }, - "pending_unbonds": { - "description": "the unbonds that are currently in the process of being withdrawn by an user", - "type": "array", - "items": { - "$ref": "#/definitions/Unbond" - } - } - }, - "additionalProperties": false, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Unbond": { - "type": "object", - "required": [ - "shares", - "stub" - ], - "properties": { - "shares": { - "$ref": "#/definitions/Uint128" - }, - "stub": { - "type": "array", - "items": { - "$ref": "#/definitions/UnbondingStub" - } - } - }, - "additionalProperties": false - }, - "UnbondResponse": { - "type": "object", - "required": [ - "unbond_id" - ], - "properties": { - "unbond_id": { - "type": "string" - } - } - }, - "UnbondingStub": { - "type": "object", - "required": [ - "address", - "unbond_funds" - ], - "properties": { - "address": { - "type": "string" - }, - "unbond_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "unbond_response": { - "anyOf": [ - { - "$ref": "#/definitions/UnbondResponse" - }, - { - "type": "null" - } - ] - }, - "unlock_time": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "token_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/execute.json b/smart-contracts/contracts/basic-vault/schema/raw/execute.json deleted file mode 100644 index b12ac940f..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/execute.json +++ /dev/null @@ -1,474 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Bond will bond all staking tokens sent with the message and release derivative tokens recipient will receive the minted vault tokens", - "type": "object", - "required": [ - "bond" - ], - "properties": { - "bond": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Unbond will \"burn\" the given amount of derivative tokens and send the unbonded staking tokens to the message sender (after exit tax is deducted)", - "type": "object", - "required": [ - "unbond" - ], - "properties": { - "unbond": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the chain-defined waiting period (eg. 3 weeks)", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "bond_response" - ], - "properties": { - "bond_response": { - "$ref": "#/definitions/BondResponse" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "start_unbond_response" - ], - "properties": { - "start_unbond_response": { - "$ref": "#/definitions/StartUnbondResponse" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "unbond_response" - ], - "properties": { - "unbond_response": { - "$ref": "#/definitions/UnbondResponse" - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "clear_cache" - ], - "properties": { - "clear_cache": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "BondResponse": { - "description": "BondResponse is the response of a the primitive once the funds are succesfully bonded", - "type": "object", - "required": [ - "bond_id", - "share_amount" - ], - "properties": { - "bond_id": { - "type": "string" - }, - "share_amount": { - "description": "the amount of tokens that were bonded", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "StartUnbondResponse": { - "description": "UnbondResponse is the response of a primitive once shares succesfully start unbonding", - "type": "object", - "required": [ - "unbond_id", - "unlock_time" - ], - "properties": { - "unbond_id": { - "type": "string" - }, - "unlock_time": { - "$ref": "#/definitions/Timestamp" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "UnbondResponse": { - "type": "object", - "required": [ - "unbond_id" - ], - "properties": { - "unbond_id": { - "type": "string" - } - } - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/instantiate.json b/smart-contracts/contracts/basic-vault/schema/raw/instantiate.json deleted file mode 100644 index 981b261a0..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/instantiate.json +++ /dev/null @@ -1,220 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "decimals", - "min_withdrawal", - "name", - "primitives", - "reward_distribution_schedules", - "reward_token", - "symbol", - "thesis", - "total_cap", - "vault_rewards_code_id" - ], - "properties": { - "decimals": { - "description": "decimal places of the derivative token (for UI)", - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "min_withdrawal": { - "description": "This is the minimum amount we will pull out to reinvest, as well as a minimum that can be unbonded (to avoid needless staking tx)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "name": { - "description": "name of the derivative token", - "type": "string" - }, - "primitives": { - "type": "array", - "items": { - "$ref": "#/definitions/PrimitiveConfig" - } - }, - "reward_distribution_schedules": { - "type": "array", - "items": { - "$ref": "#/definitions/DistributionSchedule" - } - }, - "reward_token": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - }, - "symbol": { - "description": "symbol / ticker of the derivative token", - "type": "string" - }, - "thesis": { - "description": "description of the derivative token", - "type": "string" - }, - "total_cap": { - "$ref": "#/definitions/Uint128" - }, - "vault_rewards_code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "DistributionSchedule": { - "type": "object", - "required": [ - "amount", - "end", - "start" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "end": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "InstantiateMsg": { - "type": "object", - "required": [ - "base_denom", - "expected_connection", - "local_denom", - "lock_period", - "pool_denom", - "pool_id", - "quote_denom", - "return_source_channel", - "transfer_channel" - ], - "properties": { - "base_denom": { - "type": "string" - }, - "expected_connection": { - "type": "string" - }, - "local_denom": { - "type": "string" - }, - "lock_period": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_denom": { - "type": "string" - }, - "pool_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "quote_denom": { - "type": "string" - }, - "return_source_channel": { - "type": "string" - }, - "transfer_channel": { - "type": "string" - } - }, - "additionalProperties": false - }, - "PrimitiveConfig": { - "type": "object", - "required": [ - "address", - "init", - "weight" - ], - "properties": { - "address": { - "type": "string" - }, - "init": { - "$ref": "#/definitions/PrimitiveInitMsg" - }, - "weight": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "PrimitiveInitMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "l_p" - ], - "properties": { - "l_p": { - "$ref": "#/definitions/InstantiateMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/query.json b/smart-contracts/contracts/basic-vault/schema/raw/query.json deleted file mode 100644 index 9cb3b107d..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/query.json +++ /dev/null @@ -1,249 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Claims shows the number of tokens this address can access when they are done unbonding", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_cap" - ], - "properties": { - "get_cap": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Investment shows metadata on the staking info of the contract", - "type": "object", - "required": [ - "investment" - ], - "properties": { - "investment": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "DepositRatio shows the ratio of tokens that should be sent for a deposit given list of available tokens", - "type": "object", - "required": [ - "deposit_ratio" - ], - "properties": { - "deposit_ratio": { - "type": "object", - "required": [ - "funds" - ], - "properties": { - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "PendingBonds shows the bonds that are currently in the process of being deposited for a user", - "type": "object", - "required": [ - "pending_bonds" - ], - "properties": { - "pending_bonds": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "GetTvlInfo gets all info necessary for", - "type": "object", - "required": [ - "get_tvl_info" - ], - "properties": { - "get_tvl_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Get all unbonding claims of a user", - "type": "object", - "required": [ - "pending_unbonds" - ], - "properties": { - "pending_unbonds": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "GetDebug shows us debug string info", - "type": "object", - "required": [ - "get_debug" - ], - "properties": { - "get_debug": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns the current balance of the given address, 0 if unset.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20. Returns metadata on the contract - name, decimals, supply, etc.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Additional token metadata, includes regular token info too", - "type": "object", - "required": [ - "additional_token_info" - ], - "properties": { - "additional_token_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Implements CW20 \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_allowance.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_allowance.json deleted file mode 100644 index dbaf97db7..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_allowance.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_balance.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_balance.json deleted file mode 100644 index 7dcf4d4a5..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_balance.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_claims.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_claims.json deleted file mode 100644 index 2f6bdb963..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_claims.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ClaimsResponse", - "type": "object", - "required": [ - "claims" - ], - "properties": { - "claims": { - "type": "array", - "items": { - "$ref": "#/definitions/Claim" - } - } - }, - "additionalProperties": false, - "definitions": { - "Claim": { - "type": "object", - "required": [ - "amount", - "release_at" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "release_at": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_deposit_ratio.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_deposit_ratio.json deleted file mode 100644 index f5cf2dd96..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_deposit_ratio.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DepositRatioResponse", - "type": "object", - "required": [ - "primitive_funding_amounts", - "remainder" - ], - "properties": { - "primitive_funding_amounts": { - "description": "the ratio of tokens that should be sent for a deposit given list of available tokens", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "remainder": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_get_debug.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_get_debug.json deleted file mode 100644 index 000af24e8..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_get_debug.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetDebugResponse", - "type": "object", - "required": [ - "debug" - ], - "properties": { - "debug": { - "description": "the debug string", - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_get_tvl_info.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_get_tvl_info.json deleted file mode 100644 index cbb951d04..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_get_tvl_info.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TvlInfoResponse", - "type": "object", - "required": [ - "primitives" - ], - "properties": { - "primitives": { - "type": "array", - "items": { - "$ref": "#/definitions/PrimitiveInfo" - } - } - }, - "additionalProperties": false, - "definitions": { - "LpCache": { - "type": "object", - "required": [ - "d_unlocked_shares", - "locked_shares", - "w_unlocked_shares" - ], - "properties": { - "d_unlocked_shares": { - "$ref": "#/definitions/Uint128" - }, - "locked_shares": { - "$ref": "#/definitions/Uint128" - }, - "w_unlocked_shares": { - "$ref": "#/definitions/Uint128" - } - } - }, - "PrimitiveInfo": { - "type": "object", - "required": [ - "base_denom", - "ica_address", - "lp_denom", - "lp_shares", - "quote_denom" - ], - "properties": { - "base_denom": { - "type": "string" - }, - "ica_address": { - "type": "string" - }, - "lp_denom": { - "type": "string" - }, - "lp_shares": { - "$ref": "#/definitions/LpCache" - }, - "quote_denom": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_investment.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_investment.json deleted file mode 100644 index 4d8eb8433..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_investment.json +++ /dev/null @@ -1,147 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InvestmentResponse", - "type": "object", - "required": [ - "info" - ], - "properties": { - "info": { - "$ref": "#/definitions/InvestmentInfo" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "InstantiateMsg": { - "type": "object", - "required": [ - "base_denom", - "expected_connection", - "local_denom", - "lock_period", - "pool_denom", - "pool_id", - "quote_denom", - "return_source_channel", - "transfer_channel" - ], - "properties": { - "base_denom": { - "type": "string" - }, - "expected_connection": { - "type": "string" - }, - "local_denom": { - "type": "string" - }, - "lock_period": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "pool_denom": { - "type": "string" - }, - "pool_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "quote_denom": { - "type": "string" - }, - "return_source_channel": { - "type": "string" - }, - "transfer_channel": { - "type": "string" - } - }, - "additionalProperties": false - }, - "InvestmentInfo": { - "description": "Investment info is fixed at instantiation, and is used to control the function of the contract", - "type": "object", - "required": [ - "min_withdrawal", - "owner", - "primitives" - ], - "properties": { - "min_withdrawal": { - "description": "This is the minimum amount we will pull out to reinvest, as well as a minimum that can be unbonded (to avoid needless staking tx)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "owner": { - "description": "Owner created the contract and takes a cut", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] - }, - "primitives": { - "description": "this is the array of primitives that this vault will subscribe to", - "type": "array", - "items": { - "$ref": "#/definitions/PrimitiveConfig" - } - } - }, - "additionalProperties": false - }, - "PrimitiveConfig": { - "type": "object", - "required": [ - "address", - "init", - "weight" - ], - "properties": { - "address": { - "type": "string" - }, - "init": { - "$ref": "#/definitions/PrimitiveInitMsg" - }, - "weight": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "PrimitiveInitMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "l_p" - ], - "properties": { - "l_p": { - "$ref": "#/definitions/InstantiateMsg" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_pending_bonds.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_pending_bonds.json deleted file mode 100644 index 62710cadb..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_pending_bonds.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PendingBondsResponse", - "type": "object", - "required": [ - "pending_bond_ids", - "pending_bonds" - ], - "properties": { - "pending_bond_ids": { - "description": "the bond ids that are registered as pending for a user", - "type": "array", - "items": { - "type": "string" - } - }, - "pending_bonds": { - "description": "the bonds that are currently in the process of being deposited for a user", - "type": "array", - "items": { - "$ref": "#/definitions/BondingStub" - } - } - }, - "additionalProperties": false, - "definitions": { - "BondResponse": { - "description": "BondResponse is the response of a the primitive once the funds are succesfully bonded", - "type": "object", - "required": [ - "bond_id", - "share_amount" - ], - "properties": { - "bond_id": { - "type": "string" - }, - "share_amount": { - "description": "the amount of tokens that were bonded", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - } - }, - "BondingStub": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - }, - "bond_response": { - "anyOf": [ - { - "$ref": "#/definitions/BondResponse" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_pending_unbonds.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_pending_unbonds.json deleted file mode 100644 index 0044d9cf9..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_pending_unbonds.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PendingUnbondsResponse", - "type": "object", - "required": [ - "pending_unbond_ids", - "pending_unbonds" - ], - "properties": { - "pending_unbond_ids": { - "description": "the bond ids that are registered as pending for a user", - "type": "array", - "items": { - "type": "string" - } - }, - "pending_unbonds": { - "description": "the unbonds that are currently in the process of being withdrawn by an user", - "type": "array", - "items": { - "$ref": "#/definitions/Unbond" - } - } - }, - "additionalProperties": false, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Unbond": { - "type": "object", - "required": [ - "shares", - "stub" - ], - "properties": { - "shares": { - "$ref": "#/definitions/Uint128" - }, - "stub": { - "type": "array", - "items": { - "$ref": "#/definitions/UnbondingStub" - } - } - }, - "additionalProperties": false - }, - "UnbondResponse": { - "type": "object", - "required": [ - "unbond_id" - ], - "properties": { - "unbond_id": { - "type": "string" - } - } - }, - "UnbondingStub": { - "type": "object", - "required": [ - "address", - "unbond_funds" - ], - "properties": { - "address": { - "type": "string" - }, - "unbond_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "unbond_response": { - "anyOf": [ - { - "$ref": "#/definitions/UnbondResponse" - }, - { - "type": "null" - } - ] - }, - "unlock_time": { - "anyOf": [ - { - "$ref": "#/definitions/Timestamp" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/smart-contracts/contracts/basic-vault/schema/raw/response_to_token_info.json b/smart-contracts/contracts/basic-vault/schema/raw/response_to_token_info.json deleted file mode 100644 index 0e84d125f..000000000 --- a/smart-contracts/contracts/basic-vault/schema/raw/response_to_token_info.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/basic-vault/src/callback.rs b/smart-contracts/contracts/basic-vault/src/callback.rs deleted file mode 100644 index 29bf2866f..000000000 --- a/smart-contracts/contracts/basic-vault/src/callback.rs +++ /dev/null @@ -1,400 +0,0 @@ -use cosmwasm_std::{ - Addr, BankMsg, DepsMut, Env, MessageInfo, Response, SubMsg, Timestamp, Uint128, -}; -use cw20_base::contract::execute_mint; -use quasar_types::callback::{BondResponse, UnbondResponse}; - -use crate::{ - helpers::update_user_reward_index, - state::{ - Unbond, BONDING_SEQ_TO_ADDR, BOND_STATE, DEBUG_TOOL, INVESTMENT, PENDING_BOND_IDS, - PENDING_UNBOND_IDS, UNBOND_STATE, - }, - ContractError, -}; - -pub fn on_bond( - deps: DepsMut, - env: Env, - info: MessageInfo, - share_amount: Uint128, - bond_id: String, -) -> Result { - DEBUG_TOOL.save( - deps.storage, - &format!("We hit on_bond with bond_id: {bond_id}"), - )?; - - // load investment info - let invest = INVESTMENT.load(deps.storage)?; - - let mut bond_stubs = BOND_STATE.load(deps.storage, bond_id.clone())?; - - // lets find the primitive for this response - let primitive_config = invest.primitives.iter().find(|p| p.address == info.sender); - - // if we don't find a primitive, this is an unauthorized call - if primitive_config.is_none() { - return Err(ContractError::Unauthorized {}); - } - - // if we find a bond_stub coming from a primitive that already sent us one. fail - if bond_stubs - .iter() - .any(|s| s.address == info.sender && s.bond_response.is_some()) - { - return Err(ContractError::DuplicateBondResponse { bond_id }); - } - - // update deposit state here before doing anything else & save! - bond_stubs.iter_mut().for_each(|s| { - if s.address == info.sender { - // we should probably return the primitive value in the bond response - let primitive_value: lp_strategy::msg::IcaBalanceResponse = deps - .querier - .query_wasm_smart( - info.sender.clone(), - &lp_strategy::msg::QueryMsg::IcaBalance {}, - ) - .unwrap(); - s.bond_response = Some(BondResponse { - share_amount, - bond_id: bond_id.clone(), - }); - s.primitive_value = Some(primitive_value.amount.amount); - } - }); - - BOND_STATE.save(deps.storage, bond_id.clone(), &bond_stubs)?; - - // if still waiting on successful bonds, then return - if bond_stubs.iter().any(|s| s.bond_response.is_none()) { - return Ok(Response::new() - .add_attribute("action", "on_bond") - .add_attribute( - "state", - bond_stubs - .iter() - .fold(0u32, |acc, stub| { - if stub.bond_response.is_none() { - acc + 1 - } else { - acc - } - }) - .to_string() - + "pending bonds", - )); - } - // at this point we know that the deposit has succeeded fully, and we can mint shares - - let user_address = BONDING_SEQ_TO_ADDR.load(deps.storage, bond_id.clone())?; - let validated_user_address = deps.api.addr_validate(&user_address)?; - // lets updated all pending deposit info - PENDING_BOND_IDS.update(deps.storage, validated_user_address.clone(), |ids| { - if let Some(mut bond_ids) = ids { - let bond_index = bond_ids.iter().position(|id| id.eq(&bond_id)).ok_or( - ContractError::IncorrectCallbackId { - expected: bond_id.clone(), - ids: bond_ids.clone(), - }, - )?; - bond_ids.remove(bond_index); - Ok::, ContractError>(bond_ids) - } else { - Ok(vec![]) - } - })?; - - BOND_STATE.save(deps.storage, bond_id, &bond_stubs)?; - - // calculate the shares to mint by value - // at the time of bonding, we want to figure out what percentage of value in the vault the user has - - // User value per primitive = BondResponse Primitive Shares / Total Primitive Shares * ICA_BALANCE or funds send in the bond - // Total Vault Value = Total Vault shares in Primitive / Total Primitive shares * ICA_BALANCE - let total_vault_value = bond_stubs.iter().try_fold( - Uint128::zero(), - |acc, stub| -> Result { - Ok(acc - + stub - .primitive_value - .ok_or(ContractError::BondResponseIsEmpty {})?) - }, - )?; - - // User Vault Shares = Sum(user value per primitive) / Total Vault value * Total Vault Shares - let total_user_value = bond_stubs - .iter() - .fold(Uint128::zero(), |acc, stub| acc + stub.amount); - - let token_info = cw20_base::contract::query_token_info(deps.as_ref())?; - // equal to the cw20 base total supply - let total_vault_shares: Uint128 = token_info.total_supply; - - //if either is zero, then we just mint the user value - let shares_to_mint = if total_vault_shares.is_zero() || total_vault_value.is_zero() { - total_user_value - } else { - total_user_value - .checked_multiply_ratio(total_vault_shares, total_vault_value - total_user_value)? - }; - - // call into cw20-base to mint the token, call as self as no one else is allowed - let sub_info = MessageInfo { - sender: env.contract.address.clone(), - funds: vec![], - }; - - let update_user_rewards_idx_msg = - update_user_reward_index(deps.as_ref().storage, &validated_user_address)?; - execute_mint(deps, env, sub_info, user_address, shares_to_mint)?; - - let res = Response::new() - .add_submessage(SubMsg::new(update_user_rewards_idx_msg)) - .add_attribute("action", "on_bond") - .add_attribute("from", info.sender) - .add_attribute("minted", shares_to_mint); - Ok(res) -} - -pub fn on_start_unbond( - deps: DepsMut, - _env: Env, - info: MessageInfo, - unbond_id: String, - unlock_time: Timestamp, -) -> Result { - let invest = INVESTMENT.load(deps.storage)?; - let primitive_config = invest.primitives.iter().find(|p| p.address == info.sender); - - // if we don't find a primitive, this is an unauthorized call - if primitive_config.is_none() { - return Err(ContractError::Unauthorized {}); - } - - UNBOND_STATE.update( - deps.storage, - unbond_id.clone(), - |s: Option| -> Result { - let mut unbond = s.ok_or(ContractError::UnbondIsEmpty {})?; - // update the stub where the address is the same as message sender with the unlock time - - unbond - .stub - .iter_mut() - .find(|s| s.address == info.sender) - .ok_or(ContractError::UnbondStubIsEmpty {})? - .unlock_time = Option::Some(unlock_time); - Ok(Unbond { - stub: unbond.stub, - shares: unbond.shares, - }) - }, - )?; - - Ok(Response::new() - .add_attribute("action", "on_start_unbond") - .add_attribute("unbond_id", unbond_id) - .add_attribute("unlock_time", unlock_time.to_string())) -} - -pub fn on_unbond( - deps: DepsMut, - _env: Env, - info: MessageInfo, - unbond_id: String, -) -> Result { - let invest = INVESTMENT.load(deps.storage)?; - let primitive_config = invest.primitives.iter().find(|p| p.address == info.sender); - - // if we don't find a primitive, this is an unauthorized call - if primitive_config.is_none() { - return Err(ContractError::Unauthorized {}); - } - - let mut unbond_stubs = UNBOND_STATE.load(deps.storage, unbond_id.clone())?; - - // edit and save the stub where the address is the same as message sender with the unbond response - let unbonding_stub = unbond_stubs - .stub - .iter_mut() - .find(|s| s.address == info.sender) - .ok_or(ContractError::UnbondStubIsEmpty {})?; - - // update info - unbonding_stub.unbond_response = Option::Some(UnbondResponse { - unbond_id: unbond_id.clone(), - }); - unbonding_stub.unbond_funds = info.funds; - - UNBOND_STATE.save(deps.storage, unbond_id.clone(), &unbond_stubs)?; - - // if still waiting on successful unbonds, then return - // todo: should we eagerly send back funds? - if unbond_stubs - .stub - .iter() - .any(|s| s.unbond_response.is_none()) - { - return Ok(Response::new()); - } - - let user_address = BONDING_SEQ_TO_ADDR.load(deps.storage, unbond_id.clone())?; - // Construct message to return these funds to the user - let return_msgs: Vec = unbond_stubs - .stub - .iter() - .map(|s| BankMsg::Send { - to_address: user_address.to_string(), - amount: s.unbond_funds.clone(), - }) - .collect(); - - // delete this pending unbond id from the state - UNBOND_STATE.remove(deps.storage, unbond_id.clone()); - PENDING_UNBOND_IDS.update( - deps.storage, - Addr::unchecked(user_address), - |ids| -> Result, ContractError> { - Ok(ids - .ok_or(ContractError::NoPendingUnbonds {})? - .into_iter() - .filter(|id| id != &unbond_id) - .collect()) - }, - )?; - - Ok(Response::new() - .add_messages(return_msgs) - .add_attribute("action", "on_unbond") - .add_attribute("unbond_id", unbond_id)) -} - -#[cfg(test)] -mod test { - use std::str::FromStr; - - use crate::multitest::common::PrimitiveInstantiateMsg; - use crate::state::{BondingStub, BOND_STATE}; - use crate::tests::mock_deps_with_primitives; - use crate::{ - callback::on_bond, - msg::PrimitiveConfig, - multitest::common::{DENOM, LOCAL_DENOM}, - state::{InvestmentInfo, INVESTMENT}, - ContractError, - }; - use cosmwasm_std::{ - testing::{mock_env, mock_info}, - Decimal, - }; - use cosmwasm_std::{Addr, Uint128}; - - #[test] - fn fail_if_duplicate_bond_id() { - let primitive_states = vec![ - ( - "addr00001".to_string(), - LOCAL_DENOM.to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "addr00002".to_string(), - LOCAL_DENOM.to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ]; - // mock the queries so the primitives exist - let mut deps = mock_deps_with_primitives(primitive_states); - let env = mock_env(); - let info = mock_info("addr00001", &[]); - - INVESTMENT - .save( - &mut deps.storage, - &InvestmentInfo { - primitives: vec![ - PrimitiveConfig { - weight: Decimal::from_str("0.33333333333").unwrap(), - address: "addr00001".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(PrimitiveInstantiateMsg { - lock_period: 64, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: LOCAL_DENOM.to_string(), - base_denom: DENOM.to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - PrimitiveConfig { - weight: Decimal::from_str("0.33333333333").unwrap(), - address: "addr00002".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(PrimitiveInstantiateMsg { - lock_period: 64, - pool_id: 2, - pool_denom: "gamm/pool/1".to_string(), - local_denom: LOCAL_DENOM.to_string(), - base_denom: DENOM.to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - ], - owner: Addr::unchecked("owner".to_string()), - min_withdrawal: 1u128.into(), - deposit_denom: LOCAL_DENOM.to_string(), - }, - ) - .unwrap(); - - let share_amount = 100u128; - let bond_id = "1".to_string(); - - BOND_STATE - .save( - &mut deps.storage, - bond_id.clone(), - &vec![ - BondingStub { - address: "addr00001".to_string(), - bond_response: None, - primitive_value: None, - amount: Uint128::one(), - }, - BondingStub { - address: "addr00002".to_string(), - bond_response: None, - primitive_value: None, - amount: Uint128::one(), - }, - ], - ) - .unwrap(); - - // first bond should work - let res = on_bond( - deps.as_mut(), - env.clone(), - info.clone(), - share_amount.into(), - bond_id.clone(), - ) - .unwrap(); - assert_eq!(0, res.messages.len()); - - // second bond should fail - let res = on_bond(deps.as_mut(), env, info, share_amount.into(), bond_id).unwrap_err(); - match res { - ContractError::DuplicateBondResponse { .. } => {} - _ => panic!("Unexpected error: {:?}", res), - } - } -} diff --git a/smart-contracts/contracts/basic-vault/src/contract.rs b/smart-contracts/contracts/basic-vault/src/contract.rs deleted file mode 100644 index 255659366..000000000 --- a/smart-contracts/contracts/basic-vault/src/contract.rs +++ /dev/null @@ -1,614 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Order, Reply, Response, - StdError, StdResult, SubMsg, SubMsgResult, Uint128, WasmMsg, -}; - -use cw2::set_contract_version; -use cw20_base::allowances::{ - execute_burn_from, execute_decrease_allowance, execute_increase_allowance, execute_send_from, - execute_transfer_from, query_allowance, -}; -use cw20_base::contract::{ - execute_burn, execute_send, execute_transfer, query_balance, query_token_info, -}; -use cw20_base::state::{MinterData, TokenInfo, TOKEN_INFO}; -use cw_utils::parse_instantiate_response_data; -use lp_strategy::msg::ConfigResponse; -use vault_rewards::msg::InstantiateMsg as VaultRewardsInstantiateMsg; - -use crate::callback::{on_bond, on_start_unbond, on_unbond}; -use crate::error::ContractError; -use crate::execute::{bond, claim, unbond, update_cap}; -use crate::helpers::update_user_reward_index; -use crate::msg::{ - ExecuteMsg, GetCapResponse, GetDebugResponse, InstantiateMsg, MigrateMsg, PrimitiveConfig, - QueryMsg, VaultTokenInfoResponse, -}; -use crate::query::{ - query_deposit_ratio, query_investment, query_pending_bonds, query_pending_bonds_by_id, - query_pending_unbonds, query_pending_unbonds_by_id, query_tvl_info, -}; -use crate::state::{ - AdditionalTokenInfo, Cap, InvestmentInfo, ADDITIONAL_TOKEN_INFO, BONDING_SEQ, CAP, CLAIMS, - CONTRACT_NAME, CONTRACT_VERSION, DEBUG_TOOL, INVESTMENT, VAULT_REWARDS, -}; - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // store token info using cw20-base format - let token_info = TokenInfo { - name: msg.name, - symbol: msg.symbol, - decimals: msg.decimals, - total_supply: Uint128::zero(), - // set self as minter, so we can properly execute mint and burn - mint: Some(MinterData { - minter: env.contract.address.clone(), - cap: None, - }), - }; - let additional_info = AdditionalTokenInfo { - creation_time: env.block.time, - thesis: msg.thesis, - }; - TOKEN_INFO.save(deps.storage, &token_info)?; - ADDITIONAL_TOKEN_INFO.save(deps.storage, &additional_info)?; - - CAP.save(deps.storage, &Cap::new(info.sender.clone(), msg.total_cap))?; - - for prim in msg.primitives.iter() { - let config: ConfigResponse = deps - .querier - .query_wasm_smart(&prim.address, &lp_strategy::msg::QueryMsg::Config {})?; - match &prim.init { - crate::msg::PrimitiveInitMsg::LP(init) => { - assert_eq!(config.config.base_denom, init.base_denom); - assert_eq!(config.config.expected_connection, init.expected_connection); - assert_eq!(config.config.local_denom, init.local_denom); - assert_eq!(config.config.lock_period, init.lock_period); - assert_eq!(config.config.pool_denom, init.pool_denom); - assert_eq!(config.config.pool_id, init.pool_id); - assert_eq!(config.config.quote_denom, init.quote_denom); - assert_eq!( - config.config.return_source_channel, - init.return_source_channel - ); - assert_eq!(config.config.transfer_channel, init.transfer_channel); - } - } - } - - let mut invest = InvestmentInfo { - owner: info.sender.clone(), - min_withdrawal: msg.min_withdrawal, - primitives: msg.primitives, - deposit_denom: msg.deposit_denom, - }; - invest.normalize_primitive_weights(); - INVESTMENT.save(deps.storage, &invest)?; - - // initialize bonding sequence num - BONDING_SEQ.save(deps.storage, &Uint128::one())?; - - DEBUG_TOOL.save(deps.storage, &"Empty".to_string())?; - - let init_vault_rewards = SubMsg::reply_always( - WasmMsg::Instantiate { - admin: Some(info.sender.to_string()), - code_id: msg.vault_rewards_code_id, - msg: to_json_binary(&VaultRewardsInstantiateMsg { - vault_token: env.contract.address.to_string(), - reward_token: msg.reward_token, - distribution_schedules: msg.reward_distribution_schedules, - })?, - funds: vec![], - label: "vault-rewards".to_string(), - }, - REPLY_INIT_VAULT_REWARDS, - ); - - Ok(Response::new().add_submessage(init_vault_rewards)) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Bond { recipient } => bond(deps, env, info, recipient), - ExecuteMsg::Unbond { amount } => unbond(deps, env, info, amount), - ExecuteMsg::Claim {} => claim(deps, env, info), - - // calls the TryIcq ExecuteMsg in the lp-strategy contract - ExecuteMsg::ClearCache {} => { - let try_icq_msg = lp_strategy::msg::ExecuteMsg::TryIcq {}; - - let mut msgs: Vec = vec![]; - - let primitives = INVESTMENT.load(deps.storage)?.primitives; - primitives.iter().try_for_each( - |pc: &PrimitiveConfig| -> Result<(), ContractError> { - let clear_cache_msg = WasmMsg::Execute { - contract_addr: pc.address.to_string(), - funds: vec![], - msg: to_json_binary(&try_icq_msg)?, - }; - msgs.push(clear_cache_msg); - Ok(()) - }, - )?; - Ok(Response::new().add_messages(msgs)) - } - - // Callbacks entrypoint - // you cant do this - DONT TRY IT (unless you know what you're doing) - // ExecuteMsg::Callback(callback_msg) => handle_callback(deps, env, info, callback_msg), - ExecuteMsg::BondResponse(bond_response) => on_bond( - deps, - env, - info, - bond_response.share_amount, - bond_response.bond_id, - ), - ExecuteMsg::StartUnbondResponse(start_unbond_response) => on_start_unbond( - deps, - env, - info, - start_unbond_response.unbond_id, - start_unbond_response.unlock_time, - ), - ExecuteMsg::UnbondResponse(unbond_response) => { - on_unbond(deps, env, info, unbond_response.unbond_id) - } - - // Admin messages - ExecuteMsg::SetCap { - new_total, - new_cap_admin, - } => update_cap(deps, env, info, new_total, new_cap_admin), - - // these all come from cw20-base to implement the cw20 standard - ExecuteMsg::Transfer { recipient, amount } => { - let recipient = deps.api.addr_validate(&recipient)?; - let update_user_reward_indexes = vec![ - update_user_reward_index(deps.storage, &info.sender)?, - update_user_reward_index(deps.storage, &recipient)?, - ]; - Ok( - execute_transfer(deps, env, info, recipient.to_string(), amount)? - .add_messages(update_user_reward_indexes), - ) - } - ExecuteMsg::Burn { amount } => { - let update_user_reward_index = update_user_reward_index(deps.storage, &info.sender)?; - Ok(execute_burn(deps, env, info, amount)?.add_message(update_user_reward_index)) - } - ExecuteMsg::Send { - contract, - amount, - msg, - } => { - let contract = deps.api.addr_validate(&contract)?; - let update_user_reward_indexes = vec![ - update_user_reward_index(deps.storage, &info.sender)?, - update_user_reward_index(deps.storage, &contract)?, - ]; - Ok( - execute_send(deps, env, info, contract.to_string(), amount, msg)? - .add_messages(update_user_reward_indexes), - ) - } - ExecuteMsg::IncreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_increase_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::DecreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_decrease_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::TransferFrom { - owner, - recipient, - amount, - } => { - let recipient = deps.api.addr_validate(&recipient)?; - let update_user_reward_indexes = vec![ - update_user_reward_index(deps.storage, &deps.api.addr_validate(&owner)?)?, - update_user_reward_index(deps.storage, &recipient)?, - ]; - Ok( - execute_transfer_from(deps, env, info, owner, recipient.to_string(), amount)? - .add_messages(update_user_reward_indexes), - ) - } - ExecuteMsg::BurnFrom { owner, amount } => { - let owner = deps.api.addr_validate(&owner)?; - let update_user_reward_index = update_user_reward_index(deps.storage, &owner)?; - Ok( - execute_burn_from(deps, env, info, owner.to_string(), amount)? - .add_message(update_user_reward_index), - ) - } - ExecuteMsg::SendFrom { - owner, - contract, - amount, - msg, - } => { - let contract = deps.api.addr_validate(&contract)?; - let update_user_reward_indexes = vec![ - update_user_reward_index(deps.storage, &deps.api.addr_validate(&owner)?)?, - update_user_reward_index(deps.storage, &contract)?, - ]; - Ok( - execute_send_from(deps, env, info, owner, contract.to_string(), amount, msg)? - .add_messages(update_user_reward_indexes), - ) - } - } -} - -pub const REPLY_INIT_VAULT_REWARDS: u64 = 777; - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - match msg.id { - REPLY_INIT_VAULT_REWARDS => match msg.result { - SubMsgResult::Ok(res) => { - let vault_rewards = - parse_instantiate_response_data(res.data.unwrap().as_slice()).unwrap(); - update_rewards_contract(deps, vault_rewards.contract_address) - } - SubMsgResult::Err(e) => Err(StdError::generic_err(format!( - "error instantiating vault rewards contract: {e:?}" - )))?, - }, - _ => { - unimplemented!() - } - } -} - -fn update_rewards_contract( - deps: DepsMut, - rewards_contract: String, -) -> Result { - deps.api.addr_validate(&rewards_contract)?; - - VAULT_REWARDS.save(deps.storage, &deps.api.addr_validate(&rewards_contract)?)?; - - Ok(Response::default().add_attributes(vec![ - ("action", "init_vault_rewards"), - ("contract_address", rewards_contract.as_str()), - ])) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Claims { address } => { - to_json_binary(&CLAIMS.query_claims(deps, &deps.api.addr_validate(&address)?)?) - } - QueryMsg::Investment {} => to_json_binary(&query_investment(deps)?), - QueryMsg::TokenInfo {} => to_json_binary(&query_token_info(deps)?), - QueryMsg::AdditionalTokenInfo {} => to_json_binary(&query_vault_token_info(deps)?), - QueryMsg::Balance { address } => to_json_binary(&query_balance(deps, address)?), - QueryMsg::Allowance { owner, spender } => { - to_json_binary(&query_allowance(deps, owner, spender)?) - } - QueryMsg::DepositRatio { funds } => to_json_binary(&query_deposit_ratio(deps, funds)?), - QueryMsg::PendingBonds { address } => to_json_binary(&query_pending_bonds(deps, address)?), - QueryMsg::GetDebug {} => to_json_binary(&query_debug_string(deps)?), - QueryMsg::GetTvlInfo {} => to_json_binary(&query_tvl_info(deps)?), - QueryMsg::PendingUnbonds { address } => { - to_json_binary(&query_pending_unbonds(deps, address)?) - } - QueryMsg::GetCap {} => to_json_binary(&query_cap(deps)?), - QueryMsg::PendingBondsById { bond_id } => { - to_json_binary(&query_pending_bonds_by_id(deps, bond_id)?) - } - QueryMsg::PendingUnbondsById { bond_id } => { - to_json_binary(&query_pending_unbonds_by_id(deps, bond_id)?) - } - } -} - -fn query_cap(deps: Deps) -> StdResult { - Ok(GetCapResponse { - cap: CAP.load(deps.storage)?, - }) -} - -pub fn query_vault_token_info(deps: Deps) -> StdResult { - let token_info = TOKEN_INFO.load(deps.storage)?; - let additional_info = ADDITIONAL_TOKEN_INFO.load(deps.storage)?; - let res = VaultTokenInfoResponse { - name: token_info.name, - thesis: additional_info.thesis, - symbol: token_info.symbol, - decimals: token_info.decimals, - total_supply: token_info.total_supply, - creation_time: additional_info.creation_time, - }; - Ok(res) -} - -pub fn query_debug_string(deps: Deps) -> StdResult { - let debug_string = DEBUG_TOOL.load(deps.storage)?; - - Ok(GetDebugResponse { - debug: debug_string, - }) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - let msgs: Result, StdError> = cw20_base::state::BALANCES - .range(deps.storage, None, None, Order::Ascending) - .map(|val| { - let (addr, _) = val?; - update_user_reward_index(deps.storage, &addr) - }) - .collect(); - - let wrapped_msges = msgs?.into_iter().map(CosmosMsg::Wasm); - - Ok(Response::new() - .add_attribute( - "updated-rewards-indexes-msges", - wrapped_msges.len().to_string(), - ) - .add_messages(wrapped_msges)) -} - -#[cfg(test)] -mod test { - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - Addr, ContractResult, Decimal, QuerierResult, - }; - - use crate::msg::PrimitiveConfig; - - use super::*; - - #[test] - fn instantiate_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let info = MessageInfo { - sender: Addr::unchecked("owner"), - funds: vec![], - }; - - let msg = InstantiateMsg { - name: "vault".to_string(), - thesis: "to generate yield, I guess".to_string(), - symbol: "VLT".to_string(), - decimals: 6, - min_withdrawal: Uint128::new(100), - primitives: vec![ - PrimitiveConfig { - weight: Decimal::from_ratio(Uint128::one(), Uint128::new(3)), - address: "prim1".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - PrimitiveConfig { - weight: Decimal::from_ratio(Uint128::one(), Uint128::new(3)), - address: "prim2".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/2".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uqsr".to_string(), - quote_denom: "uosmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - PrimitiveConfig { - weight: Decimal::from_ratio(Uint128::one(), Uint128::new(3)), - address: "prim3".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/3".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uatom".to_string(), - quote_denom: "uqsr".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - ], - vault_rewards_code_id: 123, - reward_token: cw_asset::AssetInfoBase::Native("uqsr".to_string()), - reward_distribution_schedules: vec![vault_rewards::state::DistributionSchedule { - start: 0, - end: 500, - amount: Uint128::from(1000u128), - }], - total_cap: Uint128::new(10_000_000_000_000), - deposit_denom: "ibc/SOME_DENOM".to_string(), - }; - - // prepare 3 mock configs for prim1, prim2 and prim3 - deps.querier.update_wasm(|wq| match wq { - cosmwasm_std::WasmQuery::Smart { - contract_addr, - msg: _, - } => { - if contract_addr == "prim1" { - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&lp_strategy::msg::ConfigResponse { - config: lp_strategy::state::Config { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }, - }) - .unwrap(), - )) - } else if contract_addr == "prim2" { - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&lp_strategy::msg::ConfigResponse { - config: lp_strategy::state::Config { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/2".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uqsr".to_string(), - quote_denom: "uosmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }, - }) - .unwrap(), - )) - } else if contract_addr == "prim3" { - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&lp_strategy::msg::ConfigResponse { - config: lp_strategy::state::Config { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/3".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uatom".to_string(), - quote_denom: "uqsr".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }, - }) - .unwrap(), - )) - } else { - QuerierResult::Err(cosmwasm_std::SystemError::NoSuchContract { - addr: contract_addr.to_string(), - }) - } - } - cosmwasm_std::WasmQuery::Raw { - contract_addr: _, - key: _, - } => QuerierResult::Err(cosmwasm_std::SystemError::Unknown {}), - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Err(cosmwasm_std::SystemError::Unknown {}) - } - _ => panic!("Unimplemented query path"), - }); - - instantiate(deps.as_mut(), env, info, msg).unwrap(); - } - - #[test] - fn test_try_clear_cache() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let info = mock_info("lulu", &[]); - - let primitive_configs = vec![ - PrimitiveConfig { - weight: Decimal::from_ratio(Uint128::one(), Uint128::new(3)), - address: "prim1".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - PrimitiveConfig { - weight: Decimal::from_ratio(Uint128::one(), Uint128::new(3)), - address: "prim2".to_string(), - init: crate::msg::PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 300, - pool_id: 1, - pool_denom: "gamm/pool/2".to_string(), - local_denom: "ibc/SOME_DENOM".to_string(), - base_denom: "uqsr".to_string(), - quote_denom: "uosmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }, - ]; - - let investment_info = InvestmentInfo { - owner: Addr::unchecked("lulu"), - min_withdrawal: Uint128::from(100u128), - primitives: primitive_configs, - deposit_denom: "ibc/SOME_DENOM".to_string(), - }; - - INVESTMENT - .save(deps.as_mut().storage, &investment_info) - .unwrap(); - - let msg = ExecuteMsg::ClearCache {}; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - - assert_eq!(res.messages.len(), 2); - assert_eq!( - res.messages[0], - SubMsg::new(WasmMsg::Execute { - contract_addr: "prim1".to_string(), - funds: vec![], - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::TryIcq {}).unwrap(), - }) - ); - assert_eq!( - res.messages[1], - SubMsg::new(WasmMsg::Execute { - contract_addr: "prim2".to_string(), - funds: vec![], - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::TryIcq {}).unwrap(), - }) - ); - } -} diff --git a/smart-contracts/contracts/basic-vault/src/error.rs b/smart-contracts/contracts/basic-vault/src/error.rs deleted file mode 100644 index dd06951db..000000000 --- a/smart-contracts/contracts/basic-vault/src/error.rs +++ /dev/null @@ -1,146 +0,0 @@ -use cosmwasm_std::{ - CheckedFromRatioError, CheckedMultiplyRatioError, OverflowError, StdError, Uint128, -}; -use quasar_types::error::Error as QError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Vault is over cap")] - OverCap {}, - - #[error("Validator '{validator}' not in current validator set")] - NotInValidatorSet { validator: String }, - - #[error("Different denominations in bonds: '{denom1}' vs. '{denom2}'")] - DifferentBondDenom { denom1: String, denom2: String }, - - #[error("Stored bonded {stored}, but query bonded {queried}")] - BondedMismatch { stored: Uint128, queried: Uint128 }, - - #[error("Incorrect bonding ratio")] - IncorrectBondingRatio {}, - - #[error("No {denom} tokens sent")] - EmptyBalance { denom: String }, - - #[error("Must unbond at least {min_bonded}")] - UnbondTooSmall { min_bonded: Uint128 }, - - #[error("Cannot withdraw without vault tokens")] - NoFunds {}, - - #[error("Insufficient balance in contract to process claim")] - BalanceTooSmall {}, - - #[error("No claims that can be released currently")] - NothingToClaim {}, - - #[error("Cannot set to own account")] - CannotSetOwnAccount {}, - - #[error("Invalid expiration")] - InvalidExpiration {}, - - #[error("Invalid zero amount")] - InvalidZeroAmount {}, - - #[error("Duplicate bond response for bond_id {bond_id}")] - DuplicateBondResponse { bond_id: String }, - - #[error("Allowance is expired")] - Expired {}, - - #[error("No allowance for this account")] - NoAllowance {}, - - #[error("Minting cannot exceed the cap")] - CannotExceedCap {}, - - #[error("Duplicate initial balance addresses")] - DuplicateInitialBalanceAddresses {}, - - #[error("Incorrect callback id, expected: {expected}, got: {:?}", ids)] - IncorrectCallbackId { expected: String, ids: Vec }, - - #[error("Multiply ratio error: {0}")] - MultiplyRatioError(String), - - #[error("Missing bond response")] - MissingBondResponse {}, - - #[error("Token weight vector is empty")] - TokenWeightsIsEMpty {}, - - #[error("Coins vector is empty")] - CoinsVectorIsEmpty {}, - - #[error("Denom not found in coins vector")] - DenomNotFoundInCoinsVector {}, - - #[error("User does not have pending unbonds")] - NoPendingUnbonds {}, - - #[error("Bond response is empty")] - BondResponseIsEmpty {}, - - #[error("Unbond is empty")] - UnbondIsEmpty {}, - - #[error("Unbond stub is empty")] - UnbondStubIsEmpty {}, - - #[error("Coins weight vector is empty")] - CoinsWeightVectorIsEmpty {}, - - #[error("{0}")] - QError(#[from] QError), - - #[error("{0}")] - PaymentError(#[from] cw_utils::PaymentError), - - #[error("{0}")] - CheckedMultiplyRatioError(#[from] CheckedMultiplyRatioError), - - #[error("{0}")] - OverflowError(#[from] OverflowError), -} - -impl From for ContractError { - fn from(err: CheckedFromRatioError) -> Self { - ContractError::MultiplyRatioError(err.to_string()) - } -} - -impl From for ContractError { - fn from(err: cw20_base::ContractError) -> Self { - match err { - cw20_base::ContractError::Std(error) => ContractError::Std(error), - cw20_base::ContractError::Unauthorized {} => ContractError::Unauthorized {}, - cw20_base::ContractError::CannotSetOwnAccount {} => { - ContractError::CannotSetOwnAccount {} - } - cw20_base::ContractError::InvalidExpiration {} => ContractError::InvalidExpiration {}, - #[allow(deprecated)] - cw20_base::ContractError::InvalidZeroAmount {} => ContractError::InvalidZeroAmount {}, - cw20_base::ContractError::Expired {} => ContractError::Expired {}, - cw20_base::ContractError::NoAllowance {} => ContractError::NoAllowance {}, - cw20_base::ContractError::CannotExceedCap {} => ContractError::CannotExceedCap {}, - // This should never happen, as this contract doesn't use logo - cw20_base::ContractError::LogoTooBig {} - | cw20_base::ContractError::InvalidPngHeader {} - | cw20_base::ContractError::InvalidXmlPreamble {} => { - ContractError::Std(StdError::generic_err(err.to_string())) - } - cw20_base::ContractError::DuplicateInitialBalanceAddresses {} => { - ContractError::DuplicateInitialBalanceAddresses {} - } - } - } -} diff --git a/smart-contracts/contracts/basic-vault/src/execute.rs b/smart-contracts/contracts/basic-vault/src/execute.rs deleted file mode 100644 index c7641da45..000000000 --- a/smart-contracts/contracts/basic-vault/src/execute.rs +++ /dev/null @@ -1,1098 +0,0 @@ -use cosmwasm_std::{ - coin, to_json_binary, Attribute, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, Response, - StdError, Uint128, WasmMsg, -}; - -use cw20::BalanceResponse; -use cw20_base::contract::execute_burn; -use cw_utils::{must_pay, nonpayable, PaymentError}; - -use lp_strategy::msg::{IcaBalanceResponse, PrimitiveSharesResponse}; -use quasar_types::types::{CoinRatio, CoinWeight}; - -use crate::error::ContractError; -use crate::helpers::{can_unbond_from_primitive, is_contract_admin, update_user_reward_index}; -use crate::msg::PrimitiveConfig; -use crate::state::{ - BondingStub, Cap, InvestmentInfo, Unbond, UnbondingStub, BONDING_SEQ, BONDING_SEQ_TO_ADDR, - BOND_STATE, CAP, INVESTMENT, PENDING_BOND_IDS, PENDING_UNBOND_IDS, UNBOND_STATE, -}; -use crate::types::FromUint128; - -// returns amount if the coin is found and amount is non-zero -// errors otherwise -pub fn must_pay_multi(funds: &[Coin], denom: &str) -> Result { - match funds.iter().find(|c| c.denom == denom) { - Some(coin) => { - if coin.amount.is_zero() { - Err(PaymentError::MissingDenom(denom.to_string())) - } else { - Ok(coin.amount) - } - } - None => Err(PaymentError::MissingDenom(denom.to_string())), - } -} - -pub fn get_deposit_amount_weights( - deps: &Deps, - primitives: &[PrimitiveConfig], -) -> Result { - let weights = primitives - .iter() - .map(|pc| -> Result { - let balance: IcaBalanceResponse = deps.querier.query_wasm_smart( - pc.address.clone(), - &lp_strategy::msg::QueryMsg::IcaBalance {}, - )?; - let supply: PrimitiveSharesResponse = deps.querier.query_wasm_smart( - pc.address.clone(), - &lp_strategy::msg::QueryMsg::PrimitiveShares {}, - )?; - - // if only one of the two is zero, we should error - if (supply.total.is_zero() && !balance.amount.amount.is_zero()) || (!supply.total.is_zero() && balance.amount.amount.is_zero()) { - return Err(ContractError::Std(StdError::GenericErr { - msg: "Unexpected primitive state, either both supply and balance should be zero, or neither.".to_string(), - })); - } - - let ratio = match supply.total.is_zero() { - true => Decimal::one(), - false => Decimal::from_ratio(balance.amount.amount, supply.total), - }; - - Ok(CoinWeight { - weight: ratio.checked_mul(pc.weight)?, - denom: balance.amount.denom, - }) - }) - .collect::, ContractError>>()?; - - let mut ratio = CoinRatio { ratio: weights }; - ratio.normalize()?; - - Ok(ratio) -} - -pub fn get_token_amount_weights( - deposit_amount_weights: &[CoinWeight], -) -> Result, ContractError> { - deposit_amount_weights.iter().try_fold( - vec![], - |mut acc: Vec, - coin_weight: &CoinWeight| - -> Result, ContractError> { - // look through acc for existing denom and add weight, or else push it to the back of the vec - // todo: verify this works for multiple tokens, this might not overwrite when two primitives have the same token - let existing_weight = acc.iter_mut().find(|cw| cw.denom == coin_weight.denom); - match existing_weight { - Some(weight) => weight.weight = weight.weight.checked_add(coin_weight.weight)?, - None => acc.push(coin_weight.clone()), - }; - Ok(acc) - }, - ) -} - -pub fn get_max_bond( - funds: &[Coin], - token_weights: &Vec, -) -> Result { - let mut max_bond = Decimal::MAX; - for coin_weight in token_weights { - let amount = must_pay_multi(funds, &coin_weight.denom)?; - let bond_for_token = Decimal::from_uint128(amount).checked_div(coin_weight.weight)?; - - if bond_for_token < max_bond { - max_bond = bond_for_token; - } - } - Ok(max_bond) -} - -pub fn get_deposit_and_remainder_for_ratio( - funds: &[Coin], - max_bond: Decimal, - ratio: &CoinRatio, -) -> Result<(Vec, Vec), ContractError> { - // verify that >0 of each token in ratio is passed in, return (funds, remainder)) - // where funds is the max amount we can use in compliance with the ratio - // and remainder is the change to return to user - let mut remainder = funds.to_owned(); - - let coins: Result, ContractError> = ratio - .ratio - .iter() - .filter(|r| r.weight > Decimal::zero()) - .map(|r| { - let amount = Decimal::from_uint128(must_pay_multi(funds, &r.denom)?); - let expected_amount = max_bond.checked_mul(r.weight)?; - - if expected_amount > amount { - return Err(ContractError::IncorrectBondingRatio {}); - } - - remainder = remainder - .iter() - .map(|c| -> Result { - if c.denom == r.denom { - Ok(Coin { - amount: c.amount.checked_sub(expected_amount.to_uint_floor())?, - denom: c.denom.clone(), - }) - } else { - Ok(c.clone()) - } - }) - .collect::, ContractError>>()?; - - Ok(Coin { - denom: r.denom.clone(), - amount: expected_amount.to_uint_floor(), - }) - }) - .collect(); - - Ok((coins?, remainder)) -} - -pub fn divide_by_ratio( - funds: Coin, - invest: InvestmentInfo, -) -> Result, ContractError> { - let coins: Result, cosmwasm_std::OverflowError> = invest - .primitives - .iter() - .map( - |config| -> Result<(Coin, String), cosmwasm_std::OverflowError> { - config - .weight - .checked_mul(Decimal::from_uint128(funds.amount)) - .map(|dec| { - ( - coin(dec.to_uint_floor().u128(), funds.denom.as_str()), - config.address.clone(), - ) - }) - }, - ) - .collect(); - Ok(coins?) -} - -pub fn may_pay_with_ratio( - deps: &Deps, - funds: &[Coin], - mut invest: InvestmentInfo, -) -> Result<(Vec, Vec), ContractError> { - // normalize primitives - invest.normalize_primitive_weights(); - - // load cached balance of primitive contracts - let deposit_amount_ratio = get_deposit_amount_weights(deps, &invest.primitives)?; - - if deposit_amount_ratio - .ratio - .first() - .ok_or(ContractError::CoinsWeightVectorIsEmpty {})? - .weight - == Decimal::zero() - { - return Err(ContractError::Std(StdError::GenericErr { - msg: "Deposit amount weight for primitive is zero".to_string(), - })); - } - - let token_weights: Vec = get_token_amount_weights(&deposit_amount_ratio.ratio)?; - - if token_weights - .first() - .ok_or(ContractError::TokenWeightsIsEMpty {})? - .weight - == Decimal::zero() - { - return Err(ContractError::Std(StdError::GenericErr { - msg: format!( - "token weight is zero for {}", - token_weights.first().unwrap().denom - ), - })); - } - - let max_bond = get_max_bond(funds, &token_weights)?; - - if max_bond == Decimal::zero() || max_bond == Decimal::MAX { - return Err(ContractError::Std(StdError::GenericErr { - msg: format!("Unable to correctly determine max_bond, value: {max_bond}"), - })); - } - - let (coins, remainder) = - get_deposit_and_remainder_for_ratio(funds, max_bond, &deposit_amount_ratio)?; - - if coins - .first() - .ok_or(ContractError::CoinsVectorIsEmpty {})? - .amount - == Uint128::zero() - { - return Err(ContractError::Std(StdError::GenericErr { - msg: "we failed here".to_string(), - })); - } - - Ok((coins, remainder)) -} - -pub fn bond( - deps: DepsMut, - _env: Env, - info: MessageInfo, - recipient: Option, -) -> Result { - let invest = INVESTMENT.load(deps.storage)?; - - // load vault info & sequence number - let bond_seq = BONDING_SEQ.load(deps.storage)?; - - // get the deposited funds - let amount = must_pay(&info, invest.deposit_denom.as_str())?; - - // find recipient - let recipient_addr = match recipient { - Some(r) => deps.api.addr_validate(&r)?, - None => info.sender, - }; - - let mut deposit_stubs = vec![]; - let divided = divide_by_ratio(coin(amount.u128(), invest.deposit_denom.as_str()), invest)?; - - CAP.update( - deps.storage, - |cap| -> Result { cap.update_current(amount) }, - )?; - - let bond_msgs: Result, ContractError> = divided - .into_iter() - .map(|(coin, prim_addr)| { - let deposit_stub = BondingStub { - address: prim_addr.clone(), - bond_response: None, - primitive_value: None, - amount: coin.amount, - }; - deposit_stubs.push(deposit_stub); - - Ok(WasmMsg::Execute { - contract_addr: prim_addr, - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::Bond { - id: bond_seq.to_string(), - })?, - funds: vec![coin], - }) - }) - .collect(); - - // let (primitive_funding_amounts, remainder) = - // may_pay_with_ratio(&deps.as_ref(), &info.funds, invest.clone())?; - - // let bond_msgs: Result, ContractError> = invest - // .primitives - // .iter() - // .zip(primitive_funding_amounts) - // .map(|(pc, funds)| { - // let deposit_stub = BondingStub { - // address: pc.address.clone(), - // bond_response: None, - // primitive_value: None, - // amount: funds.amount, - // }; - // deposit_stubs.push(deposit_stub); - - // Ok(WasmMsg::Execute { - // contract_addr: pc.address.clone(), - // msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::Bond { - // id: bond_seq.to_string(), - // })?, - // funds: vec![funds], - // }) - // }) - // .collect(); - - // save bonding state for use during the callback - PENDING_BOND_IDS.update(deps.storage, recipient_addr.clone(), |ids| match ids { - Some(mut bond_ids) => { - bond_ids.push(bond_seq.to_string()); - Ok::, ContractError>(bond_ids) - } - None => Ok(vec![bond_seq.to_string()]), - })?; - BOND_STATE.save(deps.storage, bond_seq.to_string(), &deposit_stubs)?; - BONDING_SEQ_TO_ADDR.save( - deps.storage, - bond_seq.to_string(), - &recipient_addr.to_string(), - )?; - BONDING_SEQ.save(deps.storage, &bond_seq.checked_add(Uint128::new(1))?)?; - - // let remainder_msg = BankMsg::Send { - // to_address: recipient_addr.to_string(), - // amount: remainder - // .iter() - // .filter(|c| !c.amount.is_zero()) - // .map(|r| Coin { - // denom: r.denom.clone(), - // amount: r.amount, - // }) - // .collect(), - // }; - - Ok(Response::new() - .add_attribute("bond_id", bond_seq.to_string()) - .add_messages(bond_msgs?)) - // .add_message(remainder_msg)) -} - -pub fn unbond( - mut deps: DepsMut, - env: Env, - info: MessageInfo, - amount: Option, -) -> Result { - nonpayable(&info)?; - - let start_unbond_response = - do_start_unbond(deps.branch(), &env, &info, amount)?.unwrap_or(Response::new()); - - let start_unbond_msgs = start_unbond_response - .messages - .iter() - .map(|sm| sm.msg.clone()); - - Ok(Response::new() - .add_messages(start_unbond_msgs) - .add_attributes(start_unbond_response.attributes)) -} - -pub fn do_start_unbond( - mut deps: DepsMut, - env: &Env, - info: &MessageInfo, - amount: Option, -) -> Result, ContractError> { - let unbond_amount = amount.unwrap_or(Uint128::zero()); - if unbond_amount.is_zero() { - // skip start unbond - return Ok(None); - } - - let invest = INVESTMENT.load(deps.storage)?; - let bond_seq = BONDING_SEQ.load(deps.storage)?; - - // check that user has vault tokens and the amount is > min_withdrawal - if unbond_amount < invest.min_withdrawal { - return Err(ContractError::UnbondTooSmall { - min_bonded: invest.min_withdrawal, - }); - } - - // burn if balance is more than or equal to amount (handled in execute_burn) - let update_user_rewards_idx_msg = - update_user_reward_index(deps.as_ref().storage, &info.sender)?; - - let mut unbonding_stubs = vec![]; - let supply = cw20_base::contract::query_token_info(deps.as_ref())?.total_supply; - - let start_unbond_msgs: Vec = invest - .primitives - .iter() - .map(|pc| -> Result { - // get this vaults primitive share balance - let our_balance: BalanceResponse = deps.querier.query_wasm_smart( - pc.address.clone(), - &lp_strategy::msg::QueryMsg::Balance { - address: env.contract.address.to_string(), - }, - )?; - - // lets get the amount of tokens to unbond for this primitive: p_unbond_amount = (v_unbond_amount / v_total_supply) * our_p_balance - let primitive_share_amount = Decimal::from_ratio(unbond_amount, supply) - .checked_mul(Decimal::from_uint128(our_balance.balance))? - .to_uint_floor(); - - unbonding_stubs.push(UnbondingStub { - address: pc.address.clone(), - unlock_time: None, - unbond_response: None, - unbond_funds: vec![], - }); - - Ok(WasmMsg::Execute { - contract_addr: pc.address.clone(), - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::StartUnbond { - id: bond_seq.to_string(), - share_amount: primitive_share_amount, - })?, - funds: vec![], - }) - }) - .collect::, ContractError>>()?; - - // We need to save the unbonding state for use during the callback - PENDING_UNBOND_IDS.update(deps.storage, info.sender.clone(), |ids| match ids { - Some(mut bond_ids) => { - bond_ids.push(bond_seq.to_string()); - Ok::, ContractError>(bond_ids) - } - None => Ok(vec![bond_seq.to_string()]), - })?; - UNBOND_STATE.save( - deps.storage, - bond_seq.to_string(), - &Unbond { - stub: unbonding_stubs, - shares: unbond_amount, - }, - )?; - BONDING_SEQ_TO_ADDR.save(deps.storage, bond_seq.to_string(), &info.sender.to_string())?; - BONDING_SEQ.save(deps.storage, &bond_seq.checked_add(Uint128::from(1u128))?)?; - - execute_burn(deps.branch(), env.clone(), info.clone(), unbond_amount)?; - Ok(Some( - Response::new() - .add_messages(start_unbond_msgs) - .add_message(update_user_rewards_idx_msg) - .add_attributes(vec![ - Attribute { - key: "action".to_string(), - value: "start_unbond".to_string(), - }, - Attribute { - key: "from".to_string(), - value: info.sender.to_string(), - }, - Attribute { - key: "burnt".to_string(), - value: unbond_amount.to_string(), - }, - Attribute { - key: "bond_id".to_string(), - value: bond_seq.to_string(), - }, - ]), - )) -} - -// find all unbondable pending unbonds where unlock_time < env.block.time -// then trigger unbonds -pub fn do_unbond( - mut deps: DepsMut, - env: &Env, - info: &MessageInfo, -) -> Result, ContractError> { - let pending_unbond_ids_opt = PENDING_UNBOND_IDS.may_load(deps.storage, info.sender.clone())?; - - match pending_unbond_ids_opt { - Some(pending_unbond_ids) => { - let mut unbond_msgs: Vec = vec![]; - for unbond_id in pending_unbond_ids.iter() { - let unbond_stubs_opt = UNBOND_STATE.may_load(deps.storage, unbond_id.clone())?; - if let Some(unbond_stubs) = unbond_stubs_opt { - let mut current_unbond_msgs = find_and_return_unbondable_msgs( - deps.branch(), - env, - info, - unbond_id, - unbond_stubs.stub, - )?; - unbond_msgs.append(current_unbond_msgs.as_mut()); - } - } - - Ok(Some( - Response::new() - .add_messages(unbond_msgs.clone()) - .add_attributes(vec![ - Attribute { - key: "action".to_string(), - value: "unbond".to_string(), - }, - Attribute { - key: "from".to_string(), - value: info.sender.to_string(), - }, - Attribute { - key: "num_unbondable_ids".to_string(), - value: unbond_msgs.len().to_string(), - }, - ]), - )) - } - None => Ok(None), - } -} - -pub fn find_and_return_unbondable_msgs( - deps: DepsMut, - env: &Env, - _info: &MessageInfo, - unbond_id: &str, - unbond_stubs: Vec, -) -> Result, ContractError> { - // go through unbond_stubs and find ones where unlock_time < env.block.time and execute - let mut unbond_msgs = vec![]; - - for stub in unbond_stubs.iter() { - let can_unbond = can_unbond_from_primitive(deps.as_ref(), env, unbond_id, stub)?; - - if can_unbond { - unbond_msgs.push(WasmMsg::Execute { - contract_addr: stub.address.clone(), - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::Unbond { - id: unbond_id.to_string(), - })?, - funds: vec![], - }) - } - } - - Ok(unbond_msgs) -} - -// claim is equivalent to calling unbond with amount: 0 -pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> Result { - nonpayable(&info)?; - - Ok(do_unbond(deps, &env, &info)?.unwrap_or(Response::new())) -} - -pub fn update_cap( - deps: DepsMut, - env: Env, - info: MessageInfo, - new_total: Option, - new_cap_admin: Option, -) -> Result { - nonpayable(&info)?; - is_contract_admin(&deps.querier, &env, &info.sender)?; - let mut attributes = vec![]; - - if let Some(new_total) = new_total { - CAP.update(deps.storage, |c| -> Result { - Ok(c.update_total_cap(new_total)) - })?; - attributes.push(Attribute { - key: "new_total".to_string(), - value: new_total.to_string(), - }) - } - - if let Some(new_cap_admin) = new_cap_admin { - let new_cap_admin_validated = deps.api.addr_validate(&new_cap_admin)?; - CAP.update(deps.storage, |c| -> Result { - Ok(c.update_cap_admin(new_cap_admin_validated)) - })?; - attributes.push(Attribute { - key: "new_cap_admin".to_string(), - value: new_cap_admin, - }) - } - - Ok(Response::new() - .add_attribute("action", "update_cap") - .add_attributes(attributes) - .add_attribute("success", "true")) -} - -#[cfg(test)] -mod tests { - use crate::callback::on_bond; - use crate::msg::PrimitiveInitMsg; - use crate::state::VAULT_REWARDS; - use crate::tests::{mock_deps_with_primitives, TEST_ADMIN}; - - use super::*; - use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::{attr, Addr, Coin, CosmosMsg, Uint128}; - - use cw20_base::state::{MinterData, TokenInfo, TOKEN_INFO}; - use lp_strategy::msg::InstantiateMsg; - - // this test tests 2 on_bond callbacks and a start unbond. The amounts returned slightly 'weird'. The main idea is that after the on_bond callbacks, - // our user owns 10% of the vault. When we then start to unbond, we expect the user to get 10% of the value in each primitive - #[test] - fn test_correct_start_unbond_amount() { - let primitive_states = vec![ - ( - "contract1".to_string(), - "ibc/ED07".to_string(), - // we init state with 1 primitve share being 10 tokens - Uint128::from(500u128), - Uint128::from(5000u128), - ), - ( - "contract2".to_string(), - "ibc/ED07".to_string(), - Uint128::from(500u128), - Uint128::from(5000u128), - ), - ]; - // mock the queries so the primitives exist - let mut deps = mock_deps_with_primitives(primitive_states); - let env = mock_env(); - let info = mock_info("user", &[Coin::new(10000, "token")]); - - let instantiate_msg_1 = InstantiateMsg { - lock_period: 3600, - pool_id: 2, - pool_denom: "gamm/pool/2".to_string(), - local_denom: "ibc/ED07".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "usdc".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-1".to_string(), - expected_connection: "connection-0".to_string(), - }; - - let instantiate_msg_2 = InstantiateMsg { - lock_period: 7200, - pool_id: 5, - pool_denom: "gamm/pool/5".to_string(), - local_denom: "ibc/ED07".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-2".to_string(), - return_source_channel: "channel-3".to_string(), - expected_connection: "connection-1".to_string(), - }; - - // set up the contract state - let min_withdrawal = Uint128::new(100); - let invest = InvestmentInfo { - primitives: vec![ - PrimitiveConfig { - address: "contract1".to_string(), - weight: Decimal::percent(50), - init: PrimitiveInitMsg::LP(instantiate_msg_1), - }, - PrimitiveConfig { - address: "contract2".to_string(), - weight: Decimal::percent(50), - init: PrimitiveInitMsg::LP(instantiate_msg_2), - }, - ], - min_withdrawal, - owner: Addr::unchecked("bob"), - deposit_denom: "ibc/ED07".to_string(), - }; - let bond_seq = Uint128::new(1); - - INVESTMENT.save(deps.as_mut().storage, &invest).unwrap(); - BONDING_SEQ.save(deps.as_mut().storage, &bond_seq).unwrap(); - VAULT_REWARDS - .save(deps.as_mut().storage, &Addr::unchecked("rewards-contract")) - .unwrap(); - - // store token info using cw20-base format - let token_info = TokenInfo { - name: "token".to_string(), - symbol: "token".to_string(), - decimals: 6, - total_supply: Uint128::new(5000), - // set self as minter, so we can properly execute mint and burn - mint: Some(MinterData { - minter: env.contract.address.clone(), - cap: None, - }), - }; - TOKEN_INFO.save(deps.as_mut().storage, &token_info).unwrap(); - - BONDING_SEQ_TO_ADDR - .save(deps.as_mut().storage, "1".to_string(), &"user".to_string()) - .unwrap(); - - // mock an unfilfilled stub, do 2 callbacks to fullfill the stubs, and mint shares for the user such that the user owns 50% of the shares - BOND_STATE - .save( - deps.as_mut().storage, - "1".to_string(), - &vec![ - BondingStub { - address: "contract1".to_string(), - bond_response: None, - amount: Uint128::new(5000), - primitive_value: None, - }, - BondingStub { - address: "contract2".to_string(), - bond_response: None, - amount: Uint128::new(5000), - primitive_value: None, - }, - ], - ) - .unwrap(); - - // update the querier to return underlying shares of the vault, in total our vault has 5000 internal shares - // we expect the vault to unbond 10% of the shares it owns in each primitive, so if contract 1 returns - // 4000 shares and contract 2 returns 3000 shares, and we unbond 10% of the shares, we should unbond 400 and 300 shares respectively - deps.querier.update_state(vec![ - // the primitives were mocked with 500 shares and 5000 tokens, we should have deposited 5000 more tokens so get 500 more prim shares - ("contract1", Uint128::new(1000), Uint128::new(10000)), - ("contract2", Uint128::new(1000), Uint128::new(10000)), - ]); - - // we do 2 callbacks, reflecting the updated state of the primitives - on_bond( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("contract1"), - funds: vec![], - }, - Uint128::new(500), - "1".to_string(), - ) - .unwrap(); - on_bond( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("contract2"), - funds: vec![], - }, - Uint128::new(500), - "1".to_string(), - ) - .unwrap(); - - // start trying withdrawals - // our succesful withdrawal should show that it is possible for the vault contract to unbond a different amount than 350 and 150 shares - - // case 1: amount is zero, skip start unbond - let amount = None; - let res = do_start_unbond(deps.as_mut(), &env, &info, amount).unwrap(); - assert_eq!(res, None); - - // case 2: amount is less than min_withdrawal, error - let amount = Some(Uint128::new(50)); - let res = do_start_unbond(deps.as_mut(), &env, &info, amount); - assert!(res.is_err()); - assert_eq!( - res.unwrap_err(), - ContractError::UnbondTooSmall { - min_bonded: min_withdrawal - } - ); - - // case 3: amount is valid, execute start unbond on all primitive contracts - let amount = cw20_base::contract::query_balance(deps.as_ref(), "user".to_string()) - .unwrap() - .balance; - - let res = do_start_unbond(deps.as_mut(), &env, &info, Some(amount)) - .unwrap() - .unwrap(); - assert_eq!(res.attributes.len(), 4); - assert_eq!(res.messages.len(), 3); - - // check the messages sent to each primitive contract - let msg1 = &res.messages[0]; - let msg2 = &res.messages[1]; - - // start unbond is independent of the amounts in the callback, but is dependent on the vault's amount of shares in the primitive - assert_eq!( - msg1.msg, - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "contract1".to_string(), - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::StartUnbond { - id: bond_seq.to_string(), - share_amount: Uint128::new(500), - }) - .unwrap(), - funds: vec![], - }) - ); - assert_eq!( - msg2.msg, - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "contract2".to_string(), - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::StartUnbond { - id: bond_seq.to_string(), - share_amount: Uint128::new(500), - }) - .unwrap(), - funds: vec![], - }) - ); - } - - #[test] - fn test_correct_start_unbond_amount_uneven_weights() { - let primitive_states = vec![ - ( - "contract1".to_string(), - "ibc/ED07".to_string(), - // we init state with 1 primitve share being 10 tokens - Uint128::from(900u128), - Uint128::from(9000u128), - ), - ( - "contract2".to_string(), - "ibc/ED07".to_string(), - Uint128::from(100u128), - Uint128::from(1000u128), - ), - ]; - // mock the queries so the primitives exist - let mut deps = mock_deps_with_primitives(primitive_states); - let env = mock_env(); - let info = mock_info("user", &[Coin::new(10000, "token")]); - - let instantiate_msg_1 = InstantiateMsg { - lock_period: 3600, - pool_id: 2, - pool_denom: "gamm/pool/2".to_string(), - local_denom: "ibc/ED07".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "usdc".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-1".to_string(), - expected_connection: "connection-0".to_string(), - }; - - let instantiate_msg_2 = InstantiateMsg { - lock_period: 7200, - pool_id: 5, - pool_denom: "gamm/pool/5".to_string(), - local_denom: "ibc/ED07".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-2".to_string(), - return_source_channel: "channel-3".to_string(), - expected_connection: "connection-1".to_string(), - }; - - // set up the contract state - let min_withdrawal = Uint128::new(100); - let invest = InvestmentInfo { - primitives: vec![ - PrimitiveConfig { - address: "contract1".to_string(), - weight: Decimal::percent(90), - init: PrimitiveInitMsg::LP(instantiate_msg_1), - }, - PrimitiveConfig { - address: "contract2".to_string(), - weight: Decimal::percent(10), - init: PrimitiveInitMsg::LP(instantiate_msg_2), - }, - ], - min_withdrawal, - owner: Addr::unchecked("bob"), - deposit_denom: "ibc/ED07".to_string(), - }; - let bond_seq = Uint128::new(1); - - INVESTMENT.save(deps.as_mut().storage, &invest).unwrap(); - BONDING_SEQ.save(deps.as_mut().storage, &bond_seq).unwrap(); - VAULT_REWARDS - .save(deps.as_mut().storage, &Addr::unchecked("rewards-contract")) - .unwrap(); - - // store token info using cw20-base format - let token_info = TokenInfo { - name: "token".to_string(), - symbol: "token".to_string(), - decimals: 6, - total_supply: Uint128::new(5000), - // set self as minter, so we can properly execute mint and burn - mint: Some(MinterData { - minter: env.contract.address.clone(), - cap: None, - }), - }; - TOKEN_INFO.save(deps.as_mut().storage, &token_info).unwrap(); - - BONDING_SEQ_TO_ADDR - .save(deps.as_mut().storage, "1".to_string(), &"user".to_string()) - .unwrap(); - - BOND_STATE - .save( - deps.as_mut().storage, - "1".to_string(), - &vec![ - BondingStub { - address: "contract1".to_string(), - bond_response: None, - amount: Uint128::new(9000), - primitive_value: None, - }, - BondingStub { - address: "contract2".to_string(), - bond_response: None, - amount: Uint128::new(1000), - primitive_value: None, - }, - ], - ) - .unwrap(); - // update the querier to return underlying shares of the vault, in total our vault has 5000 internal shares - // we expect the vault to unbond 10% of the shares it owns in each primitive, so if contract 1 returns - // 4000 shares and contract 2 returns 3000 shares, and we unbond 10% of the shares, we should unbond 400 and 300 shares respectively - deps.querier.update_state(vec![ - // the primitives were mocked with 500 shares and 5000 tokens, we should have deposited 5000 more tokens so get 500 more prim shares - ("contract1", Uint128::new(1800), Uint128::new(18000)), - ("contract2", Uint128::new(200), Uint128::new(2000)), - ]); - - // we do 2 callbacks, reflecting the user deposit and the primitive state update - on_bond( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("contract1"), - funds: vec![], - }, - Uint128::new(900), - "1".to_string(), - ) - .unwrap(); - on_bond( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("contract2"), - funds: vec![], - }, - Uint128::new(100), - "1".to_string(), - ) - .unwrap(); - - // start trying withdrawals - // our succesful withdrawal should show that it is possible for the vault contract to unbond a different amount than 350 and 150 shares - - // case 1: amount is zero, skip start unbond - let amount = None; - let res = do_start_unbond(deps.as_mut(), &env, &info, amount).unwrap(); - assert_eq!(res, None); - - // case 2: amount is less than min_withdrawal, error - let amount = Some(Uint128::new(50)); - let res = do_start_unbond(deps.as_mut(), &env, &info, amount); - assert!(res.is_err()); - assert_eq!( - res.unwrap_err(), - ContractError::UnbondTooSmall { - min_bonded: min_withdrawal - } - ); - - // case 3: amount is valid, execute start unbond on all primitive contracts - let amount = cw20_base::contract::query_balance(deps.as_ref(), "user".to_string()) - .unwrap() - .balance; - let _total_supply = cw20_base::contract::query_token_info(deps.as_ref()).unwrap(); - - let res = do_start_unbond(deps.as_mut(), &env, &info, Some(amount)) - .unwrap() - .unwrap(); - assert_eq!(res.attributes.len(), 4); - assert_eq!(res.messages.len(), 3); - - // check the messages sent to each primitive contract - let msg1 = &res.messages[0]; - let msg2 = &res.messages[1]; - - // start unbond is independent of the amounts in the callback, but is dependent on the vault's amount of shares in the primitive - // TODO make sure these numbers make sense - assert_eq!( - msg1.msg, - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "contract1".to_string(), - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::StartUnbond { - id: bond_seq.to_string(), - share_amount: Uint128::new(900), - }) - .unwrap(), - funds: vec![], - }) - ); - assert_eq!( - msg2.msg, - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "contract2".to_string(), - msg: to_json_binary(&lp_strategy::msg::ExecuteMsg::StartUnbond { - id: bond_seq.to_string(), - share_amount: Uint128::new(100), - }) - .unwrap(), - funds: vec![], - }) - ); - } - - #[test] - fn test_proper_update_cap() { - let mut deps = mock_deps_with_primitives(vec![( - "abc".to_string(), - "123".to_string(), - 100u128.into(), - 100u128.into(), - )]); - let env = mock_env(); - let info = mock_info(TEST_ADMIN, &[]); - CAP.save( - &mut deps.storage, - &Cap::new(Addr::unchecked(TEST_ADMIN.to_string()), Uint128::new(100)), - ) - .unwrap(); - - let cap = Uint128::new(1000); - let res = update_cap(deps.as_mut(), env.clone(), info.clone(), Some(cap), None).unwrap(); - assert_eq!(res.attributes.len(), 3); - assert_eq!(res.attributes[0], attr("action", "update_cap")); - assert_eq!(res.attributes[1], attr("new_total", cap.to_string())); - assert_eq!(res.messages.len(), 0); - - // update again - let cap = Uint128::new(5000); - let res = update_cap(deps.as_mut(), env.clone(), info.clone(), Some(cap), None).unwrap(); - assert_eq!(res.attributes.len(), 3); - assert_eq!(res.attributes[0], attr("action", "update_cap")); - assert_eq!(res.attributes[1], attr("new_total", cap.to_string())); - assert_eq!(res.messages.len(), 0); - - // clear cap - let res = update_cap(deps.as_mut(), env, info, None, None).unwrap(); - assert_eq!(res.attributes.len(), 2); - assert_eq!(res.attributes[0], attr("action", "update_cap")); - assert_eq!(res.messages.len(), 0); - } - - #[test] - fn test_unauthorized_update_cap() { - let mut deps = mock_deps_with_primitives(vec![( - "abc".to_string(), - "123".to_string(), - 100u128.into(), - 100u128.into(), - )]); - let env = mock_env(); - let info = mock_info("not_admin", &[]); - - CAP.save( - &mut deps.storage, - &Cap::new(Addr::unchecked(TEST_ADMIN.to_string()), Uint128::new(100)), - ) - .unwrap(); - - let cap = Uint128::new(1000); - let res = update_cap(deps.as_mut(), env, info, Some(cap), None); - assert!(res.is_err()); - assert_eq!(res.unwrap_err(), ContractError::Unauthorized {}); - } -} diff --git a/smart-contracts/contracts/basic-vault/src/helpers.rs b/smart-contracts/contracts/basic-vault/src/helpers.rs deleted file mode 100644 index b66296a39..000000000 --- a/smart-contracts/contracts/basic-vault/src/helpers.rs +++ /dev/null @@ -1,65 +0,0 @@ -use cosmwasm_std::{wasm_execute, Addr, Deps, Env, QuerierWrapper, StdResult, Storage, WasmMsg}; -use lp_strategy::msg::UnbondingClaimResponse; -use vault_rewards::msg::{ExecuteMsg as VaultRewardsExecuteMsg, VaultExecuteMsg}; - -use crate::state::VAULT_REWARDS; -use crate::{state::UnbondingStub, ContractError}; - -pub fn can_unbond_from_primitive( - deps: Deps, - env: &Env, - unbond_id: &str, - stub: &UnbondingStub, -) -> Result { - // only attempt if we already know we passed unlock time. - if !stub - .unlock_time - .map_or(false, |unlock_time| unlock_time < env.block.time) - { - return Ok(false); - } - - let unbonding_claim_query = lp_strategy::msg::QueryMsg::UnbondingClaim { - addr: env.contract.address.clone(), - id: unbond_id.to_string(), - }; - let unbonding_claim: UnbondingClaimResponse = deps - .querier - .query_wasm_smart(stub.address.clone(), &unbonding_claim_query)?; - - // if we attempted to unbond, don't attempt again - if let Some(unbond) = unbonding_claim.unbond { - match unbond.attempted { - true => Ok(false), - false => Ok(unbond.unlock_time < env.block.time), - } - } else { - Ok(true) - } -} - -pub fn update_user_reward_index(storage: &dyn Storage, user: &Addr) -> StdResult { - wasm_execute( - VAULT_REWARDS.load(storage)?, - &VaultRewardsExecuteMsg::Vault(VaultExecuteMsg::UpdateUserRewardIndex(user.to_string())), - vec![], - ) -} - -pub fn is_contract_admin( - querier: &QuerierWrapper, - env: &Env, - sus_admin: &Addr, -) -> Result<(), ContractError> { - let contract_admin = querier - .query_wasm_contract_info(&env.contract.address)? - .admin; - if let Some(contract_admin) = contract_admin { - if contract_admin != *sus_admin { - return Err(ContractError::Unauthorized {}); - } - } else { - return Err(ContractError::Unauthorized {}); - } - Ok(()) -} diff --git a/smart-contracts/contracts/basic-vault/src/lib.rs b/smart-contracts/contracts/basic-vault/src/lib.rs deleted file mode 100644 index f6bbe7c55..000000000 --- a/smart-contracts/contracts/basic-vault/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -mod callback; -pub mod contract; -mod error; -mod execute; -mod helpers; -pub mod msg; -mod query; -pub mod state; -pub mod types; - -pub use crate::error::ContractError; - -#[cfg(test)] -pub mod multitest; - -#[cfg(test)] -pub mod tests; diff --git a/smart-contracts/contracts/basic-vault/src/msg.rs b/smart-contracts/contracts/basic-vault/src/msg.rs deleted file mode 100644 index 8b0f9c94c..000000000 --- a/smart-contracts/contracts/basic-vault/src/msg.rs +++ /dev/null @@ -1,316 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; - -use cosmwasm_std::{Binary, Coin, Decimal, Timestamp, Uint128}; - -use cw20::{AllowanceResponse, BalanceResponse}; -use cw20::{Expiration, TokenInfoResponse}; -use cw_asset::AssetInfo; -pub use cw_controllers::ClaimsResponse; -use lp_strategy::state::LpCache; -use quasar_types::callback::{BondResponse, StartUnbondResponse, UnbondResponse}; -use vault_rewards::state::DistributionSchedule; - -use crate::state::{BondingStub, Cap, InvestmentInfo, Unbond}; - -#[cw_serde] -pub enum PrimitiveInitMsg { - LP(lp_strategy::msg::InstantiateMsg), -} - -#[cw_serde] -pub struct PrimitiveConfig { - // the weighting of this strategy that the vault should subscribe to (e.g. 30%) - // weights are normalized accross strategies, so values don't need to add up to 100% - pub weight: Decimal, - // the contract address of the stored primitive contract on the chain - pub address: String, - // the Instantiation message for the primitive. - pub init: PrimitiveInitMsg, -} - -#[cw_serde] -pub struct InstantiateMsg { - /// name of the derivative token - pub name: String, - /// description of the derivative token - pub thesis: String, - /// symbol / ticker of the derivative token - pub symbol: String, - /// decimal places of the derivative token (for UI) - pub decimals: u8, - - /// This is the minimum amount we will pull out to reinvest, as well as a minimum - /// that can be unbonded (to avoid needless staking tx) - pub min_withdrawal: Uint128, - /// the denom in which users can deposit - pub deposit_denom: String, - // the array of primitives to subscribe to for this vault - pub primitives: Vec, - // the total amount of tokens that can be deposited, eg: max uosmo of the contract - pub total_cap: Uint128, - - // vault rewards contract code id - pub vault_rewards_code_id: u64, - // vault reward token - pub reward_token: AssetInfo, - // vault reward token distribution schedule - pub reward_distribution_schedules: Vec, -} - -#[cw_serde] -pub enum ExecuteMsg { - /// Bond will bond all staking tokens sent with the message and release derivative tokens - /// recipient will receive the minted vault tokens - Bond { - recipient: Option, - }, - /// Unbond will "burn" the given amount of derivative tokens and send the unbonded - /// staking tokens to the message sender (after exit tax is deducted) - Unbond { - amount: Option, - }, - /// Claim is used to claim your native tokens that you previously "unbonded" - /// after the chain-defined waiting period (eg. 3 weeks) - Claim {}, - /// Clear cache can be triggered by anyone and hits each internal primitive with - /// the TryICQ message. - ClearCache {}, - - // Callback(Callback), - BondResponse(BondResponse), - StartUnbondResponse(StartUnbondResponse), - UnbondResponse(UnbondResponse), - - /// Admin Messages - /// Set Cap is used to set the total cap of the vault, it can also be used to - /// updated admin - SetCap { - new_total: Option, - new_cap_admin: Option, - }, - - /// CW20 Messges - - /// Implements CW20. Transfer is a base message to move tokens to another account without triggering actions - Transfer { - recipient: String, - amount: Uint128, - }, - /// Implements CW20. Burn is a base message to destroy tokens forever - Burn { - amount: Uint128, - }, - /// Implements CW20. Send is a base message to transfer tokens to a contract and trigger an action - /// on the receiving contract. - Send { - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Implements CW20 "approval" extension. Allows spender to access an additional amount tokens - /// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance - /// expiration with this one. - IncreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Implements CW20 "approval" extension. Lowers the spender's access of tokens - /// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current - /// allowance expiration with this one. - DecreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Implements CW20 "approval" extension. Transfers amount tokens from owner -> recipient - /// if `env.sender` has sufficient pre-approval. - TransferFrom { - owner: String, - recipient: String, - amount: Uint128, - }, - /// Implements CW20 "approval" extension. Sends amount tokens from owner -> contract - /// if `env.sender` has sufficient pre-approval. - SendFrom { - owner: String, - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Implements CW20 "approval" extension. Destroys tokens forever - BurnFrom { - owner: String, - amount: Uint128, - }, -} - -#[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - /// Claims shows the number of tokens this address can access when they are done unbonding - #[returns(ClaimsResponse)] - Claims { address: String }, - - #[returns(GetCapResponse)] - GetCap {}, - /// Investment shows metadata on the staking info of the contract - #[returns(InvestmentResponse)] - Investment {}, - /// DepositRatio shows the ratio of tokens that should be sent for a deposit given list of available tokens - #[returns(DepositRatioResponse)] - DepositRatio { funds: Vec }, - - /// PendingBonds shows the bonds that are currently in the process of being deposited for a user - #[returns(PendingBondsResponse)] - PendingBonds { address: String }, - - /// PendingBondsById shows the bonds that are currently in the process of being deposited for a bond id - #[returns(PendingBondsByIdResponse)] - PendingBondsById { bond_id: String }, - - /// GetTvlInfo gets all info necessary for - #[returns(TvlInfoResponse)] - GetTvlInfo {}, - - /// Get all unbonding claims of a user - #[returns(PendingUnbondsResponse)] - PendingUnbonds { address: String }, - - /// Get all unbonding claims for an id - #[returns(PendingUnbondsByIdResponse)] - PendingUnbondsById { bond_id: String }, - - /// GetDebug shows us debug string info - #[returns(GetDebugResponse)] - GetDebug {}, - - /// Implements CW20. Returns the current balance of the given address, 0 if unset. - #[returns(BalanceResponse)] - Balance { address: String }, - /// Implements CW20. Returns metadata on the contract - name, decimals, supply, etc. - #[returns(TokenInfoResponse)] - TokenInfo {}, - /// Additional token metadata, includes regular token info too - #[returns(VaultTokenInfoResponse)] - AdditionalTokenInfo {}, - /// Implements CW20 "allowance" extension. - /// Returns how much spender can use from owner account, 0 if unset. - #[returns(AllowanceResponse)] - Allowance { owner: String, spender: String }, -} - -#[cw_serde] -pub struct MigrateMsg {} - -#[cw_serde] -pub struct InvestmentResponse { - pub info: InvestmentInfo, -} - -#[cw_serde] -pub struct GetCapResponse { - pub cap: Cap, -} - -#[cw_serde] -pub struct DepositRatioResponse { - /// the ratio of tokens that should be sent for a deposit given list of available tokens - pub primitive_funding_amounts: Vec, - pub remainder: Vec, -} - -#[cw_serde] -pub struct PendingBondsResponse { - /// the bonds that are currently in the process of being deposited for a user - pub pending_bonds: Vec, - /// the bond ids that are registered as pending for a user - pub pending_bond_ids: Vec, -} - -#[cw_serde] -pub struct PendingBondsByIdResponse { - /// the bonds that are currently in the process of being deposited for a user - pub pending_bonds: Vec, -} - -#[cw_serde] -pub struct PendingUnbondsByIdResponse { - /// the unbonds that are currently in the process of being withdrawn by an user - pub pending_unbonds: Unbond, -} - -#[cw_serde] -pub struct PendingUnbondsResponse { - /// the unbonds that are currently in the process of being withdrawn by an user - pub pending_unbonds: Vec, - /// the bond ids that are registered as pending for a user - pub pending_unbond_ids: Vec, -} - -#[cw_serde] -pub struct VaultTokenInfoResponse { - pub name: String, - pub thesis: String, - pub symbol: String, - pub decimals: u8, - pub total_supply: Uint128, - pub creation_time: Timestamp, -} - -#[cw_serde] -pub struct GetDebugResponse { - /// the debug string - pub debug: String, -} - -#[cw_serde] -pub struct TvlInfoResponse { - pub primitives: Vec, -} - -#[cw_serde] -pub struct PrimitiveInfo { - pub ica_address: String, - pub base_denom: String, - pub quote_denom: String, - pub lp_denom: String, - pub lp_shares: LpCache, -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::Timestamp; - - use super::*; - - #[test] - fn callback_equals_execute() { - let bond_response = BondResponse { - share_amount: Uint128::one(), - bond_id: "id".to_string(), - }; - let cb = quasar_types::callback::Callback::BondResponse(bond_response.clone()); - let se = serde_json_wasm::to_string(&cb).unwrap(); - let msg: ExecuteMsg = serde_json_wasm::from_str(se.as_str()).unwrap(); - assert_eq!(msg, ExecuteMsg::BondResponse(bond_response)); - - let start_unbond_response = StartUnbondResponse { - unbond_id: "id".to_string(), - unlock_time: Timestamp::from_seconds(100), - }; - let cb = - quasar_types::callback::Callback::StartUnbondResponse(start_unbond_response.clone()); - let se = serde_json_wasm::to_string(&cb).unwrap(); - let msg: ExecuteMsg = serde_json_wasm::from_str(se.as_str()).unwrap(); - assert_eq!(msg, ExecuteMsg::StartUnbondResponse(start_unbond_response)); - - let unbond_response = UnbondResponse { - unbond_id: "id".to_string(), - }; - let cb = quasar_types::callback::Callback::UnbondResponse(unbond_response.clone()); - let se = serde_json_wasm::to_string(&cb).unwrap(); - let msg: ExecuteMsg = serde_json_wasm::from_str(se.as_str()).unwrap(); - assert_eq!(msg, ExecuteMsg::UnbondResponse(unbond_response)); - } -} diff --git a/smart-contracts/contracts/basic-vault/src/multitest/common.rs b/smart-contracts/contracts/basic-vault/src/multitest/common.rs deleted file mode 100644 index ed098f6f5..000000000 --- a/smart-contracts/contracts/basic-vault/src/multitest/common.rs +++ /dev/null @@ -1,63 +0,0 @@ -pub use anyhow::Result; -pub use derivative::Derivative; - -pub use crate::contract::{ - execute as execute_vault, instantiate as instantiate_vault, query as query_vault, - reply as reply_vault, -}; -pub use crate::{ - error::ContractError as VaultContractError, - msg::{ - ExecuteMsg as VaultExecuteMsg, InstantiateMsg as VaultInstantiateMsg, - QueryMsg as VaultQueryMsg, - }, -}; -pub use cosmwasm_std::{coin, BlockInfo, Coin, Decimal, Empty, StdResult, Uint128}; -pub use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; - -pub use cw_utils::Duration; - -pub use lp_strategy::{ - contract::{execute as execute_primitive, instantiate as instantiate_primitive}, - msg::{ - ExecuteMsg as PrimitiveExecuteMsg, InstantiateMsg as PrimitiveInstantiateMsg, - QueryMsg as PrimitiveQueryMsg, - }, - queries::query as query_primitive, -}; -pub use vault_rewards::{ - contract::{ - execute as execute_vault_rewards, instantiate as instantiate_vault_rewards, - query as query_vault_rewards, - }, - msg::{ - ExecuteMsg as VaultRewardsExecuteMsg, InstantiateMsg as VaultRewardsInstantiateMsg, - QueryMsg as VaultRewardsQueryMsg, - }, -}; - -pub const USER: &str = "user"; -pub const DEPLOYER: &str = "deployer"; -pub const EXECUTOR: &str = "executor"; -pub const DENOM: &str = "uosmo"; -pub const LOCAL_DENOM: &str = "ibc/ilovemymom"; - -pub fn contract_vault() -> Box> { - let contract = - ContractWrapper::new(execute_vault, instantiate_vault, query_vault).with_reply(reply_vault); - Box::new(contract) -} - -pub fn contract_primitive() -> Box> { - let contract = ContractWrapper::new(execute_primitive, instantiate_primitive, query_primitive); - Box::new(contract) -} - -pub fn contract_vault_rewards() -> Box> { - let contract = ContractWrapper::new( - execute_vault_rewards, - instantiate_vault_rewards, - query_vault_rewards, - ); - Box::new(contract) -} diff --git a/smart-contracts/contracts/basic-vault/src/multitest/mod.rs b/smart-contracts/contracts/basic-vault/src/multitest/mod.rs deleted file mode 100644 index bb18c4535..000000000 --- a/smart-contracts/contracts/basic-vault/src/multitest/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod common; -pub mod suite; -pub mod vault; diff --git a/smart-contracts/contracts/basic-vault/src/multitest/suite.rs b/smart-contracts/contracts/basic-vault/src/multitest/suite.rs deleted file mode 100644 index 5e8cb8b18..000000000 --- a/smart-contracts/contracts/basic-vault/src/multitest/suite.rs +++ /dev/null @@ -1,322 +0,0 @@ -use std::str::FromStr; - -use crate::{ - msg::{DepositRatioResponse, PrimitiveConfig}, - multitest::common::*, -}; -use cosmwasm_schema::{schemars, serde}; -use cosmwasm_std::{ - testing::MockApi, Addr, Binary, IbcChannel, IbcEndpoint, IbcMsg, IbcOrder, IbcQuery, - MemoryStorage, StdError, -}; -use cw_multi_test::{ - App, AppBuilder, BankKeeper, CosmosRouter, DistributionKeeper, FailingModule, Ibc, Module, - StakeKeeper, WasmKeeper, -}; -use vault_rewards::state::DistributionSchedule; - -pub type QuasarVaultApp = App< - BankKeeper, - MockApi, - MemoryStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, - AcceptingModule, ->; - -#[derive(Derivative)] -#[derivative(Debug)] -pub struct QuasarVaultSuite { - #[derivative(Debug = "ignore")] - pub app: QuasarVaultApp, - // The account that deploys everything - pub deployer: Addr, - // executor address - pub executor: Addr, - // user address - pub user: Addr, - // vault address - pub vault: Addr, - // primitive address - pub primitive: Addr, -} - -pub struct AcceptingModule; - -impl Module for AcceptingModule { - type ExecT = IbcMsg; - type QueryT = IbcQuery; - type SudoT = Empty; - - fn execute( - &self, - _api: &dyn cosmwasm_std::Api, - _storage: &mut dyn cosmwasm_std::Storage, - _router: &dyn CosmosRouter, - _block: &cosmwasm_std::BlockInfo, - _sender: cosmwasm_std::Addr, - _msg: Self::ExecT, - ) -> anyhow::Result - where - ExecC: std::fmt::Debug - + Clone - + PartialEq - + schemars::JsonSchema - + serde::de::DeserializeOwned - + 'static, - QueryC: cosmwasm_std::CustomQuery + serde::de::DeserializeOwned + 'static, - { - Ok(AppResponse::default()) - } - - fn sudo( - &self, - _api: &dyn cosmwasm_std::Api, - _storage: &mut dyn cosmwasm_std::Storage, - _router: &dyn CosmosRouter, - _block: &cosmwasm_std::BlockInfo, - _msg: Self::SudoT, - ) -> anyhow::Result - where - ExecC: std::fmt::Debug - + Clone - + PartialEq - + schemars::JsonSchema - + serde::de::DeserializeOwned - + 'static, - QueryC: cosmwasm_std::CustomQuery + serde::de::DeserializeOwned + 'static, - { - Ok(AppResponse::default()) - } - - fn query( - &self, - _api: &dyn cosmwasm_std::Api, - _storage: &dyn cosmwasm_std::Storage, - _querier: &dyn cosmwasm_std::Querier, - _block: &cosmwasm_std::BlockInfo, - _request: Self::QueryT, - ) -> anyhow::Result { - Ok(Binary::default()) - } -} - -impl Ibc for AcceptingModule {} - -impl QuasarVaultSuite { - pub fn init( - init_msg: Option, - funds: Option>, - ) -> Result { - let genesis_funds = vec![coin(150000, DENOM), coin(150000, LOCAL_DENOM)]; - let deployer = Addr::unchecked(DEPLOYER); - let executor = Addr::unchecked(EXECUTOR); - let user = Addr::unchecked(USER); - let mut app = AppBuilder::new() - .with_ibc(AcceptingModule) - .build(|router, _, storage| { - router - .bank - .init_balance(storage, &deployer, genesis_funds) - .unwrap(); - }); - // let mut app = App::new(|router, _, storage| { - // router - // .bank - // .init_balance(storage, &deployer, genesis_funds) - // .unwrap(); - // }); - app.send_tokens( - deployer.clone(), - user.clone(), - &[coin(50000, DENOM), coin(50000, LOCAL_DENOM)], - )?; - app.send_tokens( - deployer.clone(), - executor.clone(), - &[coin(50000, DENOM), coin(50000, LOCAL_DENOM)], - )?; - - let vault_id = app.store_code(contract_vault()); - let primitive_id = app.store_code(contract_primitive()); - - let primitive = app - .instantiate_contract( - primitive_id, - deployer.clone(), - &PrimitiveInstantiateMsg { - lock_period: 64, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: LOCAL_DENOM.to_string(), - base_denom: DENOM.to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }, - &[], - "router_contract", - Some(deployer.to_string()), - ) - .unwrap(); - - // IbcChannelOpenMsg::OpenInit { channel: () } - // app.wasm_sudo(contract_addr, msg) - let endpoint = IbcEndpoint { - port_id: "wasm.my_addr".to_string(), - channel_id: "channel-1".to_string(), - }; - let counterparty_endpoint = IbcEndpoint { - port_id: "icahost".to_string(), - channel_id: "channel-2".to_string(), - }; - - let version = r#"{"version":"ics27-1","encoding":"proto3","tx_type":"sdk_multi_msg","controller_connection_id":"connection-0","host_connection_id":"connection-0"}"#.to_string(); - let _channel = IbcChannel::new( - endpoint, - counterparty_endpoint, - IbcOrder::Ordered, - version, - "connection-0".to_string(), - ); - - // Todo: keep track of this issue for ibc mock support in cw-multi-test: https://github.com/CosmWasm/cw-multi-test/issues/27 - // let ibc_channel_open_msg = IbcChannelOpenMsg::OpenInit { channel }; - // let res = app.execute( - // primitive.clone(), - // CosmosMsg::Ibc(IbcMsg::SendPacket { - // channel_id: "channel-0".to_string(), - // data: to_json_binary(&ibc_channel_open_msg)?, - // timeout: IbcTimeout::with_block(IbcTimeoutBlock { - // revision: 1, - // height: app.block_info().height + 5, - // }), - // }), - // ); - // res.unwrap(); - // IbcChannelConnectMsg::OpenConfirm { channel: () } - - let vault_rewards_id = app.store_code(contract_vault_rewards()); - - let vault = app - .instantiate_contract( - vault_id, - deployer.clone(), - &init_msg.unwrap_or(VaultInstantiateMsg { - name: "orion".to_string(), - thesis: "to generate yield, I guess".to_string(), - symbol: "ORN".to_string(), - decimals: 6, - min_withdrawal: 1u128.into(), - total_cap: 100000000u128.into(), - primitives: vec![PrimitiveConfig { - weight: Decimal::from_str("0.33333333333")?, - address: primitive.to_string(), - init: crate::msg::PrimitiveInitMsg::LP(PrimitiveInstantiateMsg { - lock_period: 64, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: LOCAL_DENOM.to_string(), - base_denom: DENOM.to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }], - vault_rewards_code_id: vault_rewards_id, - reward_token: cw_asset::AssetInfoBase::Native("uqsr".to_string()), - reward_distribution_schedules: vec![ - vault_rewards::state::DistributionSchedule { - start: app.block_info().height + 1, - end: app.block_info().height + 501, - amount: Uint128::from(1000u128), - }, - ], - deposit_denom: LOCAL_DENOM.to_string(), - }), - &funds.unwrap_or_default(), - "vault_contract", - Some(deployer.to_string()), // admin: Option, will need this for upgrading - ) - .unwrap(); - - // set depositor on primitive as the vault address - let msg = PrimitiveExecuteMsg::SetDepositor { - depositor: vault.to_string(), - }; - app.execute_contract(deployer.clone(), primitive.clone(), &msg, &[]) - .unwrap(); - - Ok(QuasarVaultSuite { - app, - user, - executor, - deployer, - primitive, - vault, - }) - } - - pub fn query_balance(&self, addr: &Addr) -> StdResult { - self.app.wrap().query_balance(addr.as_str(), DENOM) - } - - pub fn unbond( - &mut self, - sender: &Addr, - unbond_amount: Option, - ) -> Result<(), VaultContractError> { - let msg = VaultExecuteMsg::Unbond { - amount: unbond_amount, - }; - self.app - .execute_contract(sender.clone(), self.vault.clone(), &msg, &[]) - .map_err(|err| err.downcast().unwrap()) - .map(|_| ()) - } - - pub fn bond(&mut self, sender: &Addr, funds: Vec) -> Result<(), VaultContractError> { - let msg = VaultExecuteMsg::Bond { - recipient: Option::None, - }; - self.app - .execute_contract(sender.clone(), self.vault.clone(), &msg, &funds) - .map_err(|err| match err.downcast::() { - Ok(err_unwrapped) => err_unwrapped, - Err(e) => VaultContractError::Std(StdError::GenericErr { - msg: e.root_cause().to_string(), - }), - }) - .map(|_| ()) - } - - pub fn query_deposit_ratio(&self, funds: Vec) -> StdResult { - let msg = VaultQueryMsg::DepositRatio { funds }; - self.app.wrap().query_wasm_smart(self.vault.clone(), &msg) - } - - pub fn add_distribution_schedule(&mut self, schedule: DistributionSchedule) { - let msg = VaultRewardsExecuteMsg::Admin( - vault_rewards::msg::AdminExecuteMsg::AddDistributionSchedule(schedule), - ); - self.app - .execute_contract(self.deployer.clone(), self.vault.clone(), &msg, &[]) - .unwrap(); - } - - pub fn fast_forward_block_time(&mut self, forward_time_sec: u64) { - let block = self.app.block_info(); - - let mock_block = BlockInfo { - height: block.height + 10, - chain_id: block.chain_id, - time: block.time.plus_seconds(forward_time_sec), - }; - - self.app.set_block(mock_block); - } -} diff --git a/smart-contracts/contracts/basic-vault/src/multitest/vault.rs b/smart-contracts/contracts/basic-vault/src/multitest/vault.rs deleted file mode 100644 index 626478699..000000000 --- a/smart-contracts/contracts/basic-vault/src/multitest/vault.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::multitest::common::*; -use crate::multitest::suite::*; - -#[test] -fn try_bond() { - let mut suite = QuasarVaultSuite::init(None, None).unwrap(); - let err = suite - .bond( - &suite.user.clone(), - vec![Coin { - denom: LOCAL_DENOM.to_string(), - amount: Uint128::from(1000u128), - }], - ) - .unwrap_err(); - // this error happens because our ibc channel is not open yet - assert_eq!( - err, - VaultContractError::Std(cosmwasm_std::StdError::GenericErr { - msg: "type: alloc::string::String; key: [69, 63, 71, 5F, 63, 68, 61, 6E, 6E, 65, 6C] not found".to_string() - }) - ); -} diff --git a/smart-contracts/contracts/basic-vault/src/query.rs b/smart-contracts/contracts/basic-vault/src/query.rs deleted file mode 100644 index 9904a7d09..000000000 --- a/smart-contracts/contracts/basic-vault/src/query.rs +++ /dev/null @@ -1,120 +0,0 @@ -use cosmwasm_std::{Addr, Coin, Deps, StdResult}; -use lp_strategy::msg::{ConfigResponse, IcaAddressResponse, LpSharesResponse, QueryMsg}; - -use crate::{ - execute::may_pay_with_ratio, - msg::{ - DepositRatioResponse, InvestmentResponse, PendingBondsByIdResponse, PendingBondsResponse, - PendingUnbondsByIdResponse, PendingUnbondsResponse, PrimitiveInfo, TvlInfoResponse, - }, - state::{Unbond, BOND_STATE, INVESTMENT, PENDING_BOND_IDS, PENDING_UNBOND_IDS, UNBOND_STATE}, -}; - -pub fn query_tvl_info(deps: Deps) -> StdResult { - let primitives = INVESTMENT.load(deps.storage)?.primitives; - let mut prim_infos: Vec = Vec::new(); - for prim in primitives { - let addr = deps.api.addr_validate(prim.address.as_str())?; - let ica = deps - .querier - .query_wasm_smart::(addr.as_str(), &QueryMsg::IcaAddress {})?; - let lp_shares = deps - .querier - .query_wasm_smart::(addr.as_str(), &QueryMsg::LpShares {})? - .lp_shares; - let config = deps - .querier - .query_wasm_smart::(addr.as_str(), &QueryMsg::Config {})? - .config; - prim_infos.push(PrimitiveInfo { - ica_address: ica.address, - base_denom: config.base_denom, - quote_denom: config.quote_denom, - lp_denom: config.pool_denom, - lp_shares, - }) - } - Ok(TvlInfoResponse { - primitives: prim_infos, - }) -} - -pub fn query_investment(deps: Deps) -> StdResult { - let invest = INVESTMENT.load(deps.storage)?; - - let res = InvestmentResponse { info: invest }; - Ok(res) -} - -pub fn query_deposit_ratio(deps: Deps, funds: Vec) -> StdResult { - let invest = INVESTMENT.load(deps.storage)?; - - let (primitive_funding_amounts, remainder) = may_pay_with_ratio(&deps, &funds, invest).unwrap(); - - let res = DepositRatioResponse { - primitive_funding_amounts, - remainder, - }; - Ok(res) -} - -pub fn query_pending_bonds(deps: Deps, address: String) -> StdResult { - let pending_bond_ids = PENDING_BOND_IDS.may_load(deps.storage, Addr::unchecked(address))?; - let mut pending_bonds = vec![]; - - pending_bond_ids.clone().unwrap().iter().for_each(|id| { - let mut deposit_stubs = BOND_STATE.load(deps.storage, id.to_string()).unwrap(); - - pending_bonds.append(deposit_stubs.as_mut()); - }); - - Ok(PendingBondsResponse { - pending_bonds, - pending_bond_ids: pending_bond_ids.unwrap(), - }) -} - -pub fn query_pending_unbonds(deps: Deps, address: String) -> StdResult { - let pending_unbond_ids = PENDING_UNBOND_IDS.may_load(deps.storage, Addr::unchecked(address))?; - let mut pending_unbonds: Vec = vec![]; - - if pending_unbond_ids.is_none() { - return Ok(PendingUnbondsResponse { - pending_unbonds, - pending_unbond_ids: vec![], - }); - } - - pending_unbond_ids - .clone() - .unwrap() - .iter() - .for_each(|id: &String| { - let unbond_stubs: Unbond = UNBOND_STATE.load(deps.storage, id.to_string()).unwrap(); - pending_unbonds.push(unbond_stubs); - }); - - Ok(PendingUnbondsResponse { - pending_unbonds, - pending_unbond_ids: pending_unbond_ids.unwrap(), - }) -} - -pub fn query_pending_bonds_by_id(deps: Deps, id: String) -> StdResult { - let deposit_stubs = BOND_STATE.load(deps.storage, id).unwrap(); - - Ok(PendingBondsByIdResponse { - pending_bonds: deposit_stubs, - }) -} - -pub fn query_pending_unbonds_by_id( - deps: Deps, - id: String, -) -> StdResult { - let unbond_stubs = UNBOND_STATE.load(deps.storage, id).unwrap(); - - Ok(PendingUnbondsByIdResponse { - pending_unbonds: unbond_stubs, - }) -} diff --git a/smart-contracts/contracts/basic-vault/src/state.rs b/smart-contracts/contracts/basic-vault/src/state.rs deleted file mode 100644 index 8b1d76ffe..000000000 --- a/smart-contracts/contracts/basic-vault/src/state.rs +++ /dev/null @@ -1,194 +0,0 @@ -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Coin, Decimal, Timestamp, Uint128}; - -use cw_controllers::Claims; -use cw_storage_plus::{Item, Map}; -use quasar_types::callback::{BondResponse, UnbondResponse}; - -use crate::{msg::PrimitiveConfig, ContractError}; - -// constants -pub const FALLBACK_RATIO: Decimal = Decimal::one(); - -// reply ids -pub const STRATEGY_BOND_ID: u64 = 80085; - -// version info for migration info -pub const CONTRACT_NAME: &str = "basic-vault"; -pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -pub const CLAIMS: Claims = Claims::new("claims"); - -/// Investment info is fixed at instantiation, and is used to control the function of the contract -#[cw_serde] -pub struct InvestmentInfo { - /// Owner created the contract and takes a cut - pub owner: Addr, - /// This is the minimum amount we will pull out to reinvest, as well as a minimum - /// that can be unbonded (to avoid needless staking tx) - pub min_withdrawal: Uint128, - /// the denom accepted by the vault - pub deposit_denom: String, - /// this is the array of primitives that this vault will subscribe to - pub primitives: Vec, -} - -pub const CAP: Item = Item::new("cap"); - -#[cw_serde] -pub struct Cap { - cap_admin: Addr, - total: Uint128, - current: Uint128, -} - -impl Cap { - pub fn new(admin: Addr, total: Uint128) -> Self { - Self { - cap_admin: admin, - total, - current: Uint128::zero(), - } - } - - pub fn update_cap_admin(mut self, new_cap_admin: Addr) -> Self { - self.cap_admin = new_cap_admin; - self - } - - pub fn update_total_cap(mut self, new_total: Uint128) -> Self { - self.total = new_total; - self - } - - pub fn update_current(mut self, to_add: Uint128) -> Result { - let new_total = self.current.checked_add(to_add)?; - // if we go over cap, reject - if new_total > self.total { - return Err(ContractError::OverCap {}); - }; - self.current = new_total; - Ok(self) - } -} - -#[cw_serde] -pub struct AdditionalTokenInfo { - pub thesis: String, - pub creation_time: Timestamp, -} - -pub const ADDITIONAL_TOKEN_INFO: Item = Item::new("additional_token_info"); -pub const OLD_INVESTMENT: Item = Item::new("invest"); -pub const INVESTMENT: Item = Item::new("new_invest"); - -/// OldInvestmentInfo is a premigration version without the single_denom -#[cw_serde] -pub struct OldInvestmentInfo { - /// Owner created the contract and takes a cut - pub owner: Addr, - /// This is the minimum amount we will pull out to reinvest, as well as a minimum - /// that can be unbonded (to avoid needless staking tx) - pub min_withdrawal: Uint128, - /// this is the array of primitives that this vault will subscribe to - pub primitives: Vec, -} - -#[cw_serde] -#[derive(Default)] -pub struct BondingStub { - // the contract address of the primitive - pub address: String, - // the response of the primitive upon successful bond or error - pub bond_response: Option, - // primitive value at the time of receiving the bond_response - pub primitive_value: Option, - // the amount sent with the Bond - pub amount: Uint128, -} - -#[cw_serde] -#[derive(Default)] -pub struct Unbond { - pub stub: Vec, - pub shares: Uint128, -} - -#[cw_serde] -#[derive(Default)] -pub struct UnbondingStub { - // the contract address of the primitive - pub address: String, - // the response of the primitive upon successful bond or error - pub unlock_time: Option, - // response of the unbond, if this is present then we have finished unbonding - pub unbond_response: Option, - // funds attached to the unbond_response - pub unbond_funds: Vec, -} - -// (un)bonding sequence number (to map primitive responses to the right bond action) -pub const BONDING_SEQ: Item = Item::new("bond_seq"); -// mapping from bonding sequence number to depositor/withdrawer address -pub const BONDING_SEQ_TO_ADDR: Map = Map::new("bond_seq_to_addr"); -// current bonds pending for a user -pub const PENDING_BOND_IDS: Map> = Map::new("pending_bond_ids"); -// current unbonds pending for a user -pub const PENDING_UNBOND_IDS: Map> = Map::new("pending_unbond_ids"); -// map of bond id to bond state -pub const BOND_STATE: Map> = Map::new("bond_state"); -// map of unbond id to unbond state -pub const UNBOND_STATE: Map = Map::new("unbond_state"); - -pub const DEBUG_TOOL: Item = Item::new("debug_tool"); - -// vault rewards contract -pub const VAULT_REWARDS: Item = Item::new("vault_rewards"); - -impl InvestmentInfo { - pub fn normalize_primitive_weights(&mut self) { - let mut total_weight = Decimal::zero(); - for p in &self.primitives { - total_weight += p.weight; - } - for p in &mut self.primitives { - p.weight /= total_weight; - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use crate::msg::{PrimitiveConfig, PrimitiveInitMsg}; - - #[test] - fn test_investment_info() { - let mut invest = InvestmentInfo { - owner: Addr::unchecked("owner".to_string()), - min_withdrawal: Uint128::from(1000u128), - primitives: vec![ - PrimitiveConfig { - address: "primitive".to_string(), - weight: Decimal::percent(50), // passing in unnormalized - init: PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 1, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: "uosmo".to_string(), - base_denom: "ibc/blah".to_string(), - quote_denom: "ibc/blah2".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }; - 4 - ], - deposit_denom: "ibc/osmo".to_string(), - }; - invest.normalize_primitive_weights(); - assert_eq!(invest.primitives[0].weight, Decimal::percent(25)); - } -} diff --git a/smart-contracts/contracts/basic-vault/src/tests.rs b/smart-contracts/contracts/basic-vault/src/tests.rs deleted file mode 100644 index c034f1d02..000000000 --- a/smart-contracts/contracts/basic-vault/src/tests.rs +++ /dev/null @@ -1,2228 +0,0 @@ -use core::panic; -use std::{marker::PhantomData, str::FromStr}; - -use cosmwasm_std::{ - coins, from_json, - testing::{mock_dependencies, mock_env, mock_info, MockApi, MockStorage}, - to_json_binary, Addr, Attribute, BankMsg, Binary, Coin, ContractInfoResponse, ContractResult, - CosmosMsg, Decimal, DepsMut, Empty, Env, Fraction, MessageInfo, OwnedDeps, Querier, - QuerierResult, QueryRequest, Reply, Response, StdError, StdResult, SubMsgResponse, - SubMsgResult, Timestamp, Uint128, WasmMsg, -}; -use cw20::BalanceResponse; - -use cw_asset::AssetInfoBase; -use cw_utils::PaymentError; -use lp_strategy::{ - msg::{ConfigResponse, IcaBalanceResponse, PrimitiveSharesResponse, UnbondingClaimResponse}, - state::{Config, Unbond}, -}; -use prost::Message; -use quasar_types::{ - callback::{BondResponse, StartUnbondResponse, UnbondResponse}, - types::{CoinRatio, CoinWeight}, -}; - -use crate::{ - callback::on_bond, - contract::execute, - contract::instantiate, - contract::query, - contract::{reply, REPLY_INIT_VAULT_REWARDS}, - execute::{ - get_deposit_amount_weights, get_deposit_and_remainder_for_ratio, get_max_bond, - get_token_amount_weights, may_pay_with_ratio, - }, - msg::{ExecuteMsg, InstantiateMsg, InvestmentResponse, PrimitiveConfig, PrimitiveInitMsg}, - state::{BONDING_SEQ, VAULT_REWARDS}, -}; - -#[derive(Clone, PartialEq, prost::Message)] -struct MsgInstantiateContractResponse { - #[prost(string, tag = "1")] - pub contract_address: ::prost::alloc::string::String, - #[prost(bytes, tag = "2")] - pub data: ::prost::alloc::vec::Vec, -} - -pub struct QuasarQuerier { - // address, denom, share, balance - pub primitive_states: Vec<(String, String, Uint128, Uint128)>, - // address, unlock_time, attempted - pub primitive_unlock_times: Vec<(String, Timestamp, bool)>, -} - -impl QuasarQuerier { - pub fn new(primitive_states: Vec<(String, String, Uint128, Uint128)>) -> QuasarQuerier { - QuasarQuerier { - primitive_states, - primitive_unlock_times: vec![], - } - } - - /// update the state of the quasar querier, expects denom, shares, balance - pub fn update_state(&mut self, new_states: Vec<(&str, Uint128, Uint128)>) { - new_states - .into_iter() - .for_each(|(address, shares, balance)| { - let val = self - .primitive_states - .iter_mut() - .find(|(prim_addr, _, _, _)| prim_addr == address) - .unwrap(); - val.2 = shares; - val.3 = balance; - }) - } - - pub fn find_states_for_primitive(&self, address: String) -> (String, Uint128, Uint128) { - let mut total_share = Uint128::zero(); - let mut total_balance = Uint128::zero(); - let mut this_denom = "".to_string(); - for (addr, denom, share, balance) in &self.primitive_states { - if addr.eq(&address) { - this_denom = denom.to_string(); - total_share = *share; - total_balance = *balance; - } - } - (this_denom, total_share, total_balance) - } - - pub fn set_unbonding_claim_for_primitive( - &mut self, - address: String, - time: Timestamp, - attempted: bool, - ) { - let put = self - .primitive_unlock_times - .iter_mut() - .find(|put| put.0 == address); - match put { - Some(p) => { - p.1 = time; - p.2 = attempted; - } - None => self.primitive_unlock_times.push((address, time, attempted)), - } - } - - pub fn get_unbonding_claim_for_primitive( - &self, - address: String, - ) -> StdResult<(Timestamp, bool)> { - let prim = self.primitive_unlock_times.iter().find(|p| p.0 == address); - - match prim { - Some(p) => Ok((p.1, p.2)), - None => Err(StdError::GenericErr { - msg: "Unbonding claim not found".to_owned(), - }), - } - } -} - -impl Querier for QuasarQuerier { - fn raw_query(&self, bin_request: &[u8]) -> cosmwasm_std::QuerierResult { - let request: QueryRequest = from_json(&Binary::from(bin_request)).unwrap(); - match request { - QueryRequest::Wasm(wasm_query) => match wasm_query { - cosmwasm_std::WasmQuery::Smart { contract_addr, msg } => { - let primitive_query = from_json::(&msg).unwrap(); - - let (this_denom, total_share, total_balance) = - self.find_states_for_primitive(contract_addr.clone()); - match primitive_query { - lp_strategy::msg::QueryMsg::PrimitiveShares {} => { - let response = PrimitiveSharesResponse { total: total_share }; - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&response).unwrap(), - )) - } - lp_strategy::msg::QueryMsg::IcaBalance {} => { - let response = IcaBalanceResponse { - amount: Coin { - denom: this_denom, - amount: total_balance, - }, - }; - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&response).unwrap(), - )) - } - lp_strategy::msg::QueryMsg::Config {} => { - let config = Config { - lock_period: 14, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: this_denom, - base_denom: "uosmo".to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }; - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&ConfigResponse { config }).unwrap(), - )) - } - lp_strategy::msg::QueryMsg::UnbondingClaim { addr: _, id } => { - let query_result = - self.get_unbonding_claim_for_primitive(contract_addr); - QuerierResult::Ok(match query_result { - Ok((unlock_time, attempted)) => ContractResult::Ok( - to_json_binary(&UnbondingClaimResponse { - unbond: Some(Unbond { - lp_shares: Uint128::from(1u128), - unlock_time, - attempted, - owner: Addr::unchecked(TEST_CREATOR), - id, - }), - }) - .unwrap(), - ), - Err(error) => ContractResult::Err(error.to_string()), - }) - } - lp_strategy::msg::QueryMsg::Balance { address: _ } => { - let response = BalanceResponse { - balance: total_share, - }; - QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&response).unwrap(), - )) - } - _ => QuerierResult::Err(cosmwasm_std::SystemError::UnsupportedRequest { - kind: format!("Unmocked primitive query type: {primitive_query:?}"), - }), - } - } - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => { - let mut response = ContractInfoResponse::default(); - response.admin = Some(TEST_ADMIN.to_string()); - QuerierResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } - _ => QuerierResult::Err(cosmwasm_std::SystemError::UnsupportedRequest { - kind: format!("Unmocked wasm query type: {wasm_query:?}"), - }), - }, - _ => QuerierResult::Err(cosmwasm_std::SystemError::UnsupportedRequest { - kind: format!("Unmocked query type: {request:?}"), - }), - } - // QuerierResult::Ok(ContractResult::Ok(to_json_binary(&"hello").unwrap())) - } -} - -pub fn mock_deps_with_primitives( - primitive_states: Vec<(String, String, Uint128, Uint128)>, -) -> OwnedDeps { - OwnedDeps { - storage: MockStorage::default(), - api: MockApi::default(), - querier: QuasarQuerier::new(primitive_states), - custom_query_type: PhantomData, - } -} - -pub const TEST_ADMIN: &str = "admin"; -pub const TEST_CREATOR: &str = "creator"; -pub const TEST_DEPOSITOR: &str = "depositor"; - -fn init_msg() -> InstantiateMsg { - InstantiateMsg { - name: "Blazar Vault".to_string(), - thesis: "to generate yield, I guess".to_string(), - symbol: "BLZR".to_string(), - decimals: 6, - min_withdrawal: Uint128::one(), - primitives: vec![PrimitiveConfig { - weight: Decimal::from_str("1.0").unwrap(), - address: "quasar123".to_string(), - init: PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 14, // this is supposed to be nanos i think - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: "ibc/uosmo".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - }], - vault_rewards_code_id: 123, - reward_token: cw_asset::AssetInfoBase::Native("uqsr".to_string()), - reward_distribution_schedules: vec![vault_rewards::state::DistributionSchedule { - start: 1, - end: 501, - amount: Uint128::from(1000u128), - }], - total_cap: Uint128::new(10_000_000_000_000), - deposit_denom: "ibc/uosmo".to_string(), - } -} - -fn reply_msg() -> Reply { - let instantiate_reply = MsgInstantiateContractResponse { - contract_address: "vault_rewards_addr".to_string(), - data: vec![], - }; - let mut encoded_instantiate_reply = Vec::::with_capacity(instantiate_reply.encoded_len()); - instantiate_reply - .encode(&mut encoded_instantiate_reply) - .unwrap(); - - // reply to init our map for the vault rewards contract - Reply { - id: REPLY_INIT_VAULT_REWARDS, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: Some(encoded_instantiate_reply.into()), - }), - } -} - -// convenience function to init primitives with a vec of tuples which are (local_denom, weight) - -fn init_msg_with_primitive_details( - primitive_details: Vec<(String, String, Decimal)>, -) -> InstantiateMsg { - InstantiateMsg { - name: "Blazar Vault".to_string(), - thesis: "to generate yield, I guess".to_string(), - symbol: "BLZR".to_string(), - decimals: 6, - min_withdrawal: Uint128::one(), - vault_rewards_code_id: 123, - reward_token: cw_asset::AssetInfoBase::Native("uqsr".to_string()), - reward_distribution_schedules: vec![vault_rewards::state::DistributionSchedule { - start: 1, - end: 501, - amount: Uint128::from(1000u128), - }], - primitives: primitive_details - .iter() - .map(|pd| { - PrimitiveConfig { - weight: pd.2, - address: pd.0.clone(), - init: PrimitiveInitMsg::LP(lp_strategy::msg::InstantiateMsg { - lock_period: 14, // this is supposed to be nanos i think - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - local_denom: pd.1.clone(), - base_denom: "uosmo".to_string(), - quote_denom: "uatom".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }), - } - }) - .collect(), - total_cap: Uint128::new(10_000_000_000_000), - // TODO this is kind of sloppy and should be a param - deposit_denom: primitive_details[0].1.clone(), - } -} - -fn init(deps: DepsMut, msg: &InstantiateMsg, env: &Env, info: &MessageInfo) -> Response { - instantiate(deps, env.clone(), info.clone(), msg.clone()).unwrap() -} - -#[test] -fn proper_initialization() { - let mut deps = mock_deps_with_primitives(even_primitives()); - let msg = init_msg(); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &msg, &env, &info); - - println!("res: {res:?}"); - assert_eq!(1, res.messages.len()); - - if let CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id, - msg, - funds, - admin, - label, - }) = &res.messages[0].msg - { - assert_eq!(123, *code_id); - assert_eq!(0, funds.len()); - assert_eq!(admin.clone().unwrap(), TEST_CREATOR); - assert_eq!(label, "vault-rewards"); - let msg: vault_rewards::msg::InstantiateMsg = from_json(msg).unwrap(); - assert_eq!( - Uint128::from(1000u128), - msg.distribution_schedules[0].amount - ); - if let AssetInfoBase::Native(native) = &msg.reward_token { - assert_eq!("uqsr", native); - } else { - panic!("Unexpected reward token type"); - } - } else { - panic!("Unexpected message type"); - } -} - -#[test] -fn proper_bond_with_one_primitive() { - let mut deps = mock_deps_with_primitives(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - )]); - let msg = init_msg(); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let _res = init(deps.as_mut(), &msg, &env, &info); - - let deposit_info = mock_info( - TEST_DEPOSITOR, - &[Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(100u128), - }], - ); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - - let res = execute(deps.as_mut(), env, deposit_info, deposit_msg).unwrap(); - assert_eq!(res.messages.len(), 1); - assert_eq!(res.attributes.first().unwrap().value, "1"); - - if let CosmosMsg::Wasm(wasm_msg) = &res.messages.first().unwrap().msg { - if let WasmMsg::Execute { - contract_addr, - msg: _, - funds, - } = wasm_msg - { - assert_eq!(contract_addr, "quasar123"); - assert_eq!(funds[0].amount, Uint128::from(100u128)); - } else { - panic!("Wrong message type") - } - } -} - -fn even_primitives() -> Vec<(String, String, Uint128, Uint128)> { - vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar125".to_string(), - "ibc/ustars".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ] -} - -fn even_primitives_single_token() -> Vec<(String, String, Uint128, Uint128)> { - vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar125".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ] -} - -fn even_primitive_details() -> Vec<(String, String, Decimal)> { - vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::one(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ( - "quasar125".to_string(), - "ibc/ustars".to_string(), - Decimal::one(), - ), - ] -} - -fn even_primitive_details_single_token() -> Vec<(String, String, Decimal)> { - vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::one(), - ), - ( - "quasar124".to_string(), - "ibc/uosmo".to_string(), - Decimal::one(), - ), - ( - "quasar125".to_string(), - "ibc/uosmo".to_string(), - Decimal::one(), - ), - ] -} - -fn even_deposit() -> Vec { - vec![ - Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(100u128), - }, - Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(100u128), - }, - Coin { - denom: "ibc/ustars".to_string(), - amount: Uint128::from(100u128), - }, - ] -} - -fn even_deposit_single_token() -> Vec { - vec![Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(300u128), - }] -} - -fn _uneven_primitives() -> Vec<(String, String, Uint128, Uint128)> { - vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ] -} - -fn _uneven_primitive_details() -> Vec<(String, String, Decimal)> { - vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("2.0").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ] -} - -fn _uneven_deposit() -> Vec { - vec![ - Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(1000u128), - }, - Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(200u128), - }, - ] -} - -#[test] -fn test_get_deposit_amount_weights() { - let primitive_states = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ]; - let primitive_deets = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("3.5").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ]; - - let mut deps = mock_deps_with_primitives(primitive_states.clone()); - let init_msg = init_msg_with_primitive_details(primitive_deets.clone()); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let weights = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let first_weight = Decimal::from_ratio( - primitive_deets[0].2 * primitive_states[0].3, - primitive_states[0].2, - ); - let second_weight = Decimal::from_ratio( - primitive_deets[1].2 * primitive_states[1].3, - primitive_states[1].2, - ); - - let total = first_weight + second_weight; - - let expected_first_weight = Decimal::from_ratio( - first_weight.numerator() * total.denominator(), - first_weight.denominator() * total.numerator(), - ); - let expected_second_weight = Decimal::from_ratio( - second_weight.numerator() * total.denominator(), - second_weight.denominator() * total.numerator(), - ); - - assert_eq!(weights.ratio[0].weight, expected_first_weight); - assert_eq!(weights.ratio[1].weight, expected_second_weight); -} - -#[test] -fn test_get_token_amount_weights() { - let primitive_states = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ]; - let primitive_deets = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("3.5").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ]; - - let mut deps = mock_deps_with_primitives(primitive_states.clone()); - let init_msg = init_msg_with_primitive_details(primitive_deets.clone()); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let _weights = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let first_weight = Decimal::from_ratio( - primitive_deets[0].2 * primitive_states[0].3, - primitive_states[0].2, - ); - let second_weight = Decimal::from_ratio( - primitive_deets[1].2 * primitive_states[1].3, - primitive_states[1].2, - ); - - let total = first_weight + second_weight; - - let expected_first_weight = Decimal::from_ratio( - first_weight.numerator() * total.denominator(), - first_weight.denominator() * total.numerator(), - ); - let expected_second_weight = Decimal::from_ratio( - second_weight.numerator() * total.denominator(), - second_weight.denominator() * total.numerator(), - ); - - let token_weights = get_token_amount_weights(&[ - CoinWeight { - denom: "ibc/uosmo".to_string(), - weight: expected_first_weight, - }, - CoinWeight { - denom: "ibc/uatom".to_string(), - weight: expected_second_weight, - }, - ]) - .unwrap(); - - assert_eq!(token_weights[0].weight, expected_first_weight); - assert_eq!(token_weights[1].weight, expected_second_weight); -} - -#[test] -fn test_get_token_amount_weights_duplicate_tokens() {} - -#[test] -fn test_get_max_bond() { - let primitive_states = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ]; - let primitive_deets = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("3.5").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ]; - - let funds = vec![ - Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(1000u128), - }, - Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(200u128), - }, - ]; - - let mut deps = mock_deps_with_primitives(primitive_states.clone()); - let init_msg = init_msg_with_primitive_details(primitive_deets.clone()); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let weights = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let first_weight = Decimal::from_ratio( - primitive_deets[0].2 * primitive_states[0].3, - primitive_states[0].2, - ); - let second_weight = Decimal::from_ratio( - primitive_deets[1].2 * primitive_states[1].3, - primitive_states[1].2, - ); - - let total = first_weight + second_weight; - - let expected_first_weight = Decimal::from_ratio( - first_weight.numerator() * total.denominator(), - first_weight.denominator() * total.numerator(), - ); - let expected_second_weight = Decimal::from_ratio( - second_weight.numerator() * total.denominator(), - second_weight.denominator() * total.numerator(), - ); - - assert_eq!(weights.ratio[0].weight, expected_first_weight); - assert_eq!(weights.ratio[1].weight, expected_second_weight); - - let token_weights = get_token_amount_weights(&[ - CoinWeight { - denom: "ibc/uosmo".to_string(), - weight: expected_first_weight, - }, - CoinWeight { - denom: "ibc/uatom".to_string(), - weight: expected_second_weight, - }, - ]) - .unwrap(); - - assert_eq!(token_weights[0].weight, expected_first_weight); - assert_eq!(token_weights[1].weight, expected_second_weight); - - let expected_max_bond = std::cmp::min( - Decimal::from_ratio( - funds[0].amount * token_weights[0].weight.denominator(), - token_weights[0].weight.numerator(), - ) - .to_uint_floor(), - Decimal::from_ratio( - funds[1].amount * token_weights[1].weight.denominator(), - token_weights[1].weight.numerator(), - ) - .to_uint_floor(), - ); - - let max_bond = get_max_bond(&funds, &token_weights).unwrap(); - - assert_eq!(max_bond.to_uint_floor(), expected_max_bond); -} - -#[test] -fn test_get_deposit_and_remainder_for_ratio() { - let primitive_states = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ]; - let primitive_deets = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("3.5").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ]; - - let funds = vec![ - Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(1000u128), - }, - Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(200u128), - }, - ]; - - let mut deps = mock_deps_with_primitives(primitive_states.clone()); - let init_msg = init_msg_with_primitive_details(primitive_deets.clone()); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let _weights = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let first_weight = Decimal::from_ratio( - primitive_deets[0].2 * primitive_states[0].3, - primitive_states[0].2, - ); - let second_weight = Decimal::from_ratio( - primitive_deets[1].2 * primitive_states[1].3, - primitive_states[1].2, - ); - - let total = first_weight + second_weight; - - let expected_first_weight = Decimal::from_ratio( - first_weight.numerator() * total.denominator(), - first_weight.denominator() * total.numerator(), - ); - let expected_second_weight = Decimal::from_ratio( - second_weight.numerator() * total.denominator(), - second_weight.denominator() * total.numerator(), - ); - - let token_weights = get_token_amount_weights(&[ - CoinWeight { - denom: "ibc/uosmo".to_string(), - weight: expected_first_weight, - }, - CoinWeight { - denom: "ibc/uatom".to_string(), - weight: expected_second_weight, - }, - ]) - .unwrap(); - - assert_eq!(token_weights[0].weight, expected_first_weight); - assert_eq!(token_weights[1].weight, expected_second_weight); - - let expected_max_bond = std::cmp::min( - Decimal::from_ratio( - funds[0].amount * token_weights[0].weight.denominator(), - token_weights[0].weight.numerator(), - ) - .to_uint_floor(), - Decimal::from_ratio( - funds[1].amount * token_weights[1].weight.denominator(), - token_weights[1].weight.numerator(), - ) - .to_uint_floor(), - ); - - let max_bond = get_max_bond(&funds, &token_weights).unwrap(); - - assert_eq!(max_bond.to_uint_floor(), expected_max_bond); - - let (deposit, remainder) = get_deposit_and_remainder_for_ratio( - &funds, - max_bond, - &CoinRatio { - ratio: token_weights.clone(), - }, - ) - .unwrap(); - - let expected_first_deposit = Decimal::from_ratio( - token_weights[0].weight.numerator() * max_bond, - token_weights[0].weight.denominator(), - ); - let expected_second_deposit = Decimal::from_ratio( - token_weights[1].weight.numerator() * max_bond, - token_weights[1].weight.denominator(), - ); - - assert_eq!(deposit[0].amount, expected_first_deposit.to_uint_floor()); - assert_eq!(deposit[1].amount, expected_second_deposit.to_uint_floor()); - - assert_eq!( - remainder[0].amount, - funds[0].amount - expected_first_deposit.to_uint_floor() - ); - assert_eq!( - remainder[1].amount, - funds[1].amount - expected_second_deposit.to_uint_floor() - ); -} - -#[test] -fn test_get_deposit_and_remainder_for_ratio_three_primitives() { - let primitive_states = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(200u128), - Uint128::from(400u128), - ), - ( - "quasar125".to_string(), - "ibc/ustars".to_string(), - Uint128::from(600u128), - Uint128::from(450u128), - ), - ]; - let primitive_deets = vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("3.5").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ( - "quasar125".to_string(), - "ibc/ustars".to_string(), - Decimal::from_str("0.5").unwrap(), - ), - ]; - - let funds = vec![ - Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(1000u128), - }, - Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(200u128), - }, - Coin { - denom: "ibc/ustars".to_string(), - amount: Uint128::from(200u128), - }, - ]; - - let mut deps = mock_deps_with_primitives(primitive_states.clone()); - let init_msg = init_msg_with_primitive_details(primitive_deets.clone()); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let weights = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let first_weight = Decimal::from_ratio( - primitive_deets[0].2 * primitive_states[0].3, - primitive_states[0].2, - ); - let second_weight = Decimal::from_ratio( - primitive_deets[1].2 * primitive_states[1].3, - primitive_states[1].2, - ); - let third_weight = Decimal::from_ratio( - primitive_deets[2].2 * primitive_states[2].3, - primitive_states[2].2, - ); - - let total = first_weight + second_weight + third_weight; - - let expected_first_weight = Decimal::from_ratio( - first_weight.numerator() * total.denominator(), - first_weight.denominator() * total.numerator(), - ); - let expected_second_weight = Decimal::from_ratio( - second_weight.numerator() * total.denominator(), - second_weight.denominator() * total.numerator(), - ); - let expected_third_weight = Decimal::from_ratio( - third_weight.numerator() * total.denominator(), - third_weight.denominator() * total.numerator(), - ); - - assert_eq!(weights.ratio[0].weight, expected_first_weight); - assert_eq!(weights.ratio[1].weight, expected_second_weight); - assert_eq!(weights.ratio[2].weight, expected_third_weight); - - let token_weights = get_token_amount_weights(&[ - CoinWeight { - denom: "ibc/uosmo".to_string(), - weight: expected_first_weight, - }, - CoinWeight { - denom: "ibc/uatom".to_string(), - weight: expected_second_weight, - }, - CoinWeight { - denom: "ibc/ustars".to_string(), - weight: expected_third_weight, - }, - ]) - .unwrap(); - - assert_eq!(token_weights[0].weight, expected_first_weight); - assert_eq!(token_weights[1].weight, expected_second_weight); - assert_eq!(token_weights[2].weight, expected_third_weight); - - let expected_max_bond = std::cmp::min( - Decimal::from_ratio( - funds[0].amount * token_weights[0].weight.denominator(), - token_weights[0].weight.numerator(), - ) - .to_uint_floor(), - Decimal::from_ratio( - funds[1].amount * token_weights[1].weight.denominator(), - token_weights[1].weight.numerator(), - ) - .to_uint_floor(), - ); - - let max_bond = get_max_bond(&funds, &token_weights).unwrap(); - - assert_eq!(max_bond.to_uint_floor(), expected_max_bond); - - let (deposit, remainder) = get_deposit_and_remainder_for_ratio( - &funds, - max_bond, - &CoinRatio { - ratio: token_weights.clone(), - }, - ) - .unwrap(); - - let expected_first_deposit = Decimal::from_ratio( - token_weights[0].weight.numerator() * max_bond, - token_weights[0].weight.denominator(), - ); - let expected_second_deposit = Decimal::from_ratio( - token_weights[1].weight.numerator() * max_bond, - token_weights[1].weight.denominator(), - ); - let expected_third_deposit = Decimal::from_ratio( - token_weights[2].weight.numerator() * max_bond, - token_weights[2].weight.denominator(), - ); - - assert_eq!(deposit[0].amount, expected_first_deposit.to_uint_floor()); - assert_eq!(deposit[1].amount, expected_second_deposit.to_uint_floor()); - assert_eq!(deposit[2].amount, expected_third_deposit.to_uint_floor()); - - println!("remainder: {remainder:?}"); - println!("deposit: {deposit:?}"); - assert_eq!( - remainder[0].amount, - funds[0].amount - expected_first_deposit.to_uint_floor() - ); - assert_eq!( - remainder[1].amount, - funds[1].amount - expected_second_deposit.to_uint_floor() - ); - assert_eq!( - remainder[2].amount, - funds[2].amount - expected_third_deposit.to_uint_floor() - ); -} - -#[test] -fn test_may_pay_with_one_primitive() { - let mut deps = mock_deps_with_primitives(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - )]); - let init_msg = init_msg_with_primitive_details(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("2.0").unwrap(), - )]); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let funds = &[Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(200u128), - }]; - - // load cached balance of primitive contracts - let deposit_amount_ratio = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let token_weights: Vec = - get_token_amount_weights(&deposit_amount_ratio.ratio).unwrap(); - - let max_bond = get_max_bond(funds, &token_weights).unwrap(); - - let (coins, remainder) = - get_deposit_and_remainder_for_ratio(funds, max_bond, &deposit_amount_ratio).unwrap(); - - assert_eq!(coins.len(), 1); - assert_eq!(coins[0].amount, Uint128::from(200u128)); - - assert_eq!(remainder.len(), 1); - assert_eq!(remainder[0].amount, Uint128::from(0u128)); -} - -#[test] -fn test_may_pay_with_even_ratio() { - let mut deps = mock_deps_with_primitives(even_primitives()); - let init_msg = init_msg_with_primitive_details(even_primitive_details()); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let (coins, remainder) = - may_pay_with_ratio(&deps.as_ref(), &even_deposit(), investment_response.info).unwrap(); - - assert_eq!(coins.len(), 3); - assert_eq!(coins[0].amount, Uint128::from(99u128)); // 99 because 0.33333 results in coins getting floored - assert_eq!(coins[1].amount, Uint128::from(99u128)); - assert_eq!(coins[2].amount, Uint128::from(99u128)); - - assert_eq!(remainder.len(), 3); - assert_eq!(remainder[0].amount, Uint128::from(1u128)); - assert_eq!(remainder[1].amount, Uint128::from(1u128)); - assert_eq!(remainder[2].amount, Uint128::from(1u128)); -} - -#[test] -fn test_may_pay_with_uneven_ratio() { - let mut deps = mock_deps_with_primitives(vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(100u128), - Uint128::from(100u128), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Uint128::from(150u128), - Uint128::from(200u128), - ), - ( - "quasar125".to_string(), - "ibc/ustars".to_string(), - Uint128::from(250u128), - Uint128::from(300u128), - ), - ]); - let init_msg = init_msg_with_primitive_details(vec![ - ( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::from_str("2.0").unwrap(), - ), - ( - "quasar124".to_string(), - "ibc/uatom".to_string(), - Decimal::one(), - ), - ( - "quasar125".to_string(), - "ibc/ustars".to_string(), - Decimal::one(), - ), - ]); - - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let invest_query = crate::msg::QueryMsg::Investment {}; - let query_res = query(deps.as_ref(), env, invest_query).unwrap(); - - let investment_response: InvestmentResponse = from_json(&query_res).unwrap(); - - let funds = &[ - Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(200u128), - }, - Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(150u128), - }, - Coin { - denom: "ibc/ustars".to_string(), - amount: Uint128::from(140u128), - }, - ]; - - // load cached balance of primitive contracts - let deposit_amount_ratio = - get_deposit_amount_weights(&deps.as_ref(), &investment_response.info.primitives).unwrap(); - - let token_weights: Vec = - get_token_amount_weights(&deposit_amount_ratio.ratio).unwrap(); - - let max_bond = get_max_bond(funds, &token_weights).unwrap(); - - let (coins, remainder) = - get_deposit_and_remainder_for_ratio(funds, max_bond, &deposit_amount_ratio).unwrap(); - - assert_eq!(coins.len(), 3); - assert_eq!(coins[0].amount, Uint128::from(199u128)); // these numbers have been verified - assert_eq!(coins[1].amount, Uint128::from(133u128)); - assert_eq!(coins[2].amount, Uint128::from(119u128)); - - assert_eq!(remainder.len(), 3); - assert_eq!(remainder[0].amount, Uint128::from(1u128)); - assert_eq!(remainder[1].amount, Uint128::from(17u128)); - assert_eq!(remainder[2].amount, Uint128::from(21u128)); -} - -#[test] -fn proper_bond() { - let mut deps = mock_deps_with_primitives(even_primitives_single_token()); - let init_msg = init_msg_with_primitive_details(even_primitive_details_single_token()); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let deposit_info = mock_info(TEST_DEPOSITOR, &even_deposit_single_token()); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - let res = execute(deps.as_mut(), env, deposit_info, deposit_msg).unwrap(); - assert_eq!(res.messages.len(), 3); - assert_eq!(res.attributes.first().unwrap().value, "1"); - - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &res.messages[0].msg - { - assert_eq!(contract_addr, "quasar123"); - assert_eq!(funds.len(), 1); - assert_eq!(funds[0].denom, "ibc/uosmo"); - assert_eq!(funds[0].amount, Uint128::from(99u128)); - if let lp_strategy::msg::ExecuteMsg::Bond { id } = from_json(msg).unwrap() { - assert_eq!(id, "1") - } else { - panic!("expected Bond msg") - } - } else { - panic!("expected wasm msg") - } - - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &res.messages[1].msg - { - assert_eq!(contract_addr, "quasar124"); - assert_eq!(funds.len(), 1); - assert_eq!(funds[0].denom, "ibc/uosmo"); - assert_eq!(funds[0].amount, Uint128::from(99u128)); - if let lp_strategy::msg::ExecuteMsg::Bond { id } = from_json(msg).unwrap() { - assert_eq!(id, "1") - } else { - panic!("expected Bond msg") - } - } else { - panic!("expected Wasm msg") - } - - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &res.messages[2].msg - { - assert_eq!(contract_addr, "quasar125"); - assert_eq!(funds.len(), 1); - assert_eq!(funds[0].denom, "ibc/uosmo"); - assert_eq!(funds[0].amount, Uint128::from(99u128)); - if let lp_strategy::msg::ExecuteMsg::Bond { id } = from_json(msg).unwrap() { - assert_eq!(id, "1") - } else { - panic!("expected Bond msg") - } - } else { - panic!("expected wasm msg") - } - - // This BankMsg should not exist since we deprecated the dust send back - // if let CosmosMsg::Bank(BankMsg::Send { to_address, amount }) = &res.messages[3].msg { - // assert_eq!(to_address, TEST_DEPOSITOR); - // assert_eq!(amount.len(), 3); - // assert_eq!(amount[0].amount, Uint128::from(1u128)); - // assert_eq!(amount[1].amount, Uint128::from(1u128)); - // assert_eq!(amount[2].amount, Uint128::from(1u128)); - // } else { - // panic!("unexpected message"); - // } -} - -#[test] -fn proper_bond_with_zero_primitive_balance() { - let mut deps = mock_deps_with_primitives(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(0u128), - Uint128::from(0u128), - )]); - let init_msg = init_msg_with_primitive_details(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::one(), - )]); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let deposit_info = mock_info(TEST_DEPOSITOR, &even_deposit_single_token()); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - let res = execute(deps.as_mut(), env, deposit_info, deposit_msg).unwrap(); - assert_eq!(res.messages.len(), 1); - assert_eq!(res.attributes.first().unwrap().value, "1"); -} - -#[test] -fn test_bond_with_zero_primitive_state() { - let mut deps_1 = mock_deps_with_primitives(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(0u128), - Uint128::from(1u128), - )]); - let mut deps_2 = mock_deps_with_primitives(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Uint128::from(1u128), - Uint128::from(0u128), - )]); - let init_msg: InstantiateMsg = init_msg_with_primitive_details(vec![( - "quasar123".to_string(), - "ibc/uosmo".to_string(), - Decimal::one(), - )]); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let _ = init(deps_1.as_mut(), &init_msg, &env, &info); - let _ = init(deps_2.as_mut(), &init_msg, &env, &info); - - // mock the rewards_contract address - VAULT_REWARDS - .save( - deps_1.as_mut().storage, - &Addr::unchecked("rewards_contract"), - ) - .unwrap(); - VAULT_REWARDS - .save( - deps_2.as_mut().storage, - &Addr::unchecked("rewards_contract"), - ) - .unwrap(); - - let deposit_info = mock_info(TEST_DEPOSITOR, &even_deposit_single_token()); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - let bond_seq_1 = BONDING_SEQ.load(deps_1.as_ref().storage).unwrap(); - let _res_1 = execute( - deps_1.as_mut(), - env.clone(), - deposit_info.clone(), - deposit_msg.clone(), - ) - .unwrap(); - - // with changing to minting by ica_balance, if either is zero, we expect to mint user value, so we should be able to callback these primitives - // and receive even deposit single token amount of shares, aka 300 - let res_1 = on_bond( - deps_1.as_mut(), - env.clone(), - mock_info("quasar123", &[]), - Uint128::new(250), - bond_seq_1.to_string(), - ) - .unwrap(); - assert!(res_1.attributes.contains(&Attribute::new("minted", "300"))); - - let bond_seq_2 = BONDING_SEQ.load(deps_2.as_ref().storage).unwrap(); - let _res_2 = execute(deps_2.as_mut(), env.clone(), deposit_info, deposit_msg).unwrap(); - - let res_2 = on_bond( - deps_2.as_mut(), - env, - mock_info("quasar123", &[]), - Uint128::new(250), - bond_seq_2.to_string(), - ) - .unwrap(); - assert!(res_2.attributes.contains(&Attribute::new("minted", "300"))); - // assert_eq!(res_2.to_string(), "Generic error: Unexpected primitive state, either both supply and balance should be zero, or neither."); -} - -#[test] -fn proper_bond_response_callback_single_token() { - let mut deps = mock_deps_with_primitives(even_primitives_single_token()); - let init_msg = init_msg_with_primitive_details(even_primitive_details_single_token()); - let info = mock_info(TEST_CREATOR, &[]); - let env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let reply_msg = reply_msg(); - let res = reply(deps.as_mut(), env.clone(), reply_msg).unwrap(); - assert_eq!(res.messages.len(), 0); - - let deposit_info = mock_info(TEST_DEPOSITOR, &even_deposit_single_token()); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - let res = execute(deps.as_mut(), env.clone(), deposit_info, deposit_msg).unwrap(); - - println!("messages: {:#?}", res.messages); - // assert_eq!(res.messages.len(), 4); - // assert_eq!(res.attributes.first().unwrap().value, "1"); - - // in this scenario we expect 1000/1000 * 100 = 100 shares back from each primitive - let primitive_1_info = mock_info("quasar123", &[]); - let primitive_1_msg = ExecuteMsg::BondResponse(BondResponse { - share_amount: 100u128.into(), - bond_id: "1".to_string(), - }); - let p1_res = execute( - deps.as_mut(), - env.clone(), - primitive_1_info, - primitive_1_msg, - ) - .unwrap(); - assert_eq!(p1_res.messages.len(), 0); - - let primitive_2_info = mock_info("quasar124", &[]); - let primitive_2_msg = ExecuteMsg::BondResponse(BondResponse { - share_amount: 100u128.into(), - bond_id: "1".to_string(), - }); - let p2_res = execute( - deps.as_mut(), - env.clone(), - primitive_2_info, - primitive_2_msg, - ) - .unwrap(); - assert_eq!(p2_res.messages.len(), 0); - - let primitive_3_info = mock_info("quasar125", &[]); - let primitive_3_msg = ExecuteMsg::BondResponse(BondResponse { - share_amount: 100u128.into(), - bond_id: "1".to_string(), - }); - let p3_res = execute( - deps.as_mut(), - env.clone(), - primitive_3_info, - primitive_3_msg, - ) - .unwrap(); - assert_eq!(p3_res.messages.len(), 1); - - let balance_query = crate::msg::QueryMsg::Balance { - address: TEST_DEPOSITOR.to_string(), - }; - let balance_res = query(deps.as_ref(), env, balance_query).unwrap(); - let balance: BalanceResponse = from_json(&balance_res).unwrap(); - - assert_eq!(balance.balance, Uint128::from(297u128)); -} - -// this looks to be a duplicate now of proper_bond_response_callback_single_token, so should no longer be supported -// #[test] -// fn proper_bond_response_callback() { -// let mut deps = mock_deps_with_primitives(even_primitives()); -// let init_msg = init_msg_with_primitive_details(even_primitive_details()); -// let info = mock_info(TEST_CREATOR, &[]); -// let env = mock_env(); -// let res = init(deps.as_mut(), &init_msg, &env, &info); -// assert_eq!(1, res.messages.len()); - -// let reply_msg = reply_msg(); -// let res = reply(deps.as_mut(), env.clone(), reply_msg).unwrap(); -// assert_eq!(res.messages.len(), 0); - -// let deposit_info = mock_info(TEST_DEPOSITOR, &even_deposit()); -// let deposit_msg = ExecuteMsg::Bond { -// recipient: Option::None, -// }; -// let res = execute(deps.as_mut(), env.clone(), deposit_info, deposit_msg).unwrap(); - -// println!("messages: {:#?}", res.messages); -// // assert_eq!(res.messages.len(), 4); -// // assert_eq!(res.attributes.first().unwrap().value, "1"); - -// // in this scenario we expect 1000/1000 * 100 = 100 shares back from each primitive -// let primitive_1_info = mock_info("quasar123", &[]); -// let primitive_1_msg = ExecuteMsg::BondResponse(BondResponse { -// share_amount: 100u128.into(), -// bond_id: "1".to_string(), -// }); -// let p1_res = execute( -// deps.as_mut(), -// env.clone(), -// primitive_1_info, -// primitive_1_msg, -// ) -// .unwrap(); -// assert_eq!(p1_res.messages.len(), 0); - -// let primitive_2_info = mock_info("quasar124", &[]); -// let primitive_2_msg = ExecuteMsg::BondResponse(BondResponse { -// share_amount: 100u128.into(), -// bond_id: "1".to_string(), -// }); -// let p2_res = execute( -// deps.as_mut(), -// env.clone(), -// primitive_2_info, -// primitive_2_msg, -// ) -// .unwrap(); -// assert_eq!(p2_res.messages.len(), 0); - -// let primitive_3_info = mock_info("quasar125", &[]); -// let primitive_3_msg = ExecuteMsg::BondResponse(BondResponse { -// share_amount: 100u128.into(), -// bond_id: "1".to_string(), -// }); -// let p3_res = execute( -// deps.as_mut(), -// env.clone(), -// primitive_3_info, -// primitive_3_msg, -// ) -// .unwrap(); -// assert_eq!(p3_res.messages.len(), 1); - -// let balance_query = crate::msg::QueryMsg::Balance { -// address: TEST_DEPOSITOR.to_string(), -// }; -// let balance_res = query(deps.as_ref(), env, balance_query).unwrap(); -// let balance: BalanceResponse = from_json(&balance_res).unwrap(); - -// assert_eq!(balance.balance, Uint128::from(300u128)); -// } - -#[test] -fn proper_unbond() { - let mut deps = mock_deps_with_primitives(even_primitives()); - let init_msg = init_msg_with_primitive_details(even_primitive_details()); - let info = mock_info(TEST_CREATOR, &[]); - let mut env = mock_env(); - let res = init(deps.as_mut(), &init_msg, &env, &info); - assert_eq!(1, res.messages.len()); - - let reply_msg = reply_msg(); - let _res = reply(deps.as_mut(), env.clone(), reply_msg).unwrap(); - - let deposit_info = mock_info(TEST_DEPOSITOR, &even_deposit_single_token()); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - let res = execute(deps.as_mut(), env.clone(), deposit_info, deposit_msg).unwrap(); - assert_eq!(res.messages.len(), 3); - assert_eq!(res.attributes.first().unwrap().value, "1"); - - // in this scenario we expect 1000/1000 * 100 = 100 shares back from each primitive - let primitive_1_info = mock_info("quasar123", &[]); - let primitive_1_msg = ExecuteMsg::BondResponse(BondResponse { - share_amount: 100u128.into(), - bond_id: "1".to_string(), - }); - let p1_res = execute( - deps.as_mut(), - env.clone(), - primitive_1_info.clone(), - primitive_1_msg, - ) - .unwrap(); - assert_eq!(p1_res.messages.len(), 0); - - let primitive_2_info = mock_info("quasar124", &[]); - let primitive_2_msg = ExecuteMsg::BondResponse(BondResponse { - share_amount: 100u128.into(), - bond_id: "1".to_string(), - }); - let p2_res = execute( - deps.as_mut(), - env.clone(), - primitive_2_info.clone(), - primitive_2_msg, - ) - .unwrap(); - assert_eq!(p2_res.messages.len(), 0); - - let primitive_3_info = mock_info("quasar125", &[]); - let primitive_3_msg = ExecuteMsg::BondResponse(BondResponse { - share_amount: 100u128.into(), - bond_id: "1".to_string(), - }); - let p3_res = execute( - deps.as_mut(), - env.clone(), - primitive_3_info.clone(), - primitive_3_msg, - ) - .unwrap(); - println!("p3_res: {p3_res:?}"); - assert_eq!(p3_res.messages.len(), 1); - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds: _, - }) = &p3_res.messages[0].msg - { - assert_eq!(contract_addr, "vault_rewards_addr"); - if let vault_rewards::msg::ExecuteMsg::Vault( - vault_rewards::msg::VaultExecuteMsg::UpdateUserRewardIndex(user_reward_index), - ) = from_json(msg).unwrap() - { - assert_eq!(user_reward_index, TEST_DEPOSITOR); - } else { - panic!("wrong message"); - } - } else { - panic!("wrong message"); - } - - let balance_query = crate::msg::QueryMsg::Balance { - address: TEST_DEPOSITOR.to_string(), - }; - let balance_res = query(deps.as_ref(), env.clone(), balance_query).unwrap(); - let balance: BalanceResponse = from_json(&balance_res).unwrap(); - - assert_eq!(balance.balance, Uint128::from(297u128)); - - // start unbond - let unbond_info = mock_info(TEST_DEPOSITOR, &[]); - let unbond_msg = ExecuteMsg::Unbond { - amount: Option::Some(balance.balance), - }; - let unbond_res = execute(deps.as_mut(), env.clone(), unbond_info, unbond_msg).unwrap(); - assert_eq!(unbond_res.messages.len(), 4); - assert_eq!(unbond_res.attributes[2].key, "burnt"); - assert_eq!(unbond_res.attributes[2].value, "297"); - assert_eq!(unbond_res.attributes[3].key, "bond_id"); - assert_eq!(unbond_res.attributes[3].value, "2"); - - // todo replace with a macro - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &unbond_res.messages[0].msg - { - assert_eq!(contract_addr, "quasar123"); - assert!(funds.is_empty()); - if let lp_strategy::msg::ExecuteMsg::StartUnbond { id, share_amount } = - from_json(msg).unwrap() - { - assert_eq!(id, "2"); - assert_eq!(share_amount, Uint128::from(100u128)); - } else { - panic!("expected start unbond") - } - } else { - panic!("expected wasm msg") - } - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &unbond_res.messages[1].msg - { - assert_eq!(contract_addr, "quasar124"); - assert!(funds.is_empty()); - if let lp_strategy::msg::ExecuteMsg::StartUnbond { id, share_amount } = - from_json(msg).unwrap() - { - assert_eq!(id, "2"); - assert_eq!(share_amount, Uint128::from(100u128)); - } else { - panic!("expected start unbond") - } - } else { - panic!("expected wasm msg") - } - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &unbond_res.messages[2].msg - { - assert_eq!(contract_addr, "quasar125"); - assert!(funds.is_empty()); - if let lp_strategy::msg::ExecuteMsg::StartUnbond { id, share_amount } = - from_json(msg).unwrap() - { - assert_eq!(id, "2"); - assert_eq!(share_amount, Uint128::from(100u128)); - } else { - panic!("expected start unbond") - } - } else { - panic!("expected wasm msg") - } - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &unbond_res.messages[3].msg - { - assert_eq!(contract_addr, "vault_rewards_addr"); - assert!(funds.is_empty()); - if let vault_rewards::msg::ExecuteMsg::Vault( - vault_rewards::msg::VaultExecuteMsg::UpdateUserRewardIndex(user_addr), - ) = from_json(msg).unwrap() - { - assert_eq!(user_addr, TEST_DEPOSITOR); - } else { - panic!("expected update user reward index") - } - } else { - panic!("expected wasm message") - } - - // get callbacks back - let start_unbond_msg_p1 = ExecuteMsg::StartUnbondResponse(StartUnbondResponse { - unbond_id: "2".to_string(), - unlock_time: Timestamp::from_seconds(env.block.time.seconds() + 5), - }); - let start_unbond_res = execute( - deps.as_mut(), - env.clone(), - primitive_1_info, - start_unbond_msg_p1, - ) - .unwrap(); - assert_eq!(start_unbond_res.messages.len(), 0); - - let start_unbond_msg_p2 = ExecuteMsg::StartUnbondResponse(StartUnbondResponse { - unbond_id: "2".to_string(), - unlock_time: Timestamp::from_seconds(env.block.time.seconds() + 5), - }); - let start_unbond_res = execute( - deps.as_mut(), - env.clone(), - primitive_2_info, - start_unbond_msg_p2, - ) - .unwrap(); - assert_eq!(start_unbond_res.messages.len(), 0); - - let start_unbond_msg_p3 = ExecuteMsg::StartUnbondResponse(StartUnbondResponse { - unbond_id: "2".to_string(), - unlock_time: Timestamp::from_seconds(env.block.time.seconds() + 60), - }); - let start_unbond_res = execute( - deps.as_mut(), - env.clone(), - primitive_3_info, - start_unbond_msg_p3, - ) - .unwrap(); - assert_eq!(start_unbond_res.messages.len(), 0); - - // do unbond - let do_unbond_info = mock_info(TEST_DEPOSITOR, &[]); - let do_unbond_msg = ExecuteMsg::Unbond { amount: None }; - let do_unbond_res = execute( - deps.as_mut(), - env.clone(), - do_unbond_info.clone(), - do_unbond_msg.clone(), - ) - .unwrap(); - - assert_eq!(do_unbond_res.messages.len(), 0); - - env.block.height += 4; - env.block.time = env.block.time.plus_seconds(30); - - // set two of the primitives to be unbondable - deps.querier.set_unbonding_claim_for_primitive( - "quasar123".to_owned(), - env.block.time.minus_seconds(5), - false, - ); - deps.querier.set_unbonding_claim_for_primitive( - "quasar124".to_owned(), - env.block.time.minus_seconds(5), - false, - ); - - // unbond and see that 2 are unbondable - let do_unbond_res = execute( - deps.as_mut(), - env.clone(), - do_unbond_info.clone(), - do_unbond_msg, - ) - .unwrap(); - // nothing here - assert_eq!(do_unbond_res.messages.len(), 0); - - let claim_msg = ExecuteMsg::Claim {}; - let claim_res = execute( - deps.as_mut(), - env.clone(), - do_unbond_info.clone(), - claim_msg, - ) - .unwrap(); - - assert_eq!(claim_res.messages.len(), 2); - assert_eq!(claim_res.attributes[2].key, "num_unbondable_ids"); - assert_eq!(claim_res.attributes[2].value, "2"); - - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &claim_res.messages[0].msg - { - assert_eq!(contract_addr, "quasar123"); - assert!(funds.is_empty()); - if let lp_strategy::msg::ExecuteMsg::Unbond { id } = from_json(msg).unwrap() { - assert_eq!(id, "2"); - } else { - panic!("expected unbond") - } - } else { - panic!("expected wasm msg") - } - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &claim_res.messages[1].msg - { - assert_eq!(contract_addr, "quasar124"); - assert!(funds.is_empty()); - if let lp_strategy::msg::ExecuteMsg::Unbond { id } = from_json(msg).unwrap() { - assert_eq!(id, "2"); - } else { - panic!("expected unbond") - } - } else { - panic!("expected wasm msg") - } - // set these two primitive unbonds to have been attempted already - deps.querier.set_unbonding_claim_for_primitive( - "quasar123".to_owned(), - env.block.time.minus_seconds(5), - true, - ); - deps.querier.set_unbonding_claim_for_primitive( - "quasar124".to_owned(), - env.block.time.minus_seconds(5), - true, - ); - - env.block.height += 5; - env.block.time = env.block.time.plus_seconds(40); - - // set last of the primitives to be unbondable - deps.querier.set_unbonding_claim_for_primitive( - "quasar125".to_owned(), - env.block.time.minus_seconds(5), - false, - ); - - // test that claim works the same way as unbond(amount:0) - let claim_msg = ExecuteMsg::Claim {}; - let claim_res = execute(deps.as_mut(), env.clone(), do_unbond_info, claim_msg).unwrap(); - - // todo: This assertion will change because we should ideally only expect one here, pending arch discussion - assert_eq!(claim_res.messages.len(), 1); - assert_eq!(claim_res.attributes[2].key, "num_unbondable_ids"); - assert_eq!(claim_res.attributes[2].value, "1"); - - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr, - msg, - funds, - }) = &claim_res.messages[0].msg - { - // todo: This assertion will change because we should ideally only expect one here, pending arch discussions - assert_eq!(contract_addr, "quasar125"); - assert!(funds.is_empty()); - if let lp_strategy::msg::ExecuteMsg::Unbond { id } = from_json(msg).unwrap() { - assert_eq!(id, "2"); - } else { - panic!("expected unbond") - } - } else { - panic!("ex[ected wasm msg") - } - - // start callbacks from primitives for unbond - let unbond_callback_msg = ExecuteMsg::UnbondResponse(UnbondResponse { - unbond_id: "2".to_string(), - }); - let p1_unbond_callback_info = mock_info( - "quasar123", - &[Coin { - denom: "ibc/uosmo".to_string(), - amount: Uint128::from(100u128), - }], - ); - let p1_unbond_callback_res = execute( - deps.as_mut(), - env.clone(), - p1_unbond_callback_info, - unbond_callback_msg.clone(), - ) - .unwrap(); - assert_eq!(p1_unbond_callback_res.messages.len(), 0); - - let p2_unbond_callback_info = mock_info( - "quasar124", - &[Coin { - denom: "ibc/uatom".to_string(), - amount: Uint128::from(100u128), - }], - ); - let p2_unbond_callback_res = execute( - deps.as_mut(), - env.clone(), - p2_unbond_callback_info, - unbond_callback_msg.clone(), - ) - .unwrap(); - assert_eq!(p2_unbond_callback_res.messages.len(), 0); - - let p3_unbond_callback_info = mock_info( - "quasar125", - &[Coin { - denom: "ibc/ustars".to_string(), - amount: Uint128::from(100u128), - }], - ); - let p3_unbond_callback_res = execute( - deps.as_mut(), - env, - p3_unbond_callback_info, - unbond_callback_msg, - ) - .unwrap(); - assert_eq!(p3_unbond_callback_res.messages.len(), 3); - - if let CosmosMsg::Bank(bank_msg) = &p3_unbond_callback_res.messages[0].msg { - if let BankMsg::Send { to_address, amount } = bank_msg { - assert_eq!(to_address, TEST_DEPOSITOR); - assert_eq!(amount.len(), 1); - assert_eq!(amount[0].denom, "ibc/uosmo"); - assert_eq!(amount[0].amount, Uint128::from(100u128)); - } else { - panic!("unexpected bank message"); - } - } else { - panic!("unexpected message"); - } - - if let CosmosMsg::Bank(bank_msg) = &p3_unbond_callback_res.messages[1].msg { - if let BankMsg::Send { to_address, amount } = bank_msg { - assert_eq!(to_address, TEST_DEPOSITOR); - assert_eq!(amount.len(), 1); - assert_eq!(amount[0].denom, "ibc/uatom"); - assert_eq!(amount[0].amount, Uint128::from(100u128)); - } else { - panic!("unexpected bank message"); - } - } else { - panic!("unexpected message"); - } - - if let CosmosMsg::Bank(bank_msg) = &p3_unbond_callback_res.messages[2].msg { - if let BankMsg::Send { to_address, amount } = bank_msg { - assert_eq!(to_address, TEST_DEPOSITOR); - assert_eq!(amount.len(), 1); - assert_eq!(amount[0].denom, "ibc/ustars"); - assert_eq!(amount[0].amount, Uint128::from(100u128)); - } else { - panic!("unexpected bank message"); - } - } else { - panic!("unexpected message"); - } -} - -#[test] -fn test_multi_user_bond_unbond() {} - -#[test] -fn test_recipient_not_sender() {} - -#[test] -fn test_dup_token_deposits() { - let env = mock_env(); - const ADDRESS: &str = "quasar"; - const DENOM_LOCAL_CHAIN: &str = "ibc/uosmo"; - const SHARES: Uint128 = Uint128::new(100); - const BALANCE: Uint128 = Uint128::new(100); - - let deposit_amounts = vec![ - Uint128::new(10), - Uint128::new(1_000), - Uint128::new(1_000_000_000), - ]; - - for deposit_amount in deposit_amounts { - // test params - let weights = [ - Decimal::from_str("0.2").unwrap(), - Decimal::from_str("0.3").unwrap(), - Decimal::from_str("0.5").unwrap(), - ]; - - let mut primitive_states: Vec<(String, String, Uint128, Uint128)> = Vec::new(); - let mut primitive_details: Vec<(String, String, Decimal)> = Vec::new(); - for i in 1..=3 { - primitive_states.push(( - format!("{ADDRESS}{i}"), - DENOM_LOCAL_CHAIN.to_string(), - SHARES, - BALANCE, - )); - primitive_details.push(( - format!("{ADDRESS}{i}"), - DENOM_LOCAL_CHAIN.to_string(), - weights[i - 1], - )); - } - let mut deps = mock_deps_with_primitives(primitive_states); - let init_info = mock_info(TEST_CREATOR, &[]); - - let init_msg = init_msg_with_primitive_details(primitive_details); - let init_res = init(deps.as_mut(), &init_msg, &env, &init_info); - assert_eq!(1, init_res.messages.len()); - - // deposit 3 times to the same vault - let deposit_info = mock_info( - TEST_CREATOR, - &[Coin { - denom: DENOM_LOCAL_CHAIN.to_string(), - amount: deposit_amount, - }], - ); - let deposit_msg = ExecuteMsg::Bond { - recipient: Option::None, - }; - let deposit_res = execute( - deps.as_mut(), - env.clone(), - deposit_info.clone(), - deposit_msg, - ) - .unwrap(); - - assert_eq!(deposit_res.messages.len(), init_msg.primitives.len()); - - // total money sent to the vault - let total_money = deposit_info.funds[0].amount; - - // total weight from init msg - let total_weight: Decimal = init_msg.primitives.iter().map(|p| p.weight).sum(); - assert_eq!(total_weight, Decimal::one()); - - for (i, msg) in deposit_res.messages.iter().enumerate() { - if let CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: _, - funds, - msg: _, - }) = &msg.msg - { - // weight[i] / total_weight * total_money = money_output[i] - let expected = init_msg.primitives[i].weight / total_weight * total_money; - assert_eq!(expected, funds[0].amount); - } - } - } -} - -#[test] -fn test_unbond_with_funds_for_none_and_some() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let info = mock_info("pepe", &coins(420, "uqsr")); - - let msg = ExecuteMsg::Unbond { amount: None }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg); - assert_eq!(res.unwrap_err(), PaymentError::NonPayable {}.into()); - - let msg = ExecuteMsg::Unbond { - amount: Some(Uint128::new(420)), - }; - let res = execute(deps.as_mut(), env, info, msg); - assert_eq!(res.unwrap_err(), PaymentError::NonPayable {}.into()); -} - -#[test] -fn test_claim_with_funds() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let info = mock_info("juan", &coins(420, "uqsr")); - - let msg = ExecuteMsg::Claim {}; - let res = execute(deps.as_mut(), env, info, msg); - assert_eq!(res.unwrap_err(), PaymentError::NonPayable {}.into()); -} diff --git a/smart-contracts/contracts/basic-vault/src/types.rs b/smart-contracts/contracts/basic-vault/src/types.rs deleted file mode 100644 index 3d540d501..000000000 --- a/smart-contracts/contracts/basic-vault/src/types.rs +++ /dev/null @@ -1,11 +0,0 @@ -use cosmwasm_std::{Decimal, Uint128}; - -pub trait FromUint128 { - fn from_uint128(value: Uint128) -> Self; -} - -impl FromUint128 for Decimal { - fn from_uint128(value: Uint128) -> Self { - Decimal::from_ratio(value, 1u128) - } -} diff --git a/smart-contracts/contracts/cl-vault/.cargo/config b/smart-contracts/contracts/cl-vault/.cargo/config deleted file mode 100644 index 271587e5f..000000000 --- a/smart-contracts/contracts/cl-vault/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --bin schema" -test-tube = "test --test * --features test-tube -- --include-ignored --test-threads=1" -test-tube-build = "build --release --lib --target wasm32-unknown-unknown --target-dir ./test-tube-build" diff --git a/smart-contracts/contracts/cl-vault/src/contract.rs b/smart-contracts/contracts/cl-vault/src/contract.rs deleted file mode 100644 index 62264466a..000000000 --- a/smart-contracts/contracts/cl-vault/src/contract.rs +++ /dev/null @@ -1,643 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, BankMsg, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, -}; -use cw2::set_contract_version; -use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::ConcentratedliquidityQuerier; - -use crate::error::ContractError; -use crate::helpers::generic::sort_tokens; -use crate::helpers::getters::get_range_admin; -use crate::helpers::prepend::prepend_claim_msg; -use crate::instantiate::{ - handle_create_denom_reply, handle_instantiate, handle_instantiate_create_position_reply, -}; -use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, ModifyRangeMsg, QueryMsg}; -use crate::query::{ - query_assets_from_shares, query_dex_router, query_info, query_metadata, query_pool, - query_position, query_total_assets, query_total_vault_token_supply, query_user_assets, - query_user_balance, query_verify_tick_cache, RangeAdminResponse, -}; -use crate::reply::Replies; -#[allow(deprecated)] -use crate::state::CURRENT_BALANCE; -#[allow(deprecated)] -use crate::state::CURRENT_SWAP; -#[allow(deprecated)] -use crate::state::{ - MigrationStatus, VaultConfig, MIGRATION_STATUS, OLD_VAULT_CONFIG, STRATEGIST_REWARDS, - VAULT_CONFIG, -}; -#[allow(deprecated)] -use crate::state::{Position, OLD_POSITION, POSITION}; -use crate::vault::admin::execute_admin; -use crate::vault::any_deposit::{execute_any_deposit, handle_any_deposit_swap_reply}; -use crate::vault::autocompound::{ - execute_autocompound, execute_migration_step, handle_autocompound_reply, -}; -use crate::vault::distribution::{ - execute_collect_rewards, handle_collect_incentives_reply, handle_collect_spread_rewards_reply, -}; -use crate::vault::exact_deposit::execute_exact_deposit; -use crate::vault::merge::{ - execute_merge_position, handle_merge_create_position_reply, - handle_merge_withdraw_position_reply, -}; -use crate::vault::range::{ - execute_update_range, handle_initial_create_position_reply, - handle_iteration_create_position_reply, handle_merge_reply, handle_swap_reply, - handle_withdraw_position_reply, -}; -use crate::vault::swap::execute_swap_non_vault_funds; -use crate::vault::withdraw::{execute_withdraw, handle_withdraw_user_reply}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cl-vault"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - handle_instantiate(deps, env, info, msg) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - cw_vault_multi_standard::VaultStandardExecuteMsg::AnyDeposit { - amount: _, - asset: _, - recipient, - max_slippage, - } => execute_any_deposit(deps, env, info, recipient, max_slippage), - cw_vault_multi_standard::VaultStandardExecuteMsg::ExactDeposit { recipient } => { - execute_exact_deposit(deps, env, info, recipient) - } - cw_vault_multi_standard::VaultStandardExecuteMsg::Redeem { recipient, amount } => { - prepend_claim_msg( - &env, - execute_withdraw(deps, &env, info, recipient, amount.into())?, - ) - } - cw_vault_multi_standard::VaultStandardExecuteMsg::VaultExtension(vault_msg) => { - match vault_msg { - crate::msg::ExtensionExecuteMsg::Admin(admin_msg) => { - execute_admin(deps, info, admin_msg) - } - crate::msg::ExtensionExecuteMsg::Authz(msg) => match msg { - crate::msg::AuthzExtension::ExactDeposit {} => { - execute_exact_deposit(deps, env, info, None) - } - crate::msg::AuthzExtension::AnyDeposit { max_slippage } => { - execute_any_deposit(deps, env, info, None, max_slippage) - } - crate::msg::AuthzExtension::Redeem { amount } => prepend_claim_msg( - &env, - execute_withdraw(deps, &env, info, None, amount.into())?, - ), - }, - crate::msg::ExtensionExecuteMsg::Merge(msg) => { - execute_merge_position(deps, env, info, msg) - } - crate::msg::ExtensionExecuteMsg::Autocompound {} => { - prepend_claim_msg(&env, execute_autocompound(deps, &env, info)?) - } - crate::msg::ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { - lower_price, - upper_price, - max_slippage, - ratio_of_swappable_funds_to_use, - twap_window_seconds, - forced_swap_route, - claim_after, - }) => prepend_claim_msg( - &env, - execute_update_range( - deps, - &env, - info, - lower_price, - upper_price, - max_slippage, - ratio_of_swappable_funds_to_use, - twap_window_seconds, - forced_swap_route, - claim_after, - )?, - ), - crate::msg::ExtensionExecuteMsg::SwapNonVaultFunds { swap_operations } => { - execute_swap_non_vault_funds(deps, env, info, swap_operations) - } - crate::msg::ExtensionExecuteMsg::CollectRewards {} => { - execute_collect_rewards(deps, env) - } - crate::msg::ExtensionExecuteMsg::MigrationStep { amount_of_users } => { - execute_migration_step(deps, env, amount_of_users) - } - } - } - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { - match msg { - cw_vault_multi_standard::VaultStandardQueryMsg::VaultStandardInfo {} => todo!(), - cw_vault_multi_standard::VaultStandardQueryMsg::Info {} => { - Ok(to_json_binary(&query_info(deps)?)?) - } - cw_vault_multi_standard::VaultStandardQueryMsg::PreviewDeposit { assets: _ } => todo!(), - cw_vault_multi_standard::VaultStandardQueryMsg::DepositRatio => todo!(), - cw_vault_multi_standard::VaultStandardQueryMsg::PreviewRedeem { amount: shares } => Ok( - to_json_binary(&query_assets_from_shares(deps, env, shares)?)?, - ), - cw_vault_multi_standard::VaultStandardQueryMsg::TotalAssets {} => { - Ok(to_json_binary(&query_total_assets(deps, env)?)?) - } - cw_vault_multi_standard::VaultStandardQueryMsg::TotalVaultTokenSupply {} => { - Ok(to_json_binary(&query_total_vault_token_supply(deps)?)?) - } - cw_vault_multi_standard::VaultStandardQueryMsg::ConvertToShares { amount: _ } => todo!(), - cw_vault_multi_standard::VaultStandardQueryMsg::ConvertToAssets { amount: shares } => Ok( - to_json_binary(&query_assets_from_shares(deps, env, shares)?)?, - ), - cw_vault_multi_standard::VaultStandardQueryMsg::VaultExtension(msg) => match msg { - crate::msg::ExtensionQueryMsg::Metadata {} => { - Ok(to_json_binary(&query_metadata(deps)?)?) - } - crate::msg::ExtensionQueryMsg::DexRouter {} => { - Ok(to_json_binary(&query_dex_router(deps)?)?) - } - crate::msg::ExtensionQueryMsg::Balances(msg) => match msg { - crate::msg::UserBalanceQueryMsg::UserSharesBalance { user } => { - Ok(to_json_binary(&query_user_balance(deps, user)?)?) - } - crate::msg::UserBalanceQueryMsg::UserAssetsBalance { user } => { - Ok(to_json_binary(&query_user_assets(deps, env, user)?)?) - } - }, - crate::msg::ExtensionQueryMsg::ConcentratedLiquidity(msg) => match msg { - crate::msg::ClQueryMsg::Pool {} => Ok(to_json_binary(&query_pool(deps)?)?), - crate::msg::ClQueryMsg::Position {} => Ok(to_json_binary(&query_position(deps)?)?), - crate::msg::ClQueryMsg::RangeAdmin {} => { - let range_admin = get_range_admin(deps)?; - Ok(to_json_binary(&RangeAdminResponse { - address: range_admin.to_string(), - })?) - } - crate::msg::ClQueryMsg::VerifyTickCache => { - Ok(to_json_binary(&query_verify_tick_cache(deps)?)?) - } - }, - }, - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result { - match msg.id.into() { - Replies::InstantiateCreatePosition => { - handle_instantiate_create_position_reply(deps, env, msg.result) - } - Replies::CollectIncentives => handle_collect_incentives_reply(deps, env, msg.result), - Replies::CollectSpreadRewards => handle_collect_spread_rewards_reply(deps, env, msg.result), - Replies::WithdrawPosition => handle_withdraw_position_reply(deps, env), - Replies::RangeInitialCreatePosition => { - handle_initial_create_position_reply(deps, env, msg.result) - } - Replies::RangeIterationCreatePosition => { - handle_iteration_create_position_reply(deps, env, msg.result) - } - Replies::Swap => handle_swap_reply(deps, env, msg.result), - Replies::Merge => handle_merge_reply(deps, env, msg.result), - Replies::CreateDenom => handle_create_denom_reply(deps, msg.result), - Replies::WithdrawUser => handle_withdraw_user_reply(deps, msg.result), - Replies::WithdrawMerge => handle_merge_withdraw_position_reply(deps, env, msg.result), - Replies::CreatePositionMerge => handle_merge_create_position_reply(deps, env, msg.result), - Replies::Autocompound => handle_autocompound_reply(deps, env, msg.result), - Replies::AnyDepositSwap => handle_any_deposit_swap_reply(deps, env, msg.result), - Replies::Unknown => unimplemented!(), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { - #[allow(deprecated)] - let old_vault_config = OLD_VAULT_CONFIG.load(deps.storage)?; - let new_vault_config = VaultConfig { - performance_fee: old_vault_config.performance_fee, - treasury: old_vault_config.treasury, - swap_max_slippage: old_vault_config.swap_max_slippage, - dex_router: deps.api.addr_validate(msg.dex_router.as_str())?, - }; - - #[allow(deprecated)] - OLD_VAULT_CONFIG.remove(deps.storage); - VAULT_CONFIG.save(deps.storage, &new_vault_config)?; - - MIGRATION_STATUS.save(deps.storage, &MigrationStatus::Open)?; - - // Declare response object as mut - let mut response = Response::new().add_attribute("migrate", "successful"); - - // Conditionally add a bank send message if the strategist rewards state is not empty - #[allow(deprecated)] - let strategist_rewards = STRATEGIST_REWARDS.load(deps.storage)?; - if !strategist_rewards.is_empty() { - let bank_send_msg = BankMsg::Send { - to_address: new_vault_config.treasury.to_string(), - amount: sort_tokens(strategist_rewards.coins()), - }; - response = response.add_message(bank_send_msg); - } - // Remove the state - #[allow(deprecated)] - STRATEGIST_REWARDS.remove(deps.storage); - - //POSITION state migration - #[allow(deprecated)] - let old_position = OLD_POSITION.load(deps.storage)?; - - let cl_querier = ConcentratedliquidityQuerier::new(&deps.querier); - let pos_response = cl_querier.position_by_id(old_position.position_id)?; - - let new_position: Position = Position { - position_id: old_position.position_id, - join_time: pos_response - .position - .unwrap() - .position - .unwrap() - .join_time - .unwrap() - .seconds - .unsigned_abs(), - claim_after: None, - }; - - POSITION.save(deps.storage, &new_position)?; - #[allow(deprecated)] - OLD_POSITION.remove(deps.storage); - #[allow(deprecated)] - CURRENT_BALANCE.remove(deps.storage); - #[allow(deprecated)] - CURRENT_SWAP.remove(deps.storage); - - Ok(response) -} - -#[cfg(test)] -mod tests { - use super::*; - #[allow(deprecated)] - use crate::state::USER_REWARDS; - #[allow(deprecated)] - use crate::{ - helpers::coinlist::CoinList, - state::{OldPosition, OldVaultConfig, Position, OLD_POSITION, POSITION}, - }; - use cosmwasm_std::{ - coin, - testing::{mock_dependencies, mock_env}, - Addr, Coin, CosmosMsg, Decimal, SubMsg, Uint128, - }; - use osmosis_std::{cosmwasm_to_proto_coins, types::cosmos::bank::v1beta1::MsgMultiSend}; - use prost::Message; - use std::str::FromStr; - - const DENOM_BASE: &str = "uatom"; - const DENOM_QUOTE: &str = "ubtc"; - const DENOM_REWARD: &str = "ustrd"; - const MAX_SLIPPAGE_HIGH: u64 = 9000; - - pub fn mock_migrate( - deps: DepsMut, - _env: Env, - msg: MigrateMsg, - ) -> Result { - #[allow(deprecated)] - let old_vault_config = OLD_VAULT_CONFIG.load(deps.storage)?; - let new_vault_config = VaultConfig { - performance_fee: old_vault_config.performance_fee, - treasury: old_vault_config.treasury, - swap_max_slippage: old_vault_config.swap_max_slippage, - dex_router: deps.api.addr_validate(msg.dex_router.as_str())?, - }; - - #[allow(deprecated)] - OLD_VAULT_CONFIG.remove(deps.storage); - VAULT_CONFIG.save(deps.storage, &new_vault_config)?; - - MIGRATION_STATUS.save(deps.storage, &MigrationStatus::Open)?; - - // Declare response object as mut - let mut response = Response::new().add_attribute("migrate", "successful"); - - // Conditionally add a bank send message if the strategist rewards state is not empty - #[allow(deprecated)] - let strategist_rewards = STRATEGIST_REWARDS.load(deps.storage)?; - if !strategist_rewards.is_empty() { - let bank_send_msg = BankMsg::Send { - to_address: new_vault_config.treasury.to_string(), - amount: sort_tokens(strategist_rewards.coins()), - }; - response = response.add_message(bank_send_msg); - } - // Remove the state - #[allow(deprecated)] - STRATEGIST_REWARDS.remove(deps.storage); - #[allow(deprecated)] - let old_position = OLD_POSITION.load(deps.storage)?; - - let new_position: Position = Position { - position_id: old_position.position_id, - join_time: 0, - claim_after: None, - }; - - POSITION.save(deps.storage, &new_position)?; - - #[allow(deprecated)] - OLD_POSITION.remove(deps.storage); - #[allow(deprecated)] - CURRENT_BALANCE.remove(deps.storage); - #[allow(deprecated)] - CURRENT_SWAP.remove(deps.storage); - - Ok(response) - } - - #[test] - fn test_migrate_position_state() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let new_dex_router = Addr::unchecked("dex_router"); // new field nested in existing VaultConfig state - - // Mock a previous state item - #[allow(deprecated)] - OLD_POSITION - .save(deps.as_mut().storage, &OldPosition { position_id: 1 }) - .unwrap(); - #[allow(deprecated)] - OLD_VAULT_CONFIG - .save( - deps.as_mut().storage, - &OldVaultConfig { - performance_fee: Decimal::from_str("0.2").unwrap(), - treasury: Addr::unchecked("treasury"), - swap_max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - }, - ) - .unwrap(); - #[allow(deprecated)] - STRATEGIST_REWARDS - .save(&mut deps.storage, &CoinList::new()) - .unwrap(); - - mock_migrate( - deps.as_mut(), - env, - MigrateMsg { - dex_router: new_dex_router, - }, - ) - .unwrap(); - - let position = POSITION.load(deps.as_mut().storage).unwrap(); - - assert_eq!(position.position_id, 1); - assert_eq!(position.join_time, 0); - assert!(position.claim_after.is_none()); - - #[allow(deprecated)] - let old_position = OLD_POSITION.may_load(deps.as_mut().storage).unwrap(); - assert!(old_position.is_none()); - - #[allow(deprecated)] - let current_balance = CURRENT_BALANCE.may_load(deps.as_mut().storage).unwrap(); - assert!(current_balance.is_none()); - - #[allow(deprecated)] - let current_swap = CURRENT_SWAP.may_load(deps.as_mut().storage).unwrap(); - assert!(current_swap.is_none()); - } - - #[test] - fn test_migrate_no_rewards() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - // Declare new items for states - let new_dex_router = Addr::unchecked("dex_router"); // new field nested in existing VaultConfig state - - // Mock a previous state item - #[allow(deprecated)] - OLD_POSITION - .save(deps.as_mut().storage, &OldPosition { position_id: 1 }) - .unwrap(); - #[allow(deprecated)] - OLD_VAULT_CONFIG - .save( - deps.as_mut().storage, - &OldVaultConfig { - performance_fee: Decimal::from_str("0.2").unwrap(), - treasury: Addr::unchecked("treasury"), - swap_max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - }, - ) - .unwrap(); - #[allow(deprecated)] - STRATEGIST_REWARDS - .save(&mut deps.storage, &CoinList::new()) - .unwrap(); - - mock_migrate( - deps.as_mut(), - env.clone(), - MigrateMsg { - dex_router: new_dex_router.clone(), - }, - ) - .unwrap(); - - // Assert OLD_VAULT_CONFIG have been correctly removed by unwrapping the error - #[allow(deprecated)] - OLD_VAULT_CONFIG.load(deps.as_mut().storage).unwrap_err(); - - // Assert new VAULT_CONFIG.dex_router field have correct value - let vault_config = VAULT_CONFIG.load(deps.as_mut().storage).unwrap(); - assert_eq!(vault_config.dex_router, new_dex_router); - - // Assert new MIGRATION_STATUS state have correct value - let migration_status = MIGRATION_STATUS.load(deps.as_mut().storage).unwrap(); - assert_eq!(migration_status, MigrationStatus::Open); - - // Assert STRATEGIST_REWARDS state have been correctly removed by unwrapping the error - #[allow(deprecated)] - STRATEGIST_REWARDS.load(deps.as_mut().storage).unwrap_err(); - - // Execute one migration step and assert the correct behavior - execute_migration_step(deps.as_mut(), env, Uint128::one()).unwrap(); - - // Assert new MIGRATION_STATUS state have correct value - let migration_status = MIGRATION_STATUS.load(deps.as_mut().storage).unwrap(); - assert_eq!(migration_status, MigrationStatus::Closed); - } - - #[test] - fn test_migrate_with_rewards_execute_steps() { - let env = mock_env(); - let mut deps = mock_dependencies(); - - // Declare new items for states - let new_dex_router = Addr::unchecked("dex_router"); // new field nested in existing VaultConfig state - - // Mock a previous state item - #[allow(deprecated)] - OLD_VAULT_CONFIG - .save( - deps.as_mut().storage, - &OldVaultConfig { - performance_fee: Decimal::from_str("0.2").unwrap(), - treasury: Addr::unchecked("treasury"), - swap_max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - }, - ) - .unwrap(); - - #[allow(deprecated)] - OLD_POSITION - .save(deps.as_mut().storage, &OldPosition { position_id: 1 }) - .unwrap(); - - // Mock USER_REWARDS in order to have something to iterate over - let rewards_coins = vec![ - coin(1000u128, DENOM_BASE), - coin(1000u128, DENOM_QUOTE), - coin(1000u128, DENOM_REWARD), - ]; - for i in 0..10 { - #[allow(deprecated)] - USER_REWARDS - .save( - deps.as_mut().storage, - Addr::unchecked(format!("user{}", i)), - &CoinList::from_coins(rewards_coins.clone()), - ) - .unwrap(); - } - // Mock STRATEGIST_REWARDS in order to have something to distribute - #[allow(deprecated)] - STRATEGIST_REWARDS - .save( - deps.as_mut().storage, - &CoinList::from_coins(rewards_coins.clone()), - ) - .unwrap(); - - let migrate_resp = mock_migrate( - deps.as_mut(), - env.clone(), - MigrateMsg { - dex_router: new_dex_router.clone(), - }, - ) - .unwrap(); - - if let Some(SubMsg { - msg: CosmosMsg::Bank(BankMsg::Send { to_address, amount }), - .. - }) = migrate_resp.messages.get(0) - { - assert_eq!(to_address, "treasury"); - assert_eq!(amount, &rewards_coins); - } else { - panic!("Expected BankMsg::Send message in the response"); - } - - // Assert USER_REWARDS state have been correctly removed by unwrapping the error - #[allow(deprecated)] - STRATEGIST_REWARDS.load(deps.as_mut().storage).unwrap_err(); - - // Assert OLD_VAULT_CONFIG have been correctly removed by unwrapping the error - #[allow(deprecated)] - OLD_VAULT_CONFIG.load(deps.as_mut().storage).unwrap_err(); - - // Assert new VAULT_CONFIG.dex_router field have correct value - let vault_config = VAULT_CONFIG.load(deps.as_mut().storage).unwrap(); - assert_eq!(vault_config.dex_router, new_dex_router); - - // Assert new MIGRATION_STATUS state have correct value - let migration_status = MIGRATION_STATUS.load(deps.as_mut().storage).unwrap(); - assert_eq!(migration_status, MigrationStatus::Open); - - // Execute 9 migration steps paginating by 2 users_amount. - // leaving the last user to close the migration in the last step - for i in 0..9 { - let migration_step = - execute_migration_step(deps.as_mut(), env.clone(), Uint128::one()).unwrap(); - - assert_multi_send( - &migration_step.messages[0].msg, - &format!("user{}", i), - &rewards_coins, - ); - - // Assert new MIGRATION_STATUS state have correct value - let migration_status = MIGRATION_STATUS.load(deps.as_mut().storage).unwrap(); - assert_eq!(migration_status, MigrationStatus::Open); - } - - // Execute the last migration step - let migration_step = - execute_migration_step(deps.as_mut(), env.clone(), Uint128::one()).unwrap(); - assert_multi_send( - &migration_step.messages[0].msg, - &"user9".to_string(), - &rewards_coins, - ); - - // Assert new MIGRATION_STATUS state have correct value - let migration_status = MIGRATION_STATUS.load(deps.as_mut().storage).unwrap(); - assert_eq!(migration_status, MigrationStatus::Closed); - - // Assert USER_REWARDS state have been correctly removed by unwrapping the error - for i in 0..10 { - #[allow(deprecated)] - USER_REWARDS - .load(deps.as_mut().storage, Addr::unchecked(format!("user{}", i))) - .unwrap_err(); - } - } - - fn assert_multi_send(msg: &CosmosMsg, expected_user: &String, user_rewards_coins: &Vec) { - if let CosmosMsg::Stargate { type_url, value } = msg { - // Decode and validate the MsgMultiSend message - // This has been decoded manually rather than encoding the expected message because its simpler to assert the values - assert_eq!(type_url, "/cosmos.bank.v1beta1.MsgMultiSend"); - let msg: MsgMultiSend = - MsgMultiSend::decode(value.as_slice()).expect("Failed to decode MsgMultiSend"); - for output in msg.outputs { - assert_eq!(&output.address, expected_user); - assert_eq!( - output.coins, - cosmwasm_to_proto_coins(user_rewards_coins.iter().cloned()) - ); - } - } else { - panic!("Expected Stargate message type, found another."); - } - } -} diff --git a/smart-contracts/contracts/cl-vault/src/helpers/assert.rs b/smart-contracts/contracts/cl-vault/src/helpers/assert.rs deleted file mode 100644 index f5c92932a..000000000 --- a/smart-contracts/contracts/cl-vault/src/helpers/assert.rs +++ /dev/null @@ -1,142 +0,0 @@ -use cosmwasm_std::{coin, Addr, Coin, Deps, MessageInfo, Storage}; - -use crate::{ - state::{ADMIN_ADDRESS, RANGE_ADMIN}, - ContractError, -}; - -/// This function compares the address of the message sender (caller) with the current admin -/// address stored in the state. This provides a convenient way to verify if the caller -/// is the admin in a single line. -pub fn assert_admin(deps: Deps, caller: &Addr) -> Result { - if ADMIN_ADDRESS.load(deps.storage)? != caller { - Err(ContractError::Unauthorized {}) - } else { - Ok(caller.clone()) - } -} - -pub fn assert_range_admin(storage: &mut dyn Storage, sender: &Addr) -> Result<(), ContractError> { - let admin = RANGE_ADMIN.load(storage)?; - if admin != sender { - return Err(ContractError::Unauthorized {}); - } - Ok(()) -} - -/// Returns the Coin of the needed denoms in the order given in denoms -pub(crate) fn must_pay_one_or_two( - info: &MessageInfo, - denoms: (String, String), -) -> Result<(Coin, Coin), ContractError> { - if info.funds.len() != 2 && info.funds.len() != 1 { - return Err(ContractError::IncorrectAmountFunds); - } - - let token0 = info - .funds - .clone() - .into_iter() - .find(|coin| coin.denom == denoms.0) - .unwrap_or(coin(0, denoms.0)); - - let token1 = info - .funds - .clone() - .into_iter() - .find(|coin| coin.denom == denoms.1) - .unwrap_or(coin(0, denoms.1)); - - Ok((token0, token1)) -} - -pub(crate) fn must_pay_one_or_two_from_balance( - funds: Vec, - denoms: (String, String), -) -> Result<(Coin, Coin), ContractError> { - if funds.len() < 2 { - return Err(ContractError::IncorrectAmountFunds); - } - - let token0 = funds - .clone() - .into_iter() - .find(|coin| coin.denom == denoms.0) - .unwrap_or(coin(0, denoms.0)); - - let token1 = funds - .clone() - .into_iter() - .find(|coin| coin.denom == denoms.1) - .unwrap_or(coin(0, denoms.1)); - - Ok((token0, token1)) -} - -#[cfg(test)] -mod tests { - - use cosmwasm_std::{coin, Addr}; - - use super::*; - - #[test] - fn must_pay_one_or_two_works_ordered() { - let expected0 = coin(100, "uatom"); - let expected1 = coin(200, "uosmo"); - let info = MessageInfo { - sender: Addr::unchecked("sender"), - funds: vec![expected0.clone(), expected1.clone()], - }; - let (token0, token1) = - must_pay_one_or_two(&info, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!(expected0, token0); - assert_eq!(expected1, token1); - } - - #[test] - fn must_pay_one_or_two_works_unordered() { - let expected0 = coin(100, "uatom"); - let expected1 = coin(200, "uosmo"); - let info = MessageInfo { - sender: Addr::unchecked("sender"), - funds: vec![expected1.clone(), expected0.clone()], - }; - let (token0, token1) = - must_pay_one_or_two(&info, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!(expected0, token0); - assert_eq!(expected1, token1); - } - - #[test] - fn must_pay_one_or_two_rejects_three() { - let expected0 = coin(100, "uatom"); - let expected1 = coin(200, "uosmo"); - let info = MessageInfo { - sender: Addr::unchecked("sender"), - funds: vec![expected1, expected0, coin(200, "uqsr")], - }; - let _err = - must_pay_one_or_two(&info, ("uatom".to_string(), "uosmo".to_string())).unwrap_err(); - } - - #[test] - fn must_pay_one_or_two_accepts_second_token() { - let info = MessageInfo { - sender: Addr::unchecked("sender"), - funds: vec![coin(200, "uosmo")], - }; - let res = must_pay_one_or_two(&info, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!((coin(0, "uatom"), coin(200, "uosmo")), res) - } - - #[test] - fn must_pay_one_or_two_accepts_first_token() { - let info = MessageInfo { - sender: Addr::unchecked("sender"), - funds: vec![coin(200, "uatom")], - }; - let res = must_pay_one_or_two(&info, ("uatom".to_string(), "uosmo".to_string())).unwrap(); - assert_eq!((coin(200, "uatom"), coin(0, "uosmo")), res) - } -} diff --git a/smart-contracts/contracts/cl-vault/src/helpers/msgs.rs b/smart-contracts/contracts/cl-vault/src/helpers/msgs.rs deleted file mode 100644 index 5e3484a97..000000000 --- a/smart-contracts/contracts/cl-vault/src/helpers/msgs.rs +++ /dev/null @@ -1,156 +0,0 @@ -use cosmwasm_std::{ - attr, to_json_binary, Addr, Attribute, BankMsg, Coin, CosmosMsg, Deps, DepsMut, Env, Uint128, - WasmMsg, -}; -use dex_router_osmosis::msg::ExecuteMsg as DexRouterExecuteMsg; -use osmosis_std::types::{ - cosmos::base::v1beta1::Coin as OsmoCoin, - osmosis::{ - concentratedliquidity::v1beta1::{MsgCollectIncentives, MsgCollectSpreadRewards}, - poolmanager::v1beta1::SwapAmountInRoute, - }, -}; - -use crate::{ - state::{DEX_ROUTER, POSITION}, - vault::swap::SwapParams, - ContractError, -}; - -// Bank - -/// Generate a bank message and attributes for refunding tokens to a recipient. -pub fn refund_bank_msg( - receiver: Addr, - refund0: Option, - refund1: Option, -) -> Result)>, ContractError> { - let mut attributes: Vec = vec![]; - let mut coins: Vec = vec![]; - - if let Some(refund0) = refund0 { - if refund0.amount > Uint128::zero() { - attributes.push(attr("refund0", refund0.amount)); - coins.push(refund0) - } - } - if let Some(refund1) = refund1 { - if refund1.amount > Uint128::zero() { - attributes.push(attr("refund1", refund1.amount)); - coins.push(refund1) - } - } - let result: Option<(BankMsg, Vec)> = if !coins.is_empty() { - Some(( - BankMsg::Send { - to_address: receiver.to_string(), - amount: coins, - }, - attributes, - )) - } else { - None - }; - Ok(result) -} - -/// Swaps - -/// swap will always swap over the CL pool. In the future we may expand the -/// feature such that it chooses best swaps over all routes -pub fn swap_msg(deps: &DepsMut, env: &Env, params: SwapParams) -> Result { - // let pool_config = POOL_CONFIG.load(deps.storage)?; - let dex_router = DEX_ROUTER.may_load(deps.storage)?; - - // we will only ever have a route length of one, this will likely change once we start selecting different routes - let pool_route = SwapAmountInRoute { - pool_id: params.pool_id, - token_out_denom: params.token_out_denom.to_string(), - }; - - // if we don't have a dex_router, we will always swap over the osmosis pool - if dex_router.is_none() { - return Ok(osmosis_swap_exact_amount_in_msg( - env, - pool_route, - params.token_in_amount, - ¶ms.token_in_denom.to_string(), - params.token_out_min_amount, - )); - } - - // we know we have a dex_router, so we can unwrap it and execute the swap - cw_dex_execute_swap_operations_msg( - dex_router.clone().unwrap(), - params.forced_swap_route, - params.token_in_denom.to_string(), - params.token_in_amount, - params.token_out_denom.to_string(), - params.token_out_min_amount, - ) -} - -fn osmosis_swap_exact_amount_in_msg( - env: &Env, - pool_route: SwapAmountInRoute, - token_in_amount: Uint128, - token_in_denom: &String, - token_out_min_amount: Uint128, -) -> CosmosMsg { - osmosis_std::types::osmosis::poolmanager::v1beta1::MsgSwapExactAmountIn { - sender: env.contract.address.to_string(), - routes: vec![pool_route], - token_in: Some(OsmoCoin { - denom: token_in_denom.to_string(), - amount: token_in_amount.to_string(), - }), - token_out_min_amount: token_out_min_amount.to_string(), - } - .into() -} - -fn cw_dex_execute_swap_operations_msg( - dex_router_address: Addr, - path: Option>, - token_in_denom: String, - token_in_amount: Uint128, - token_out_denom: String, - token_out_min_amount: Uint128, -) -> Result { - let swap_msg: CosmosMsg = WasmMsg::Execute { - contract_addr: dex_router_address.to_string(), - msg: to_json_binary(&DexRouterExecuteMsg::Swap { - path, - out_denom: token_out_denom, - minimum_receive: Some(token_out_min_amount), - })?, - funds: vec![Coin { - denom: token_in_denom, - amount: token_in_amount, - }], - } - .into(); - - Ok(swap_msg) -} - -/// Collect Incentives - -pub fn collect_incentives_msg(deps: Deps, env: Env) -> Result { - let position = POSITION.load(deps.storage)?; - Ok(MsgCollectIncentives { - position_ids: vec![position.position_id], - sender: env.contract.address.into(), - }) -} - -pub fn collect_spread_rewards_msg( - deps: Deps, - env: Env, -) -> Result { - let position = POSITION.load(deps.storage)?; - Ok(MsgCollectSpreadRewards { - position_ids: vec![position.position_id], - sender: env.contract.address.into(), - }) -} diff --git a/smart-contracts/contracts/cl-vault/src/math/liquidity.rs b/smart-contracts/contracts/cl-vault/src/math/liquidity.rs deleted file mode 100644 index c7010eb2a..000000000 --- a/smart-contracts/contracts/cl-vault/src/math/liquidity.rs +++ /dev/null @@ -1,126 +0,0 @@ -use crate::ContractError; -use cosmwasm_std::{Decimal, Decimal256, OverflowError, StdError, Uint256, Uint512}; - -/// liquidity0 calculates the amount of liquitiy gained from adding an amount of token0 to a position -pub fn _liquidity0( - amount: Decimal, - sqrt_price_a: Decimal, - sqrt_price_b: Decimal, -) -> Result { - let mut sqrt_price_a: Uint512 = sqrt_price_a.atomics().into(); - let mut sqrt_price_b: Uint512 = sqrt_price_b.atomics().into(); - let amount: Uint512 = amount.atomics().into(); - - if sqrt_price_a > sqrt_price_b { - std::mem::swap(&mut sqrt_price_a, &mut sqrt_price_b); - } - - let product = sqrt_price_a.checked_mul(sqrt_price_b)?; - // let product = Uint256::from(sqrt_price_a.atomics().u128()).checked_mul(Uint256::from(sqrt_price_b.atomics().u128()))?; - let diff = sqrt_price_b.checked_sub(sqrt_price_a)?; - - if diff.is_zero() { - return Err(ContractError::Std(StdError::generic_err( - "liquidity0 diff is zero", - ))); - } - - // during this check mul, the result is being truncated and giving is a different final result than expected - let result = amount.checked_mul(product)?.checked_div(diff)?; - // convert the Uint512 back to a decimal, we want to place the decimal at decimal_place 36 - // to do this, we truncate the first 18 digits, and then call Decimal::new - // Should we check here that the leftover bytes are zero? that is technically an overflow - let result_bytes: [u8; 64] = result.to_le_bytes(); - for b in result_bytes[32..64].iter() { - if *b != 0_u8 { - return Err(ContractError::OverflowError(OverflowError { - operation: cosmwasm_std::OverflowOperation::Mul, // this is just a mock - operand1: result.to_string(), - operand2: "Conversion to Decimal".to_string(), // this too as we have no operand2 on this conversion step - })); - } - } - - let intermediate = Uint256::from_le_bytes(result_bytes[..32].try_into().unwrap()); - // we use Decimal256 to - let intermediate_2 = Decimal256::from_atomics(intermediate, 36)?; - - // since we start with Decimal and multiply with big_factor, we expect to be able to convert back here - Ok(Decimal::new(intermediate_2.atomics().try_into()?)) -} - -// TODO figure out if liquidity1 need to be Uint512's aswell, currently I (Laurens) don't believe so since we should only need more precision if we multiply decimals -/// liquidity1 calculates the amount of liquitiy gained from adding an amount of token1 to a position -pub fn _liquidity1( - amount: Decimal, - sqrt_price_a: Decimal, - sqrt_price_b: Decimal, -) -> Result { - let mut sqrt_price_a = sqrt_price_a; - let mut sqrt_price_b = sqrt_price_b; - - if sqrt_price_a > sqrt_price_b { - std::mem::swap(&mut sqrt_price_a, &mut sqrt_price_b); - } - - let diff = sqrt_price_b - .checked_sub(sqrt_price_a) - .map_err(|err| StdError::generic_err(err.to_string()))?; - if diff.is_zero() { - return Err(ContractError::Std(StdError::generic_err( - "liquidity1 diff is zero", - ))); - } - - let result = amount.checked_div(diff)?; - Ok(result) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_liquidity0() { - // from the osmosis math tests - // current_sqrt_p: sqrt5000BigDec, // 5000 - // sqrtPHigh: sqrt5500BigDec, // 5500 - // amount0Desired: sdk.NewInt(1000000), - // expectedLiquidity: "1519437308.014768571720923239", - let amount0_desired: Decimal = Decimal::from_ratio(1000000_u128, 1_u128); - let current_sqrt_p = Decimal::from_atomics(70710678118654752440_u128, 18).unwrap(); - let sqrt_p_high = Decimal::from_atomics(74161984870956629487_u128, 18).unwrap(); - - let result = _liquidity0(amount0_desired, current_sqrt_p, sqrt_p_high).unwrap(); - // TODO our amount is slightly different 10 digits behind the comma, do we care about that? - assert_eq!(result.to_string(), "1519437308.014768571720923239") - } - - #[test] - fn test_liquidity1() { - let amount1_desired = Decimal::from_atomics(5000000000_u128, 0).unwrap(); - let current_sqrt_p = Decimal::from_atomics(70710678118654752440_u128, 18).unwrap(); - let sqrt_p_low = Decimal::from_atomics(67416615162732695594_u128, 18).unwrap(); - - let result = _liquidity1(amount1_desired, current_sqrt_p, sqrt_p_low).unwrap(); - assert_eq!(result.to_string(), "1517882343.751510418088349649"); - } - - #[test] - fn test_max_liquidity0() { - let max_sqrt_price = Decimal::raw(10000000000000000000000000000000000000_u128); - let max_sqrt_price_low = Decimal::raw(300000000000000000000000000000000_u128); - let amount0_desired: Decimal = Decimal::from_ratio(1000000_u128, 1_u128); - // we only care about overflows here - let _ = _liquidity0(amount0_desired, max_sqrt_price, max_sqrt_price_low).unwrap(); - } - - #[test] - fn test_max_liquidity1() { - let max_sqrt_price = Decimal::raw(10000000000000000000000000000000000000_u128); - let max_sqrt_price_low = Decimal::raw(1000000000000000000000000000000000000_u128); - let amount0_desired: Decimal = Decimal::from_ratio(1000000_u128, 1_u128); - // we only care about overflows here - let _ = _liquidity1(amount0_desired, max_sqrt_price, max_sqrt_price_low).unwrap(); - } -} diff --git a/smart-contracts/contracts/cl-vault/src/math/mod.rs b/smart-contracts/contracts/cl-vault/src/math/mod.rs deleted file mode 100644 index b9284683b..000000000 --- a/smart-contracts/contracts/cl-vault/src/math/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod liquidity; -pub mod tick; diff --git a/smart-contracts/contracts/cl-vault/src/vault/any_deposit.rs b/smart-contracts/contracts/cl-vault/src/vault/any_deposit.rs deleted file mode 100644 index 5ec61379d..000000000 --- a/smart-contracts/contracts/cl-vault/src/vault/any_deposit.rs +++ /dev/null @@ -1,354 +0,0 @@ -use cosmwasm_std::{ - attr, coin, Addr, Coin, Decimal, DepsMut, Env, Fraction, MessageInfo, Response, SubMsg, - SubMsgResult, Uint128, Uint256, -}; -use osmosis_std::types::osmosis::poolmanager::v1beta1::MsgSwapExactAmountInResponse; -use osmosis_std::types::osmosis::tokenfactory::v1beta1::MsgMint; - -use crate::helpers::assert::must_pay_one_or_two; -use crate::helpers::getters::{ - get_asset0_value, get_depositable_tokens, get_single_sided_deposit_0_to_1_swap_amount, - get_single_sided_deposit_1_to_0_swap_amount, get_twap_price, -}; -use crate::helpers::msgs::swap_msg; -use crate::query::query_total_vault_token_supply; -use crate::reply::Replies; -use crate::state::{PoolConfig, CURRENT_SWAP_ANY_DEPOSIT}; -use crate::vault::concentrated_liquidity::get_cl_pool_info; -use crate::vault::range::SwapDirection; -use crate::vault::swap::SwapParams; -use crate::{ - query::query_total_assets, - state::{POOL_CONFIG, SHARES, VAULT_DENOM}, - vault::concentrated_liquidity::get_position, - ContractError, -}; - -use super::swap::SwapCalculationResult; - -pub fn execute_any_deposit( - mut deps: DepsMut, - env: Env, - info: MessageInfo, - recipient: Option, - max_slippage: Decimal, -) -> Result { - // Unwrap recipient or use caller's address - let recipient = recipient.map_or(Ok(info.sender.clone()), |x| deps.api.addr_validate(&x))?; - - let pool_config = POOL_CONFIG.load(deps.storage)?; - let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; - let position = get_position(deps.storage, &deps.querier)? - .position - .ok_or(ContractError::MissingPosition {})?; - - let (token0, token1) = must_pay_one_or_two( - &info, - (pool_config.token0.clone(), pool_config.token1.clone()), - )?; - - // get the amount of funds we can deposit from this ratio - let (deposit_amount_in_ratio, swappable_amount): ((Uint128, Uint128), (Uint128, Uint128)) = - get_depositable_tokens(deps.branch(), token0.clone(), token1.clone())?; - - // Swap logic - // TODO_FUTURE: Optimize this if conditions - if !swappable_amount.0.is_zero() { - let (swap_amount, swap_direction) = ( - // range is above current tick - if pool_details.current_tick > position.upper_tick { - swappable_amount.0 - } else { - get_single_sided_deposit_0_to_1_swap_amount( - swappable_amount.0, - position.lower_tick, - pool_details.current_tick, - position.upper_tick, - )? - }, - SwapDirection::ZeroToOne, - ); - let swap_calc_result = calculate_swap_amount( - deps, - &env, - pool_config, - swap_direction, - swap_amount, - swappable_amount, - deposit_amount_in_ratio, - max_slippage, - &recipient, - )?; - - // rest minting logic remains same - Ok(Response::new() - .add_submessage(SubMsg::reply_on_success( - swap_calc_result.swap_msg, - Replies::AnyDepositSwap.into(), - )) - .add_attributes(vec![ - attr("method", "execute"), - attr("action", "any_deposit"), - attr( - "token_in", - format!("{}{}", swap_amount, swap_calc_result.token_in_denom), - ), - attr( - "token_out_min", - format!("{}", swap_calc_result.token_out_min_amount), - ), - ])) - } else if !swappable_amount.1.is_zero() { - let (swap_amount, swap_direction) = ( - // current tick is above range - if pool_details.current_tick < position.lower_tick { - swappable_amount.1 - } else { - get_single_sided_deposit_1_to_0_swap_amount( - swappable_amount.1, - position.lower_tick, - pool_details.current_tick, - position.upper_tick, - )? - }, - SwapDirection::OneToZero, - ); - let swap_calc_result = calculate_swap_amount( - deps, - &env, - pool_config, - swap_direction, - swap_amount, - swappable_amount, - deposit_amount_in_ratio, - max_slippage, - &recipient, - )?; - - // rest minting logic remains same - Ok(Response::new() - .add_submessage(SubMsg::reply_on_success( - swap_calc_result.swap_msg, - Replies::AnyDepositSwap.into(), - )) - .add_attributes(vec![ - attr("method", "execute"), - attr("action", "any_deposit"), - attr( - "token_in", - format!("{}{}", swap_amount, swap_calc_result.token_in_denom), - ), - attr( - "token_out_min", - format!("{}", swap_calc_result.token_out_min_amount), - ), - ])) - } else { - let (mint_msg, user_shares) = - mint_msg_user_shares(deps, &env, &deposit_amount_in_ratio, &recipient)?; - - Ok(Response::new() - .add_attribute("method", "execute") - .add_attribute("action", "any_deposit") - .add_attribute("amount0", deposit_amount_in_ratio.0) - .add_attribute("amount1", deposit_amount_in_ratio.1) - .add_message(mint_msg) - .add_attribute("mint_shares_amount", user_shares) - .add_attribute("receiver", recipient.as_str())) - } -} - -pub fn handle_any_deposit_swap_reply( - mut deps: DepsMut, - env: Env, - data: SubMsgResult, -) -> Result { - // Attempt to directly parse the data to MsgSwapExactAmountInResponse outside of the match - let resp: MsgSwapExactAmountInResponse = data.try_into()?; - - let (swap_direction, left_over_amount, recipient, deposit_amount_in_ratio) = - CURRENT_SWAP_ANY_DEPOSIT.load(deps.storage)?; - - let pool_config = POOL_CONFIG.load(deps.storage)?; - - // get post swap balances to create positions with - let (balance0, balance1): (Uint128, Uint128) = match swap_direction { - SwapDirection::ZeroToOne => ( - left_over_amount, - Uint128::new(resp.token_out_amount.parse()?), - ), - SwapDirection::OneToZero => ( - Uint128::new(resp.token_out_amount.parse()?), - left_over_amount, - ), - }; - - // Create the tuple for minting coins - let coins_to_mint_for = ( - Coin { - denom: pool_config.token0.clone(), - amount: balance0 + deposit_amount_in_ratio.0, - }, - Coin { - denom: pool_config.token1.clone(), - amount: balance1 + deposit_amount_in_ratio.1, - }, - ); - - let (mint_msg, user_shares) = mint_msg_user_shares( - deps.branch(), - &env, - &(coins_to_mint_for.0.amount, coins_to_mint_for.1.amount), - &recipient, - )?; - - CURRENT_SWAP_ANY_DEPOSIT.remove(deps.storage); - - Ok(Response::new() - .add_attribute("method", "reply") - .add_attribute("action", "handle_any_deposit_swap") - .add_attribute("amount0", balance0) - .add_attribute("amount1", balance1) - .add_message(mint_msg) - .add_attribute("mint_shares_amount", user_shares) - .add_attribute("receiver", recipient.as_str())) -} - -fn mint_msg_user_shares( - deps: DepsMut, - env: &Env, - deposit_amount_in_ratio: &(Uint128, Uint128), - recipient: &Addr, -) -> Result<(MsgMint, Uint128), ContractError> { - // calculate the amount of shares we can mint for this - let total_assets = query_total_assets(deps.as_ref(), env.clone())?; - let total_assets_value = get_asset0_value( - deps.storage, - &deps.querier, - total_assets.token0.amount, - total_assets.token1.amount, - )?; - - let vault_denom = VAULT_DENOM.load(deps.storage)?; - let total_vault_shares: Uint256 = query_total_vault_token_supply(deps.as_ref())?.total.into(); - - let user_value = get_asset0_value( - deps.storage, - &deps.querier, - deposit_amount_in_ratio.0, - deposit_amount_in_ratio.1, - )?; - - // total_vault_shares.is_zero() should never be zero. This should ideally always enter the else and we are just sanity checking. - let user_shares: Uint128 = if total_vault_shares.is_zero() { - user_value - } else { - total_vault_shares - .checked_mul(user_value.into())? - .checked_div(total_assets_value.into())? - .try_into()? - }; - - // save the shares in the user map - SHARES.update( - deps.storage, - recipient.clone(), - |old| -> Result { - if let Some(existing_user_shares) = old { - Ok(user_shares + existing_user_shares) - } else { - Ok(user_shares) - } - }, - )?; - - // TODO the locking of minted shares is a band-aid for giving out rewards to users, - // once tokenfactory has send hooks, we can remove the lockup and have the users - // own the shares in their balance - // we mint shares to the contract address here, so we can lock those shares for the user later in the same call - // this is blocked by Osmosis v17 update - let mint_msg = MsgMint { - sender: env.clone().contract.address.to_string(), - amount: Some(coin(user_shares.into(), vault_denom).into()), - mint_to_address: env.clone().contract.address.to_string(), - }; - - Ok((mint_msg, user_shares)) -} - -#[allow(clippy::too_many_arguments)] -fn calculate_swap_amount( - deps: DepsMut, - env: &Env, - pool_config: PoolConfig, - swap_direction: SwapDirection, - token_in_amount: Uint128, - swappable_amount: (Uint128, Uint128), - deposit_amount_in_ratio: (Uint128, Uint128), - max_slippage: Decimal, - recipient: &Addr, -) -> Result { - // TODO check that this math is right with spot price (numerators, denominators) if taken by legacy gamm module instead of poolmanager - // TODO check on the twap_window_seconds (taking hardcoded value for now) - let twap_price = get_twap_price(deps.storage, &deps.querier, env, 24u64)?; - let (token_in_denom, token_out_denom, token_out_ideal_amount, left_over_amount) = - match swap_direction { - SwapDirection::ZeroToOne => ( - &pool_config.token0, - &pool_config.token1, - token_in_amount - .checked_multiply_ratio(twap_price.numerator(), twap_price.denominator()), - swappable_amount.0.checked_sub(token_in_amount)?, - ), - SwapDirection::OneToZero => ( - &pool_config.token1, - &pool_config.token0, - token_in_amount - .checked_multiply_ratio(twap_price.denominator(), twap_price.numerator()), - swappable_amount.1.checked_sub(token_in_amount)?, - ), - }; - - CURRENT_SWAP_ANY_DEPOSIT.save( - deps.storage, - &( - swap_direction, - left_over_amount, - recipient.clone(), - deposit_amount_in_ratio, - ), - )?; - - let token_out_min_amount = token_out_ideal_amount? - .checked_multiply_ratio(max_slippage.numerator(), max_slippage.denominator())?; - - if !pool_config.pool_contains_token(token_in_denom) { - return Err(ContractError::BadTokenForSwap { - base_token: pool_config.token0, - quote_token: pool_config.token1, - }); - } - - // generate a swap message with recommended path as the current - // pool on which the vault is running - let swap_msg = swap_msg( - &deps, - env, - SwapParams { - pool_id: pool_config.pool_id, - token_in_amount, - token_out_min_amount, - token_in_denom: token_in_denom.clone(), - token_out_denom: token_out_denom.clone(), - forced_swap_route: None, // TODO: check this None - }, - )?; - - Ok(SwapCalculationResult { - swap_msg, - token_in_denom: token_in_denom.to_string(), - token_out_min_amount, - token_in_amount, - position_id: None, - }) -} diff --git a/smart-contracts/contracts/cl-vault/src/vault/concentrated_liquidity.rs b/smart-contracts/contracts/cl-vault/src/vault/concentrated_liquidity.rs deleted file mode 100644 index d65ab2382..000000000 --- a/smart-contracts/contracts/cl-vault/src/vault/concentrated_liquidity.rs +++ /dev/null @@ -1,225 +0,0 @@ -use cosmwasm_std::{Coin, Decimal256, DepsMut, Env, QuerierWrapper, Storage, Uint128}; -use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::{ - ConcentratedliquidityQuerier, FullPositionBreakdown, MsgCreatePosition, MsgWithdrawPosition, - Pool, -}; -use osmosis_std::types::osmosis::poolmanager::v1beta1::PoolmanagerQuerier; -use prost::Message; - -use crate::helpers::generic::{round_up_to_nearest_multiple, sort_tokens}; -use crate::{ - state::{POOL_CONFIG, POSITION}, - ContractError, -}; - -pub fn create_position( - deps: DepsMut, - env: &Env, - lower_tick: i64, - upper_tick: i64, - tokens_provided: Vec, - token_min_amount0: Uint128, - token_min_amount1: Uint128, -) -> Result { - let pool_config = POOL_CONFIG.load(deps.storage)?; - let sender = env.contract.address.to_string(); - - let sorted_tokens = sort_tokens(tokens_provided); - - let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; - let tick_spacing = pool_details - .tick_spacing - .try_into() - .expect("tick spacing is too big to fit into i64"); - - let create_position = MsgCreatePosition { - pool_id: pool_config.pool_id, - sender, - lower_tick: round_up_to_nearest_multiple(lower_tick, tick_spacing), - upper_tick: round_up_to_nearest_multiple(upper_tick, tick_spacing), - tokens_provided: sorted_tokens.into_iter().map(|c| c.into()).collect(), - // An sdk.Int in the Go code - token_min_amount0: token_min_amount0.to_string(), - // An sdk.Int in the Go code - token_min_amount1: token_min_amount1.to_string(), - }; - Ok(create_position) -} - -// TODO verify that liquidity amount should be Decimal256 -pub fn withdraw_from_position( - storage: &dyn Storage, - env: &Env, - liquidity_amount: Decimal256, -) -> Result { - let sender = env.contract.address.to_string(); - let position = POSITION.load(storage)?; - - let withdraw_position = MsgWithdrawPosition { - position_id: position.position_id, - sender, - liquidity_amount: liquidity_amount.atomics().to_string(), - }; - Ok(withdraw_position) -} - -pub fn get_position( - storage: &dyn Storage, - querier: &QuerierWrapper, -) -> Result { - let position = POSITION.load(storage)?; - - let cl_querier = ConcentratedliquidityQuerier::new(querier); - let position = cl_querier.position_by_id(position.position_id)?; - position.position.ok_or(ContractError::PositionNotFound) -} - -pub fn get_cl_pool_info(querier: &QuerierWrapper, pool_id: u64) -> Result { - let pm_querier = PoolmanagerQuerier::new(querier); - let pool = pm_querier.pool(pool_id)?; - - match pool.pool { - // Some(pool) => Some(Pool::decode(pool.value.as_slice())?), - Some(pool) => { - let decoded_pool = Message::decode(pool.value.as_ref())?; - Ok(decoded_pool) - } - None => Err(ContractError::PoolNotFound { pool_id }), - } -} - -pub fn _may_get_position( - storage: &dyn Storage, - querier: &QuerierWrapper, - _env: &Env, -) -> Result, ContractError> { - let position = POSITION.may_load(storage)?; - if let Some(position) = position { - let cl_querier = ConcentratedliquidityQuerier::new(querier); - let position = cl_querier.position_by_id(position.position_id)?; - Ok(Some( - position.position.ok_or(ContractError::PositionNotFound)?, - )) - } else { - Ok(None) - } -} - -#[cfg(test)] -mod tests { - use crate::{ - state::{PoolConfig, Position}, - test_helpers::QuasarQuerier, - }; - use cosmwasm_std::{ - coin, - testing::{mock_dependencies, mock_env}, - Coin, Uint128, - }; - - use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::Position as OsmoPosition; - - use super::*; - - #[test] - fn test_create_position() { - let mut deps = mock_dependencies(); - let pool_id = 1; - POOL_CONFIG - .save( - deps.as_mut().storage, - &PoolConfig { - pool_id, - token0: "uosmo".to_string(), - token1: "uatom".to_string(), - }, - ) - .unwrap(); - let qq = QuasarQuerier::new( - FullPositionBreakdown { - position: Some(OsmoPosition { - position_id: 1, - address: "bob".to_string(), - pool_id: 1, - lower_tick: 1, - upper_tick: 100, - join_time: None, - liquidity: "123.214".to_string(), - }), - asset0: Some(coin(1000, "uosmo").into()), - asset1: Some(coin(1000, "uatom").into()), - claimable_spread_rewards: vec![coin(1000, "uosmo").into()], - claimable_incentives: vec![coin(123, "uatom").into()], - forfeited_incentives: vec![], - }, - 100, - ); - - let mut deps_mut = deps.as_mut(); - deps_mut.querier = QuerierWrapper::new(&qq); - - let env = mock_env(); - let lower_tick = 100; - let upper_tick = 200; - let tokens_provided = vec![Coin::new(100, "uosmo"), Coin::new(200, "uatom")]; - let token_min_amount0 = Uint128::new(1000); - let token_min_amount1 = Uint128::new(2000); - - let result = create_position( - deps_mut, - &env, - lower_tick, - upper_tick, - tokens_provided.clone(), - token_min_amount0, - token_min_amount1, - ) - .unwrap(); - - assert_eq!( - result, - MsgCreatePosition { - pool_id, - sender: env.contract.address.into(), - lower_tick, - upper_tick, - tokens_provided: sort_tokens(tokens_provided) - .into_iter() - .map(|c| c.into()) - .collect(), - token_min_amount0: token_min_amount0.to_string(), - token_min_amount1: token_min_amount1.to_string() - } - ); - } - - #[test] - fn test_withdraw_from_position() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let liquidity_amount = Decimal256::from_ratio(100_u128, 1_u128); - - let position_id = 1; - POSITION - .save( - deps.as_mut().storage, - &Position { - position_id, - join_time: 0, - claim_after: None, - }, - ) - .unwrap(); - - let result = withdraw_from_position(&mut deps.storage, &env, liquidity_amount).unwrap(); - - assert_eq!( - result, - MsgWithdrawPosition { - position_id, - sender: env.contract.address.into(), - liquidity_amount: liquidity_amount.atomics().to_string() - } - ); - } -} diff --git a/smart-contracts/contracts/cl-vault/src/vault/exact_deposit.rs b/smart-contracts/contracts/cl-vault/src/vault/exact_deposit.rs deleted file mode 100644 index 8378b3e28..000000000 --- a/smart-contracts/contracts/cl-vault/src/vault/exact_deposit.rs +++ /dev/null @@ -1,451 +0,0 @@ -use cosmwasm_std::{coin, DepsMut, Env, MessageInfo, Response, Uint128, Uint256}; - -use osmosis_std::types::osmosis::tokenfactory::v1beta1::MsgMint; - -use crate::helpers::assert::must_pay_one_or_two; -use crate::helpers::getters::{get_asset0_value, get_depositable_tokens}; -use crate::helpers::msgs::refund_bank_msg; -use crate::query::query_total_vault_token_supply; -use crate::{ - query::query_total_assets, - state::{POOL_CONFIG, SHARES, VAULT_DENOM}, - ContractError, -}; - -/// Try to deposit as much user funds as we can in the current ratio of the vault and -/// refund the rest to the caller. -pub(crate) fn execute_exact_deposit( - mut deps: DepsMut, - env: Env, - info: MessageInfo, - recipient: Option, -) -> Result { - // Unwrap recipient or use caller's address - let recipient = recipient.map_or(Ok(info.sender.clone()), |x| deps.api.addr_validate(&x))?; - - let pool = POOL_CONFIG.load(deps.storage)?; - let (token0, token1) = must_pay_one_or_two(&info, (pool.token0.clone(), pool.token1.clone()))?; - - // get the amount of funds we can deposit from this ratio - let (deposit, refund): ((Uint128, Uint128), (Uint128, Uint128)) = - get_depositable_tokens(deps.branch(), token0.clone(), token1.clone())?; - - let vault_denom = VAULT_DENOM.load(deps.storage)?; - let total_vault_shares: Uint256 = query_total_vault_token_supply(deps.as_ref())?.total.into(); - - let user_value = get_asset0_value(deps.storage, &deps.querier, deposit.0, deposit.1)?; - let refund_value = get_asset0_value(deps.storage, &deps.querier, refund.0, refund.1)?; - - // calculate the amount of shares we can mint for this - let total_assets = query_total_assets(deps.as_ref(), env.clone())?; - let total_assets_value = get_asset0_value( - deps.storage, - &deps.querier, - total_assets.token0.amount, - total_assets.token1.amount, - )?; - - // total_vault_shares.is_zero() should never be zero. This should ideally always enter the else and we are just sanity checking. - let user_shares: Uint128 = if total_vault_shares.is_zero() { - user_value - } else { - total_vault_shares - .checked_mul(user_value.into())? - .checked_div( - total_assets_value - .checked_sub(user_value)? - .checked_sub(refund_value)? - .into(), - )? - .try_into()? - }; - - // save the shares in the user map - SHARES.update( - deps.storage, - recipient.clone(), - |old| -> Result { - if let Some(existing_user_shares) = old { - Ok(user_shares + existing_user_shares) - } else { - Ok(user_shares) - } - }, - )?; - - // TODO the locking of minted shares is a band-aid for giving out rewards to users, - // once tokenfactory has send hooks, we can remove the lockup and have the users - // own the shares in their balance - // we mint shares to the contract address here, so we can lock those shares for the user later in the same call - // this is blocked by Osmosis v17 update - let mint_msg = MsgMint { - sender: env.clone().contract.address.to_string(), - amount: Some(coin(user_shares.into(), vault_denom).into()), - mint_to_address: env.clone().contract.address.to_string(), - }; - - let mut resp = Response::new() - .add_attribute("method", "execute") - .add_attribute("action", "exact_deposit") - .add_attribute("amount0", deposit.0) - .add_attribute("amount1", deposit.1) - .add_message(mint_msg) - .add_attribute("mint_shares_amount", user_shares) - .add_attribute("receiver", recipient.as_str()); - - if let Some((bank_msg, bank_attr)) = refund_bank_msg( - recipient, - Some(coin(refund.0.u128(), pool.token0)), - Some(coin(refund.1.u128(), pool.token1)), - )? { - resp = resp.add_message(bank_msg).add_attributes(bank_attr); - } - - Ok(resp) -} - -#[cfg(test)] -mod tests { - use std::{marker::PhantomData, str::FromStr}; - - use cosmwasm_std::{ - testing::{mock_env, MockApi, MockStorage, MOCK_CONTRACT_ADDR}, - Addr, BankMsg, Coin, Decimal256, Empty, Fraction, OwnedDeps, Uint256, - }; - - use osmosis_std::types::{ - cosmos::base::v1beta1::Coin as OsmoCoin, - osmosis::concentratedliquidity::v1beta1::{ - FullPositionBreakdown, Position as OsmoPosition, - }, - }; - - use crate::{ - helpers::{getters::get_depositable_tokens, msgs::refund_bank_msg}, - state::{Position, POSITION}, - test_helpers::{mock_deps_with_querier, QuasarQuerier}, - }; - - use super::*; - - #[test] - fn test_position_in_both_asset() { - let token0 = Coin { - denom: "token0".to_string(), - amount: Uint128::new(1_000_000_000u128), - }; - let token1 = Coin { - denom: "token1".to_string(), - amount: Uint128::new(100_000_000_000_000_000_000_000_000_000u128), - }; - - let mut deps = mock_deps_with_position(Some(token0.clone()), Some(token1.clone())); - let mutdeps = deps.as_mut(); - - let result = get_depositable_tokens(mutdeps, token0, token1).unwrap(); - assert_eq!( - result, - ( - ( - Uint128::zero(), - Uint128::new(100_000_000_000_000_000_000_000_000_000u128) - ), - (Uint128::new(1_000_000_000u128), Uint128::zero()) - ) - ); - } - - #[test] - fn test_position_in_asset1_only() { - let token0 = Coin { - denom: "token0".to_string(), - amount: Uint128::new(50), - }; - let token1 = Coin { - denom: "token1".to_string(), - amount: Uint128::new(100), - }; - - // Osmosis is not using None for missing assets, but Some with amount 0, so we need to mimic that here - let mut deps = mock_deps_with_position( - Some(Coin { - denom: "token0".to_string(), - amount: Uint128::zero(), - }), - Some(token1.clone()), - ); - - let result = get_depositable_tokens(deps.as_mut(), token0, token1).unwrap(); - assert_eq!( - result, - ( - (Uint128::zero(), Uint128::new(100)), - (Uint128::new(50), Uint128::zero()) - ) - ); - } - - #[test] - fn test_position_in_asset0_only() { - let token0 = Coin { - denom: "token0".to_string(), - amount: Uint128::new(50), - }; - let token1 = Coin { - denom: "token1".to_string(), - amount: Uint128::new(100), - }; - - // Osmosis is not using None for missing assets, but Some with amount 0, so we need to mimic that here - let mut deps = mock_deps_with_position( - Some(token0.clone()), - Some(Coin { - denom: "token1".to_string(), - amount: Uint128::zero(), - }), - ); - - let result = get_depositable_tokens(deps.as_mut(), token0, token1).unwrap(); - assert_eq!( - result, - ( - (Uint128::new(50), Uint128::zero()), - (Uint128::zero(), Uint128::new(100)) - ) - ); - } - - #[test] - fn test_both_assets_present_token0_limiting() { - let token0 = Coin { - denom: "token0".to_string(), - amount: Uint128::new(50), - }; - let token1 = Coin { - denom: "token1".to_string(), - amount: Uint128::new(100), - }; - - // we use a ratio of 1/2 - let mut deps = mock_deps_with_position(Some(token0.clone()), Some(token1.clone())); - - let result = - get_depositable_tokens(deps.as_mut(), coin(2000, "token0"), coin(5000, "token1")) - .unwrap(); - assert_eq!( - result, - ( - (Uint128::new(2000), Uint128::new(4000)), - (Uint128::zero(), Uint128::new(1000)) - ) - ); - } - - #[test] - fn test_both_assets_present_token1_limiting() { - let token0 = Coin { - denom: "token0".to_string(), - amount: Uint128::new(50), - }; - let token1 = Coin { - denom: "token1".to_string(), - amount: Uint128::new(100), - }; - - // we use a ratio of 1/2 - let mut deps = mock_deps_with_position(Some(token0.clone()), Some(token1.clone())); - let mutdeps = deps.as_mut(); - - let result = - get_depositable_tokens(mutdeps, coin(2000, "token0"), coin(3000, "token1")).unwrap(); - assert_eq!( - result, - ( - (Uint128::new(1500), Uint128::new(3000)), - (Uint128::new(500), Uint128::zero()) - ) - ); - } - - #[test] - fn execute_exact_deposit_works() { - let mut deps = mock_deps_with_querier(&MessageInfo { - sender: Addr::unchecked("alice"), - funds: vec![], - }); - let env = mock_env(); - let sender = Addr::unchecked("alice"); - VAULT_DENOM - .save(deps.as_mut().storage, &"money".to_string()) - .unwrap(); - POSITION - .save( - deps.as_mut().storage, - &Position { - position_id: 1, - join_time: 0, - claim_after: None, - }, - ) - .unwrap(); - - // STRATEGIST_REWARDS - // .save(deps.as_mut().storage, &CoinList::new()) - // .unwrap(); - // POOL_CONFIG - // .save( - // deps.as_mut().storage, - // &PoolConfig { - // pool_id: 1, - // token0: "token0".to_string(), - // token1: "token1".to_string(), - // }, - // ) - // .unwrap(); - - execute_exact_deposit( - deps.as_mut(), - env, - MessageInfo { - sender: sender.clone(), - funds: vec![coin(100, "token0"), coin(100, "token1")], - }, - None, - ) - .unwrap(); - - // we currently have 100_000 total_vault_shares outstanding and the equivalent of 1999500token0, the user deposits the equivalent of 199token0, thus shares are - // 199 * 100000 / 1999500 = 9.95, which we round down. Thus we expect 9 shares in this example - assert_eq!( - SHARES.load(deps.as_ref().storage, sender).unwrap(), - Uint128::new(9) - ); - } - - #[test] - fn test_shares() { - let total_shares = Uint256::from(1000000000_u128); - let total_liquidity = Decimal256::from_str("1000000000").unwrap(); - let liquidity = Decimal256::from_str("5000000").unwrap(); - - let _user_shares: Uint128 = if total_shares.is_zero() && total_liquidity.is_zero() { - liquidity.to_uint_floor().try_into().unwrap() - } else { - let _ratio = liquidity.checked_div(total_liquidity).unwrap(); - total_shares - .multiply_ratio(liquidity.numerator(), liquidity.denominator()) - .multiply_ratio(total_liquidity.denominator(), total_liquidity.numerator()) - .try_into() - .unwrap() - }; - } - - #[test] - fn refund_bank_msg_2_coins() { - let _env = mock_env(); - let user = Addr::unchecked("alice"); - - let refund0 = coin(150, "uosmo"); - let refund1 = coin(250, "uatom"); - - let response = refund_bank_msg(user.clone(), Some(refund0), Some(refund1)).unwrap(); - assert!(response.is_some()); - assert_eq!( - response.unwrap().0, - BankMsg::Send { - to_address: user.to_string(), - amount: vec![coin(150, "uosmo"), coin(250, "uatom")], - } - ) - } - - #[test] - fn refund_bank_msg_token0() { - let _env = mock_env(); - let user = Addr::unchecked("alice"); - - let refund0 = coin(150, "uosmo"); - let refund1 = coin(0, "uatom"); - - let response = refund_bank_msg(user.clone(), Some(refund0), Some(refund1)).unwrap(); - assert!(response.is_some()); - assert_eq!( - response.unwrap().0, - BankMsg::Send { - to_address: user.to_string(), - amount: vec![coin(150, "uosmo")], - } - ) - } - - #[test] - fn refund_bank_msg_token1() { - let _env = mock_env(); - let user = Addr::unchecked("alice"); - - let refund0 = coin(0, "uosmo"); - let refund1 = coin(250, "uatom"); - - let response = refund_bank_msg(user.clone(), Some(refund0), Some(refund1)).unwrap(); - assert!(response.is_some()); - assert_eq!( - response.unwrap().0, - BankMsg::Send { - to_address: user.to_string(), - amount: vec![coin(250, "uatom")], - } - ) - } - - fn mock_deps_with_position( - token0: Option, - token1: Option, - ) -> OwnedDeps { - let position_id = 2; - - let mut deps = OwnedDeps { - storage: MockStorage::default(), - api: MockApi::default(), - querier: QuasarQuerier::new( - FullPositionBreakdown { - position: Some(OsmoPosition { - position_id, - address: MOCK_CONTRACT_ADDR.to_string(), - pool_id: 1, - lower_tick: 100, - upper_tick: 1000, - join_time: None, - liquidity: "1000000.2".to_string(), - }), - asset0: token0.map(|c| c.into()), - asset1: token1.map(|c| c.into()), - claimable_spread_rewards: vec![ - OsmoCoin { - denom: "token0".to_string(), - amount: "100".to_string(), - }, - OsmoCoin { - denom: "token1".to_string(), - amount: "100".to_string(), - }, - ], - claimable_incentives: vec![], - forfeited_incentives: vec![], - }, - 500, - ), - custom_query_type: PhantomData, - }; - POSITION - .save( - deps.as_mut().storage, - &Position { - position_id, - join_time: 0, - claim_after: None, - }, - ) - .unwrap(); - deps - } -} diff --git a/smart-contracts/contracts/cl-vault/src/vault/range.rs b/smart-contracts/contracts/cl-vault/src/vault/range.rs deleted file mode 100644 index cdfc29700..000000000 --- a/smart-contracts/contracts/cl-vault/src/vault/range.rs +++ /dev/null @@ -1,753 +0,0 @@ -use crate::{ - helpers::{ - assert::assert_range_admin, - getters::{ - get_single_sided_deposit_0_to_1_swap_amount, - get_single_sided_deposit_1_to_0_swap_amount, get_tokens_provided, get_twap_price, - get_unused_pair_balances, - }, - msgs::swap_msg, - }, - math::tick::price_to_tick, - msg::{ExecuteMsg, MergePositionMsg}, - reply::Replies, - state::{ - ModifyRangeState, PoolConfig, Position, SwapDepositMergeState, MODIFY_RANGE_STATE, - POOL_CONFIG, POSITION, SWAP_DEPOSIT_MERGE_STATE, - }, - vault::{ - concentrated_liquidity::{create_position, get_position}, - merge::MergeResponse, - }, - ContractError, -}; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - attr, to_json_binary, Decimal, Decimal256, DepsMut, Env, Fraction, MessageInfo, Response, - SubMsg, SubMsgResult, Uint128, -}; -use osmosis_std::types::osmosis::{ - concentratedliquidity::v1beta1::{MsgCreatePositionResponse, MsgWithdrawPosition}, - poolmanager::v1beta1::SwapAmountInRoute, -}; -use std::str::FromStr; - -use super::{ - concentrated_liquidity::get_cl_pool_info, - swap::{SwapCalculationResult, SwapParams}, -}; - -/// This function is the entrypoint into the dsm routine that will go through the following steps -/// * how much liq do we have in current range -/// * so how much of each asset given liq would we have at current price -/// * how much of each asset do we need to move to get to new range -/// * deposit up to max liq we can right now, then swap remaining over and deposit again -#[allow(clippy::too_many_arguments)] -pub fn execute_update_range( - deps: DepsMut, - env: &Env, - info: MessageInfo, - lower_price: Decimal, - upper_price: Decimal, - max_slippage: Decimal, - ratio_of_swappable_funds_to_use: Decimal, - twap_window_seconds: u64, - forced_swap_route: Option>, - claim_after: Option, -) -> Result { - assert_range_admin(deps.storage, &info.sender)?; - - let lower_tick: i64 = price_to_tick(deps.storage, Decimal256::from(lower_price))? - .try_into() - .expect("Overflow when converting lower price to tick"); - let upper_tick: i64 = price_to_tick(deps.storage, Decimal256::from(upper_price))? - .try_into() - .expect("Overflow when converting upper price to tick"); - - // validate ratio of swappable funds to use - if ratio_of_swappable_funds_to_use > Decimal::one() - || ratio_of_swappable_funds_to_use <= Decimal::zero() - { - return Err(ContractError::InvalidRatioOfSwappableFundsToUse {}); - } - - let modify_range_config = ModifyRangeState { - lower_tick, - upper_tick, - max_slippage, - new_range_position_ids: vec![], - ratio_of_swappable_funds_to_use, - twap_window_seconds, - forced_swap_route, - }; - - execute_update_range_ticks(deps, env, info, modify_range_config, claim_after) -} - -/// This function is the entrypoint into the dsm routine that will go through the following steps -/// * how much liq do we have in current range -/// * so how much of each asset given liq would we have at current price -/// * how much of each asset do we need to move to get to new range -/// * deposit up to max liq we can right now, then swap remaining over and deposit again -#[allow(clippy::too_many_arguments)] -pub fn execute_update_range_ticks( - deps: DepsMut, - env: &Env, - info: MessageInfo, - modify_range_config: ModifyRangeState, - claim_after: Option, -) -> Result { - assert_range_admin(deps.storage, &info.sender)?; - - // todo: prevent re-entrancy by checking if we have anything in MODIFY_RANGE_STATE (redundant check but whatever) - - // this will error if we dont have a position anyway - let position_breakdown = get_position(deps.storage, &deps.querier)?; - let position = position_breakdown - .position - .ok_or(ContractError::MissingPosition {})?; - - let withdraw_msg = MsgWithdrawPosition { - position_id: position.position_id, - sender: env.contract.address.to_string(), - liquidity_amount: Decimal256::from_str(position.liquidity.as_str())? - .atomics() - .to_string(), - }; - - MODIFY_RANGE_STATE.save( - deps.storage, - // todo: should ModifyRangeState be an enum? - &Some(modify_range_config), - )?; - - // Load the current Position to set new join_time and claim_after, leaving current position_id unchanged. - let position_state = POSITION.load(deps.storage)?; - POSITION.save( - deps.storage, - &Position { - position_id: position_state.position_id, - join_time: env.block.time.seconds(), - claim_after, - }, - )?; - - Ok(Response::default() - .add_submessage(SubMsg::reply_on_success( - withdraw_msg, - Replies::WithdrawPosition.into(), - )) - .add_attribute("method", "execute") - .add_attribute("action", "update_range_ticks") - .add_attribute("position_id", position.position_id.to_string()) - .add_attribute("liquidity_amount", position.liquidity)) -} - -// do create new position -pub fn handle_withdraw_position_reply(deps: DepsMut, env: Env) -> Result { - let modify_range_state = MODIFY_RANGE_STATE.load(deps.storage)?.unwrap(); - let pool_config = POOL_CONFIG.load(deps.storage)?; - let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; - - let unused_pair_balances = get_unused_pair_balances(&deps, &env, &pool_config)?; - let tokens_provided = - get_tokens_provided(unused_pair_balances.0, unused_pair_balances.1, &pool_config)?; - - // if only one token is being deposited, and we are moving into a position where any amount of the other token is needed, - // creating the position here will fail because liquidityNeeded is calculated as 0 on chain level - // we can fix this by going straight into a swap-deposit-merge before creating any positions - - // 0 token0 and current_tick > lower_tick - // 0 token1 and current_tick < upper_tick - // if (lower < current < upper) && amount0 == 0 || amount1 == 0 - // also onesided but wrong token - // bad complexity demon, grug no like - if (unused_pair_balances.0.is_zero() - && pool_details.current_tick < modify_range_state.upper_tick) - || (unused_pair_balances.1.is_zero() - && pool_details.current_tick > modify_range_state.lower_tick) - { - do_swap_deposit_merge( - deps, - env, - modify_range_state.lower_tick, - modify_range_state.upper_tick, - (unused_pair_balances.0, unused_pair_balances.1), - None, // we just withdrew our only position - modify_range_state.ratio_of_swappable_funds_to_use, - modify_range_state.twap_window_seconds, - ) - } else { - // we can naively re-deposit up to however much keeps the proportion of tokens the same. - // Then swap & re-deposit the proper ratio with the remaining tokens - let create_position_msg = create_position( - deps, - &env, - modify_range_state.lower_tick, - modify_range_state.upper_tick, - tokens_provided, - Uint128::zero(), - Uint128::zero(), - )?; - - Ok(Response::new() - .add_submessage(SubMsg::reply_on_success( - create_position_msg, - Replies::RangeInitialCreatePosition.into(), - )) - .add_attribute("method", "reply") - .add_attribute("action", "handle_withdraw_position") - .add_attribute("lower_tick", modify_range_state.lower_tick.to_string()) - .add_attribute("upper_tick", modify_range_state.upper_tick.to_string()) - .add_attribute( - "token0", - format!("{}{}", unused_pair_balances.0, pool_config.token0), - ) - .add_attribute( - "token1", - format!("{}{}", unused_pair_balances.1, pool_config.token1), - )) - } -} - -// do swap -pub fn handle_initial_create_position_reply( - deps: DepsMut, - env: Env, - data: SubMsgResult, -) -> Result { - let create_position_message: MsgCreatePositionResponse = data.try_into()?; - let modify_range_state = MODIFY_RANGE_STATE.load(deps.storage)?.unwrap(); - let pool_config = POOL_CONFIG.load(deps.storage)?; - - // target range for our imminent swap - // taking from response message is important because they may differ from the ones in our request - let target_lower_tick = create_position_message.lower_tick; - let target_upper_tick = create_position_message.upper_tick; - - let unused_pair_balances = get_unused_pair_balances(&deps, &env, &pool_config)?; - - do_swap_deposit_merge( - deps, - env, - target_lower_tick, - target_upper_tick, - (unused_pair_balances.0, unused_pair_balances.1), - Some(create_position_message.position_id), - modify_range_state.ratio_of_swappable_funds_to_use, - modify_range_state.twap_window_seconds, - ) -} - -/// this function assumes that we are swapping and depositing into a valid range -/// -/// It also calculates the exact amount we should be swapping based on current balances and the new range -#[allow(clippy::too_many_arguments)] -pub fn do_swap_deposit_merge( - deps: DepsMut, - env: Env, - target_lower_tick: i64, - target_upper_tick: i64, - tokens_provided: (Uint128, Uint128), - position_id: Option, - ratio_of_swappable_funds_to_use: Decimal, - twap_window_seconds: u64, -) -> Result { - if SWAP_DEPOSIT_MERGE_STATE.may_load(deps.storage)?.is_some() { - return Err(ContractError::SwapInProgress {}); - } - - let (balance0, balance1) = ( - tokens_provided.0.checked_multiply_ratio( - ratio_of_swappable_funds_to_use.numerator(), - ratio_of_swappable_funds_to_use.denominator(), - )?, - tokens_provided.1.checked_multiply_ratio( - ratio_of_swappable_funds_to_use.numerator(), - ratio_of_swappable_funds_to_use.denominator(), - )?, - ); - - let mut target_range_position_ids = vec![]; - if let Some(pos_id) = position_id { - target_range_position_ids.push(pos_id); - } - - SWAP_DEPOSIT_MERGE_STATE.save( - deps.storage, - &SwapDepositMergeState { - target_lower_tick, - target_upper_tick, - target_range_position_ids, - }, - )?; - - let pool_config = POOL_CONFIG.load(deps.storage)?; - let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; - let swap_calc_result = calculate_swap_amount( - deps, - env, - &pool_config, - pool_details.current_tick, - position_id, - balance0, - balance1, - target_lower_tick, - target_upper_tick, - twap_window_seconds, - )?; - - // Start constructing the response - let response = Response::new() - .add_attribute("method", "reply") - .add_attribute("action", "do_swap_deposit_merge"); - - // Check if there is a swap message and append accordingly - if let Some(calculated) = swap_calc_result { - Ok(response - .add_submessage(SubMsg::reply_on_success( - calculated.swap_msg, - Replies::Swap.into(), - )) - .add_attributes(vec![ - attr( - "token_in", - format!( - "{}{}", - calculated.token_in_amount, calculated.token_in_denom - ), - ), - attr("token_out_min", calculated.token_out_min_amount.to_string()), - ])) - } else { - // If no swap message, add a new position attribute - Ok(response.add_attribute("new_position", position_id.unwrap().to_string())) - } -} - -#[allow(clippy::too_many_arguments)] -fn calculate_swap_amount( - deps: DepsMut, - env: Env, - pool_config: &PoolConfig, - current_tick: i64, - position_id: Option, - balance0: Uint128, - balance1: Uint128, - target_lower_tick: i64, - target_upper_tick: i64, - twap_window_seconds: u64, -) -> Result, ContractError> { - //TODO: further optimizations can be made by increasing the swap amount by half of our expected slippage, - // to reduce the total number of non-deposited tokens that we will then need to refund - let (token_in_amount, swap_direction) = if !balance0.is_zero() { - ( - // range is above current tick - if current_tick > target_upper_tick { - balance0 - } else { - get_single_sided_deposit_0_to_1_swap_amount( - balance0, - target_lower_tick, - current_tick, - target_upper_tick, - )? - }, - SwapDirection::ZeroToOne, - ) - } else if !balance1.is_zero() { - ( - // current tick is above range - if current_tick < target_lower_tick { - balance1 - } else { - get_single_sided_deposit_1_to_0_swap_amount( - balance1, - target_lower_tick, - current_tick, - target_upper_tick, - )? - }, - SwapDirection::OneToZero, - ) - } else { - // Load the current Position to extract join_time and claim_after which is unchangeable in this context - let position = POSITION.load(deps.storage)?; - - // if we have not tokens to swap, that means all tokens we correctly used in the create position - // this means we can save the position id of the first create_position - POSITION.save( - deps.storage, - &Position { - // if position not found, then we should panic here anyway ? - position_id: position_id.expect("position id should be set if no swap is needed"), - join_time: position.join_time, - claim_after: position.claim_after, - }, - )?; - - SWAP_DEPOSIT_MERGE_STATE.remove(deps.storage); - - return Ok(None); - }; - - // TODO: check that this math is right with spot price (numerators, denominators) if taken by legacy gamm module instead of poolmanager - let twap_price = get_twap_price(deps.storage, &deps.querier, &env, twap_window_seconds)?; - let (token_in_denom, token_out_denom, token_out_ideal_amount) = match swap_direction { - SwapDirection::ZeroToOne => ( - &pool_config.token0, - &pool_config.token1, - token_in_amount - .checked_multiply_ratio(twap_price.numerator(), twap_price.denominator()), - ), - SwapDirection::OneToZero => ( - &pool_config.token1, - &pool_config.token0, - token_in_amount - .checked_multiply_ratio(twap_price.denominator(), twap_price.numerator()), - ), - }; - - let mrs = MODIFY_RANGE_STATE.load(deps.storage)?.unwrap(); - let token_out_min_amount = token_out_ideal_amount? - .checked_multiply_ratio(mrs.max_slippage.numerator(), mrs.max_slippage.denominator())?; - - if !pool_config.pool_contains_token(token_in_denom) { - return Err(ContractError::BadTokenForSwap { - base_token: pool_config.token0.clone(), - quote_token: pool_config.token1.clone(), - }); - } - - let swap_msg = swap_msg( - &deps, - &env, - SwapParams { - pool_id: pool_config.pool_id, - token_in_amount, - token_out_min_amount, - token_in_denom: token_in_denom.clone(), - token_out_denom: token_out_denom.to_string(), - forced_swap_route: mrs.forced_swap_route, - }, - )?; - - Ok(Some(SwapCalculationResult { - swap_msg, - token_in_denom: token_in_denom.to_string(), - token_in_amount, - token_out_min_amount, - position_id: None, - })) -} - -// do deposit -pub fn handle_swap_reply( - deps: DepsMut, - env: Env, - data: SubMsgResult, -) -> Result { - match data.clone() { - SubMsgResult::Ok(_) => { - let swap_deposit_merge_state = match SWAP_DEPOSIT_MERGE_STATE.may_load(deps.storage)? { - Some(swap_deposit_merge) => swap_deposit_merge, - None => return Err(ContractError::SwapDepositMergeStateNotFound {}), - }; - - let pool_config = POOL_CONFIG.load(deps.storage)?; - let unused_pair_balances = get_unused_pair_balances(&deps, &env, &pool_config)?; - let tokens_provided = - get_tokens_provided(unused_pair_balances.0, unused_pair_balances.1, &pool_config)?; - - let create_position_msg = create_position( - deps, - &env, - swap_deposit_merge_state.target_lower_tick, - swap_deposit_merge_state.target_upper_tick, - tokens_provided, - Uint128::zero(), - Uint128::zero(), - )?; - - Ok(Response::new() - .add_submessage(SubMsg::reply_on_success( - create_position_msg, - Replies::RangeIterationCreatePosition.into(), - )) - .add_attribute("method", "reply") - .add_attribute("action", "handle_swap_success") - .add_attribute( - "lower_tick", - swap_deposit_merge_state.target_lower_tick.to_string(), - ) - .add_attribute( - "upper_tick", - swap_deposit_merge_state.target_upper_tick.to_string(), - ) - .add_attribute( - "token0", - format!("{:?}{:?}", unused_pair_balances.0, pool_config.token0), - ) - .add_attribute( - "token1", - format!("{:?}{:?}", unused_pair_balances.1, pool_config.token1), - )) - } - SubMsgResult::Err(msg) => Err(ContractError::SwapFailed { message: msg }), - } -} - -// do merge position & exit -pub fn handle_iteration_create_position_reply( - deps: DepsMut, - env: Env, - data: SubMsgResult, -) -> Result { - let create_position_message: MsgCreatePositionResponse = data.try_into()?; - - let mut swap_deposit_merge_state = match SWAP_DEPOSIT_MERGE_STATE.may_load(deps.storage)? { - Some(swap_deposit_merge) => swap_deposit_merge, - None => return Err(ContractError::SwapDepositMergeStateNotFound {}), - }; - - // add the position id to the ones we need to merge - swap_deposit_merge_state - .target_range_position_ids - .push(create_position_message.position_id); - - // call merge - let merge_msg = - ExecuteMsg::VaultExtension(crate::msg::ExtensionExecuteMsg::Merge(MergePositionMsg { - position_ids: swap_deposit_merge_state.target_range_position_ids.clone(), - })); - - let merge_submsg = SubMsg::reply_on_success( - cosmwasm_std::WasmMsg::Execute { - contract_addr: env.contract.address.to_string(), - msg: to_json_binary(&merge_msg)?, - funds: vec![], - }, - Replies::Merge.into(), - ); - - // clear state to allow for new liquidity movement operations - SWAP_DEPOSIT_MERGE_STATE.remove(deps.storage); - - Ok(Response::new() - .add_submessage(merge_submsg) - .add_attribute("method", "reply") - .add_attribute("action", "handle_iteration_create_position") - .add_attribute( - "position_ids", - format!("{:?}", swap_deposit_merge_state.target_range_position_ids), - )) -} - -// store new position id and exit -pub fn handle_merge_reply( - deps: DepsMut, - env: Env, - data: SubMsgResult, -) -> Result { - let merge_response: MergeResponse = data.try_into()?; - - // Load the current Position to extract join_time and claim_after which is unchangeable in this context - let position = POSITION.load(deps.storage)?; - - POSITION.save( - deps.storage, - &Position { - position_id: merge_response.new_position_id, - join_time: env.block.time.seconds(), - claim_after: position.claim_after, - }, - )?; - - Ok(Response::new() - .add_attribute("method", "reply") - .add_attribute("action", "handle_merge_reply") - .add_attribute("swap_deposit_merge_status", "success") - .add_attribute("status", "success")) -} - -#[cw_serde] -pub enum SwapDirection { - ZeroToOne, - OneToZero, -} - -#[cfg(test)] -mod tests { - use std::str::FromStr; - - use cosmwasm_std::{ - coin, - testing::{mock_dependencies, mock_env, mock_info, MOCK_CONTRACT_ADDR}, - Addr, Decimal, - }; - - use crate::{ - helpers::getters::get_range_admin, - math::tick::build_tick_exp_cache, - state::{MODIFY_RANGE_STATE, RANGE_ADMIN}, - test_helpers::{mock_deps_with_querier, mock_deps_with_querier_with_balance}, - }; - - #[test] - fn test_assert_range_admin() { - let mut deps = mock_dependencies(); - let info = mock_info("addr0000", &[]); - - RANGE_ADMIN.save(&mut deps.storage, &info.sender).unwrap(); - - super::assert_range_admin(&mut deps.storage, &info.sender).unwrap(); - - let info = mock_info("addr0001", &[]); - super::assert_range_admin(&mut deps.storage, &info.sender).unwrap_err(); - - let info = mock_info("addr0000", &[]); - RANGE_ADMIN.save(&mut deps.storage, &info.sender).unwrap(); - - super::assert_range_admin(&mut deps.storage, &Addr::unchecked("someoneelse")).unwrap_err(); - } - - #[test] - fn test_get_range_admin() { - let mut deps = mock_dependencies(); - let info = mock_info("addr0000", &[]); - - RANGE_ADMIN.save(&mut deps.storage, &info.sender).unwrap(); - - assert_eq!(get_range_admin(deps.as_ref()).unwrap(), info.sender); - } - - #[test] - fn test_execute_update_range() { - let info = mock_info("addr0000", &[]); - let mut deps = mock_deps_with_querier(&info); - build_tick_exp_cache(deps.as_mut().storage).unwrap(); - - let env = mock_env(); - let lower_price = Decimal::from_str("100").unwrap(); - let upper_price = Decimal::from_str("100.20").unwrap(); - let max_slippage = Decimal::from_str("0.5").unwrap(); - - let res = super::execute_update_range( - deps.as_mut(), - &env, - info, - lower_price, - upper_price, - max_slippage, - Decimal::one(), - 45, - None, - None, - ) - .unwrap(); - - assert_eq!(res.messages.len(), 1); - assert_eq!(res.attributes[0].value, "execute"); - assert_eq!(res.attributes[1].value, "update_range_ticks"); - assert_eq!(res.attributes[2].value, "1"); - assert_eq!(res.attributes[3].value, "1000000.1"); - } - - #[test] - fn test_handle_withdraw_position_reply_selects_correct_next_step_for_new_range() { - let info = mock_info("addr0000", &[]); - let env = mock_env(); - - // let mut deps = mock_deps_with_querier_with_balance( - // &info, - // &[(MOCK_CONTRACT_ADDR, &[coin(11234, "token1")])], - // ); - - // // moving into a range - // MODIFY_RANGE_STATE - // .save( - // deps.as_mut().storage, - // &Some(crate::state::ModifyRangeState { - // lower_tick: 100, - // upper_tick: 1000, // since both times we are moving into range and in the quasarquerier we configured the current_tick as 500, this would mean we are trying to move into range - // new_range_position_ids: vec![], - // max_slippage: Decimal::zero(), - // ratio_of_swappable_funds_to_use: Decimal::one(), - // twap_window_seconds: 45, - // recommended_swap_route: None, - // force_swap_route: false, - // }), - // ) - // .unwrap(); - - // // Reply - // //first test fully one-sided withdraw - // let data = SubMsgResult::Ok(SubMsgResponse { - // events: vec![], - // data: Some( - // MsgWithdrawPositionResponse { - // amount0: "0".to_string(), - // amount1: "10000".to_string(), - // } - // .try_into() - // .unwrap(), - // ), - // }); - - // let res = super::handle_withdraw_position_reply(deps.as_mut(), env.clone(), data).unwrap(); - - // // verify that we went straight to swap_deposit_merge - // assert_eq!(res.messages.len(), 1); - // assert_eq!(res.attributes[1].value, "do_swap_deposit_merge"); - // // check that our token1 attribute is incremented with the local balance - // assert_eq!( - // res.attributes - // .iter() - // .find(|a| { a.key == "token_in" }) - // .unwrap() - // .value, - // "5962token1" - // ); - - // SECOND CASE STARTS HERE - - let mut deps = mock_deps_with_querier_with_balance( - &info, - &[( - MOCK_CONTRACT_ADDR, - &[coin(11000, "token0"), coin(11234, "token1")], - )], - ); - - // moving into a range - MODIFY_RANGE_STATE - .save( - deps.as_mut().storage, - &Some(crate::state::ModifyRangeState { - lower_tick: 100, - upper_tick: 1000, // since both times we are moving into range and in the quasarquerier we configured the current_tick as 500, this would mean we are trying to move into range - new_range_position_ids: vec![], - max_slippage: Decimal::zero(), - ratio_of_swappable_funds_to_use: Decimal::one(), - twap_window_seconds: 45, - forced_swap_route: None, - }), - ) - .unwrap(); - - let res = super::handle_withdraw_position_reply(deps.as_mut(), env).unwrap(); - - // verify that we did create_position first - assert_eq!(res.messages.len(), 1); - assert_eq!(res.attributes[0].value, "reply"); - assert_eq!(res.attributes[1].value, "handle_withdraw_position"); - assert_eq!( - res.attributes - .iter() - .find(|a| { a.key == "token1" }) - .unwrap() - .value, - "11234token1" - ); // 10000 withdrawn + 1234 local balance - } -} diff --git a/smart-contracts/contracts/cl-vault/src/vault/swap.rs b/smart-contracts/contracts/cl-vault/src/vault/swap.rs deleted file mode 100644 index d2d5e15e3..000000000 --- a/smart-contracts/contracts/cl-vault/src/vault/swap.rs +++ /dev/null @@ -1,271 +0,0 @@ -use cosmwasm_std::{CosmosMsg, DepsMut, Env, Fraction, MessageInfo, Response, Uint128}; -use osmosis_std::types::osmosis::poolmanager::v1beta1::SwapAmountInRoute; - -use crate::helpers::assert::assert_range_admin; -use crate::helpers::msgs::swap_msg; -use crate::msg::SwapOperation; -use crate::state::POOL_CONFIG; -use crate::{state::VAULT_CONFIG, ContractError}; - -/// SwapCalculationResult holds the result of a swap calculation -pub struct SwapCalculationResult { - pub swap_msg: CosmosMsg, - pub token_in_denom: String, - pub token_in_amount: Uint128, - pub token_out_min_amount: Uint128, - pub position_id: Option, -} - -/// SwapParams holds the parameters for a swap -pub struct SwapParams { - pub pool_id: u64, // the osmosis pool id in case of no cw_dex_router or no best/recommended route - pub token_in_amount: Uint128, - pub token_in_denom: String, - pub token_out_min_amount: Uint128, - pub token_out_denom: String, - pub forced_swap_route: Option>, -} - -pub fn execute_swap_non_vault_funds( - deps: DepsMut, - env: Env, - info: MessageInfo, - swap_operations: Vec, -) -> Result { - // validate auto compound admin as the purpose of swaps are mainly around autocompound non-vault assets into assets that can be actually compounded. - assert_range_admin(deps.storage, &info.sender)?; - - let vault_config = VAULT_CONFIG.load(deps.storage)?; - let pool_config = POOL_CONFIG.load(deps.storage)?; - - if swap_operations.is_empty() { - return Err(ContractError::EmptySwapOperations {}); - } - - let mut swap_msgs: Vec = vec![]; - - for swap_operation in swap_operations { - let token_in_denom = swap_operation.token_in_denom.clone(); - let pool_token_0 = pool_config.token0.clone(); - let pool_token_1 = pool_config.token1.clone(); - - // Assert that no BASE_DENOM or QUOTE_DENOM is trying to be swapped as token_in - if token_in_denom == pool_token_0 || token_in_denom == pool_token_1 { - return Err(ContractError::InvalidSwapAssets {}); - } - - // Throw an Error if contract balance for the wanted denom is 0 - let balance_in_contract = deps - .querier - .query_balance( - env.clone().contract.address, - swap_operation.clone().token_in_denom, - )? - .amount; - - // TODO_FUTURE: This could be a <= condition against a threshold value mayube in dollars to avoid dust swaps - if balance_in_contract == Uint128::zero() { - // TODO: Use InsufficientFundsForSwap instead, this has been removed after STRATEGIST_REWARDS state eval removal - return Err(ContractError::InsufficientFunds {}); - } - - // TODO_FUTURE: We could be swapping into the actual vault balance so we could prepend_swap() the autocompound entrypoint. - let part_0_amount = balance_in_contract.checked_div(Uint128::new(2))?; - let part_1_amount = balance_in_contract - .checked_add(Uint128::new(1))? - .checked_div(Uint128::new(2))?; - - // TODO_FUTURE: We should be passing the max_slippage from outside as we do during ModifyRange - let token_out_min_amount_0 = part_0_amount.checked_multiply_ratio( - vault_config.swap_max_slippage.numerator(), - vault_config.swap_max_slippage.denominator(), - )?; - let token_out_min_amount_1 = part_1_amount.checked_multiply_ratio( - vault_config.swap_max_slippage.numerator(), - vault_config.swap_max_slippage.denominator(), - )?; - - swap_msgs.push(swap_msg( - &deps, - &env, - SwapParams { - pool_id: swap_operation.pool_id_0, - token_in_amount: part_0_amount, - token_in_denom: token_in_denom.clone(), - token_out_min_amount: token_out_min_amount_0, - token_out_denom: pool_token_0, - forced_swap_route: swap_operation.forced_swap_route_token_0, - }, - )?); - swap_msgs.push(swap_msg( - &deps, - &env, - SwapParams { - pool_id: swap_operation.pool_id_1, - token_in_amount: part_1_amount, - token_in_denom: token_in_denom.clone(), - token_out_min_amount: token_out_min_amount_1, - token_out_denom: pool_token_1, - forced_swap_route: swap_operation.forced_swap_route_token_1, - }, - )?); - } - - Ok(Response::new() - .add_messages(swap_msgs) - .add_attribute("method", "execute") - .add_attribute("action", "swap_non_vault_funds")) -} - -/// estimate_swap can be used to pass correct token_out_min_amount values into swap() -/// for now this function can only be used for our pool -/// this will likely be expanded once we allow arbitrary pool swaps -// pub fn _estimate_swap( -// querier: &QuerierWrapper, -// storage: &mut dyn Storage, -// _env: &Env, -// token_in_amount: Uint128, -// token_in_denom: &String, -// _token_out_min_amount: Uint128, -// ) -> Result { -// let pool_config = POOL_CONFIG.load(storage)?; - -// if !pool_config.pool_contains_token(token_in_denom) { -// return Err(ContractError::BadTokenForSwap { -// base_token: pool_config.token0, -// quote_token: pool_config.token1, -// }); -// } - -// // get token_out_denom -// let token_out_denom = if *token_in_denom == pool_config.token0 { -// pool_config.token1 -// } else { -// pool_config.token0 -// }; - -// // we will only ever have a route length of one, this will likely change once we start selecting different routes -// let pool_route = SwapAmountInRoute { -// pool_id: pool_config.pool_id, -// token_out_denom: token_out_denom.to_string(), -// }; - -// let pm_querier = -// osmosis_std::types::osmosis::poolmanager::v1beta1::PoolmanagerQuerier::new(querier); - -// let result = pm_querier.estimate_swap_exact_amount_in( -// pool_config.pool_id, -// token_in_amount.to_string() + token_in_denom, -// vec![pool_route], -// )?; - -// Ok(Coin { -// denom: token_out_denom, -// amount: Uint128::from_str(&result.token_out_amount)?, -// }) -// } - -#[cfg(test)] -mod tests { - use crate::vault::swap::SwapParams; - use cosmwasm_std::{ - testing::{mock_dependencies_with_balance, mock_env}, - Coin, CosmosMsg, Uint128, - }; - - use crate::state::{PoolConfig, POOL_CONFIG}; - - fn mock_pool_config() -> PoolConfig { - PoolConfig { - pool_id: 1, - token0: "token0".to_string(), - token1: "token1".to_string(), - } - } - - #[test] - fn test_proper_swap() { - let mut deps = mock_dependencies_with_balance(&[Coin { - denom: "token0".to_string(), - amount: Uint128::new(1000), - }]); - let deps_mut = deps.as_mut(); - - let env = mock_env(); - - let token_in_amount = Uint128::new(100); - let token_in_denom = "token0".to_string(); - let token_out_min_amount = Uint128::new(100); - let token_out_denom = "token1".to_string(); - - POOL_CONFIG - .save(deps_mut.storage, &mock_pool_config()) - .unwrap(); - let swap_params = SwapParams { - pool_id: 1, - token_in_amount, - token_out_min_amount, - token_in_denom, - token_out_denom, - forced_swap_route: None, - }; - - let result = super::swap_msg(&deps_mut, &env, swap_params).unwrap(); - - if let CosmosMsg::Stargate { type_url: _, value } = result { - let msg_swap = - osmosis_std::types::osmosis::poolmanager::v1beta1::MsgSwapExactAmountIn::try_from( - value, - ) - .unwrap(); - - assert!(msg_swap.sender == env.contract.address); - assert!(msg_swap.routes.len() == 1); - assert!(msg_swap.routes[0].pool_id == 1); - assert!(msg_swap.routes[0].token_out_denom == *"token1"); - assert!(msg_swap.token_in.clone().unwrap().denom == *"token0"); - assert!(msg_swap.token_in.unwrap().amount == *"100"); - assert!(token_out_min_amount.to_string() == *"100"); - } else { - panic!("Unexpected message type: {:?}", result); - } - } - - // TODO: Move this test logic into any invoker of swap_msg tests as now its their concern to - // validate the token_in_denom based on the context we swap (either non vault funds or during a rerange / anydeposit) - // #[test] - // fn test_bad_denom_swap() { - // let mut deps = mock_dependencies_with_balance(&[Coin { - // denom: "token0".to_string(), - // amount: Uint128::new(1000), - // }]); - // let deps_mut = deps.as_mut(); - - // let env = mock_env(); - - // let token_in_amount = Uint128::new(100); - // let token_in_denom = "token3".to_string(); - // let token_out_min_amount = Uint128::new(100); - // let token_out_denom = "token1".to_string(); - - // let swap_params = SwapParams { - // token_in_amount, - // token_out_min_amount, - // token_in_denom, - // token_out_denom, - // recommended_swap_route: None, - // force_swap_route: false, - // }; - - // POOL_CONFIG - // .save(deps_mut.storage, &mock_pool_config()) - // .unwrap(); - - // let err = super::swap_msg(&deps_mut, &env, swap_params).unwrap_err(); - - // assert_eq!( - // err.to_string(), - // "Bad token out requested for swap, must be one of: \"token0\", \"token1\"".to_string() - // ); - // } -} diff --git a/smart-contracts/contracts/cl-vault/tests/authz.rs b/smart-contracts/contracts/cl-vault/tests/authz.rs deleted file mode 100644 index f15777c6c..000000000 --- a/smart-contracts/contracts/cl-vault/tests/authz.rs +++ /dev/null @@ -1,283 +0,0 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ - fixture_default, get_amount_from_denom, DENOM_BASE, DENOM_QUOTE, PERFORMANCE_FEE_DEFAULT, -}; - -use cl_vault::{ - msg::{ - AuthzExtension, ExecuteMsg, ExtensionExecuteMsg, ExtensionQueryMsg, QueryMsg, - UserBalanceQueryMsg, - }, - query::UserSharesBalanceResponse, -}; -use cosmwasm_std::{assert_approx_eq, Coin, Decimal}; -use osmosis_test_tube::{Account, Module, Wasm}; - -const INITIAL_BALANCE_AMOUNT: u128 = 1_000_000_000_000_000_000_000_000_000_000; - -// check that the authz interface returns the exact same response as -// the regular interface. Thus the actual authz functionality is out of -// scope but contract functionality is in scope here - -#[test] -fn exact_deposit_withdraw_equal() { - let (app, contract_address, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); - let wasm = Wasm::new(&app); - - let alice = app - .init_account(&[ - Coin::new(INITIAL_BALANCE_AMOUNT, "uosmo"), - Coin::new(INITIAL_BALANCE_AMOUNT, DENOM_BASE), - Coin::new(INITIAL_BALANCE_AMOUNT, DENOM_QUOTE), - ]) - .unwrap(); - - let deposit0 = 1_000_000_000_000_000; - let deposit1 = 1_000_000_000_000_000; - - let deposit_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::ExactDeposit { recipient: None }, - &[ - Coin::new(deposit0, DENOM_BASE), - Coin::new(deposit1, DENOM_QUOTE), - ], - &alice, - ) - .unwrap(); - - let authz_deposit_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::Authz( - AuthzExtension::ExactDeposit {}, - )), - &[ - Coin::new(deposit0, DENOM_BASE), - Coin::new(deposit1, DENOM_QUOTE), - ], - &alice, - ) - .unwrap(); - - assert_eq!(deposit_response.data, authz_deposit_response.data); - - assert_eq!( - deposit_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()), - authz_deposit_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()) - ); - - let shares: UserSharesBalanceResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::Balances( - UserBalanceQueryMsg::UserSharesBalance { - user: alice.address(), - }, - )), - ) - .unwrap(); - assert!(!shares.balance.is_zero()); - - let to_withdraw = shares.balance.u128() / 2; - - let withdraw_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::Redeem { - recipient: None, - amount: to_withdraw.into(), - }, - &[], - &alice, - ) - .unwrap(); - - let authz_withdraw_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::Redeem { - recipient: None, - amount: to_withdraw.into(), - }, - &[], - &alice, - ) - .unwrap(); - - assert_eq!(withdraw_response.data, authz_withdraw_response.data); - assert_eq!( - withdraw_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()), - authz_withdraw_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()) - ); -} - -#[test] -fn any_deposit_withdraw_equal() { - let (app, contract_address, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); - let wasm = Wasm::new(&app); - - // Create Alice account - let alice = app - .init_account(&[ - Coin::new(INITIAL_BALANCE_AMOUNT, "uosmo"), - Coin::new(INITIAL_BALANCE_AMOUNT, DENOM_BASE), - ]) - .unwrap(); - - let deposit0 = 1_000_000_000_000_000; - - // Deposit - let deposit_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::AnyDeposit { - amount: deposit0.into(), - asset: DENOM_BASE.to_string(), - recipient: None, - max_slippage: Decimal::bps(900), - }, - &[Coin::new(deposit0, DENOM_BASE)], - &alice, - ) - .unwrap(); - // Deposit via AuthZ - let authz_deposit_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::Authz(AuthzExtension::AnyDeposit { - max_slippage: Decimal::bps(900), - })), - &[Coin::new(deposit0, DENOM_BASE)], - &alice, - ) - .unwrap(); - - // Assert deposits are equal - assert_eq!(deposit_response.data, authz_deposit_response.data); - let deposit_event = deposit_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()) - .unwrap(); - let authz_deposit_event = authz_deposit_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()) - .unwrap(); - // Assert events are equal - assert_eq!(deposit_event.ty, authz_deposit_event.ty); - assert_eq!( - deposit_event.attributes.len(), - authz_deposit_event.attributes.len() - ); - // We need to assert approx here as in the any_deposit case, - // depositing involve a swap that changes the pool's condition for the subsequent one. - for (attr1, attr2) in deposit_event - .attributes - .iter() - .zip(&authz_deposit_event.attributes) - { - if attr1.key == "token_in" || attr1.key == "token_out_min" { - assert_approx_eq!( - get_amount_from_denom(&attr1.value), - get_amount_from_denom(&attr2.value), - "0.00001" - ); - } else { - assert_eq!(attr1, attr2); - } - } - - // Check the shares and compute the balance to withdraw - let shares: UserSharesBalanceResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::Balances( - UserBalanceQueryMsg::UserSharesBalance { - user: alice.address(), - }, - )), - ) - .unwrap(); - assert!(!shares.balance.is_zero()); - let to_withdraw = shares.balance.u128() / 2; - - // Withdraw - let withdraw_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::Redeem { - recipient: None, - amount: to_withdraw.into(), - }, - &[], - &alice, - ) - .unwrap(); - // Withdraw via AuthZ - let authz_withdraw_response = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::Redeem { - recipient: None, - amount: to_withdraw.into(), - }, - &[], - &alice, - ) - .unwrap(); - - // Assert withdraws are equal - assert_eq!(withdraw_response.data, authz_withdraw_response.data); - let withdraw_event = withdraw_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()) - .unwrap(); - let authz_withdraw_event = authz_withdraw_response - .events - .iter() - .find(|e| e.ty == "wasm".to_string()) - .unwrap(); - // Assert events are equal - assert_eq!(withdraw_event.ty, authz_withdraw_event.ty); - assert_eq!( - withdraw_event.attributes.len(), - authz_withdraw_event.attributes.len() - ); - // We need to assert approx here as in the any_deposit case, - // depositing involve a swap that changes the pool's condition for the subsequent one. - for (attr1, attr2) in withdraw_event - .attributes - .iter() - .zip(&authz_withdraw_event.attributes) - { - if attr1.key == "liquidity_amount" { - assert_approx_eq!( - get_amount_from_denom(&attr1.value), - get_amount_from_denom(&attr2.value), - "0.000000000000000001" - ); - } else { - assert_eq!(attr1, attr2); - } - } -} diff --git a/smart-contracts/contracts/cl-vault/tests/range.rs b/smart-contracts/contracts/cl-vault/tests/range.rs deleted file mode 100644 index cc800b6d3..000000000 --- a/smart-contracts/contracts/cl-vault/tests/range.rs +++ /dev/null @@ -1,296 +0,0 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ - fixture_default, fixture_dex_router, init_test_contract, ADMIN_BALANCE_AMOUNT, DENOM_BASE, - DENOM_QUOTE, MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT, -}; - -use cosmwasm_std::{coin, Coin, Decimal, Uint128}; -use osmosis_std::types::{ - cosmos::base::v1beta1, - osmosis::{ - concentratedliquidity::{ - poolmodel::concentrated::v1beta1::MsgCreateConcentratedPool, - v1beta1::{MsgCreatePosition, Pool, PoolsRequest}, - }, - poolmanager::v1beta1::SwapAmountInRoute, - }, -}; -use osmosis_test_tube::{Account, ConcentratedLiquidity, Module, Wasm}; -use prost::Message; -use std::str::FromStr; - -use cl_vault::{ - msg::{ - ClQueryMsg, ExecuteMsg, ExtensionExecuteMsg, ExtensionQueryMsg, ModifyRangeMsg, QueryMsg, - }, - query::PositionResponse, -}; - -#[test] -fn move_range_works() { - let (app, contract_address, _cl_pool_id, admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); - let wasm = Wasm::new(&app); - - let _before_position: PositionResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( - ClQueryMsg::Position {}, - )), - ) - .unwrap(); - - let _result = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { - lower_price: Decimal::from_str("0.65").unwrap(), - upper_price: Decimal::from_str("1.3").unwrap(), - max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - ratio_of_swappable_funds_to_use: Decimal::one(), - twap_window_seconds: 45, - forced_swap_route: None, - claim_after: None, - })), - &[], - &admin, - ) - .unwrap(); - - let _after_position: PositionResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( - ClQueryMsg::Position {}, - )), - ) - .unwrap(); -} - -#[test] -fn move_range_cw_dex_works() { - let ( - app, - contract_address, - _dex_router_addr, - _vault_pool_id, - _swap_pools_ids, - admin, - _deposit_ratio, - _deposit_ratio_approx, - ) = fixture_dex_router(PERFORMANCE_FEE_DEFAULT); - let wasm = Wasm::new(&app); - - let _before_position: PositionResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( - ClQueryMsg::Position {}, - )), - ) - .unwrap(); - - let _result = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { - lower_price: Decimal::from_str("400").unwrap(), - upper_price: Decimal::from_str("1466").unwrap(), - max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - ratio_of_swappable_funds_to_use: Decimal::one(), - twap_window_seconds: 45, - // forced_swap_route: Some(vec![path1]), - forced_swap_route: None, - claim_after: None, - })), - &[], - &admin, - ) - .unwrap(); - - let _after_position: PositionResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( - ClQueryMsg::Position {}, - )), - ) - .unwrap(); -} - -// TODO: further enhance this forced swap test logic -#[test] -fn move_range_cw_dex_works_forced_swap_route() { - let ( - app, - contract_address, - _dex_router_addr, - vault_pool_id, - _swap_pools_ids, - admin, - _deposit_ratio, - _deposit_ratio_approx, - ) = fixture_dex_router(PERFORMANCE_FEE_DEFAULT); - let wasm = Wasm::new(&app); - - let _before_position: PositionResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( - ClQueryMsg::Position {}, - )), - ) - .unwrap(); - - // Define CW Dex Router swap route to force - // In this case we are going from in range, to out of range to the upper side, so we swap all the quote token to base token - let path1 = SwapAmountInRoute { - pool_id: vault_pool_id, - token_out_denom: DENOM_BASE.to_string(), - }; - - let _result = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { - lower_price: Decimal::from_str("400").unwrap(), - upper_price: Decimal::from_str("1466").unwrap(), - max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - ratio_of_swappable_funds_to_use: Decimal::one(), - twap_window_seconds: 45, - forced_swap_route: Some(vec![path1]), - claim_after: None, - })), - &[], - &admin, - ) - .unwrap(); - - let _after_position: PositionResponse = wasm - .query( - contract_address.as_str(), - &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( - ClQueryMsg::Position {}, - )), - ) - .unwrap(); -} - -#[test] -fn move_range_single_side_works() { - let (app, contract_address, _cl_pool_id, admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); - let wasm = Wasm::new(&app); - - let _result = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { - lower_price: Decimal::from_str("20.71").unwrap(), - upper_price: Decimal::from_str("45").unwrap(), - max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - ratio_of_swappable_funds_to_use: Decimal::one(), - twap_window_seconds: 45, - forced_swap_route: None, - claim_after: None, - })), - &[], - &admin, - ) - .unwrap(); - - let _result = wasm - .execute( - contract_address.as_str(), - &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { - lower_price: Decimal::from_str("0.1").unwrap(), - upper_price: Decimal::from_str("0.2").unwrap(), - max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - ratio_of_swappable_funds_to_use: Decimal::one(), - twap_window_seconds: 45, - forced_swap_route: None, - claim_after: None, - })), - &[], - &admin, - ) - .unwrap(); -} - -/* -we try the following position from https://docs.google.com/spreadsheets/d/1xPsKsQkM0apTZQPBBwVlEyB5Sk31sw6eE8U0FgnTWUQ/edit?usp=sharing -lower_price: 4500 -current_price: 4692.937 -upper_price: 5500 - -the spreadsheet says we need to leave 42806.28569 in token x and swap over 157193.7143 -157193.7143 / 4692.937 = 33.49580749 -both token amounts are used in 5 decimals, since the leftover amount is in 5 decimals -so we want to deposit 4280628569 and 3349580 -*/ -#[test] -fn test_swap_math_poc() { - let (app, _contract, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - init_test_contract( - // TODO: Evaluate using fixture_default() - "./test-tube-build/wasm32-unknown-unknown/release/cl_vault.wasm", - &[ - Coin::new(ADMIN_BALANCE_AMOUNT, "uosmo"), - Coin::new(ADMIN_BALANCE_AMOUNT, DENOM_BASE), - Coin::new(ADMIN_BALANCE_AMOUNT, DENOM_QUOTE), - ], - MsgCreateConcentratedPool { - sender: "overwritten".to_string(), - denom0: DENOM_BASE.to_string(), //token0 is uatom - denom1: DENOM_QUOTE.to_string(), //token1 is uosmo - tick_spacing: 100, - spread_factor: Decimal::from_str("0.0001").unwrap().atomics().to_string(), - }, - 30500000, // 4500 - 31500000, // 5500 - vec![ - v1beta1::Coin { - denom: DENOM_BASE.to_string(), - amount: "1000000".to_string(), - }, - v1beta1::Coin { - denom: DENOM_QUOTE.to_string(), - amount: "1000000".to_string(), - }, - ], - Uint128::zero(), - Uint128::zero(), - PERFORMANCE_FEE_DEFAULT, - ); - let alice = app - .init_account(&[ - Coin::new(1_000_000_000_000, "uosmo"), - Coin::new(1_000_000_000_000, DENOM_BASE), - Coin::new(1_000_000_000_000, DENOM_QUOTE), - ]) - .unwrap(); - - let cl = ConcentratedLiquidity::new(&app); - - let pools = cl.query_pools(&PoolsRequest { pagination: None }).unwrap(); - let pool: Pool = Pool::decode(pools.pools[0].value.as_slice()).unwrap(); - - // from the spreadsheet - // create a basic position on the pool - let initial_position = MsgCreatePosition { - pool_id: pool.id, - sender: alice.address(), - lower_tick: 30500000, - upper_tick: 31500000, - tokens_provided: vec![ - coin(3349580, DENOM_BASE).into(), - coin(4280628569, DENOM_QUOTE).into(), - ], - token_min_amount0: "0".to_string(), - token_min_amount1: "0".to_string(), - }; - let _position = cl.create_position(initial_position, &alice).unwrap(); -} diff --git a/smart-contracts/contracts/cw-4626/.cargo/config b/smart-contracts/contracts/cw-4626/.cargo/config deleted file mode 100644 index 8d4bc738b..000000000 --- a/smart-contracts/contracts/cw-4626/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/smart-contracts/contracts/cw-4626/Cargo.lock b/smart-contracts/contracts/cw-4626/Cargo.lock deleted file mode 100644 index 089cfe022..000000000 --- a/smart-contracts/contracts/cw-4626/Cargo.lock +++ /dev/null @@ -1,745 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "arrayvec" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f95658fed27bc64d4547da6fdbd2f7375bbf84e2f4c6ee6f0cab544294ecaca" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-4626" -version = "0.13.4" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "cw20-base", - "quasar-traits", - "quasar-types", - "schemars", - "serde", - "share-distributor", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "cw20" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" -dependencies = [ - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "cw20-base" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0306e606581f4fb45e82bcbb7f0333179ed53dd949c6523f01a99b4bfc1475a0" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "cw-utils", - "cw2", - "cw20", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quasar-traits" -version = "0.1.0" -dependencies = [ - "cosmwasm-std", - "cw20", - "schemars", - "serde", -] - -[[package]] -name = "quasar-types" -version = "0.1.0" -dependencies = [ - "cosmwasm-std", - "cw20", - "quasar-traits", - "rust_decimal", - "schemars", - "serde", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "rust_decimal" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34a3bb58e85333f1ab191bf979104b586ebd77475bc6681882825f4532dfe87c" -dependencies = [ - "arrayvec", - "num-traits", - "serde", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "schemars" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b5a3c80cea1ab61f4260238409510e814e38b4b563c06044edf91e7dc070e3" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ae4dce13e8614c46ac3c38ef1c0d668b101df6ac39817aebdaa26642ddae9b" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "share-distributor" -version = "0.1.0" -dependencies = [ - "cosmwasm-std", - "cw20", - "quasar-traits", - "schemars", - "serde", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-xid" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/smart-contracts/contracts/cw-4626/Cargo.toml b/smart-contracts/contracts/cw-4626/Cargo.toml deleted file mode 100644 index 836d41947..000000000 --- a/smart-contracts/contracts/cw-4626/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -name = "cw-4626" -version = "0.13.4" -authors = ["Laurens Kubat "] -edition = "2021" -description = "Basic implementation of the Quasar vault" -license = "Apache-2.0" -repository = "https://github.com/quasar-finance/quasar" -homepage = "https://www.quasar.fi/" -documentation = "" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -serde_json = { workspace = true } -thiserror = { workspace = true } -cw-utils = { workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cw20-base = { workspace = true } - -quasar-traits = { path = "../../packages/quasar-traits" } -quasar-types = { path = "../../packages/quasar-types"} -strategy = { path = "../strategy", features = ["library"]} - -[dev-dependencies] -cosmwasm-schema = { workspace = true } diff --git a/smart-contracts/contracts/cw-4626/NOTICE b/smart-contracts/contracts/cw-4626/NOTICE deleted file mode 100644 index 84b1c2103..000000000 --- a/smart-contracts/contracts/cw-4626/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-Base: A reference implementation for fungible token on CosmWasm -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/smart-contracts/contracts/cw-4626/README.md b/smart-contracts/contracts/cw-4626/README.md deleted file mode 100644 index 7ab7f7aa3..000000000 --- a/smart-contracts/contracts/cw-4626/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# CW-4626 - CW20 Base - -Built on the [CW20 Base](https://github.com/CosmWasm/cw-plus/tree/main/contracts/cw20-base) contract, this contract -is a basic implementation of [eip-4626](https://eips.ethereum.org/EIPS/eip-4626). -This is a basic implementation of a cw20 contract. It implements -the [CW20 spec](quasar-finance/quasar/smart-contracts/cw-plus/packages/cw20/README.md) and is designed to -be deployed as is, or imported into other contracts to easily build -cw20-compatible tokens with custom logic. - -Implements: - -- [x] CW20 Base -- [x] Mintable extension -- [x] Allowances extension -- [ ] EIP-4626 implementation - - [ ] Change CW-20 asset to vault share - - [ ] implement EIP-4626 interface for cosmwasm - - [x] Implement token whitelist - - [ ] Add share minting logic - - [ ] Add share burning logic - - [ ] Add support for all queries - - [ ] Add support for all execute messages -- [ ] Multi-Asset Deposit -- [ ] Multi-Asset Withdrawal -- [ ] Strategy trait - -## Running this contract - -You will need Rust 1.44.1+ with `wasm32-unknown-unknown` target installed. - -You can run unit tests on this via: - -`cargo test` - -Once you are happy with the content, you can compile it to wasm via: - -``` -RUSTFLAGS='-C link-arg=-s' cargo wasm -cp ../../target/wasm32-unknown-unknown/release/cw20_base.wasm . -ls -l cw20_base.wasm -sha256sum cw20_base.wasm -``` - -Or for a production-ready (optimized) build, run a build command in the -the repository root: https://github.com/CosmWasm/cw-plus#compiling. - -## Importing this contract - -You can also import much of the logic of this contract to build another -ERC20-contract, such as a bonding curve, overiding or extending what you -need. - -Basically, you just need to write your handle function and import -`cw20_base::contract::handle_transfer`, etc and dispatch to them. -This allows you to use custom `ExecuteMsg` and `QueryMsg` with your additional -calls, but then use the underlying implementation for the standard cw20 -messages you want to support. The same with `QueryMsg`. You *could* reuse `instantiate` -as it, but it is likely you will want to change it. And it is rather simple. - -Look at [`cw20-staking`](https://github.com/CosmWasm/cw-tokens/tree/main/contracts/cw20-staking) for an example of how to "inherit" -all this token functionality and combine it with custom logic. diff --git a/smart-contracts/contracts/cw-4626/examples/schema.rs b/smart-contracts/contracts/cw-4626/examples/schema.rs deleted file mode 100644 index ebc8fc33e..000000000 --- a/smart-contracts/contracts/cw-4626/examples/schema.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; -extern crate cw_4626; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; -use cw20::{ - AllAccountsResponse, AllAllowancesResponse, AllowanceResponse, BalanceResponse, - TokenInfoResponse, -}; -use cw20_base::msg::{ExecuteMsg, QueryMsg}; -use cw_4626::msg::{ - AssetResponse, ConvertToAssetsResponse, ConvertToSharesResponse, InstantiateMsg, - MaxDepositResponse, TotalAssetResponse, VaultInfoResponse, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(AllowanceResponse), &out_dir); - export_schema(&schema_for!(BalanceResponse), &out_dir); - export_schema(&schema_for!(TokenInfoResponse), &out_dir); - export_schema(&schema_for!(AllAllowancesResponse), &out_dir); - export_schema(&schema_for!(AllAccountsResponse), &out_dir); - // the cw-4626 schemas - export_schema(&schema_for!(AssetResponse), &out_dir); - export_schema(&schema_for!(TotalAssetResponse), &out_dir); - export_schema(&schema_for!(ConvertToSharesResponse), &out_dir); - export_schema(&schema_for!(ConvertToAssetsResponse), &out_dir); - export_schema(&schema_for!(MaxDepositResponse), &out_dir); - export_schema(&schema_for!(VaultInfoResponse), &out_dir); -} diff --git a/smart-contracts/contracts/cw-4626/schema/all_accounts_response.json b/smart-contracts/contracts/cw-4626/schema/all_accounts_response.json deleted file mode 100644 index cea50fba4..000000000 --- a/smart-contracts/contracts/cw-4626/schema/all_accounts_response.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAccountsResponse", - "type": "object", - "required": [ - "accounts" - ], - "properties": { - "accounts": { - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/all_allowances_response.json b/smart-contracts/contracts/cw-4626/schema/all_allowances_response.json deleted file mode 100644 index 6bb2291ce..000000000 --- a/smart-contracts/contracts/cw-4626/schema/all_allowances_response.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAllowancesResponse", - "type": "object", - "required": [ - "allowances" - ], - "properties": { - "allowances": { - "type": "array", - "items": { - "$ref": "#/definitions/AllowanceInfo" - } - } - }, - "definitions": { - "AllowanceInfo": { - "type": "object", - "required": [ - "allowance", - "expires", - "spender" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "spender": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/allowance_response.json b/smart-contracts/contracts/cw-4626/schema/allowance_response.json deleted file mode 100644 index c4f98d6fc..000000000 --- a/smart-contracts/contracts/cw-4626/schema/allowance_response.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/asset_response.json b/smart-contracts/contracts/cw-4626/schema/asset_response.json deleted file mode 100644 index e5ff52aa7..000000000 --- a/smart-contracts/contracts/cw-4626/schema/asset_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AssetResponse", - "type": "object", - "required": [ - "denom" - ], - "properties": { - "denom": { - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/balance_response.json b/smart-contracts/contracts/cw-4626/schema/balance_response.json deleted file mode 100644 index 4e1a0be2b..000000000 --- a/smart-contracts/contracts/cw-4626/schema/balance_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/convert_to_assets_response.json b/smart-contracts/contracts/cw-4626/schema/convert_to_assets_response.json deleted file mode 100644 index 803477018..000000000 --- a/smart-contracts/contracts/cw-4626/schema/convert_to_assets_response.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConvertToAssetsResponse", - "type": "object", - "required": [ - "assets" - ], - "properties": { - "assets": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/convert_to_shares_response.json b/smart-contracts/contracts/cw-4626/schema/convert_to_shares_response.json deleted file mode 100644 index fcf1dd75c..000000000 --- a/smart-contracts/contracts/cw-4626/schema/convert_to_shares_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConvertToSharesResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/cw20_execute_msg.json b/smart-contracts/contracts/cw-4626/schema/cw20_execute_msg.json deleted file mode 100644 index e4bc559cd..000000000 --- a/smart-contracts/contracts/cw-4626/schema/cw20_execute_msg.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Cw20ExecuteMsg", - "oneOf": [ - { - "description": "Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"mintable\" extension. If authorized, creates amount new tokens and adds to the recipient balance.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"marketing\" extension. If authorized, updates marketing metadata. Setting None/null for any of these will leave it unchanged. Setting Some(\"\") will clear this field on the contract storage", - "type": "object", - "required": [ - "update_marketing" - ], - "properties": { - "update_marketing": { - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "type": [ - "string", - "null" - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "If set as the \"marketing\" role on the contract, upload a new URL, SVG, or PNG for the token", - "type": "object", - "required": [ - "upload_logo" - ], - "properties": { - "upload_logo": { - "$ref": "#/definitions/Logo" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object" - } - }, - "additionalProperties": false - } - ] - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/instantiate_msg.json b/smart-contracts/contracts/cw-4626/schema/instantiate_msg.json deleted file mode 100644 index 859785a73..000000000 --- a/smart-contracts/contracts/cw-4626/schema/instantiate_msg.json +++ /dev/null @@ -1,240 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "curve_type", - "initial_balances", - "name", - "reserve_decimals", - "reserve_denom", - "reserve_total_supply", - "supply_decimals", - "symbol" - ], - "properties": { - "curve_type": { - "$ref": "#/definitions/CurveType" - }, - "initial_balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "marketing": { - "anyOf": [ - { - "$ref": "#/definitions/InstantiateMarketingInfo" - }, - { - "type": "null" - } - ] - }, - "mint": { - "anyOf": [ - { - "$ref": "#/definitions/MinterResponse" - }, - { - "type": "null" - } - ] - }, - "name": { - "type": "string" - }, - "reserve_decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "reserve_denom": { - "type": "string" - }, - "reserve_total_supply": { - "$ref": "#/definitions/Uint128" - }, - "supply_decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "symbol": { - "type": "string" - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec", - "type": "string" - }, - "CurveType": { - "oneOf": [ - { - "type": "object", - "required": [ - "constant" - ], - "properties": { - "constant": { - "type": "object", - "required": [ - "scale", - "value" - ], - "properties": { - "scale": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "value": { - "$ref": "#/definitions/Uint128" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - } - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "InstantiateMarketingInfo": { - "type": "object", - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "logo": { - "anyOf": [ - { - "$ref": "#/definitions/Logo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "type": [ - "string", - "null" - ] - }, - "project": { - "type": [ - "string", - "null" - ] - } - } - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "MinterResponse": { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/max_deposit_response.json b/smart-contracts/contracts/cw-4626/schema/max_deposit_response.json deleted file mode 100644 index e442f80e7..000000000 --- a/smart-contracts/contracts/cw-4626/schema/max_deposit_response.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MaxDepositResponse", - "description": "A None response indicates that the vault has no cap an thus no max deposit", - "type": "object", - "properties": { - "max_assets": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/query_msg.json b/smart-contracts/contracts/cw-4626/schema/query_msg.json deleted file mode 100644 index 7c33c352d..000000000 --- a/smart-contracts/contracts/cw-4626/schema/query_msg.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse.", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Returns metadata on the contract - name, decimals, supply, etc. Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"mintable\" extension. Returns who can mint and the hard cap on maximum tokens after minting. Return type: MinterResponse.", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset. Return type: AllowanceResponse.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension (and \"allowances\") Returns all allowances this owner has approved. Supports pagination. Return type: AllAllowancesResponse.", - "type": "object", - "required": [ - "all_allowances" - ], - "properties": { - "all_allowances": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension Returns all accounts that have balances. Supports pagination. Return type: AllAccountsResponse.", - "type": "object", - "required": [ - "all_accounts" - ], - "properties": { - "all_accounts": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Returns more metadata on the contract to display in the client: - description, logo, project url, etc. Return type: MarketingInfoResponse", - "type": "object", - "required": [ - "marketing_info" - ], - "properties": { - "marketing_info": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Downloads the embedded logo data (if stored on chain). Errors if no logo data is stored for this contract. Return type: DownloadLogoResponse.", - "type": "object", - "required": [ - "download_logo" - ], - "properties": { - "download_logo": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/smart-contracts/contracts/cw-4626/schema/token_info_response.json b/smart-contracts/contracts/cw-4626/schema/token_info_response.json deleted file mode 100644 index 9920c841f..000000000 --- a/smart-contracts/contracts/cw-4626/schema/token_info_response.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/total_asset_response.json b/smart-contracts/contracts/cw-4626/schema/total_asset_response.json deleted file mode 100644 index fb1624ad4..000000000 --- a/smart-contracts/contracts/cw-4626/schema/total_asset_response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TotalAssetResponse", - "type": "object", - "required": [ - "total_managed_assets" - ], - "properties": { - "total_managed_assets": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/schema/vault_info_response.json b/smart-contracts/contracts/cw-4626/schema/vault_info_response.json deleted file mode 100644 index 1a8f605cf..000000000 --- a/smart-contracts/contracts/cw-4626/schema/vault_info_response.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VaultInfoResponse", - "type": "object", - "required": [ - "reserve_denom", - "total_supply" - ], - "properties": { - "reserve_denom": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/cw-4626/src/contract.rs b/smart-contracts/contracts/cw-4626/src/contract.rs deleted file mode 100644 index 466cfe70f..000000000 --- a/smart-contracts/contracts/cw-4626/src/contract.rs +++ /dev/null @@ -1,958 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - coins, to_json_binary, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, - Uint128, -}; -use cw2::set_contract_version; -use cw20::{EmbeddedLogo, Logo, LogoInfo, MarketingInfoResponse}; - -// TODO decide if we want to use deduct allowance -use cw20_base::allowances::{ - execute_decrease_allowance, execute_increase_allowance, execute_send_from, - execute_transfer_from, query_allowance, -}; -use cw20_base::contract::{ - execute_burn, execute_mint, execute_send, execute_transfer, execute_update_marketing, - execute_upload_logo, query_balance, query_download_logo, query_marketing_info, query_minter, - query_token_info, -}; -use cw20_base::enumerable::{query_all_accounts, query_all_allowances}; -use cw20_base::state::{MinterData, TokenInfo, LOGO, MARKETING_INFO, TOKEN_INFO}; -use cw_utils::{must_pay, nonpayable}; - -use quasar_types::curve::DecimalPlaces; -use strategy::contract::{execute_deposit as execute_strategy_deposit, execute_withdraw_request}; - -use crate::error::ContractError; -use crate::msg::{ - AssetResponse, ConvertToAssetsResponse, ConvertToSharesResponse, ExecuteMsg, InstantiateMsg, - MaxDepositResponse, QueryMsg, TotalAssetResponse, VaultInfoResponse, -}; -use crate::state::{VaultInfo, VAULT_CURVE, VAULT_INFO}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:cw-4626"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -const LOGO_SIZE_CAP: usize = 5 * 1024; - -/// Checks if data starts with XML preamble -fn verify_xml_preamble(data: &[u8]) -> Result<(), cw20_base::ContractError> { - // The easiest way to perform this check would be just match on regex, however regex - // compilation is heavy and probably not worth it. - - let preamble = data - .split_inclusive(|c| *c == b'>') - .next() - .ok_or(cw20_base::ContractError::InvalidXmlPreamble {})?; - - const PREFIX: &[u8] = b""; - - if !(preamble.starts_with(PREFIX) && preamble.ends_with(POSTFIX)) { - Err(cw20_base::ContractError::InvalidXmlPreamble {}) - } else { - Ok(()) - } - - // Additionally attributes format could be validated as they are well defined, as well as - // comments presence inside of preable, but it is probably not worth it. -} - -/// Validates XML logo -fn verify_xml_logo(logo: &[u8]) -> Result<(), cw20_base::ContractError> { - verify_xml_preamble(logo)?; - - if logo.len() > LOGO_SIZE_CAP { - Err(cw20_base::ContractError::LogoTooBig {}) - } else { - Ok(()) - } -} - -/// Validates png logo -fn verify_png_logo(logo: &[u8]) -> Result<(), cw20_base::ContractError> { - // PNG header format: - // 0x89 - magic byte, out of ASCII table to fail on 7-bit systems - // "PNG" ascii representation - // [0x0d, 0x0a] - dos style line ending - // 0x1a - dos control character, stop displaying rest of the file - // 0x0a - unix style line ending - const HEADER: [u8; 8] = [0x89, b'P', b'N', b'G', 0x0d, 0x0a, 0x1a, 0x0a]; - if logo.len() > LOGO_SIZE_CAP { - Err(cw20_base::ContractError::LogoTooBig {}) - } else if !logo.starts_with(&HEADER) { - Err(cw20_base::ContractError::InvalidPngHeader {}) - } else { - Ok(()) - } -} - -/// Checks if passed logo is correct, and if not, returns an error -fn verify_logo(logo: &Logo) -> Result<(), cw20_base::ContractError> { - match logo { - Logo::Embedded(EmbeddedLogo::Svg(logo)) => verify_xml_logo(logo), - Logo::Embedded(EmbeddedLogo::Png(logo)) => verify_png_logo(logo), - Logo::Url(_) => Ok(()), // Any reasonable url validation would be regex based, probably not worth it - } -} - -// TODO add the curve of the vault here -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // check valid token info - msg.validate()?; - - // set the share distributor of the vault to the single token distributor - VAULT_INFO.save( - deps.storage, - &VaultInfo { - reserve_denom: msg.reserve_denom.to_string(), - total_supply: msg.reserve_total_supply, - decimals: DecimalPlaces { - supply: msg.supply_decimals as u32, - reserve: msg.reserve_decimals as u32, - }, - }, - )?; - - // store token info - let data = TokenInfo { - name: msg.name, - symbol: msg.symbol, - decimals: msg.supply_decimals, - total_supply: Uint128::zero(), - // set self as minter, so we can properly execute mint and burn - mint: Some(MinterData { - minter: env.contract.address, - cap: None, - }), - }; - TOKEN_INFO.save(deps.storage, &data)?; - - if let Some(marketing) = msg.marketing { - let logo = if let Some(logo) = marketing.logo { - verify_logo(&logo)?; - LOGO.save(deps.storage, &logo)?; - - match logo { - Logo::Url(url) => Some(LogoInfo::Url(url)), - Logo::Embedded(_) => Some(LogoInfo::Embedded), - } - } else { - None - }; - - let data = MarketingInfoResponse { - project: marketing.project, - description: marketing.description, - marketing: marketing - .marketing - .map(|addr| deps.api.addr_validate(&addr)) - .transpose()?, - logo, - }; - MARKETING_INFO.save(deps.storage, &data)?; - } - - VAULT_CURVE.save(deps.storage, &msg.curve_type)?; - - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - // the vault execute messages - ExecuteMsg::Deposit {} => execute_deposit(deps, env, info), - ExecuteMsg::Withdraw { amount } => execute_withdraw(deps, env, info, amount), - // the cw-20 execute messages - ExecuteMsg::Transfer { recipient, amount } => { - Ok(execute_transfer(deps, env, info, recipient, amount)?) - } - ExecuteMsg::Burn { amount } => Ok(execute_burn(deps, env, info, amount)?), - ExecuteMsg::Send { - contract, - amount, - msg, - } => Ok(execute_send(deps, env, info, contract, amount, msg)?), - ExecuteMsg::Mint { recipient, amount } => { - Ok(execute_mint(deps, env, info, recipient, amount)?) - } - ExecuteMsg::IncreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_increase_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::DecreaseAllowance { - spender, - amount, - expires, - } => Ok(execute_decrease_allowance( - deps, env, info, spender, amount, expires, - )?), - ExecuteMsg::TransferFrom { - owner, - recipient, - amount, - } => Ok(execute_transfer_from( - deps, env, info, owner, recipient, amount, - )?), - ExecuteMsg::BurnFrom { owner, amount } => { - Ok(execute_burn_from(deps, env, info, owner, amount)?) - } - ExecuteMsg::SendFrom { - owner, - contract, - amount, - msg, - } => Ok(execute_send_from( - deps, env, info, owner, contract, amount, msg, - )?), - ExecuteMsg::UpdateMarketing { - project, - description, - marketing, - } => Ok(execute_update_marketing( - deps, - env, - info, - project, - description, - marketing, - )?), - ExecuteMsg::UploadLogo(logo) => Ok(execute_upload_logo(deps, env, info, logo)?), - ExecuteMsg::Receive { .. } => { - todo!() - } - } -} - -pub fn execute_deposit( - mut deps: DepsMut, - env: Env, - info: MessageInfo, -) -> Result { - // do all reasonable checks - let vault_info = VAULT_INFO.load(deps.storage)?; - let curve = VAULT_CURVE.load(deps.storage)?; - let curve_fn = curve.to_curve_fn(); - let curve = curve_fn(vault_info.decimals); - // only accept one token, change this for multi asset - - // TODO this is a hardcoded amount of a linear 1-1 price, we need to change this with customizable curves - let amount = must_pay(&info, vault_info.reserve_denom.as_str())?; - - // deposit the funds into the strategy - // TODO remove clones and decide whether we directly pass info - execute_strategy_deposit(deps.branch(), env.clone(), info.clone())?; - - let shares = curve.deposit(&amount); - // call into cw20-base to mint the token, call as self as no one else is allowed - let sub_info = MessageInfo { - sender: env.contract.address.clone(), - funds: vec![], - }; - // exchange all the free balance for shares, mint shares of the underlying cw-20 - execute_mint(deps, env, sub_info, info.sender.to_string(), shares)?; - - let res = Response::new() - .add_attribute("action", "buy") - .add_attribute("from", info.sender) - .add_attribute("reserve", amount) - .add_attribute("shares", shares); - Ok(res) -} - -// TODO decide on whether to add owner here for allowance support -pub fn execute_withdraw( - mut deps: DepsMut, - env: Env, - info: MessageInfo, - amount: Option, -) -> Result { - // check that no funds are sent with the withdraw - nonpayable(&info)?; - - // TODO make this a bit nicer with a helper - let vault_info = VAULT_INFO.load(deps.storage)?; - let curve_type = VAULT_CURVE.load(deps.storage)?; - let curve_fn = curve_type.to_curve_fn(); - let curve = curve_fn(vault_info.decimals); - - // if amount is None, sell all shares of sender - let shares = if let Some(value) = amount { - value - } else { - let addr = &info.sender.to_string(); - query_balance(deps.as_ref(), addr.clone())?.balance - }; - - let withdraw_amount = curve.withdraw(&shares); - - // TODO here we need to withdraw from the strategy, if the strategy has the funds, we can simply withdraw - // if the withdraw is queued, do we already burn and mint again if we need to reverse or not burn at all? - let withdraw_res = execute_withdraw_request( - deps.branch(), - env.clone(), - info.clone(), - info.sender.to_string(), - vault_info.reserve_denom, - withdraw_amount, - )?; - - // execute_burn will error if the sender does not have enough tokens to burn - // TODO make sure that we can discard the result of execute_burn - execute_burn(deps.branch(), env, info.clone(), shares)?; - - // we have created the Send bankmessage in the strategy contract, thus we pass res.messages here - let res = Response::new() - .add_submessages(withdraw_res.messages) - .add_attributes(withdraw_res.attributes) - .add_attribute("action", "sell") - .add_attribute("to", &info.sender) - .add_attribute("amount", shares); - Ok(res) -} - -// TODO implement burn_from to support the cw20 allowances -// execute_burn_from tries to burn the shares from owner if sender has an allowance over those tokens -// in the cw20 contract. The underlying reserve tokens should be returned to who? probably the sender -// and not the owner -pub fn execute_burn_from( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _owner: String, - _amount: Uint128, -) -> Result { - todo!() -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Balance { address } => to_json_binary(&query_balance(deps, address)?), - QueryMsg::TokenInfo {} => to_json_binary(&query_token_info(deps)?), - QueryMsg::Minter {} => to_json_binary(&query_minter(deps)?), - QueryMsg::Allowance { owner, spender } => { - to_json_binary(&query_allowance(deps, owner, spender)?) - } - QueryMsg::AllAllowances { - owner, - start_after, - limit, - } => to_json_binary(&query_all_allowances(deps, owner, start_after, limit)?), - QueryMsg::AllAccounts { start_after, limit } => { - to_json_binary(&query_all_accounts(deps, start_after, limit)?) - } - QueryMsg::MarketingInfo {} => to_json_binary(&query_marketing_info(deps)?), - QueryMsg::DownloadLogo {} => to_json_binary(&query_download_logo(deps)?), - QueryMsg::Asset {} => to_json_binary(&query_asset(deps)?), - QueryMsg::TotalAssets {} => to_json_binary(&query_total_assets(deps, env)?), - QueryMsg::ConvertToShares { assets } => to_json_binary(&query_convert_to_shares(deps, assets)?), - QueryMsg::ConvertToAssets { shares } => to_json_binary(&query_convert_to_assets(deps, shares)?), - QueryMsg::MaxDeposit { - receiver: _receiver, - } => { - // max deposit needs to check the underlying cw-20 token for the maximum supply, convert that - // to the amount - to_json_binary(&query_max_deposit(deps)?) - } - QueryMsg::PreviewDeposit { .. } => { - todo!() - } - QueryMsg::MaxMint { .. } => { - todo!() - } - QueryMsg::PreviewMint { .. } => { - todo!() - } - QueryMsg::MaxWithdraw { .. } => { - todo!() - } - QueryMsg::PreviewWithdraw { .. } => { - todo!() - } - QueryMsg::MaxRedeem { .. } => { - todo!() - } - QueryMsg::PreviewRedeem { .. } => { - todo!() - } - QueryMsg::VaultInfo {} => to_json_binary(&query_vault_info(deps)?), - } -} - -pub fn query_asset(deps: Deps) -> StdResult { - let vault_info = VAULT_INFO.load(deps.storage)?; - Ok(AssetResponse { - denom: vault_info.reserve_denom, - }) -} - -pub fn query_total_assets(deps: Deps, env: Env) -> StdResult { - let vault_info = VAULT_INFO.load(deps.storage)?; - let balance = deps - .querier - .query_balance(env.contract.address, vault_info.reserve_denom)?; - Ok(TotalAssetResponse { - total_managed_assets: balance.amount, - }) -} - -pub fn query_convert_to_shares( - deps: Deps, - assets: Vec, -) -> StdResult { - let vault_info = VAULT_INFO.load(deps.storage)?; - let curve_type = VAULT_CURVE.load(deps.storage)?; - let curve_fn = curve_type.to_curve_fn(); - let curve = curve_fn(vault_info.decimals); - - // error on wrong amount of assets - if assets.len() != 1 { - return Err(StdError::generic_err("Query only supports one asset")); - } - - // error on wrong denom - if assets[0].denom != vault_info.reserve_denom { - return Err(StdError::generic_err(format!( - "Expected {} instead of {}", - vault_info.reserve_denom, assets[0].denom - ))); - } - - let shares = curve.deposit(&assets[0].amount); - - Ok(ConvertToSharesResponse { amount: shares }) -} - -pub fn query_convert_to_assets(deps: Deps, shares: Uint128) -> StdResult { - let vault_info = VAULT_INFO.load(deps.storage)?; - let curve_type = VAULT_CURVE.load(deps.storage)?; - let curve_fn = curve_type.to_curve_fn(); - let curve = curve_fn(vault_info.decimals); - - let amount = curve.withdraw(&shares); - Ok(ConvertToAssetsResponse { - assets: coins(amount.u128(), vault_info.reserve_denom), - }) -} - -fn query_max_deposit(deps: Deps) -> StdResult { - let vault_info = VAULT_INFO.load(deps.storage)?; - let curve_type = VAULT_CURVE.load(deps.storage)?; - let curve_fn = curve_type.to_curve_fn(); - let curve = curve_fn(vault_info.decimals); - - let minter = query_minter(deps)?; - let free_tokens: Uint128; - if let Some(min) = minter { - // calculate the outstanding tokens - let accounts = query_all_accounts(deps, None, None)?; - let mut outstanding = Uint128::zero(); - for acc in accounts.accounts { - let balance = query_balance(deps, acc)?; - outstanding = outstanding.checked_add(balance.balance)? - } - // if we have a cap, calculate the difference between current outstanding supply and cap - if min.cap.is_some() { - free_tokens = min.cap.unwrap() - outstanding; - } else { - // if there is no cap, what do we do? We can return Uint128::MAX - outstanding tokens - // This does create an issue with normalizing so that probably is not best. - // thus we have to return None here to indicate the vault has no cap - return Ok(MaxDepositResponse { max_assets: None }); - } - } else { - return Err(StdError::generic_err("no minter found in vault")); - } - // in order to get this many shares, we calculate F^-1(X), or withdraw, since withdraw and deposit are reversible - let asset = curve.deposit(&free_tokens); - Ok(MaxDepositResponse { - max_assets: Some(coins(asset.u128(), vault_info.reserve_denom)), - }) -} - -pub fn query_vault_info(deps: Deps) -> StdResult { - let info = VAULT_INFO.load(deps.storage)?; - let res = VaultInfoResponse { - reserve_denom: info.reserve_denom, - total_supply: info.total_supply, - }; - Ok(res) -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; - use cosmwasm_std::{ - coin, BankMsg, Decimal, OverflowError, OverflowOperation, StdError, SubMsg, - }; - use cw_utils::PaymentError; - use quasar_types::curve::CurveType; - use std::borrow::BorrowMut; - - const DENOM: &str = "satoshi"; - const CREATOR: &str = "creator"; - const INVESTOR: &str = "investor"; - const BUYER: &str = "buyer"; - - fn default_instantiate( - supply_decimals: u8, - reserve_decimals: u8, - reserve_supply: Uint128, - ) -> InstantiateMsg { - InstantiateMsg { - name: "Bonded".to_string(), - symbol: "EPOXY".to_string(), - reserve_denom: DENOM.to_string(), - reserve_total_supply: reserve_supply, - reserve_decimals, - supply_decimals, - initial_balances: vec![], - // initiate with a constant 1 to 1 curve - curve_type: CurveType::Constant { - value: Uint128::new(10), - scale: 1, - }, - mint: None, - marketing: None, - } - } - - fn get_balance>(deps: Deps, addr: U) -> Uint128 { - query_balance(deps, addr.into()).unwrap().balance - } - - fn setup_test( - deps: DepsMut, - supply_decimals: u8, - reserve_decimals: u8, - reserve_supply: Uint128, - ) { - // this matches `constant_curve` test case from curves.rs - let creator = String::from(CREATOR); - let msg = default_instantiate(supply_decimals, reserve_decimals, reserve_supply); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps, mock_env(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - } - - fn setup_test_with_deposit( - mut deps: DepsMut, - env: Env, - supply_decimals: u8, - reserve_decimals: u8, - reserve_supply: Uint128, - deposited_funds: u128, - received_shares: u128, - ) { - // this matches `constant_curve` test case from curves.rs - let creator = String::from(CREATOR); - let msg = default_instantiate(supply_decimals, reserve_decimals, reserve_supply); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.branch(), env.clone(), info, msg).unwrap(); - assert_eq!(0, res.messages.len()); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // setup_test() defaults to a 1-1 curve - // bob buys some shares, spends 45 9 decimal coins (45_000_000_000) and receives 45 6 decimal (45_000_000) shares - let info = mock_info(bob, &coins(deposited_funds, DENOM)); - let buy = ExecuteMsg::Deposit {}; - execute(deps.branch(), env, info, buy).unwrap(); - - // check that bob has the shares - assert_eq!( - get_balance(deps.as_ref(), bob), - Uint128::new(received_shares) - ); - } - - #[test] - fn proper_instantiation() { - let mut deps = mock_dependencies(); - - // this matches `linear_curve` test case from curves.rs - let creator = String::from("creator"); - let msg = default_instantiate(2, 8, Uint128::MAX); - let info = mock_info(&creator, &[]); - - // make sure we can instantiate with this - let res = instantiate(deps.as_mut(), mock_env(), info, msg.clone()).unwrap(); - assert_eq!(0, res.messages.len()); - - // token info is proper - let token = query_token_info(deps.as_ref()).unwrap(); - assert_eq!(&token.name, &msg.name); - assert_eq!(&token.symbol, &msg.symbol); - assert_eq!(token.decimals, 2); - assert_eq!(token.total_supply, Uint128::zero()); - // - // // curve state is sensible - // let state = query_curve_info(deps.as_ref(), curve_type.to_curve_fn()).unwrap(); - let state = VAULT_INFO.load(deps.storage.borrow_mut()).unwrap(); - assert_eq!(state.total_supply, Uint128::MAX); - assert_eq!(state.reserve_denom.as_str(), DENOM); - // spot price 0 as supply is 0 - // assert_eq!(state.spot_price, Decimal::zero()); - - // no balance - assert_eq!(get_balance(deps.as_ref(), &creator), Uint128::zero()); - } - - #[test] - fn deposit_works() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // setup_test() defaults to a 1-1 curve - // bob buys some shares, spends 45 9 decimal coins (45_000_000_000) and receives 45 6 decimal (45_000_000) shares - let info = mock_info(bob, &coins(45_000_000_000, DENOM)); - let buy = ExecuteMsg::Deposit {}; - execute(deps.as_mut(), mock_env(), info, buy).unwrap(); - - // check that bob has the shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)); - } - - #[test] - fn deposit_needs_right_denom() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // setup_test() defaults to a 1-1 curve - // bob buys some shares, spends 45 9 decimal coins (45_000_000_000) and receives 45 6 decimal (45_000_000) shares - let info = mock_info(bob, &coins(45_000_000_000, "wrong-denom")); - let buy = ExecuteMsg::Deposit {}; - execute(deps.as_mut(), mock_env(), info, buy).unwrap_err(); - - // check that bob has no shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(0)); - } - - fn deposit_needs_funds() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // setup_test() defaults to a 1-1 curve - // bob tries to buy some shares without any funds - let info = mock_info(bob, &[]); - let buy = ExecuteMsg::Deposit {}; - execute(deps.as_mut(), mock_env(), info, buy).unwrap_err(); - - // check that bob has no shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(0)); - } - - #[test] - fn withdraw_works() { - let mut deps = mock_dependencies(); - // setup_test() defaults to a 1-1 curve - // bob buys some shares, spends 45 9 decimal coins (45_000_000_000) and receives 45 6 decimal (45_000_000) shares - setup_test_with_deposit( - deps.as_mut(), - mock_env(), - 9, - 6, - Uint128::MAX, - 45_000_000_000, - 45_000_000, - ); - - deps.querier - .update_balance(mock_env().contract.address, coins(45_000_000_000, DENOM)); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // check that bob has the shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)); - - let info = mock_info(bob, &[]); - // withdraw all shares - let sell = ExecuteMsg::Withdraw { amount: None }; - let res = execute(deps.as_mut(), mock_env(), info, sell).unwrap(); - - // check that bob's balance is completely gone - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::zero()); - - assert_eq!(res.messages.len(), 1); - // check that bob received a bankmessage containing funds - assert_eq!( - res.messages[0], - SubMsg::new(BankMsg::Send { - to_address: bob.to_string(), - amount: coins(45_000_000_000, DENOM) - }) - ) - } - - #[test] - fn cannot_withdraw_too_many_funds() { - let mut deps = mock_dependencies(); - setup_test_with_deposit( - deps.as_mut(), - mock_env(), - 9, - 6, - Uint128::MAX, - 45_000_000_000, - 45_000_000, - ); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // check that bob has the shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)); - - let info = mock_info(bob, &[]); - // withdraw too many shares - let sell = ExecuteMsg::Withdraw { - amount: Some(Uint128::new(999_000_000)), - }; - execute(deps.as_mut(), mock_env(), info, sell).unwrap_err(); - - // check that bob's balance has not changed - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)) - } - - #[test] - fn cannot_send_funds_with_withdraw() { - let mut deps = mock_dependencies(); - setup_test_with_deposit( - deps.as_mut(), - mock_env(), - 9, - 6, - Uint128::MAX, - 45_000_000_000, - 45_000_000, - ); - - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - // check that bob has the shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)); - - // check that bob has the shares - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)); - - let info = mock_info(bob, &coins(45_000_000_000, DENOM)); - // withdraw too many shares - let sell = ExecuteMsg::Withdraw { - amount: Some(Uint128::new(999_000_000)), - }; - execute(deps.as_mut(), mock_env(), info, sell).unwrap_err(); - - // check that bob's balance has not changed - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000_000)) - } - - #[test] - fn cw20_imports_work() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let alice: &str = "alice"; - let bob: &str = "bobby"; - let carl: &str = "carl"; - - // setup_test() defaults to a 1-1 curve, the supply has 9 decimals and the shares 6 decimals - // spend 45_000_000 uatom for 45_000 shares - let info = mock_info(bob, &coins(45_000_000, DENOM)); - let buy = ExecuteMsg::Deposit {}; - execute(deps.as_mut(), mock_env(), info, buy).unwrap(); - - // check balances - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(45_000)); - assert_eq!(get_balance(deps.as_ref(), carl), Uint128::zero()); - - // send coins to carl - let bob_info = mock_info(bob, &[]); - let transfer = ExecuteMsg::Transfer { - recipient: carl.into(), - amount: Uint128::new(20_000), - }; - execute(deps.as_mut(), mock_env(), bob_info.clone(), transfer).unwrap(); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(25_000)); - assert_eq!(get_balance(deps.as_ref(), carl), Uint128::new(20_000)); - - // allow alice - let allow = ExecuteMsg::IncreaseAllowance { - spender: alice.into(), - amount: Uint128::new(10_000), - expires: None, - }; - execute(deps.as_mut(), mock_env(), bob_info, allow).unwrap(); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(25_000)); - assert_eq!(get_balance(deps.as_ref(), alice), Uint128::zero()); - assert_eq!( - query_allowance(deps.as_ref(), bob.into(), alice.into()) - .unwrap() - .allowance, - Uint128::new(10_000) - ); - - // alice takes some for herself - let self_pay = ExecuteMsg::TransferFrom { - owner: bob.into(), - recipient: alice.into(), - amount: Uint128::new(5_000), - }; - let alice_info = mock_info(alice, &[]); - execute(deps.as_mut(), mock_env(), alice_info, self_pay).unwrap(); - assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(20_000)); - assert_eq!(get_balance(deps.as_ref(), alice), Uint128::new(5_000)); - assert_eq!(get_balance(deps.as_ref(), carl), Uint128::new(20_000)); - assert_eq!( - query_allowance(deps.as_ref(), bob.into(), alice.into()) - .unwrap() - .allowance, - Uint128::new(5_000) - ); - - // test burn from works properly (burn tested in burning_sends_reserve) - // cannot burn more than they have - - // TODO burn_from needs to be implemented and these tests added back here - - // let info = mock_info(alice, &[]); - // let burn_from = ExecuteMsg::BurnFrom { - // owner: bob.into(), - // amount: Uint128::new(3_300_000), - // }; - // let err = execute(deps.as_mut(), mock_env(), info, burn_from).unwrap_err(); - // assert_eq!( - // err, - // ContractError::Base(cw20_base::ContractError::Std(StdError::overflow( - // OverflowError::new(OverflowOperation::Sub, 5000 as u128, 3300000 as u128) - // ))) - // ); - - // burn 1_500 EPOXY to get back 1_500 DENOM (constant curve) - // let info = mock_info(alice, &[]); - // let burn_from = ExecuteMsg::BurnFrom { - // owner: bob.into(), - // amount: Uint128::new(1_500), - // }; - // let res = execute(deps.as_mut(), mock_env(), info, burn_from).unwrap(); - - // bob balance is lower, not alice - // assert_eq!(get_balance(deps.as_ref(), alice), Uint128::new(5000)); - // assert_eq!(get_balance(deps.as_ref(), bob), Uint128::new(18500)); - - // ensure alice got our money back - // TODO, currently this is not supported, we will need to support it, in cw-20 bonding curve, this is routed to sell from - // assert_eq!(1, res.messages.len()); - // assert_eq!( - // &res.messages[0], - // &SubMsg::new(BankMsg::Send { - // to_address: alice.into(), - // amount: coins(1_500, DENOM), - // }) - // ); - } - - #[test] - fn query_asset_works() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let asset = query_asset(deps.as_ref()).unwrap(); - assert_eq!(asset.denom, "satoshi".to_string()) - } - - #[test] - fn query_total_assets_works() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - // check that total_assets is zero upon instantiation - let total_assets = query_total_assets(deps.as_ref(), mock_env()).unwrap(); - assert_eq!(total_assets.total_managed_assets, Uint128::new(0)); - - // deposit some funds in different accounts and check assets after each deposit - let alice: &str = "alice"; - let bob: &str = "bobbyb"; - let carl: &str = "carl"; - - deps.querier - .update_balance(mock_env().contract.address, coins(45_000_000_000, DENOM)); - - let total_assets = query_total_assets(deps.as_ref(), mock_env()).unwrap(); - assert_eq!( - total_assets.total_managed_assets, - Uint128::new(45_000_000_000) - ); - } - - #[test] - fn query_convert_to_shares_works() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let response = - query_convert_to_shares(deps.as_ref(), coins(45_000_000_000, DENOM)).unwrap(); - assert_eq!(response.amount, Uint128::new(45_000_000)) - } - - #[test] - fn query_convert_to_assets_works() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let response = query_convert_to_assets(deps.as_ref(), Uint128::new(45_000_000)).unwrap(); - assert_eq!(response.assets, coins(45_000_000_000, DENOM)) - } - - #[test] - fn query_max_deposit_works() { - let mut deps = mock_dependencies(); - setup_test(deps.as_mut(), 9, 6, Uint128::MAX); - - let response = query_max_deposit(deps.as_ref()).unwrap(); - // the vault has no cap to minting by default, thus we expect None - assert_eq!(response.max_assets, None) - } -} diff --git a/smart-contracts/contracts/cw-4626/src/error.rs b/smart-contracts/contracts/cw-4626/src/error.rs deleted file mode 100644 index 5cb8514fb..000000000 --- a/smart-contracts/contracts/cw-4626/src/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Base(#[from] cw20_base::ContractError), - - #[error("{0}")] - PaymentError(#[from] cw_utils::PaymentError), - - #[error("{0}")] - StrategyError(#[from] strategy::error::ContractError), -} diff --git a/smart-contracts/contracts/cw-4626/src/lib.rs b/smart-contracts/contracts/cw-4626/src/lib.rs deleted file mode 100644 index dfedc9dc6..000000000 --- a/smart-contracts/contracts/cw-4626/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod contract; -mod error; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/smart-contracts/contracts/cw-4626/src/msg.rs b/smart-contracts/contracts/cw-4626/src/msg.rs deleted file mode 100644 index 554e3bb48..000000000 --- a/smart-contracts/contracts/cw-4626/src/msg.rs +++ /dev/null @@ -1,283 +0,0 @@ -use cosmwasm_std::{Binary, Coin, StdError, StdResult, Uint128, Uint256}; -use cw20::{Cw20Coin, Logo, MinterResponse}; -use cw_utils::Expiration; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] -pub struct InstantiateMarketingInfo { - pub project: Option, - pub description: Option, - pub marketing: Option, - pub logo: Option, -} - -#[derive(Serialize, Deserialize, JsonSchema, Debug, Clone, PartialEq)] -pub struct InstantiateMsg { - pub name: String, - pub symbol: String, - // the token accepted by the contract. - pub reserve_denom: String, - // the total amount of tokens that can be put in the reserve. - // TODO change to Option to allow for no cap on reserve supply - pub reserve_total_supply: Uint128, - pub reserve_decimals: u8, - // supply is the amount of tokens this vault has issued. - // supply_decimals is the amount of decimals of the supply token - pub supply_decimals: u8, - // TODO should this be an Option to not need the field in the initialization json - pub initial_balances: Vec, - pub mint: Option, - pub marketing: Option, - - pub curve_type: quasar_types::curve::CurveType, -} - -impl InstantiateMsg { - pub fn get_cap(&self) -> Option { - self.mint.as_ref().and_then(|v| v.cap) - } - - pub fn validate(&self) -> StdResult<()> { - // Check name, symbol, decimals - if !is_valid_name(&self.name) { - return Err(StdError::generic_err( - "Name is not in the expected format (3-50 UTF-8 bytes)", - )); - } - if !is_valid_symbol(&self.symbol) { - return Err(StdError::generic_err( - "Ticker symbol is not in expected format [a-zA-Z\\-]{3,12}", - )); - } - if self.reserve_denom.is_empty() { - return Err(StdError::generic_err("No reserve denom")); - } - if self.supply_decimals > 18 { - return Err(StdError::generic_err("Decimals must not exceed 18")); - } - Ok(()) - } -} - -fn is_valid_name(name: &str) -> bool { - let bytes = name.as_bytes(); - if bytes.len() < 3 || bytes.len() > 50 { - return false; - } - true -} - -fn is_valid_symbol(symbol: &str) -> bool { - let bytes = symbol.as_bytes(); - if bytes.len() < 3 || bytes.len() > 12 { - return false; - } - for byte in bytes.iter() { - if (*byte != 45) && (*byte < 65 || *byte > 90) && (*byte < 97 || *byte > 122) { - return false; - } - } - true -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Returns the denomination of the vaults reserve token - /// Return type: AssetResponse - Asset {}, - /// Returns the total amount of underlying reserve assets that is managed by the vault - /// Return type: TotalAssetsResponse - TotalAssets {}, - /// Returns the current balance of shares of the given address, 0 if unset. - /// Return type: BalanceResponse. - Balance { address: String }, - /// Returns the amount of shares the vault would exchange for the underlying reserve asset, in the ideal scenario - /// Return type: TODO - ConvertToShares { assets: Vec }, - /// Returns the amount of assets the vault would exchange for the amount of shares, in the ideal scenario - /// Return type: ConvertToSharesResponse - ConvertToAssets { shares: Uint128 }, - /// Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, through a deposit call. - /// If None is returned in the response, the vault does not have a cap - /// Return type: ConvertToAssetsResponse - MaxDeposit { receiver: String }, - /// Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given current on-chain conditions. - /// Return type: TODO - PreviewDeposit { assets: Uint256 }, - /// Return the maximum amount of shares that can be minted from the vault for the receiver, through a mint call - /// Return type: TODO - MaxMint { receiver: String }, - /// Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given current on-chain conditions. - /// Return type: TODO - PreviewMint { shares: Uint256 }, - /// Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the Vault, through a withdraw call. - /// Return type: TODO - MaxWithdraw { owner: String }, - /// Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, given current on-chain conditions. - /// Return type: TODO - PreviewWithdraw { assets: Uint256 }, - /// Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, through a redeem call. - MaxRedeem { owner: String }, - /// Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, given current on-chain conditions. - PreviewRedeem { shares: Uint256 }, - /// Returns metadata on the contract - name, decimals, supply, etc. - /// Return type: TokenInfoResponse. - TokenInfo {}, - /// Returns the metadata on the vault - whitelist, etc. - /// Return type: VaultInfoResponse. - VaultInfo {}, - /// Only with "mintable" extension. - /// Returns who can mint and the hard cap on maximum tokens after minting. - /// Return type: MinterResponse. - Minter {}, - /// Only with "allowance" extension. - /// Returns how much spender can use from owner account, 0 if unset. - /// Return type: AllowanceResponse. - Allowance { owner: String, spender: String }, - /// Only with "enumerable" extension (and "allowances") - /// Returns all allowances this owner has approved. Supports pagination. - /// Return type: AllAllowancesResponse. - AllAllowances { - owner: String, - start_after: Option, - limit: Option, - }, - /// Only with "enumerable" extension - /// Returns all accounts that have balances. Supports pagination. - /// Return type: AllAccountsResponse. - AllAccounts { - start_after: Option, - limit: Option, - }, - /// Only with "marketing" extension - /// Returns more metadata on the contract to display in the client: - /// - description, logo, project url, etc. - /// Return type: MarketingInfoResponse - MarketingInfo {}, - /// Only with "marketing" extension - /// Downloads the embedded logo data (if stored on chain). Errors if no logo data is stored for this - /// contract. - /// Return type: DownloadLogoResponse. - DownloadLogo {}, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct AssetResponse { - pub denom: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct TotalAssetResponse { - pub total_managed_assets: Uint128, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ConvertToSharesResponse { - pub amount: Uint128, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct ConvertToAssetsResponse { - pub assets: Vec, -} - -/// A None response indicates that the vault has no cap an thus no max deposit -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct MaxDepositResponse { - pub max_assets: Option>, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct VaultInfoResponse { - pub reserve_denom: String, - pub total_supply: Uint128, -} - -// we give our own ExecuteMsg instead of the cw-20 executeMsg so we can easily extend it -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - /// Deposits assets and mints shares - Deposit {}, - /// Burns shares from owner and sends exactly assets of underlying tokens to receiver. - /// If amount is None, all shares are sold - Withdraw { amount: Option }, - - //cw20-base messages - /// Transfer is a base message to move tokens to another account without triggering actions - Transfer { recipient: String, amount: Uint128 }, - /// Burn is a base message to destroy tokens forever - Burn { amount: Uint128 }, - /// Send is a base message to transfer tokens to a contract and trigger an action - /// on the receiving contract. - Send { - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Receive is a base message to receive tokens from another contract and trigger an action on - /// this contract. the address of the contract is stored in env.sender. Sender should match the - /// contract we expect to handle. Sender is the original account moving the tokens. The vault - /// needs to support sender if we expect people to be able to move their shares out of the vault. - Receive { - sender: String, - amount: Uint128, - msg: Binary, - }, - /// Only with "approval" extension. Allows spender to access an additional amount tokens - /// from the owner's (env.sender) account. If expires is Some(), overwrites current allowance - /// expiration with this one. - IncreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Only with "approval" extension. Lowers the spender's access of tokens - /// from the owner's (env.sender) account by amount. If expires is Some(), overwrites current - /// allowance expiration with this one. - DecreaseAllowance { - spender: String, - amount: Uint128, - expires: Option, - }, - /// Only with "approval" extension. Transfers amount tokens from owner -> recipient - /// if `env.sender` has sufficient pre-approval. - TransferFrom { - owner: String, - recipient: String, - amount: Uint128, - }, - /// Only with "approval" extension. Sends amount tokens from owner -> contract - /// if `env.sender` has sufficient pre-approval. - SendFrom { - owner: String, - contract: String, - amount: Uint128, - msg: Binary, - }, - /// Only with "approval" extension. Destroys tokens forever - BurnFrom { owner: String, amount: Uint128 }, - /// Only with the "mintable" extension. If authorized, creates amount new tokens - /// and adds to the recipient balance. - Mint { recipient: String, amount: Uint128 }, - /// Only with the "marketing" extension. If authorized, updates marketing metadata. - /// Setting None/null for any of these will leave it unchanged. - /// Setting Some("") will clear this field on the contract storage - UpdateMarketing { - /// A URL pointing to the project behind this token. - project: Option, - /// A longer description of the token and it's utility. Designed for tooltips or such - description: Option, - /// The address (if any) who can update this data structure - marketing: Option, - }, - /// If set as the "marketing" role on the contract, upload a new URL, SVG, or PNG for the token - UploadLogo(Logo), -} diff --git a/smart-contracts/contracts/cw-4626/src/state.rs b/smart-contracts/contracts/cw-4626/src/state.rs deleted file mode 100644 index a2e198cd3..000000000 --- a/smart-contracts/contracts/cw-4626/src/state.rs +++ /dev/null @@ -1,22 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt::Debug; - -use cosmwasm_std::Uint128; -use cw_storage_plus::Item; -use quasar_types::curve::{CurveType, DecimalPlaces}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct VaultInfo { - // reserve_denom is the denomination accepted by this vault. If the accepted token should be - // a cw20-token, one should wrap the token using the tokenfactory and the wrapping contract - pub reserve_denom: String, - // total_supply is the total supply of shares this contract - pub total_supply: Uint128, - // the decimals of the vault supply and reserve - pub decimals: DecimalPlaces, -} - -pub const VAULT_INFO: Item = Item::new("vault_info"); -pub const VAULT_CURVE: Item = Item::new("vault_curve"); diff --git a/smart-contracts/contracts/ibc-transfer/.cargo/config b/smart-contracts/contracts/ibc-transfer/.cargo/config deleted file mode 100644 index 7c115322a..000000000 --- a/smart-contracts/contracts/ibc-transfer/.cargo/config +++ /dev/null @@ -1,6 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -unit-test = "test --lib --features backtraces" -integration-test = "test --test integration" -schema = "run --example schema" diff --git a/smart-contracts/contracts/ibc-transfer/Cargo.toml b/smart-contracts/contracts/ibc-transfer/Cargo.toml deleted file mode 100644 index 99618bb5b..000000000 --- a/smart-contracts/contracts/ibc-transfer/Cargo.toml +++ /dev/null @@ -1,54 +0,0 @@ -[package] -name = "ibc_transfer" -version = "0.1.0" -edition = "2021" - - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[profile.release] -opt-level = 3 -debug = false -rpath = false -lto = true -debug-assertions = false -codegen-units = 1 -panic = 'abort' -incremental = false -overflow-checks = true - -[features] -# for quicker tests, cargo test --lib -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -library = [] - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -cw-utils = { workspace = true } -cw20-base = { workspace = true } -serde-json-wasm = { workspace = true } - -# Quasar packages -quasar-types = { path = "../../packages/quasar-types", version = "0.1.0"} -quasar-traits = { path = "../../packages/quasar-traits", version = "0.1.0"} -quasar-bindings = { path = "../../packages/quasar-bindings", version = "0.1.0"} - -[dev-dependencies] -cosmwasm-schema = { workspace = true } diff --git a/smart-contracts/contracts/ibc-transfer/README.md b/smart-contracts/contracts/ibc-transfer/README.md deleted file mode 100644 index da7dc9a95..000000000 --- a/smart-contracts/contracts/ibc-transfer/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# ibc-transfer demo contract -This contract is modified from Neutrons ibc-transfer demo contract. - -The main difference is they use a Sudo message to re-enter the contract, while we comply with the ibc standards for it - -## IBC transfer contract -Interacting with counterpart chain via ibc transfer is two phases process. -1. Send ibc transfer message -2. Accept and process ibc acknowlegement(ibc_packet_ack call) - -to run the contract you need to init two chain network connected with go relayer - - -## See demos/ibc-transfer-test/README.md for running instructions \ No newline at end of file diff --git a/smart-contracts/contracts/ibc-transfer/examples/schema.rs b/smart-contracts/contracts/ibc-transfer/examples/schema.rs deleted file mode 100644 index 873570c92..000000000 --- a/smart-contracts/contracts/ibc-transfer/examples/schema.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2022 Neutron -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use ibc_transfer::contract::{ExecuteMsg, InstantiateMsg}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); -} diff --git a/smart-contracts/contracts/ibc-transfer/schema/execute_msg.json b/smart-contracts/contracts/ibc-transfer/schema/execute_msg.json deleted file mode 100644 index 5c6683e85..000000000 --- a/smart-contracts/contracts/ibc-transfer/schema/execute_msg.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to" - ], - "properties": { - "amount": { - "type": "integer", - "format": "uint128", - "minimum": 0.0 - }, - "to": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] -} diff --git a/smart-contracts/contracts/ibc-transfer/schema/instantiate_msg.json b/smart-contracts/contracts/ibc-transfer/schema/instantiate_msg.json deleted file mode 100644 index 44588cf22..000000000 --- a/smart-contracts/contracts/ibc-transfer/schema/instantiate_msg.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object" -} diff --git a/smart-contracts/contracts/ibc-transfer/src/contract.rs b/smart-contracts/contracts/ibc-transfer/src/contract.rs deleted file mode 100644 index 7da5d5b6f..000000000 --- a/smart-contracts/contracts/ibc-transfer/src/contract.rs +++ /dev/null @@ -1,128 +0,0 @@ -use cosmwasm_std::{ - entry_point, to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Env, IbcBasicResponse, IbcMsg, - IbcTimeout, MessageInfo, Reply, Response, StdError, StdResult, Storage, -}; - -use crate::{ - error::ContractError, - helpers::{create_reply, parse_seq, IbcMsgKind, MsgKind}, - state::{State, STATE}, -}; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::state::{PENDING_ACK, REPLIES}; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -pub struct InstantiateMsg {} - -#[entry_point] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: InstantiateMsg, -) -> StdResult { - deps.api.debug("WASMDEBUG: Instantiate"); - - let initial_state = State { - transfer_happened: false, - }; - - STATE.save(deps.storage, &initial_state)?; - - Ok(Response::default()) -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - Transfer { to_address: String, channel: String }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - // this will just confirm that a transfer happened - State {}, -} - -#[entry_point] -pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { - deps.api - .debug(format!("WASMDEBUG: execute: received msg: {msg:?}").as_str()); - match msg { - ExecuteMsg::Transfer { - to_address, - channel, - } => execute_transfer(deps, env, info, channel, to_address), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> StdResult { - // Save the ibc message together with the sequence number, to be handled properly later at the ack - let kind = REPLIES.load(deps.storage, msg.id)?; - match kind { - MsgKind::Ibc(ibc_kind) => { - let seq = parse_seq(msg)?; - PENDING_ACK.save(deps.storage, seq, &ibc_kind)?; - } - } - Ok(Response::default()) -} - -pub fn do_ibc_lock_tokens( - _deps: &mut dyn Storage, - _token_amount: String, -) -> Result { - todo!() -} - -fn execute_transfer( - deps: DepsMut, - env: Env, - info: MessageInfo, - channel: String, - to_address: String, -) -> StdResult { - if info.funds.len() != 1 { - return Err(StdError::GenericErr { - msg: "invalid number of denoms sent (send one)".to_string(), - }); - } - - let funds = info.funds[0].clone(); - let transfer = IbcMsg::Transfer { - channel_id: channel.clone(), - to_address: to_address.clone(), - amount: funds, - timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(300)), - }; - Ok( - create_reply(deps.storage, MsgKind::Ibc(IbcMsgKind::Transfer), transfer)? - .add_attribute("ibc-tranfer-channel", channel) - .add_attribute("ibc-transfer-receiver", to_address), - ) -} - -pub fn confirm_transfer(deps: DepsMut) -> Result { - let mut state = STATE.load(deps.storage)?; - state.transfer_happened = true; - STATE.save(deps.storage, &state)?; - Ok(IbcBasicResponse::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::State {} => to_json_binary(&query_state(deps)?), - } -} - -pub fn query_state(deps: Deps) -> StdResult { - let state = STATE.load(deps.storage)?; - - Ok(state) -} diff --git a/smart-contracts/contracts/ibc-transfer/src/error.rs b/smart-contracts/contracts/ibc-transfer/src/error.rs deleted file mode 100644 index 90548bab0..000000000 --- a/smart-contracts/contracts/ibc-transfer/src/error.rs +++ /dev/null @@ -1,34 +0,0 @@ -use cosmwasm_std::StdError; -use quasar_types::error::Error as QError; -use thiserror::Error; - -/// Never is a placeholder to ensure we don't return any errors -#[derive(Error, Debug)] -pub enum Never {} - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Base(#[from] cw20_base::ContractError), - - #[error("{0}")] - QError(#[from] QError), - - #[error("{0}")] - PaymentError(#[from] cw_utils::PaymentError), - - #[error("{0}")] - QueueError(String), - - #[error("no counterpart ica address found")] - NoCounterpartyIcaAddress, - - #[error("channel is not an ica channel")] - NoIcaChannel, - - #[error("not enough funds in the strategy to withdraw")] - InsufficientOutStandingFunds, -} diff --git a/smart-contracts/contracts/ibc-transfer/src/helpers.rs b/smart-contracts/contracts/ibc-transfer/src/helpers.rs deleted file mode 100644 index f2938110b..000000000 --- a/smart-contracts/contracts/ibc-transfer/src/helpers.rs +++ /dev/null @@ -1,87 +0,0 @@ -use crate::state::REPLIES; -use cosmwasm_std::{CosmosMsg, Order, Reply, Response, StdError, Storage, SubMsg}; - -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub fn create_reply( - storage: &mut dyn Storage, - msg_kind: MsgKind, - msg: impl Into, -) -> Result { - let last = REPLIES.range(storage, None, None, Order::Descending).next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0; - } - // register the message in the replies for handling - REPLIES.save(storage, id, &msg_kind)?; - Ok(Response::new().add_submessage(SubMsg::reply_always(msg, id))) -} - -pub fn create_submsg( - storage: &mut dyn Storage, - msg_kind: MsgKind, - msg: impl Into, -) -> Result { - let last = REPLIES.range(storage, None, None, Order::Descending).next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0; - } - // register the message in the replies for handling - REPLIES.save(storage, id, &msg_kind)?; - Ok(SubMsg::reply_always(msg, id)) -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum IbcMsgKind { - Transfer, - Ica(IcaMessages), - Icq, -} - -// All enums supported by this contract -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum IcaMessages { - JoinSwapExternAmountIn, - LockTokens, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum MsgKind { - Ibc(IbcMsgKind), -} - -pub(crate) fn parse_seq(reply: Reply) -> Result { - reply - .result - .into_result() - .map_err(|msg| StdError::GenericErr { msg })? - .events - .iter() - .find(|e| e.ty == "send_packet") - .ok_or(StdError::NotFound { - kind: "send_packet_event".into(), - })? - .attributes - .iter() - .find(|attr| attr.key == "packet_sequence") - .ok_or(StdError::NotFound { - kind: "packet_sequence".into(), - })? - .value - .parse::() - .map_err(|e| StdError::ParseErr { - target_type: "u64".into(), - msg: e.to_string(), - }) -} - -#[cfg(test)] -mod tests { - // TODO write some tests for helpers -} diff --git a/smart-contracts/contracts/ibc-transfer/src/ibc.rs b/smart-contracts/contracts/ibc-transfer/src/ibc.rs deleted file mode 100644 index 853c63412..000000000 --- a/smart-contracts/contracts/ibc-transfer/src/ibc.rs +++ /dev/null @@ -1,269 +0,0 @@ -use crate::contract::{confirm_transfer, do_ibc_lock_tokens}; -use crate::error::{ContractError, Never}; -use crate::helpers::{create_submsg, IbcMsgKind, IcaMessages, MsgKind}; -use crate::state::{CHANNELS, PENDING_ACK}; -use osmosis_std::types::osmosis::gamm::v1beta1::MsgJoinSwapExternAmountInResponse; -use quasar_types::error::Error as QError; -use quasar_types::ibc::{ - enforce_order_and_version, ChannelInfo, ChannelType, HandshakeState, IcsAck, -}; -use quasar_types::ica::handshake::enforce_ica_order_and_metadata; -use quasar_types::icq::ICQ_ORDERING; -use quasar_types::{ibc, ica::handshake::IcaMetadata, icq::ICQ_VERSION}; - -use cosmwasm_std::{ - entry_point, from_json, Binary, DepsMut, Env, IbcBasicResponse, IbcChannel, - IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcPacket, IbcPacketAckMsg, - IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, StdError, -}; - -#[cfg_attr(not(feature = "library"), entry_point)] -/// enforces ordering and versioning constraints, this combines ChanOpenInit and ChanOpenTry -pub fn ibc_channel_open( - deps: DepsMut, - _env: Env, - msg: IbcChannelOpenMsg, -) -> Result<(), ContractError> { - // save the channel as an channel in ChanOpenInit, we support inits from icq and ica channels - if msg.channel().version == ICQ_VERSION { - handle_icq_channel(deps, msg.channel().clone())?; - } else { - handle_ica_channel(deps, msg.channel().clone())?; - } - - Ok(()) -} - -fn handle_icq_channel(deps: DepsMut, channel: IbcChannel) -> Result<(), ContractError> { - ibc::enforce_order_and_version(&channel, None, &channel.version, channel.order.clone())?; - // save the channel state here - let info = ChannelInfo { - id: channel.endpoint.channel_id.clone(), - counterparty_endpoint: channel.counterparty_endpoint, - connection_id: channel.connection_id, - channel_type: ChannelType::Icq { - channel_ty: channel.version, - }, - handshake_state: HandshakeState::Init, - }; - CHANNELS.save(deps.storage, channel.endpoint.channel_id, &info)?; - Ok(()) -} - -fn handle_ica_channel(deps: DepsMut, channel: IbcChannel) -> Result<(), ContractError> { - let metadata: IcaMetadata = serde_json_wasm::from_str(&channel.version).map_err(|error| { - QError::InvalidIcaMetadata { - raw_metadata: channel.version.clone(), - error: error.to_string(), - } - })?; - - enforce_ica_order_and_metadata(&channel, None, &metadata)?; - // save the current state of the initializing channel - let info = ChannelInfo { - id: channel.endpoint.channel_id.clone(), - counterparty_endpoint: channel.counterparty_endpoint, - connection_id: channel.connection_id, - channel_type: ChannelType::Ica { - channel_ty: metadata, - counter_party_address: None, - }, - handshake_state: HandshakeState::Init, - }; - CHANNELS.save(deps.storage, channel.endpoint.channel_id, &info)?; - Ok(()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// record the channel in CHANNEL_INFO, this combines the ChanOpenAck and ChanOpenConfirm steps -pub fn ibc_channel_connect( - deps: DepsMut, - _env: Env, - msg: IbcChannelConnectMsg, -) -> Result { - // try to fetch the connecting channel, we should error if it does not exist\ - let mut info: ChannelInfo = CHANNELS - .load(deps.storage, msg.channel().endpoint.channel_id.clone()) - .map_err(|err| StdError::GenericErr { - msg: err.to_string(), - })?; - // we need to check the counter party version in try and ack (sometimes here) - // TODO we can wrap this match in a function in our ibc package - - // TODO think of a better datastructure so we dont have to parse ICA channels like this - match info.channel_type { - ChannelType::Icq { ref channel_ty } => enforce_order_and_version( - msg.channel(), - msg.counterparty_version(), - channel_ty.as_str(), - ICQ_ORDERING, - )?, - ChannelType::Ica { - channel_ty, - counter_party_address: _, - } => { - let counter_party_metadata = enforce_ica_order_and_metadata( - msg.channel(), - msg.counterparty_version(), - &channel_ty, - )?; - - let counter_party = counter_party_metadata - .ok_or(ContractError::QError(QError::NoCounterpartyIcaAddress))?; - // at this point, we expect a counterparty address, if it's none, we have to error - if counter_party.address().is_none() { - return Err(ContractError::NoCounterpartyIcaAddress); - } - let addr = counter_party.address(); - if addr.is_none() { - return Err(ContractError::NoCounterpartyIcaAddress); - } - info.channel_type = ChannelType::Ica { - channel_ty, - counter_party_address: addr, - } - } - ChannelType::Ics20 { channel_ty: _ } => todo!(), - } - - info.handshake_state = HandshakeState::Open; - - CHANNELS.save( - deps.storage, - msg.channel().endpoint.channel_id.clone(), - &info, - )?; - - Ok(IbcBasicResponse::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_channel_close( - _deps: DepsMut, - _env: Env, - _channel: IbcChannelCloseMsg, -) -> Result { - // TODO: what to do here? - // we will have locked funds that need to be returned somehow - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// Check to see if we have any balance here -/// We should not return an error if possible, but rather an acknowledgement of failure -pub fn ibc_packet_receive( - _deps: DepsMut, - _env: Env, - _msg: IbcPacketReceiveMsg, -) -> Result { - // Contract does not handle packets/queries. - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// check if success or failure and update balance, or return funds -pub fn ibc_packet_ack( - deps: DepsMut, - env: Env, - msg: IbcPacketAckMsg, -) -> Result { - // TODO: trap error like in receive? - let ack: IcsAck = from_json(&msg.acknowledgement.data)?; - match ack { - IcsAck::Result(val) => handle_succesful_ack(deps, env, msg, val), - IcsAck::Error(err) => handle_failing_ack(deps, env, msg, err), - } -} - -pub fn handle_succesful_ack( - deps: DepsMut, - _env: Env, - pkt: IbcPacketAckMsg, - ack_bin: Binary, -) -> Result { - let kind = PENDING_ACK.load(deps.storage, pkt.original_packet.sequence)?; - match kind { - crate::helpers::IbcMsgKind::Transfer => confirm_transfer(deps), - crate::helpers::IbcMsgKind::Ica(ica_kind) => match ica_kind { - crate::helpers::IcaMessages::JoinSwapExternAmountIn => { - let response: MsgJoinSwapExternAmountInResponse = from_json(&ack_bin)?; - let msg = do_ibc_lock_tokens(deps.storage, response.share_out_amount)?; - let msg_kind = MsgKind::Ibc(IbcMsgKind::Ica(IcaMessages::LockTokens)); - Ok(IbcBasicResponse::new().add_submessage(create_submsg( - deps.storage, - msg_kind, - msg, - )?)) - } - crate::helpers::IcaMessages::LockTokens => todo!(), - }, - crate::helpers::IbcMsgKind::Icq => todo!(), - } -} - -pub fn handle_failing_ack( - _deps: DepsMut, - _env: Env, - _pkt: IbcPacketAckMsg, - error: String, -) -> Result { - // TODO we can expand error handling here to fetch the packet by the - Ok(IbcBasicResponse::new().add_attribute("ibc-error", error.as_str())) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// return fund to original sender (same as failure in ibc_packet_ack) -pub fn ibc_packet_timeout( - deps: DepsMut, - _env: Env, - msg: IbcPacketTimeoutMsg, -) -> Result { - // TODO: trap error like in receive? - on_packet_failure(deps, msg.packet, "timeout".to_string())?; - Ok(IbcBasicResponse::default()) -} - -fn on_packet_failure( - _deps: DepsMut, - _packet: IbcPacket, - _error: String, -) -> Result { - todo!() -} - -// #[cfg(test)] -// mod test { -// use super::*; -// use crate::test_helpers::*; - -// use crate::contract::query_channel; -// use cosmwasm_std::testing::mock_env; -// use cosmwasm_std::{coins, to_vec, IbcEndpoint}; - -// #[test] -// fn check_ack_json() { -// let success = StrategyAck::Result(b"1".into()); -// let fail = StrategyAck::Error("bad coin".into()); - -// let success_json = String::from_utf8(to_vec(&success).unwrap()).unwrap(); -// assert_eq!(r#"{"result":"MQ=="}"#, success_json.as_str()); - -// let fail_json = String::from_utf8(to_vec(&fail).unwrap()).unwrap(); -// assert_eq!(r#"{"error":"bad coin"}"#, fail_json.as_str()); -// } - -// #[test] -// fn check_packet_json() { -// let packet = StrategyPacket::new( -// Uint128(12345), -// "ucosm", -// "cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n", -// "wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc", -// ); -// // Example message generated from the SDK -// let expected = r#"{"amount":"12345","denom":"ucosm","receiver":"wasm1fucynrfkrt684pm8jrt8la5h2csvs5cnldcgqc","sender":"cosmos1zedxv25ah8fksmg2lzrndrpkvsjqgk4zt5ff7n"}"#; - -// let encdoded = String::from_utf8(to_vec(&packet).unwrap()).unwrap(); -// assert_eq!(expected, encdoded.as_str()); -// } -// } diff --git a/smart-contracts/contracts/ibc-transfer/src/lib.rs b/smart-contracts/contracts/ibc-transfer/src/lib.rs deleted file mode 100644 index 7468ac82e..000000000 --- a/smart-contracts/contracts/ibc-transfer/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2022 Neutron -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![warn(clippy::unwrap_used, clippy::expect_used)] - -pub mod contract; -mod error; -pub mod helpers; -pub mod ibc; -pub mod state; diff --git a/smart-contracts/contracts/ibc-transfer/src/state.rs b/smart-contracts/contracts/ibc-transfer/src/state.rs deleted file mode 100644 index 3c2c06dec..000000000 --- a/smart-contracts/contracts/ibc-transfer/src/state.rs +++ /dev/null @@ -1,30 +0,0 @@ -use quasar_types::ibc::ChannelInfo; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cw_storage_plus::{Item, Map}; - -use crate::helpers::{IbcMsgKind, MsgKind}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub enum Origin { - Sample, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct Config { - pub default_timeout: u64, -} - -pub(crate) const CHANNELS: Map = Map::new("channels"); - -pub(crate) const REPLIES: Map = Map::new("replies"); - -pub(crate) const PENDING_ACK: Map = Map::new("pending_acks"); - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct State { - pub transfer_happened: bool, -} - -pub(crate) const STATE: Item = Item::new("state"); diff --git a/smart-contracts/contracts/ica/.cargo/config b/smart-contracts/contracts/ica/.cargo/config deleted file mode 100644 index dba2c3f7a..000000000 --- a/smart-contracts/contracts/ica/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" -lint = "clippy -- -D warnings" \ No newline at end of file diff --git a/smart-contracts/contracts/ica/Cargo.toml b/smart-contracts/contracts/ica/Cargo.toml deleted file mode 100644 index 4ed7a8fc3..000000000 --- a/smart-contracts/contracts/ica/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "ica" -version = "0.1.0" -authors = ["Laurens Kubat "] -edition = "2018" -description = "IBC Enabled contracts for interchain queries" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all init/handle/query exports -library = [] - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -prost = { workspace = true } -cw-controllers = { workspace = true } -cw-utils = { workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cosmos-sdk-proto = { workspace = true } -base64 = { workspace = true } - -semver = "1" diff --git a/smart-contracts/contracts/ica/NOTICE b/smart-contracts/contracts/ica/NOTICE deleted file mode 100644 index bc266454e..000000000 --- a/smart-contracts/contracts/ica/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-ICS20: IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/smart-contracts/contracts/ica/README.md b/smart-contracts/contracts/ica/README.md deleted file mode 100644 index 3f5f43452..000000000 --- a/smart-contracts/contracts/ica/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# ICQ - -This is an *IBC Enabled* contract that allows us to send ICQ queries from one chain over the standard ICQ -protocol to the bank module of another chain. - -## Workflow - -The contract starts with minimal state. It just stores a default timeout in seconds for all packets it sends. -Most importantly it binds a local IBC port to enable channel connections. - -An external party first needs to make one or more channels using this contract as one endpoint. It will use standard -unordered channels for the version negotiation. Once established, it manages a list of known channels. - -After there is at least one channel, you can send any ICQ query to this contract. It may optionally include a custom timeout. - -## Messages - -It only accepts ICQQueryMsg. The data sent along with that message must be a JSON-serialized -TransferMsg: - -## Queries - -Queries only make sense relative to the established channels of this contract. - -* `Port{}` - returns the port ID this contract has bound, so you can create channels. This info can be queried - via wasmd contract info query, but we expose another query here for convenience. -* `ListChannels{}` - returns a (currently unpaginated) list of all channels that have been created on this contract. - Returns their local channelId along with some basic metadata, like the remote port/channel and the connection they - run on top of. -* `Channel{id}` - returns more detailed information on one specific channel. In addition to the information available - in the list view, it returns the current outstanding balance on that channel, as well as the total amount that - has ever been sent on the channel. diff --git a/smart-contracts/contracts/ica/create_and_execute.sh b/smart-contracts/contracts/ica/create_and_execute.sh index cf91a6993..e69de29bb 100755 --- a/smart-contracts/contracts/ica/create_and_execute.sh +++ b/smart-contracts/contracts/ica/create_and_execute.sh @@ -1,32 +0,0 @@ -#!/bin/sh - -CHAIN_ID="quasar" -TESTNET_NAME="quasar" -FEE_DENOM="uqsr" -RPC="http://127.0.0.1:26659" -NODE="--node $RPC" -TXFLAG="$NODE --chain-id $CHAIN_ID --gas-prices 10$FEE_DENOM --gas auto --gas-adjustment 1.3" -echo $NODE -INIT='{"default_timeout": 600}' -# quasar <-> osmosis channel is connection 2 in current setup -# MSG='{"register_interchain_account":{"connection_id":"connection-0"}}' - -cd ../../ - -docker run --rm -v "$(pwd)":/code --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/rust-optimizer:0.12.6 - -echo "Running store code" -RES=$(quasard tx wasm store artifacts/icq.wasm --from alice --keyring-backend test -y --output json -b block $TXFLAG) -CODE_ID=$(echo $RES | jq -r '.logs[0].events[-1].attributes[0].value') -echo "Got CODE_ID = $CODE_ID" - -echo "Deploying contract" -# swallow output -OUT=$(quasard tx wasm instantiate $CODE_ID "$INIT" --from alice --keyring-backend test --label "my first contract" --gas-prices 10$FEE_DENOM --gas auto --gas-adjustment 1.3 -b block -y --no-admin $NODE --chain-id $CHAIN_ID) -ADDR=$(quasard query wasm list-contract-by-code $CODE_ID --output json $NODE | jq -r '.contracts[0]') -echo "Got address of deployed contract = $ADDR" - -# echo "Executing register ica message... ('$MSG')" -# quasard tx wasm execute $ADDR "$MSG" -y --from alice --keyring-backend test --gas-prices 10$FEE_DENOM --gas auto --gas-adjustment 1.3 $NODE --chain-id $CHAIN_ID - -cd - \ No newline at end of file diff --git a/smart-contracts/contracts/ica/examples/schema.rs b/smart-contracts/contracts/ica/examples/schema.rs deleted file mode 100644 index 4948e9c07..000000000 --- a/smart-contracts/contracts/ica/examples/schema.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use ica::msg::{ - ChannelResponse, ExecuteMsg, ICQQueryMsg, InitMsg, ListChannelsResponse, PortResponse, QueryMsg, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InitMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(ICQQueryMsg), &out_dir); - export_schema(&schema_for!(ChannelResponse), &out_dir); - export_schema(&schema_for!(ListChannelsResponse), &out_dir); - export_schema(&schema_for!(PortResponse), &out_dir); -} diff --git a/smart-contracts/contracts/ica/schema/channel_response.json b/smart-contracts/contracts/ica/schema/channel_response.json deleted file mode 100644 index 1744539e6..000000000 --- a/smart-contracts/contracts/ica/schema/channel_response.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ChannelResponse", - "type": "object", - "required": [ - "info" - ], - "properties": { - "info": { - "description": "Information on the channel's connection", - "allOf": [ - { - "$ref": "#/definitions/ChannelInfo" - } - ] - } - }, - "definitions": { - "ChannelInfo": { - "type": "object", - "required": [ - "connection_id", - "counterparty_endpoint", - "id" - ], - "properties": { - "connection_id": { - "description": "the connection this exists on (you can use to query client/consensus info)", - "type": "string" - }, - "counterparty_endpoint": { - "description": "the remote channel/port we connect to", - "allOf": [ - { - "$ref": "#/definitions/IbcEndpoint" - } - ] - }, - "id": { - "description": "id of this channel", - "type": "string" - } - } - }, - "IbcEndpoint": { - "type": "object", - "required": [ - "channel_id", - "port_id" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "port_id": { - "type": "string" - } - } - } - } -} diff --git a/smart-contracts/contracts/ica/schema/execute_msg.json b/smart-contracts/contracts/ica/schema/execute_msg.json deleted file mode 100644 index 858ddc8c3..000000000 --- a/smart-contracts/contracts/ica/schema/execute_msg.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "join_pool" - ], - "properties": { - "join_pool": { - "type": "object", - "required": [ - "channel", - "pool_id", - "sender", - "share_out_amount", - "token_in_maxs" - ], - "properties": { - "channel": { - "type": "string" - }, - "pool_id": { - "$ref": "#/definitions/Uint64" - }, - "sender": { - "type": "string" - }, - "share_out_amount": { - "type": "string" - }, - "token_in_maxs": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Coin": { - "description": "Coin defines a token with a denomination and an amount.\n\nNOTE: The amount field is an Int which implements the custom method signatures required by gogoproto.", - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "type": "string" - }, - "denom": { - "type": "string" - } - } - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/ica/schema/i_c_q_query_msg.json b/smart-contracts/contracts/ica/schema/i_c_q_query_msg.json deleted file mode 100644 index 316cd71ce..000000000 --- a/smart-contracts/contracts/ica/schema/i_c_q_query_msg.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ICQQueryMsg", - "description": "This is the message we accept via Receive", - "type": "object", - "required": [ - "channel", - "requests" - ], - "properties": { - "channel": { - "description": "The local channel to send the packets on", - "type": "string" - }, - "requests": { - "type": "array", - "items": { - "$ref": "#/definitions/RequestQueryJSON" - } - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "RequestQueryJSON": { - "type": "object", - "required": [ - "data", - "height", - "path", - "prove" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "height": { - "type": "integer", - "format": "int64" - }, - "path": { - "type": "string" - }, - "prove": { - "type": "boolean" - } - } - } - } -} diff --git a/smart-contracts/contracts/ica/schema/init_msg.json b/smart-contracts/contracts/ica/schema/init_msg.json deleted file mode 100644 index 33a291fc3..000000000 --- a/smart-contracts/contracts/ica/schema/init_msg.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InitMsg", - "type": "object", - "required": [ - "default_timeout" - ], - "properties": { - "default_timeout": { - "description": "Default timeout for icq packets, specified in seconds", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/smart-contracts/contracts/ica/schema/list_channels_response.json b/smart-contracts/contracts/ica/schema/list_channels_response.json deleted file mode 100644 index 69f020c93..000000000 --- a/smart-contracts/contracts/ica/schema/list_channels_response.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ListChannelsResponse", - "type": "object", - "required": [ - "channels" - ], - "properties": { - "channels": { - "type": "array", - "items": { - "$ref": "#/definitions/ChannelInfo" - } - } - }, - "definitions": { - "ChannelInfo": { - "type": "object", - "required": [ - "connection_id", - "counterparty_endpoint", - "id" - ], - "properties": { - "connection_id": { - "description": "the connection this exists on (you can use to query client/consensus info)", - "type": "string" - }, - "counterparty_endpoint": { - "description": "the remote channel/port we connect to", - "allOf": [ - { - "$ref": "#/definitions/IbcEndpoint" - } - ] - }, - "id": { - "description": "id of this channel", - "type": "string" - } - } - }, - "IbcEndpoint": { - "type": "object", - "required": [ - "channel_id", - "port_id" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "port_id": { - "type": "string" - } - } - } - } -} diff --git a/smart-contracts/contracts/ica/schema/port_response.json b/smart-contracts/contracts/ica/schema/port_response.json deleted file mode 100644 index 4561b3a72..000000000 --- a/smart-contracts/contracts/ica/schema/port_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PortResponse", - "type": "object", - "required": [ - "port_id" - ], - "properties": { - "port_id": { - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/ica/schema/query_msg.json b/smart-contracts/contracts/ica/schema/query_msg.json deleted file mode 100644 index be42f505f..000000000 --- a/smart-contracts/contracts/ica/schema/query_msg.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return the port ID bound by this contract. Returns PortResponse", - "type": "object", - "required": [ - "port" - ], - "properties": { - "port": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Show all channels we have connected to. Return type is ListChannelsResponse.", - "type": "object", - "required": [ - "list_channels" - ], - "properties": { - "list_channels": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns the details of the name channel, error if not created. Return type: ChannelResponse.", - "type": "object", - "required": [ - "channel" - ], - "properties": { - "channel": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Show the Config. Returns ConfigResponse (currently including admin as well)", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/smart-contracts/contracts/ica/src/contract.rs b/smart-contracts/contracts/ica/src/contract.rs deleted file mode 100644 index 400a55a69..000000000 --- a/smart-contracts/contracts/ica/src/contract.rs +++ /dev/null @@ -1,194 +0,0 @@ -use cosmos_sdk_proto::ibc::applications::interchain_accounts::v1::InterchainAccountPacketData; -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, IbcTimeout, MessageInfo, Order, - PortIdResponse, Reply, Response, StdResult, SubMsg, Uint64, -}; -use prost::Message; - -use osmosis_std::types::cosmos::base::v1beta1::Coin as OsmoCoin; -use osmosis_std::types::osmosis::gamm::v1beta1::MsgJoinPool; - -use cw2::set_contract_version; - -use crate::error::ContractError; -use crate::helpers::{handle_reply_sample, set_reply}; -use crate::msg::{ - ChannelResponse, ConfigResponse, ExecuteMsg, InitMsg, ListChannelsResponse, MigrateMsg, - PortResponse, QueryMsg, -}; -use crate::state::{Config, Origin, CHANNEL_INFO, CONFIG, QUERY_RESULT_COUNTER, REPLIES}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:icq"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InitMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let cfg = Config { - default_timeout: msg.default_timeout, - }; - CONFIG.save(deps.storage, &cfg)?; - QUERY_RESULT_COUNTER.save(deps.storage, &0)?; - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - _info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::JoinPool { - channel, - sender, - pool_id, - share_out_amount, - token_in_maxs, - } => execute_bank_send( - deps, - env, - channel, - sender, - pool_id, - share_out_amount, - token_in_maxs, - ), - } -} - -fn execute_bank_send( - deps: DepsMut, - env: Env, - channel: String, - sender: String, - pool_id: Uint64, - share_out_amount: String, - token_in_maxs: Vec, -) -> Result { - let msg = MsgJoinPool { - sender, - pool_id: pool_id.u64(), - share_out_amount, - token_in_maxs, - }; - let packet = InterchainAccountPacketData { - r#type: 1, - data: msg.encode_to_vec(), - memo: "".into(), - }; - - let send_packet_msg = IbcMsg::SendPacket { - channel_id: channel, - data: to_json_binary(&packet.encode_to_vec())?, - timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(300)), - }; - - let id = set_reply(deps, &Origin::Sample)?; - let res = Response::new() - .add_submessage(SubMsg::reply_on_success(send_packet_msg, id)) - .add_attribute("action", "query"); - Ok(res) -} - -#[entry_point] -pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> StdResult { - let origin = REPLIES.load(deps.storage, msg.id)?; - match origin { - Origin::Sample => handle_reply_sample(deps, msg), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - Ok(Response::new()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Port {} => to_json_binary(&query_port(deps)?), - QueryMsg::ListChannels {} => to_json_binary(&query_list(deps)?), - QueryMsg::Channel { id } => to_json_binary(&query_channel(deps, id)?), - QueryMsg::Config {} => to_json_binary(&query_config(deps)?), - } -} - -fn query_port(deps: Deps) -> StdResult { - let query = IbcQuery::PortId {}.into(); - let PortIdResponse { port_id } = deps.querier.query(&query)?; - Ok(PortResponse { port_id }) -} - -fn query_list(deps: Deps) -> StdResult { - let channels = CHANNEL_INFO - .range_raw(deps.storage, None, None, Order::Ascending) - .map(|r| r.map(|(_, v)| v)) - .collect::>()?; - Ok(ListChannelsResponse { channels }) -} - -// make public for ibc tests -pub fn query_channel(deps: Deps, id: String) -> StdResult { - let info = CHANNEL_INFO.load(deps.storage, &id)?; - Ok(ChannelResponse { info }) -} - -fn query_config(deps: Deps) -> StdResult { - let cfg = CONFIG.load(deps.storage)?; - let res = ConfigResponse { - default_timeout: cfg.default_timeout, - }; - Ok(res) -} - -#[cfg(test)] -mod test { - use super::*; - - use crate::test_helpers::*; - - use cosmwasm_std::testing::mock_env; - use cosmwasm_std::{from_json, StdError}; - - #[test] - fn setup_and_query() { - let deps = setup(&["channel-3", "channel-7"]); - - let raw_list = query(deps.as_ref(), mock_env(), QueryMsg::ListChannels {}).unwrap(); - let list_res: ListChannelsResponse = from_json(&raw_list).unwrap(); - assert_eq!(2, list_res.channels.len()); - assert_eq!(mock_channel_info("channel-3"), list_res.channels[0]); - assert_eq!(mock_channel_info("channel-7"), list_res.channels[1]); - - let raw_channel = query( - deps.as_ref(), - mock_env(), - QueryMsg::Channel { - id: "channel-3".to_string(), - }, - ) - .unwrap(); - let chan_res: ChannelResponse = from_json(&raw_channel).unwrap(); - assert_eq!(chan_res.info, mock_channel_info("channel-3")); - - let err = query( - deps.as_ref(), - mock_env(), - QueryMsg::Channel { - id: "channel-10".to_string(), - }, - ) - .unwrap_err(); - assert_eq!(err, StdError::not_found("icq::state::ChannelInfo")); - } -} diff --git a/smart-contracts/contracts/ica/src/error.rs b/smart-contracts/contracts/ica/src/error.rs deleted file mode 100644 index 10c38ef77..000000000 --- a/smart-contracts/contracts/ica/src/error.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::string::FromUtf8Error; -use thiserror::Error; - -use cosmwasm_std::StdError; - -/// Never is a placeholder to ensure we don't return any errors -#[derive(Error, Debug)] -pub enum Never {} - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Channel doesn't exist: {id}")] - NoSuchChannel { id: String }, - - #[error("Only supports channel with ibc version {contract_version}, got {version}")] - InvalidIbcVersion { - contract_version: String, - version: String, - }, - - #[error("Only supports unordered channel")] - OnlyOrderedChannel {}, - - #[error("Parsed port from denom ({port}) doesn't match packet")] - FromOtherPort { port: String }, - - #[error("Parsed channel from denom ({channel}) doesn't match packet")] - FromOtherChannel { channel: String }, - - #[error("Cannot migrate from different contract type: {previous_contract}")] - CannotMigrate { previous_contract: String }, - - #[error("Cannot migrate from unsupported version: {previous_version}")] - CannotMigrateVersion { previous_version: String }, - - #[error("Failed to proto encode")] - EncodingFail, - - #[error("Failed to proto decode")] - DecodingFail, - - #[error("Only the governance contract can do this")] - Unauthorized, -} - -impl From for ContractError { - fn from(_: FromUtf8Error) -> Self { - ContractError::Std(StdError::invalid_utf8("parsing denom key")) - } -} diff --git a/smart-contracts/contracts/ica/src/helpers.rs b/smart-contracts/contracts/ica/src/helpers.rs deleted file mode 100644 index bee098683..000000000 --- a/smart-contracts/contracts/ica/src/helpers.rs +++ /dev/null @@ -1,85 +0,0 @@ -use crate::{ - proto::CosmosResponse, - state::{Origin, PENDING_QUERIES, QUERY_RESULT_COUNTER, REPLIES}, - ContractError, -}; -use cosmwasm_std::{ - attr, DepsMut, Env, IbcBasicResponse, IbcPacket, Order, Reply, Response, StdError, StdResult, -}; - -pub(crate) fn handle_reply_sample(deps: DepsMut, msg: Reply) -> StdResult { - let val = msg - .result - .into_result() - .map_err(|msg| StdError::GenericErr { msg })?; - - let event = val - .events - .iter() - .find(|e| e.ty == "send_packet") - .ok_or(StdError::NotFound { - kind: "send_packet_event".into(), - })?; - - // here we can do further stuff with a succesful package if necessary, in this case we can simply - // save the package, under the sequence number and channel id - let seq = event - .attributes - .iter() - .find(|attr| attr.key == "packet_sequence") - .ok_or(StdError::NotFound { - kind: "packet_sequence".into(), - })?; - let s = seq.value.parse::().map_err(|e| StdError::ParseErr { - target_type: "u64".into(), - msg: e.to_string(), - })?; - let channel = event - .attributes - .iter() - .find(|attr| attr.key == "packet_src_channel") - .ok_or(StdError::NotFound { - kind: "packet_src_channel".into(), - })?; - - PENDING_QUERIES.save(deps.storage, (s, &channel.value), &Origin::Sample)?; - Ok(Response::new().add_attribute("reply_registered", msg.id.to_string())) -} - -pub fn set_reply(deps: DepsMut, origin: &Origin) -> Result { - let last = REPLIES - .range(deps.storage, None, None, Order::Descending) - .next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0; - } - - // register the message in the replies for handling - REPLIES.save(deps.storage, id, origin)?; - // send response - Ok(id) -} - -// for our sample origin callback, we increment the query counter and leave it at that -pub fn handle_sample_callback( - deps: DepsMut, - _env: Env, - response: CosmosResponse, - _original: IbcPacket, -) -> Result { - let attrs = vec![ - attr("action", "acknowledge"), - attr("num_messages", response.responses.len().to_string()), - attr("success", "true"), - ]; - - // Store result counter. - let mut counter = QUERY_RESULT_COUNTER.load(deps.storage)?; - counter += response.responses.len() as u64; - QUERY_RESULT_COUNTER.save(deps.storage, &counter)?; - Ok(IbcBasicResponse::new().add_attributes(attrs)) -} - -#[cfg(test)] -mod test {} diff --git a/smart-contracts/contracts/ica/src/ibc.rs b/smart-contracts/contracts/ica/src/ibc.rs deleted file mode 100644 index 45da2da41..000000000 --- a/smart-contracts/contracts/ica/src/ibc.rs +++ /dev/null @@ -1,225 +0,0 @@ -use prost::bytes::Bytes; -use prost::Message; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{ - attr, entry_point, from_json, Binary, DepsMut, Env, IbcBasicResponse, IbcChannel, - IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcOrder, IbcPacket, - IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, -}; - -use crate::error::{ContractError, Never}; -use crate::helpers::handle_sample_callback; -use crate::proto::CosmosResponse; -use crate::state::{ChannelInfo, Origin, CHANNEL_INFO, PENDING_QUERIES}; - -pub const ICA_VERSION: &str = "{\"version\":\"ics-20\"}"; -pub const ICA_ORDERING: IbcOrder = IbcOrder::Ordered; - -/// This is compatible with the JSON serialization -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] -pub struct InterchainQueryPacketAck { - pub data: Binary, -} - -impl InterchainQueryPacketAck { - pub fn new(data: Binary) -> Self { - InterchainQueryPacketAck { data } - } - - pub fn validate(&self) -> Result<(), ContractError> { - Ok(()) - } -} - -/// This is a generic ICS acknowledgement format. -/// Proto defined here: https://github.com/cosmos/cosmos-sdk/blob/v0.42.0/proto/ibc/core/channel/v1/channel.proto#L141-L147 -/// This is compatible with the JSON serialization -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum IcsAck { - Result(Binary), - Error(String), -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// enforces ordering and versioning constraints -pub fn ibc_channel_open( - _deps: DepsMut, - _env: Env, - msg: IbcChannelOpenMsg, -) -> Result<(), ContractError> { - enforce_order_and_version(msg.channel(), msg.counterparty_version())?; - Ok(()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// record the channel in CHANNEL_INFO -pub fn ibc_channel_connect( - deps: DepsMut, - _env: Env, - msg: IbcChannelConnectMsg, -) -> Result { - // we need to check the counter party version in try and ack (sometimes here) - enforce_order_and_version(msg.channel(), msg.counterparty_version())?; - - let channel: IbcChannel = msg.into(); - let info = ChannelInfo { - id: channel.endpoint.channel_id, - counterparty_endpoint: channel.counterparty_endpoint, - connection_id: channel.connection_id, - }; - CHANNEL_INFO.save(deps.storage, &info.id, &info)?; - - Ok(IbcBasicResponse::default()) -} - -fn enforce_order_and_version( - channel: &IbcChannel, - _counterparty_version: Option<&str>, -) -> Result<(), ContractError> { - // if channel.version != ICA_VERSION { - // return Err(ContractError::InvalidIbcVersion { - // contract_version: ICA_VERSION.to_string(), - // version: channel.version.clone(), - // }); - // } - // if let Some(version) = counterparty_version { - // if version != ICA_VERSION { - // return Err(ContractError::InvalidIbcVersion { - // contract_version: ICA_VERSION.to_string(), - // version: version.to_string(), - // }); - // } - // } - if channel.order != ICA_ORDERING { - return Err(ContractError::OnlyOrderedChannel {}); - } - Ok(()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_channel_close( - _deps: DepsMut, - _env: Env, - _channel: IbcChannelCloseMsg, -) -> Result { - // TODO: what to do here? - // we will have locked funds that need to be returned somehow - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// Check to see if we have any balance here -/// We should not return an error if possible, but rather an acknowledgement of failure -pub fn ibc_packet_receive( - _deps: DepsMut, - _env: Env, - _msg: IbcPacketReceiveMsg, -) -> Result { - // Contract does not handle packets/queries. - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// check if success or failure and update balance, or return funds -pub fn ibc_packet_ack( - deps: DepsMut, - env: Env, - msg: IbcPacketAckMsg, -) -> Result { - // Design decision: should we trap error like in receive? - // TODO: unsure... as it is now a failed ack handling would revert the tx and would be - // retried again and again. is that good? - let ics_msg: IcsAck = from_json(&msg.acknowledgement.data)?; - match ics_msg { - IcsAck::Result(data) => on_packet_success(deps, data, msg.original_packet, env), - IcsAck::Error(err) => on_packet_failure(deps, msg.original_packet, err), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// return fund to original sender (same as failure in ibc_packet_ack) -pub fn ibc_packet_timeout( - deps: DepsMut, - _env: Env, - msg: IbcPacketTimeoutMsg, -) -> Result { - // TODO: trap error like in receive? (same question as ack above) - let packet = msg.packet; - on_packet_failure(deps, packet, "timeout".to_string()) -} - -fn on_packet_success( - deps: DepsMut, - data: Binary, - original: IbcPacket, - env: Env, -) -> Result { - let ack: InterchainQueryPacketAck = from_json(&data)?; - - let buf = Bytes::copy_from_slice(ack.data.as_slice()); - let resp: CosmosResponse = match CosmosResponse::decode(buf) { - Ok(resp) => resp, - Err(_) => return Err(ContractError::DecodingFail {}), - }; - - // load the msg from the pending queries so we know what to do - let origin = - PENDING_QUERIES.load(deps.storage, (original.sequence, &original.src.channel_id))?; - match origin { - Origin::Sample => Ok(handle_sample_callback(deps, env, resp, original)?), - } -} - -fn on_packet_failure( - _deps: DepsMut, - _packet: IbcPacket, - err: String, -) -> Result { - let attributes = vec![ - attr("action", "acknowledge"), - attr("success", "false"), - attr("error", err), - ]; - - Ok(IbcBasicResponse::new().add_attributes(attributes)) -} - -#[cfg(test)] -mod test { - use super::*; - use crate::state::QUERY_RESULT_COUNTER; - use crate::ContractError; - - use cosmwasm_std::testing::{mock_dependencies, mock_env}; - use cosmwasm_std::{Binary, IbcAcknowledgement, IbcEndpoint, IbcPacket, IbcTimeout, Timestamp}; - - #[test] - fn test_ibc_packet_ack() -> Result<(), ContractError> { - let mut deps = mock_dependencies(); - let timeout = IbcTimeout::with_timestamp(Timestamp::from_nanos(0)); - let src = IbcEndpoint { - port_id: "port-0".to_string(), - channel_id: "channel-0".to_string(), - }; - let dest = IbcEndpoint { - port_id: "port-1".to_string(), - channel_id: "channel-1".to_string(), - }; - let packet = IbcPacket::new(Binary::default(), src, dest, 0, timeout); - let ack = IbcAcknowledgement::new(Binary::from_base64( - "eyJyZXN1bHQiOiJleUprWVhSaElqb2lRMmRaU1VWcmFXUnpaMFU5SW4wPSJ9", - )?); - let msg = IbcPacketAckMsg::new(ack, packet); - QUERY_RESULT_COUNTER.save(deps.as_mut().storage, &0)?; // Save a 0 - match ibc_packet_ack(deps.as_mut(), mock_env(), msg) { - Ok(_) => { - assert_eq!(QUERY_RESULT_COUNTER.load(deps.as_mut().storage)?, 1); - Ok(()) - } - Err(err) => Err(err), - } - } -} diff --git a/smart-contracts/contracts/ica/src/lib.rs b/smart-contracts/contracts/ica/src/lib.rs deleted file mode 100644 index c785d5eef..000000000 --- a/smart-contracts/contracts/ica/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub mod contract; -mod error; -mod helpers; -pub mod ibc; -pub mod msg; -mod proto; -pub mod state; -mod test_helpers; - -pub use crate::error::ContractError; - -// pub mod items { -// include!(concat!(env!("OUT_DIR"), "/queries.rs")); -// } diff --git a/smart-contracts/contracts/ica/src/msg.rs b/smart-contracts/contracts/ica/src/msg.rs deleted file mode 100644 index 88c2a670a..000000000 --- a/smart-contracts/contracts/ica/src/msg.rs +++ /dev/null @@ -1,95 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::state::ChannelInfo; -use cosmwasm_std::{Binary, Uint64}; -use osmosis_std::types::cosmos::base::v1beta1::Coin as OsmoCoin; - -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] -pub struct InitMsg { - /// Default timeout for icq packets, specified in seconds - pub default_timeout: u64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] -pub struct MigrateMsg { - pub default_gas_limit: Option, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - JoinPool { - channel: String, - sender: String, - pool_id: Uint64, - share_out_amount: String, - token_in_maxs: Vec, - }, -} - -/// This is the message we accept via Receive -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct ICQQueryMsg { - /// The local channel to send the packets on - pub channel: String, - pub requests: Vec, - // How long the packet lives in seconds. If not specified, use default_timeout - pub timeout: Option, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct RequestQueryJSON { - pub data: Binary, - pub path: String, - pub height: i64, - pub prove: bool, -} - -// ResponseQuery does not contain all of the response fields. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct ResponseQuery { - pub key: Binary, - pub value: String, - pub height: i64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct InterchainQueryPacketData { - pub data: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Return the port ID bound by this contract. Returns PortResponse - Port {}, - /// Show all channels we have connected to. Return type is ListChannelsResponse. - ListChannels {}, - /// Returns the details of the name channel, error if not created. - /// Return type: ChannelResponse. - Channel { id: String }, - /// Show the Config. Returns ConfigResponse (currently including admin as well) - Config {}, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ListChannelsResponse { - pub channels: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ChannelResponse { - /// Information on the channel's connection - pub info: ChannelInfo, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct PortResponse { - pub port_id: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ConfigResponse { - pub default_timeout: u64, -} diff --git a/smart-contracts/contracts/ica/src/proto.rs b/smart-contracts/contracts/ica/src/proto.rs deleted file mode 100644 index 31cd1090c..000000000 --- a/smart-contracts/contracts/ica/src/proto.rs +++ /dev/null @@ -1,15 +0,0 @@ -use cosmos_sdk_proto::tendermint::abci::{RequestQuery, ResponseQuery}; - -/// CosmosQuery contains a list of tendermint ABCI query requests. It should be used when sending queries to an SDK host chain. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CosmosQuery { - #[prost(message, repeated, tag = "1")] - pub requests: ::prost::alloc::vec::Vec, -} - -/// CosmosResponse contains a list of tendermint ABCI query responses. It should be used when receiving responses from an SDK host chain. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CosmosResponse { - #[prost(message, repeated, tag = "1")] - pub responses: ::prost::alloc::vec::Vec, -} diff --git a/smart-contracts/contracts/ica/src/state.rs b/smart-contracts/contracts/ica/src/state.rs deleted file mode 100644 index 1e555d458..000000000 --- a/smart-contracts/contracts/ica/src/state.rs +++ /dev/null @@ -1,40 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::IbcEndpoint; -use cw_storage_plus::{Item, Map}; - -pub const CONFIG: Item = Item::new("icq_config"); - -/// static info on one channel that doesn't change -pub const CHANNEL_INFO: Map<&str, ChannelInfo> = Map::new("channel_info"); - -pub const QUERY_RESULT_COUNTER: Item = Item::new("query_result_counter"); - -// pending queries lets us register a sequence number on a specific channel and set a corresponding enum. -// using the Origin enum, we can write a function for the callback on acknowledgement. -// we want to use an enum and some form of state here so we support callbacks for multiple queries batches together -// and different callbacks for the same set of queries from a different origin -pub const PENDING_QUERIES: Map<(u64, &str), Origin> = Map::new("pending_queries"); - -pub const REPLIES: Map = Map::new("replies"); - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub enum Origin { - Sample, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct Config { - pub default_timeout: u64, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ChannelInfo { - /// id of this channel - pub id: String, - /// the remote channel/port we connect to - pub counterparty_endpoint: IbcEndpoint, - /// the connection this exists on (you can use to query client/consensus info) - pub connection_id: String, -} diff --git a/smart-contracts/contracts/ica/src/test_helpers.rs b/smart-contracts/contracts/ica/src/test_helpers.rs deleted file mode 100644 index 2dfac85af..000000000 --- a/smart-contracts/contracts/ica/src/test_helpers.rs +++ /dev/null @@ -1,72 +0,0 @@ -#![cfg(test)] - -use crate::contract::instantiate; -use crate::ibc::{ibc_channel_connect, ibc_channel_open, ICA_ORDERING, ICA_VERSION}; -use crate::state::ChannelInfo; - -use cosmwasm_std::testing::{ - mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, -}; -use cosmwasm_std::{ - DepsMut, IbcChannel, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcEndpoint, OwnedDeps, -}; - -use crate::msg::InitMsg; - -pub const DEFAULT_TIMEOUT: u64 = 3600; // 1 hour, -pub const CONTRACT_PORT: &str = "ibc:wasm1234567890abcdef"; -pub const REMOTE_PORT: &str = "icahost"; -pub const CONNECTION_ID: &str = "connection-2"; - -pub fn mock_channel(channel_id: &str) -> IbcChannel { - IbcChannel::new( - IbcEndpoint { - port_id: CONTRACT_PORT.into(), - channel_id: channel_id.into(), - }, - IbcEndpoint { - port_id: REMOTE_PORT.into(), - channel_id: format!("{}5", channel_id), - }, - ICA_ORDERING, - ICA_VERSION, - CONNECTION_ID, - ) -} - -pub fn mock_channel_info(channel_id: &str) -> ChannelInfo { - ChannelInfo { - id: channel_id.to_string(), - counterparty_endpoint: IbcEndpoint { - port_id: REMOTE_PORT.into(), - channel_id: format!("{}5", channel_id), - }, - connection_id: CONNECTION_ID.into(), - } -} - -// we simulate instantiate and ack here -pub fn add_channel(mut deps: DepsMut, channel_id: &str) { - let channel = mock_channel(channel_id); - let open_msg = IbcChannelOpenMsg::new_init(channel.clone()); - ibc_channel_open(deps.branch(), mock_env(), open_msg).unwrap(); - let connect_msg = IbcChannelConnectMsg::new_ack(channel, ICA_VERSION); - ibc_channel_connect(deps.branch(), mock_env(), connect_msg).unwrap(); -} - -pub fn setup(channels: &[&str]) -> OwnedDeps { - let mut deps = mock_dependencies(); - - // instantiate an empty contract - let instantiate_msg = InitMsg { - default_timeout: DEFAULT_TIMEOUT, - }; - let info = mock_info(&String::from("anyone"), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - for channel in channels { - add_channel(deps.as_mut(), channel); - } - deps -} diff --git a/smart-contracts/contracts/icq/.cargo/config b/smart-contracts/contracts/icq/.cargo/config deleted file mode 100644 index dba2c3f7a..000000000 --- a/smart-contracts/contracts/icq/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" -lint = "clippy -- -D warnings" \ No newline at end of file diff --git a/smart-contracts/contracts/icq/Cargo.toml b/smart-contracts/contracts/icq/Cargo.toml deleted file mode 100644 index ade605545..000000000 --- a/smart-contracts/contracts/icq/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "icq" -version = "0.1.0" -authors = ["Bo Du "] -edition = "2018" -description = "IBC Enabled contracts for interchain queries" -license = "Apache-2.0" -repository = "https://github.com/CosmWasm/cw-plus" -homepage = "https://cosmwasm.com" -documentation = "https://docs.cosmwasm.com" - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] -# backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all init/handle/query exports -library = [] - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -prost = { workspace = true } -cw-controllers = { workspace = true } -cw-utils = { workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cosmos-sdk-proto = { workspace = true } -base64 = { workspace = true } - -semver = "1" \ No newline at end of file diff --git a/smart-contracts/contracts/icq/NOTICE b/smart-contracts/contracts/icq/NOTICE deleted file mode 100644 index bc266454e..000000000 --- a/smart-contracts/contracts/icq/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -CW20-ICS20: IBC Enabled contracts that receives CW20 tokens and sends them over ICS20 to a remote chain -Copyright (C) 2020 Confio OÃœ - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/smart-contracts/contracts/icq/README.md b/smart-contracts/contracts/icq/README.md deleted file mode 100644 index 3f5f43452..000000000 --- a/smart-contracts/contracts/icq/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# ICQ - -This is an *IBC Enabled* contract that allows us to send ICQ queries from one chain over the standard ICQ -protocol to the bank module of another chain. - -## Workflow - -The contract starts with minimal state. It just stores a default timeout in seconds for all packets it sends. -Most importantly it binds a local IBC port to enable channel connections. - -An external party first needs to make one or more channels using this contract as one endpoint. It will use standard -unordered channels for the version negotiation. Once established, it manages a list of known channels. - -After there is at least one channel, you can send any ICQ query to this contract. It may optionally include a custom timeout. - -## Messages - -It only accepts ICQQueryMsg. The data sent along with that message must be a JSON-serialized -TransferMsg: - -## Queries - -Queries only make sense relative to the established channels of this contract. - -* `Port{}` - returns the port ID this contract has bound, so you can create channels. This info can be queried - via wasmd contract info query, but we expose another query here for convenience. -* `ListChannels{}` - returns a (currently unpaginated) list of all channels that have been created on this contract. - Returns their local channelId along with some basic metadata, like the remote port/channel and the connection they - run on top of. -* `Channel{id}` - returns more detailed information on one specific channel. In addition to the information available - in the list view, it returns the current outstanding balance on that channel, as well as the total amount that - has ever been sent on the channel. diff --git a/smart-contracts/contracts/icq/examples/schema.rs b/smart-contracts/contracts/icq/examples/schema.rs deleted file mode 100644 index 645b8b312..000000000 --- a/smart-contracts/contracts/icq/examples/schema.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use icq::msg::{ - ChannelResponse, ExecuteMsg, ICQQueryMsg, InitMsg, ListChannelsResponse, PortResponse, QueryMsg, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InitMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(ICQQueryMsg), &out_dir); - export_schema(&schema_for!(ChannelResponse), &out_dir); - export_schema(&schema_for!(ListChannelsResponse), &out_dir); - export_schema(&schema_for!(PortResponse), &out_dir); -} diff --git a/smart-contracts/contracts/icq/schema/channel_response.json b/smart-contracts/contracts/icq/schema/channel_response.json deleted file mode 100644 index 1744539e6..000000000 --- a/smart-contracts/contracts/icq/schema/channel_response.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ChannelResponse", - "type": "object", - "required": [ - "info" - ], - "properties": { - "info": { - "description": "Information on the channel's connection", - "allOf": [ - { - "$ref": "#/definitions/ChannelInfo" - } - ] - } - }, - "definitions": { - "ChannelInfo": { - "type": "object", - "required": [ - "connection_id", - "counterparty_endpoint", - "id" - ], - "properties": { - "connection_id": { - "description": "the connection this exists on (you can use to query client/consensus info)", - "type": "string" - }, - "counterparty_endpoint": { - "description": "the remote channel/port we connect to", - "allOf": [ - { - "$ref": "#/definitions/IbcEndpoint" - } - ] - }, - "id": { - "description": "id of this channel", - "type": "string" - } - } - }, - "IbcEndpoint": { - "type": "object", - "required": [ - "channel_id", - "port_id" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "port_id": { - "type": "string" - } - } - } - } -} diff --git a/smart-contracts/contracts/icq/schema/execute_msg.json b/smart-contracts/contracts/icq/schema/execute_msg.json deleted file mode 100644 index 87c427c4c..000000000 --- a/smart-contracts/contracts/icq/schema/execute_msg.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "query" - ], - "properties": { - "query": { - "$ref": "#/definitions/ICQQueryMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "query_balance" - ], - "properties": { - "query_balance": { - "type": "object", - "required": [ - "address", - "channel", - "denom" - ], - "properties": { - "address": { - "type": "string" - }, - "channel": { - "type": "string" - }, - "denom": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "query_all_balance" - ], - "properties": { - "query_all_balance": { - "type": "object", - "required": [ - "address", - "channel" - ], - "properties": { - "address": { - "type": "string" - }, - "channel": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "query_mint" - ], - "properties": { - "query_mint": { - "type": "object", - "required": [ - "channel" - ], - "properties": { - "channel": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ICQQueryMsg": { - "description": "This is the message we accept via Receive", - "type": "object", - "required": [ - "channel", - "requests" - ], - "properties": { - "channel": { - "description": "The local channel to send the packets on", - "type": "string" - }, - "requests": { - "type": "array", - "items": { - "$ref": "#/definitions/RequestQueryJSON" - } - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - } - }, - "RequestQueryJSON": { - "type": "object", - "required": [ - "data", - "height", - "path", - "prove" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "height": { - "type": "integer", - "format": "int64" - }, - "path": { - "type": "string" - }, - "prove": { - "type": "boolean" - } - } - } - } -} diff --git a/smart-contracts/contracts/icq/schema/i_c_q_query_msg.json b/smart-contracts/contracts/icq/schema/i_c_q_query_msg.json deleted file mode 100644 index 316cd71ce..000000000 --- a/smart-contracts/contracts/icq/schema/i_c_q_query_msg.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ICQQueryMsg", - "description": "This is the message we accept via Receive", - "type": "object", - "required": [ - "channel", - "requests" - ], - "properties": { - "channel": { - "description": "The local channel to send the packets on", - "type": "string" - }, - "requests": { - "type": "array", - "items": { - "$ref": "#/definitions/RequestQueryJSON" - } - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "RequestQueryJSON": { - "type": "object", - "required": [ - "data", - "height", - "path", - "prove" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "height": { - "type": "integer", - "format": "int64" - }, - "path": { - "type": "string" - }, - "prove": { - "type": "boolean" - } - } - } - } -} diff --git a/smart-contracts/contracts/icq/schema/init_msg.json b/smart-contracts/contracts/icq/schema/init_msg.json deleted file mode 100644 index 33a291fc3..000000000 --- a/smart-contracts/contracts/icq/schema/init_msg.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InitMsg", - "type": "object", - "required": [ - "default_timeout" - ], - "properties": { - "default_timeout": { - "description": "Default timeout for icq packets, specified in seconds", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/smart-contracts/contracts/icq/schema/list_channels_response.json b/smart-contracts/contracts/icq/schema/list_channels_response.json deleted file mode 100644 index 69f020c93..000000000 --- a/smart-contracts/contracts/icq/schema/list_channels_response.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ListChannelsResponse", - "type": "object", - "required": [ - "channels" - ], - "properties": { - "channels": { - "type": "array", - "items": { - "$ref": "#/definitions/ChannelInfo" - } - } - }, - "definitions": { - "ChannelInfo": { - "type": "object", - "required": [ - "connection_id", - "counterparty_endpoint", - "id" - ], - "properties": { - "connection_id": { - "description": "the connection this exists on (you can use to query client/consensus info)", - "type": "string" - }, - "counterparty_endpoint": { - "description": "the remote channel/port we connect to", - "allOf": [ - { - "$ref": "#/definitions/IbcEndpoint" - } - ] - }, - "id": { - "description": "id of this channel", - "type": "string" - } - } - }, - "IbcEndpoint": { - "type": "object", - "required": [ - "channel_id", - "port_id" - ], - "properties": { - "channel_id": { - "type": "string" - }, - "port_id": { - "type": "string" - } - } - } - } -} diff --git a/smart-contracts/contracts/icq/schema/port_response.json b/smart-contracts/contracts/icq/schema/port_response.json deleted file mode 100644 index 4561b3a72..000000000 --- a/smart-contracts/contracts/icq/schema/port_response.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PortResponse", - "type": "object", - "required": [ - "port_id" - ], - "properties": { - "port_id": { - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/icq/schema/query_msg.json b/smart-contracts/contracts/icq/schema/query_msg.json deleted file mode 100644 index be42f505f..000000000 --- a/smart-contracts/contracts/icq/schema/query_msg.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Return the port ID bound by this contract. Returns PortResponse", - "type": "object", - "required": [ - "port" - ], - "properties": { - "port": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Show all channels we have connected to. Return type is ListChannelsResponse.", - "type": "object", - "required": [ - "list_channels" - ], - "properties": { - "list_channels": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "description": "Returns the details of the name channel, error if not created. Return type: ChannelResponse.", - "type": "object", - "required": [ - "channel" - ], - "properties": { - "channel": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Show the Config. Returns ConfigResponse (currently including admin as well)", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/smart-contracts/contracts/icq/src/contract.rs b/smart-contracts/contracts/icq/src/contract.rs deleted file mode 100644 index b7e8485c2..000000000 --- a/smart-contracts/contracts/icq/src/contract.rs +++ /dev/null @@ -1,324 +0,0 @@ -use cosmos_sdk_proto::cosmos::bank::v1beta1::{QueryAllBalancesRequest, QueryBalanceRequest}; -use cosmos_sdk_proto::tendermint::abci::RequestQuery; -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, Binary, Deps, DepsMut, Env, IbcMsg, IbcQuery, MessageInfo, Order, PortIdResponse, - Reply, Response, StdResult, -}; -use osmosis_std::types::osmosis::gamm::v1beta1::QueryNumPoolsRequest; -use prost::Message; - -use cw2::set_contract_version; - -use crate::error::ContractError; -use crate::helpers::{prepare_query, Query}; -use crate::msg::{ - ChannelResponse, ConfigResponse, ExecuteMsg, ICQQueryMsg, InitMsg, InterchainQueryPacketData, - ListChannelsResponse, MigrateMsg, PortResponse, QueryMsg, -}; -use crate::proto::CosmosQuery; -use crate::state::{Config, CHANNEL_INFO, CONFIG, QUERY_RESULT_COUNTER}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:icq"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InitMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let cfg = Config { - default_timeout: msg.default_timeout, - }; - CONFIG.save(deps.storage, &cfg)?; - QUERY_RESULT_COUNTER.save(deps.storage, &0)?; - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - _info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Query(msg) => execute_query(deps, env, msg), - ExecuteMsg::QueryBalance { - address, - denom, - channel, - } => execute_balance_query(deps, env, address, denom, channel), - ExecuteMsg::QueryAllBalance { address, channel } => { - execute_all_balance_query(deps, env, address, channel) - } - ExecuteMsg::QueryMint { channel } => execute_mint_params_query(deps, env, channel), - } -} - -pub fn execute_balance_query( - deps: DepsMut, - env: Env, - address: String, - denom: String, - channel: String, -) -> Result { - let timeout = prepare_query(deps.storage, env, &channel)?; - let query = QueryBalanceRequest { address, denom }; - let packet = Query::new() - .add_request( - query.encode_to_vec(), - "/cosmos.bank.v1beta1.Query/Balance".into(), - ) - .encode_pkt(); - - // prepare ibc message - let send_packet_msg = IbcMsg::SendPacket { - channel_id: channel, - data: to_json_binary(&packet)?, - timeout: timeout.into(), - }; - - let res = Response::new() - .add_message(send_packet_msg) - .add_attribute("action", "query"); - Ok(res) -} - -pub fn execute_all_balance_query( - deps: DepsMut, - env: Env, - address: String, - channel: String, -) -> Result { - let timeout = prepare_query(deps.storage, env, &channel)?; - - let query = QueryAllBalancesRequest { - address, - pagination: None, - }; - - let packet = Query::new() - .add_request( - query.encode_to_vec(), - "/cosmos.bank.v1beta1.Query/AllBalances".into(), - ) - .encode_pkt(); - - // prepare ibc message - let send_packet_msg = IbcMsg::SendPacket { - channel_id: channel, - data: to_json_binary(&packet)?, - timeout: timeout.into(), - }; - - let res = Response::new() - .add_message(send_packet_msg) - .add_attribute("action", "query"); - Ok(res) -} - -fn execute_mint_params_query( - deps: DepsMut, - env: Env, - channel: String, -) -> Result { - let timeout = prepare_query(deps.storage, env, &channel)?; - let data = QueryNumPoolsRequest {}; - let packet = Query::new() - .add_request( - data.encode_to_vec(), - "/osmosis.gamm.v1beta1.Query/NumPools".into(), - ) - .encode_pkt(); - - // prepare ibc message - let send_packet_msg = IbcMsg::SendPacket { - channel_id: channel, - data: to_json_binary(&packet)?, - timeout: timeout.into(), - }; - - let res = Response::new() - .add_message(send_packet_msg) - .add_attribute("action", "query"); - Ok(res) -} - -pub fn execute_query(deps: DepsMut, env: Env, msg: ICQQueryMsg) -> Result { - // ensure the requested channel is registered - if !CHANNEL_INFO.has(deps.storage, &msg.channel) { - return Err(ContractError::NoSuchChannel { id: msg.channel }); - } - let config = CONFIG.load(deps.storage)?; - // delta from user is in seconds - let timeout_delta = match msg.timeout { - Some(t) => t, - None => config.default_timeout, - }; - // timeout is in nanoseconds - let timeout = env.block.time.plus_seconds(timeout_delta); - let num_requests = msg.requests.len(); - - let q = CosmosQuery { - requests: msg - .requests - .iter() - .map(|req| RequestQuery { - data: req.data.clone().into(), - path: req.path.clone(), - height: req.height, - prove: req.prove, - }) - .collect::>(), - }; - let mut data = Vec::new(); - if q.encode(&mut data).is_err() { - return Err(ContractError::EncodingFail {}); - } - - let packet = InterchainQueryPacketData { data }; - // prepare ibc message - let send_packet_msg = IbcMsg::SendPacket { - channel_id: msg.channel, - data: to_json_binary(&packet)?, - timeout: timeout.into(), - }; - - // send response - let res = Response::new() - .add_message(send_packet_msg) - .add_attribute("action", "query") - .add_attribute("num_requests", num_requests.to_string()); - Ok(res) -} - -#[entry_point] -pub fn reply(_deps: DepsMut, _env: Env, _msg: Reply) -> StdResult { - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - Ok(Response::new()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Port {} => to_json_binary(&query_port(deps)?), - QueryMsg::ListChannels {} => to_json_binary(&query_list(deps)?), - QueryMsg::Channel { id } => to_json_binary(&query_channel(deps, id)?), - QueryMsg::Config {} => to_json_binary(&query_config(deps)?), - } -} - -fn query_port(deps: Deps) -> StdResult { - let query = IbcQuery::PortId {}.into(); - let PortIdResponse { port_id } = deps.querier.query(&query)?; - Ok(PortResponse { port_id }) -} - -fn query_list(deps: Deps) -> StdResult { - let channels = CHANNEL_INFO - .range_raw(deps.storage, None, None, Order::Ascending) - .map(|r| r.map(|(_, v)| v)) - .collect::>()?; - Ok(ListChannelsResponse { channels }) -} - -// make public for ibc tests -pub fn query_channel(deps: Deps, id: String) -> StdResult { - let info = CHANNEL_INFO.load(deps.storage, &id)?; - Ok(ChannelResponse { info }) -} - -fn query_config(deps: Deps) -> StdResult { - let cfg = CONFIG.load(deps.storage)?; - let res = ConfigResponse { - default_timeout: cfg.default_timeout, - }; - Ok(res) -} - -#[cfg(test)] -mod test { - use super::*; - use crate::msg::RequestQueryJSON; - use crate::test_helpers::*; - - use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::{from_json, CosmosMsg, StdError}; - - #[test] - fn setup_and_query() { - let deps = setup(&["channel-3", "channel-7"]); - - let raw_list = query(deps.as_ref(), mock_env(), QueryMsg::ListChannels {}).unwrap(); - let list_res: ListChannelsResponse = from_json(&raw_list).unwrap(); - assert_eq!(2, list_res.channels.len()); - assert_eq!(mock_channel_info("channel-3"), list_res.channels[0]); - assert_eq!(mock_channel_info("channel-7"), list_res.channels[1]); - - let raw_channel = query( - deps.as_ref(), - mock_env(), - QueryMsg::Channel { - id: "channel-3".to_string(), - }, - ) - .unwrap(); - let chan_res: ChannelResponse = from_json(&raw_channel).unwrap(); - assert_eq!(chan_res.info, mock_channel_info("channel-3")); - - let err = query( - deps.as_ref(), - mock_env(), - QueryMsg::Channel { - id: "channel-10".to_string(), - }, - ) - .unwrap_err(); - assert_eq!(err, StdError::not_found("icq::state::ChannelInfo")); - } - - #[test] - fn execute_query_success() { - let send_channel = "channel-5"; - let mut deps = setup(&[send_channel, "channel-10"]); - - let requests = vec![RequestQueryJSON { - data: Binary::from([0, 1, 0, 1]), - path: "/path".to_string(), - height: 0, - prove: false, - }]; - let q = ICQQueryMsg { - channel: send_channel.to_string(), - requests, - timeout: None, - }; - - let msg = ExecuteMsg::Query(q); - let info = mock_info("foobar", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - if let CosmosMsg::Ibc(IbcMsg::SendPacket { - channel_id, - data, - timeout, - }) = &res.messages[0].msg - { - let expected_timeout = mock_env().block.time.plus_seconds(DEFAULT_TIMEOUT); - assert_eq!(timeout, &expected_timeout.into()); - assert_eq!(channel_id.as_str(), send_channel); - let _: InterchainQueryPacketData = from_json(data).unwrap(); - } else { - panic!("Unexpected return message: {:?}", res.messages[0]); - } - } -} diff --git a/smart-contracts/contracts/icq/src/error.rs b/smart-contracts/contracts/icq/src/error.rs deleted file mode 100644 index e531295a8..000000000 --- a/smart-contracts/contracts/icq/src/error.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::string::FromUtf8Error; -use thiserror::Error; - -use cosmwasm_std::StdError; - -/// Never is a placeholder to ensure we don't return any errors -#[derive(Error, Debug)] -pub enum Never {} - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Channel doesn't exist: {id}")] - NoSuchChannel { id: String }, - - #[error("Only supports channel with ibc version icq-1, got {version}")] - InvalidIbcVersion { version: String }, - - #[error("Only supports unordered channel")] - OnlyOrderedChannel {}, - - #[error("Parsed port from denom ({port}) doesn't match packet")] - FromOtherPort { port: String }, - - #[error("Parsed channel from denom ({channel}) doesn't match packet")] - FromOtherChannel { channel: String }, - - #[error("Cannot migrate from different contract type: {previous_contract}")] - CannotMigrate { previous_contract: String }, - - #[error("Cannot migrate from unsupported version: {previous_version}")] - CannotMigrateVersion { previous_version: String }, - - #[error("Failed to proto encode")] - EncodingFail, - - #[error("Failed to proto decode")] - DecodingFail, - - #[error("Only the governance contract can do this")] - Unauthorized, -} - -impl From for ContractError { - fn from(_: FromUtf8Error) -> Self { - ContractError::Std(StdError::invalid_utf8("parsing denom key")) - } -} diff --git a/smart-contracts/contracts/icq/src/helpers.rs b/smart-contracts/contracts/icq/src/helpers.rs deleted file mode 100644 index 264f46647..000000000 --- a/smart-contracts/contracts/icq/src/helpers.rs +++ /dev/null @@ -1,147 +0,0 @@ -use crate::{ - msg::InterchainQueryPacketData, - proto::{CosmosQuery, CosmosResponse}, - state::{CHANNEL_INFO, CONFIG, QUERY_RESULT_COUNTER}, - ContractError, -}; -use cosmos_sdk_proto::tendermint::abci::RequestQuery; -use cosmwasm_std::{attr, DepsMut, Env, IbcBasicResponse, IbcPacket, Storage, Timestamp}; -use prost::Message; - -pub fn prepare_query( - storage: &dyn Storage, - env: Env, - channel: &str, -) -> Result { - // ensure the requested channel is registered - if !CHANNEL_INFO.has(storage, channel) { - return Err(ContractError::NoSuchChannel { id: channel.into() }); - } - let config = CONFIG.load(storage)?; - // delta from user is in seconds - let timeout_delta = config.default_timeout; - - // timeout is in nanoseconds - Ok(env.block.time.plus_seconds(timeout_delta)) -} - -// for our sample origin callback, we increment the query counter and leave it at that -pub fn handle_sample_callback( - deps: DepsMut, - _env: Env, - response: CosmosResponse, - _original: IbcPacket, -) -> Result { - let attrs = vec![ - attr("action", "acknowledge"), - attr("num_messages", response.responses.len().to_string()), - attr("success", "true"), - ]; - - // Store result counter. - let mut counter = QUERY_RESULT_COUNTER.load(deps.storage)?; - counter += response.responses.len() as u64; - QUERY_RESULT_COUNTER.save(deps.storage, &counter)?; - Ok(IbcBasicResponse::new().add_attributes(attrs)) -} - -#[derive(Clone, Debug, PartialEq)] -pub struct Query { - requests: Vec, -} - -impl Query { - pub fn new() -> Query { - Query { - requests: Vec::new(), - } - } - - pub fn add_request(mut self, data: Vec, path: String) -> Self { - self.requests.push(RequestQuery { - data, - path, - height: 0, - prove: false, - }); - self - } - - pub fn encode(self) -> Vec { - CosmosQuery { - requests: self.requests, - } - .encode_to_vec() - } - - pub fn encode_pkt(self) -> InterchainQueryPacketData { - InterchainQueryPacketData { - data: self.encode(), - } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - pub fn single_query_works() { - let req = RequestQuery { - data: vec![1, 0, 1, 0], - path: "/cosmos.bank.v1beta1.Query/AllBalances".into(), - height: 0, - prove: false, - }; - - let data = Query::new().add_request(req.data.clone(), req.path.clone()); - - assert_eq!( - data, - Query { - requests: vec![req.clone()] - } - ); - assert_eq!( - data.encode(), - CosmosQuery { - requests: vec![req] - } - .encode_to_vec() - ) - } - - #[test] - pub fn multiple_query_works() { - let req1 = RequestQuery { - data: vec![1, 0, 1, 0], - path: "/cosmos.bank.v1beta1.Query/AllBalances".into(), - height: 0, - prove: false, - }; - let req2 = RequestQuery { - data: vec![1, 0, 0, 0], - path: "/cosmos.bank.v1beta1.Query/Balance".into(), - height: 0, - prove: false, - }; - - let data = Query::new() - .add_request(req1.data.clone(), req1.path.clone()) - .add_request(req2.data.clone(), req2.path.clone()); - - assert_eq!( - data, - Query { - requests: vec![req1.clone(), req2.clone()] - } - ); - assert_eq!( - data.encode(), - CosmosQuery { - requests: vec![req1, req2] - } - .encode_to_vec() - ) - } -} diff --git a/smart-contracts/contracts/icq/src/ibc.rs b/smart-contracts/contracts/icq/src/ibc.rs deleted file mode 100644 index 1cd280716..000000000 --- a/smart-contracts/contracts/icq/src/ibc.rs +++ /dev/null @@ -1,221 +0,0 @@ -use prost::bytes::Bytes; -use prost::Message; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{ - attr, entry_point, from_json, Binary, DepsMut, Env, IbcBasicResponse, IbcChannel, - IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcOrder, IbcPacket, - IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, -}; - -use crate::error::{ContractError, Never}; -use crate::helpers::handle_sample_callback; -use crate::proto::CosmosResponse; -use crate::state::{ChannelInfo, CHANNEL_INFO}; - -pub const ICQ_VERSION: &str = "icq-1"; -pub const ICQ_ORDERING: IbcOrder = IbcOrder::Unordered; - -/// This is compatible with the JSON serialization -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug, Default)] -pub struct InterchainQueryPacketAck { - pub data: Binary, -} - -impl InterchainQueryPacketAck { - pub fn new(data: Binary) -> Self { - InterchainQueryPacketAck { data } - } - - pub fn validate(&self) -> Result<(), ContractError> { - Ok(()) - } -} - -/// This is a generic ICS acknowledgement format. -/// Proto defined here: https://github.com/cosmos/cosmos-sdk/blob/v0.42.0/proto/ibc/core/channel/v1/channel.proto#L141-L147 -/// This is compatible with the JSON serialization -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum IcsAck { - Result(Binary), - Error(String), -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// enforces ordering and versioning constraints -pub fn ibc_channel_open( - _deps: DepsMut, - _env: Env, - msg: IbcChannelOpenMsg, -) -> Result<(), ContractError> { - enforce_order_and_version(msg.channel(), msg.counterparty_version())?; - Ok(()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// record the channel in CHANNEL_INFO -pub fn ibc_channel_connect( - deps: DepsMut, - _env: Env, - msg: IbcChannelConnectMsg, -) -> Result { - // we need to check the counter party version in try and ack (sometimes here) - enforce_order_and_version(msg.channel(), msg.counterparty_version())?; - - let channel: IbcChannel = msg.into(); - let info = ChannelInfo { - id: channel.endpoint.channel_id, - counterparty_endpoint: channel.counterparty_endpoint, - connection_id: channel.connection_id, - }; - CHANNEL_INFO.save(deps.storage, &info.id, &info)?; - - Ok(IbcBasicResponse::default()) -} - -fn enforce_order_and_version( - channel: &IbcChannel, - counterparty_version: Option<&str>, -) -> Result<(), ContractError> { - if channel.version != ICQ_VERSION { - return Err(ContractError::InvalidIbcVersion { - version: channel.version.clone(), - }); - } - if let Some(version) = counterparty_version { - if version != ICQ_VERSION { - return Err(ContractError::InvalidIbcVersion { - version: version.to_string(), - }); - } - } - if channel.order != ICQ_ORDERING { - return Err(ContractError::OnlyOrderedChannel {}); - } - Ok(()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_channel_close( - _deps: DepsMut, - _env: Env, - _channel: IbcChannelCloseMsg, -) -> Result { - // TODO: what to do here? - // we will have locked funds that need to be returned somehow - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// Check to see if we have any balance here -/// We should not return an error if possible, but rather an acknowledgement of failure -pub fn ibc_packet_receive( - _deps: DepsMut, - _env: Env, - _msg: IbcPacketReceiveMsg, -) -> Result { - // Contract does not handle packets/queries. - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// check if success or failure and update balance, or return funds -pub fn ibc_packet_ack( - deps: DepsMut, - env: Env, - msg: IbcPacketAckMsg, -) -> Result { - // Design decision: should we trap error like in receive? - // TODO: unsure... as it is now a failed ack handling would revert the tx and would be - // retried again and again. is that good? - let ics_msg: IcsAck = from_json(&msg.acknowledgement.data)?; - match ics_msg { - IcsAck::Result(data) => on_packet_success(deps, data, msg.original_packet, env), - IcsAck::Error(err) => on_packet_failure(deps, msg.original_packet, err), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -/// return fund to original sender (same as failure in ibc_packet_ack) -pub fn ibc_packet_timeout( - deps: DepsMut, - _env: Env, - msg: IbcPacketTimeoutMsg, -) -> Result { - // TODO: trap error like in receive? (same question as ack above) - let packet = msg.packet; - on_packet_failure(deps, packet, "timeout".to_string()) -} - -fn on_packet_success( - deps: DepsMut, - data: Binary, - original: IbcPacket, - env: Env, -) -> Result { - let ack: InterchainQueryPacketAck = from_json(&data)?; - - let buf = Bytes::copy_from_slice(ack.data.as_slice()); - let resp: CosmosResponse = match CosmosResponse::decode(buf) { - Ok(resp) => resp, - Err(_) => return Err(ContractError::DecodingFail {}), - }; - - handle_sample_callback(deps, env, resp, original) -} - -fn on_packet_failure( - _deps: DepsMut, - _packet: IbcPacket, - err: String, -) -> Result { - let attributes = vec![ - attr("action", "acknowledge"), - attr("success", "false"), - attr("error", err), - ]; - - Ok(IbcBasicResponse::new().add_attributes(attributes)) -} - -#[cfg(test)] -mod test { - - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env}, - Binary, IbcAcknowledgement, IbcEndpoint, IbcPacket, IbcPacketAckMsg, IbcTimeout, Timestamp, - }; - - use crate::{state::QUERY_RESULT_COUNTER, ContractError}; - - use super::ibc_packet_ack; - - #[test] - fn test_ibc_packet_ack() -> Result<(), ContractError> { - let mut deps = mock_dependencies(); - let timeout = IbcTimeout::with_timestamp(Timestamp::from_nanos(0)); - let src = IbcEndpoint { - port_id: "port-0".to_string(), - channel_id: "channel-0".to_string(), - }; - let dest = IbcEndpoint { - port_id: "port-1".to_string(), - channel_id: "channel-1".to_string(), - }; - let packet = IbcPacket::new(Binary::default(), src, dest, 0, timeout); - let ack = IbcAcknowledgement::new(Binary::from_base64( - "eyJyZXN1bHQiOiJleUprWVhSaElqb2lRMmRaU1VWcmFXUnpaMFU5SW4wPSJ9", - )?); - let msg = IbcPacketAckMsg::new(ack, packet); - QUERY_RESULT_COUNTER.save(deps.as_mut().storage, &0)?; // Save a 0 - match ibc_packet_ack(deps.as_mut(), mock_env(), msg) { - Ok(_) => { - assert_eq!(QUERY_RESULT_COUNTER.load(deps.as_mut().storage)?, 1); - Ok(()) - } - Err(err) => Err(err), - } - } -} diff --git a/smart-contracts/contracts/icq/src/lib.rs b/smart-contracts/contracts/icq/src/lib.rs deleted file mode 100644 index c785d5eef..000000000 --- a/smart-contracts/contracts/icq/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub mod contract; -mod error; -mod helpers; -pub mod ibc; -pub mod msg; -mod proto; -pub mod state; -mod test_helpers; - -pub use crate::error::ContractError; - -// pub mod items { -// include!(concat!(env!("OUT_DIR"), "/queries.rs")); -// } diff --git a/smart-contracts/contracts/icq/src/msg.rs b/smart-contracts/contracts/icq/src/msg.rs deleted file mode 100644 index 6fc91dac2..000000000 --- a/smart-contracts/contracts/icq/src/msg.rs +++ /dev/null @@ -1,100 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::state::ChannelInfo; -use cosmwasm_std::Binary; - -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] -pub struct InitMsg { - /// Default timeout for icq packets, specified in seconds - pub default_timeout: u64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] -pub struct MigrateMsg { - pub default_gas_limit: Option, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - Query(ICQQueryMsg), - QueryBalance { - address: String, - denom: String, - channel: String, - }, - QueryAllBalance { - address: String, - channel: String, - }, - QueryMint { - channel: String, - }, -} - -/// This is the message we accept via Receive -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct ICQQueryMsg { - /// The local channel to send the packets on - pub channel: String, - pub requests: Vec, - // How long the packet lives in seconds. If not specified, use default_timeout - pub timeout: Option, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct RequestQueryJSON { - pub data: Binary, - pub path: String, - pub height: i64, - pub prove: bool, -} - -// ResponseQuery does not contain all of the response fields. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct ResponseQuery { - pub key: Binary, - pub value: String, - pub height: i64, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct InterchainQueryPacketData { - pub data: Vec, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - /// Return the port ID bound by this contract. Returns PortResponse - Port {}, - /// Show all channels we have connected to. Return type is ListChannelsResponse. - ListChannels {}, - /// Returns the details of the name channel, error if not created. - /// Return type: ChannelResponse. - Channel { id: String }, - /// Show the Config. Returns ConfigResponse (currently including admin as well) - Config {}, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ListChannelsResponse { - pub channels: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ChannelResponse { - /// Information on the channel's connection - pub info: ChannelInfo, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct PortResponse { - pub port_id: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ConfigResponse { - pub default_timeout: u64, -} diff --git a/smart-contracts/contracts/icq/src/proto.rs b/smart-contracts/contracts/icq/src/proto.rs deleted file mode 100644 index 31cd1090c..000000000 --- a/smart-contracts/contracts/icq/src/proto.rs +++ /dev/null @@ -1,15 +0,0 @@ -use cosmos_sdk_proto::tendermint::abci::{RequestQuery, ResponseQuery}; - -/// CosmosQuery contains a list of tendermint ABCI query requests. It should be used when sending queries to an SDK host chain. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CosmosQuery { - #[prost(message, repeated, tag = "1")] - pub requests: ::prost::alloc::vec::Vec, -} - -/// CosmosResponse contains a list of tendermint ABCI query responses. It should be used when receiving responses from an SDK host chain. -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct CosmosResponse { - #[prost(message, repeated, tag = "1")] - pub responses: ::prost::alloc::vec::Vec, -} diff --git a/smart-contracts/contracts/icq/src/state.rs b/smart-contracts/contracts/icq/src/state.rs deleted file mode 100644 index 1d8a115dd..000000000 --- a/smart-contracts/contracts/icq/src/state.rs +++ /dev/null @@ -1,32 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::IbcEndpoint; -use cw_storage_plus::{Item, Map}; - -pub const CONFIG: Item = Item::new("icq_config"); - -/// static info on one channel that doesn't change -pub const CHANNEL_INFO: Map<&str, ChannelInfo> = Map::new("channel_info"); - -pub const QUERY_RESULT_COUNTER: Item = Item::new("query_result_counter"); - -// pending queries lets us register a sequence number on a specific channel and set a corresponding enum. -// using the Origin enum, we can write a function for the callback on acknowledgement. -// we want to use an enum and some form of state here so we support callbacks for multiple queries batches together -// and different callbacks for the same set of queries from a different origin - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct Config { - pub default_timeout: u64, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct ChannelInfo { - /// id of this channel - pub id: String, - /// the remote channel/port we connect to - pub counterparty_endpoint: IbcEndpoint, - /// the connection this exists on (you can use to query client/consensus info) - pub connection_id: String, -} diff --git a/smart-contracts/contracts/icq/src/test_helpers.rs b/smart-contracts/contracts/icq/src/test_helpers.rs deleted file mode 100644 index 0c7ced3de..000000000 --- a/smart-contracts/contracts/icq/src/test_helpers.rs +++ /dev/null @@ -1,72 +0,0 @@ -#![cfg(test)] - -use crate::contract::instantiate; -use crate::ibc::{ibc_channel_connect, ibc_channel_open, ICQ_ORDERING, ICQ_VERSION}; -use crate::state::ChannelInfo; - -use cosmwasm_std::testing::{ - mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, -}; -use cosmwasm_std::{ - DepsMut, IbcChannel, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcEndpoint, OwnedDeps, -}; - -use crate::msg::InitMsg; - -pub const DEFAULT_TIMEOUT: u64 = 3600; // 1 hour, -pub const CONTRACT_PORT: &str = "ibc:wasm1234567890abcdef"; -pub const REMOTE_PORT: &str = "icqhost"; -pub const CONNECTION_ID: &str = "connection-2"; - -pub fn mock_channel(channel_id: &str) -> IbcChannel { - IbcChannel::new( - IbcEndpoint { - port_id: CONTRACT_PORT.into(), - channel_id: channel_id.into(), - }, - IbcEndpoint { - port_id: REMOTE_PORT.into(), - channel_id: format!("{channel_id}5"), - }, - ICQ_ORDERING, - ICQ_VERSION, - CONNECTION_ID, - ) -} - -pub fn mock_channel_info(channel_id: &str) -> ChannelInfo { - ChannelInfo { - id: channel_id.to_string(), - counterparty_endpoint: IbcEndpoint { - port_id: REMOTE_PORT.into(), - channel_id: format!("{channel_id}5"), - }, - connection_id: CONNECTION_ID.into(), - } -} - -// we simulate instantiate and ack here -pub fn add_channel(mut deps: DepsMut, channel_id: &str) { - let channel = mock_channel(channel_id); - let open_msg = IbcChannelOpenMsg::new_init(channel.clone()); - ibc_channel_open(deps.branch(), mock_env(), open_msg).unwrap(); - let connect_msg = IbcChannelConnectMsg::new_ack(channel, ICQ_VERSION); - ibc_channel_connect(deps.branch(), mock_env(), connect_msg).unwrap(); -} - -pub fn setup(channels: &[&str]) -> OwnedDeps { - let mut deps = mock_dependencies(); - - // instantiate an empty contract - let instantiate_msg = InitMsg { - default_timeout: DEFAULT_TIMEOUT, - }; - let info = mock_info(&String::from("anyone"), &[]); - let res = instantiate(deps.as_mut(), mock_env(), info, instantiate_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - for channel in channels { - add_channel(deps.as_mut(), channel); - } - deps -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/.editorconfig b/smart-contracts/contracts/intergamm-bindings-test/.editorconfig deleted file mode 100644 index 3d36f20b1..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.rs] -indent_size = 4 diff --git a/smart-contracts/contracts/intergamm-bindings-test/.gitignore b/smart-contracts/contracts/intergamm-bindings-test/.gitignore deleted file mode 100644 index dfdaaa6bc..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Build results -/target - -# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) -.cargo-ok - -# Text file backups -**/*.rs.bk - -# macOS -.DS_Store - -# IDEs -*.iml -.idea diff --git a/smart-contracts/contracts/intergamm-bindings-test/.gitpod.Dockerfile b/smart-contracts/contracts/intergamm-bindings-test/.gitpod.Dockerfile deleted file mode 100644 index bff8bc536..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/.gitpod.Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -### wasmd ### -FROM cosmwasm/wasmd:v0.18.0 as wasmd - -### rust-optimizer ### -FROM cosmwasm/rust-optimizer:0.11.5 as rust-optimizer - -FROM gitpod/workspace-full:latest - -COPY --from=wasmd /usr/bin/wasmd /usr/local/bin/wasmd -COPY --from=wasmd /opt/* /opt/ - -RUN sudo apt-get update \ - && sudo apt-get install -y jq \ - && sudo rm -rf /var/lib/apt/lists/* - -RUN rustup update stable \ - && rustup target add wasm32-unknown-unknown diff --git a/smart-contracts/contracts/intergamm-bindings-test/.gitpod.yml b/smart-contracts/contracts/intergamm-bindings-test/.gitpod.yml deleted file mode 100644 index d03610c21..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/.gitpod.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: cosmwasm/cw-gitpod-base:v0.16 - -vscode: - extensions: - - rust-lang.rust - -tasks: - - name: Dependencies & Build - init: | - cargo build diff --git a/smart-contracts/contracts/intergamm-bindings-test/Cargo.lock b/smart-contracts/contracts/intergamm-bindings-test/Cargo.lock deleted file mode 100644 index 91fb09ff8..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/Cargo.lock +++ /dev/null @@ -1,738 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-multi-test" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbea57e5be4a682268a5eca1a57efece57a54ff216bfd87603d5e864aad40e12" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools", - "prost", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993df11574f29574dd443eb0c189484bb91bc0638b6de3e32ab7f9319c92122d" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21ecb263bf75fc69d5e74b0f2a60b6dd80cfd9fb0eba15c4b9d1104ceffc77" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219b924f5b39f25b7d7c9203873a2698fdac8db2b396aaea6fa099b699cc40e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "testgen-local" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/smart-contracts/contracts/intergamm-bindings-test/Cargo.toml b/smart-contracts/contracts/intergamm-bindings-test/Cargo.toml deleted file mode 100644 index df06f6249..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/Cargo.toml +++ /dev/null @@ -1,61 +0,0 @@ -[package] -name = "intergamm-bindings-test" -version = "0.1.0" -authors = ["LaurensKubat "] -edition = "2018" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[profile.release] -opt-level = 3 -debug = false -rpath = false -lto = true -debug-assertions = false -codegen-units = 1 -panic = 'abort' -incremental = false -overflow-checks = true - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -# Replaced by justfile -# [package.metadata.scripts] -# optimize = """docker run --rm -v "$(pwd)":/code \ -# --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ -# --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ -# cosmwasm/rust-optimizer:0.12.6 -# """ - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -cw-utils = { workspace = true } -cw2 = { workspace = true } - -# Quasar packages -intergamm-bindings = { path = "../../packages/intergamm-bindings", version = "0.1.0"} - -[dev-dependencies] -cosmwasm-schema = { workspace = true } -cw-multi-test = {workspace = true} - diff --git a/smart-contracts/contracts/intergamm-bindings-test/Developing.md b/smart-contracts/contracts/intergamm-bindings-test/Developing.md deleted file mode 100644 index 2dd572cee..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/Developing.md +++ /dev/null @@ -1,104 +0,0 @@ -# Developing - -If you have recently created a contract with this template, you probably could use some -help on how to build and test the contract, as well as prepare it for production. This -file attempts to provide a brief overview, assuming you have installed a recent -version of Rust already (eg. 1.58.1+). - -## Prerequisites - -Before starting, make sure you have [rustup](https://rustup.rs/) along with a -recent `rustc` and `cargo` version installed. Currently, we are testing on 1.58.1+. - -And you need to have the `wasm32-unknown-unknown` target installed as well. - -You can check that via: - -```sh -rustc --version -cargo --version -rustup target list --installed -# if wasm32 is not listed above, run this -rustup target add wasm32-unknown-unknown -``` - -## Compiling and running tests - -Now that you created your custom contract, make sure you can compile and run it before -making any changes. Go into the repository and do: - -```sh -# this will produce a wasm build in ./target/wasm32-unknown-unknown/release/YOUR_NAME_HERE.wasm -cargo wasm - -# this runs unit tests with helpful backtraces -RUST_BACKTRACE=1 cargo unit-test - -# auto-generate json schema -cargo schema -``` - -### Understanding the tests - -The main code is in `src/contract.rs` and the unit tests there run in pure rust, -which makes them very quick to execute and give nice output on failures, especially -if you do `RUST_BACKTRACE=1 cargo unit-test`. - -We consider testing critical for anything on a blockchain, and recommend to always keep -the tests up to date. - -## Generating JSON Schema - -While the Wasm calls (`instantiate`, `execute`, `query`) accept JSON, this is not enough -information to use it. We need to expose the schema for the expected messages to the -clients. You can generate this schema by calling `cargo schema`, which will output -4 files in `./schema`, corresponding to the 3 message types the contract accepts, -as well as the internal `State`. - -These files are in standard json-schema format, which should be usable by various -client side tools, either to auto-generate codecs, or just to validate incoming -json wrt. the defined schema. - -## Preparing the Wasm bytecode for production - -Before we upload it to a chain, we need to ensure the smallest output size possible, -as this will be included in the body of a transaction. We also want to have a -reproducible build process, so third parties can verify that the uploaded Wasm -code did indeed come from the claimed rust code. - -To solve both these issues, we have produced `rust-optimizer`, a docker image to -produce an extremely small build output in a consistent manner. The suggest way -to run it is this: - -```sh -docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.6 -``` - -Or, If you're on an arm64 machine, you should use a docker image built with arm64. -```sh -docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer-arm64:0.12.6 -``` - -We must mount the contract code to `/code`. You can use a absolute path instead -of `$(pwd)` if you don't want to `cd` to the directory first. The other two -volumes are nice for speedup. Mounting `/code/target` in particular is useful -to avoid docker overwriting your local dev files with root permissions. -Note the `/code/target` cache is unique for each contract being compiled to limit -interference, while the registry cache is global. - -This is rather slow compared to local compilations, especially the first compile -of a given contract. The use of the two volume caches is very useful to speed up -following compiles of the same contract. - -This produces an `artifacts` directory with a `PROJECT_NAME.wasm`, as well as -`checksums.txt`, containing the Sha256 hash of the wasm file. -The wasm file is compiled deterministically (anyone else running the same -docker on the same git commit should get the identical file with the same Sha256 hash). -It is also stripped and minimized for upload to a blockchain (we will also -gzip it in the uploading process to make it even smaller). diff --git a/smart-contracts/contracts/intergamm-bindings-test/Importing.md b/smart-contracts/contracts/intergamm-bindings-test/Importing.md deleted file mode 100644 index a572ba05e..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/Importing.md +++ /dev/null @@ -1,62 +0,0 @@ -# Importing - -In [Publishing](quasar-finance/quasar/smart-contracts/contracts/intergamm-bindings-testt/Publishing.md), we discussed how you can publish your contract to the world. -This looks at the flip-side, how can you use someone else's contract (which is the same -question as how they will use your contract). Let's go through the various stages. - -## Verifying Artifacts - -Before using remote code, you most certainly want to verify it is honest. - -The simplest audit of the repo is to simply check that the artifacts in the repo -are correct. This involves recompiling the claimed source with the claimed builder -and validating that the locally compiled code (hash) matches the code hash that was -uploaded. This will verify that the source code is the correct preimage. Which allows -one to audit the original (Rust) source code, rather than looking at wasm bytecode. - -We have a script to do this automatic verification steps that can -easily be run by many individuals. Please check out -[`cosmwasm-verify`](https://github.com/CosmWasm/cosmwasm-verify/blob/master/README.md) -to see a simple shell script that does all these steps and easily allows you to verify -any uploaded contract. - -## Reviewing - -Once you have done the quick programatic checks, it is good to give at least a quick -look through the code. A glance at `examples/schema.rs` to make sure it is outputing -all relevant structs from `contract.rs`, and also ensure `src/lib.rs` is just the -default wrapper (nothing funny going on there). After this point, we can dive into -the contract code itself. Check the flows for the execute methods, any invariants and -permission checks that should be there, and a reasonable data storage format. - -You can dig into the contract as far as you want, but it is important to make sure there -are no obvious backdoors at least. - -## Decentralized Verification - -It's not very practical to do a deep code review on every dependency you want to use, -which is a big reason for the popularity of code audits in the blockchain world. We trust -some experts review in lieu of doing the work ourselves. But wouldn't it be nice to do this -in a decentralized manner and peer-review each other's contracts? Bringing in deeper domain -knowledge and saving fees. - -Luckily, there is an amazing project called [crev](https://github.com/crev-dev/cargo-crev/blob/master/cargo-crev/README.md) -that provides `A cryptographically verifiable code review system for the cargo (Rust) package manager`. - -I highly recommend that CosmWasm contract developers get set up with this. At minimum, we -can all add a review on a package that programmatically checked out that the json schemas -and wasm bytecode do match the code, and publish our claim, so we don't all rely on some -central server to say it validated this. As we go on, we can add deeper reviews on standard -packages. - -If you want to use `cargo-crev`, please follow their -[getting started guide](https://github.com/crev-dev/cargo-crev/blob/master/cargo-crev/src/doc/getting_started.md) -and once you have made your own *proof repository* with at least one *trust proof*, -please make a PR to the [`cawesome-wasm`]() repo with a link to your repo and -some public name or pseudonym that people know you by. This allows people who trust you -to also reuse your proofs. - -There is a [standard list of proof repos](https://github.com/crev-dev/cargo-crev/wiki/List-of-Proof-Repositories) -with some strong rust developers in there. This may cover dependencies like `serde` and `snafu` -but will not hit any CosmWasm-related modules, so we look to bootstrap a very focused -review community. diff --git a/smart-contracts/contracts/intergamm-bindings-test/LICENSE b/smart-contracts/contracts/intergamm-bindings-test/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/smart-contracts/contracts/intergamm-bindings-test/NOTICE b/smart-contracts/contracts/intergamm-bindings-test/NOTICE deleted file mode 100644 index 1270a9c2f..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2022 LaurensKubat - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/smart-contracts/contracts/intergamm-bindings-test/Publishing.md b/smart-contracts/contracts/intergamm-bindings-test/Publishing.md deleted file mode 100644 index c94f8675d..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/Publishing.md +++ /dev/null @@ -1,115 +0,0 @@ -# Publishing Contracts - -This is an overview of how to publish the contract's source code in this repo. -We use Cargo's default registry [crates.io](https://crates.io/) for publishing contracts written in Rust. - -## Preparation - -Ensure the `Cargo.toml` file in the repo is properly configured. In particular, you want to -choose a name starting with `cw-`, which will help a lot finding CosmWasm contracts when -searching on crates.io. For the first publication, you will probably want version `0.1.0`. -If you have tested this on a public net already and/or had an audit on the code, -you can start with `1.0.0`, but that should imply some level of stability and confidence. -You will want entries like the following in `Cargo.toml`: - -```toml -name = "cw-escrow" -version = "0.1.0" -description = "Simple CosmWasm contract for an escrow with arbiter and timeout" -repository = "https://github.com/confio/cosmwasm-examples" -``` - -You will also want to add a valid [SPDX license statement](https://spdx.org/licenses/), -so others know the rules for using this crate. You can use any license you wish, -even a commercial license, but we recommend choosing one of the following, unless you have -specific requirements. - -* Permissive: [`Apache-2.0`](https://spdx.org/licenses/Apache-2.0.html#licenseText) or [`MIT`](https://spdx.org/licenses/MIT.html#licenseText) -* Copyleft: [`GPL-3.0-or-later`](https://spdx.org/licenses/GPL-3.0-or-later.html#licenseText) or [`AGPL-3.0-or-later`](https://spdx.org/licenses/AGPL-3.0-or-later.html#licenseText) -* Commercial license: `Commercial` (not sure if this works, I cannot find examples) - -It is also helpful to download the LICENSE text (linked to above) and store this -in a LICENSE file in your repo. Now, you have properly configured your crate for use -in a larger ecosystem. - -### Updating schema - -To allow easy use of the contract, we can publish the schema (`schema/*.json`) together -with the source code. - -```sh -cargo schema -``` - -Ensure you check in all the schema files, and make a git commit with the final state. -This commit will be published and should be tagged. Generally, you will want to -tag with the version (eg. `v0.1.0`), but in the `cosmwasm-examples` repo, we have -multiple contracts and label it like `escrow-0.1.0`. Don't forget a -`git push && git push --tags` - -### Note on build results - -Build results like Wasm bytecode or expected hash don't need to be updated since -they don't belong to the source publication. However, they are excluded from packaging -in `Cargo.toml` which allows you to commit them to your git repository if you like. - -```toml -exclude = ["artifacts"] -``` - -A single source code can be built with multiple different optimizers, so -we should not make any strict assumptions on the tooling that will be used. - -## Publishing - -Now that your package is properly configured and all artifacts are committed, it -is time to share it with the world. -Please refer to the [complete instructions for any questions](https://rurust.github.io/cargo-docs-ru/crates-io.html), -but I will try to give a quick overview of the happy path here. - -### Registry - -You will need an account on [crates.io](https://crates.io) to publish a rust crate. -If you don't have one already, just click on "Log in with GitHub" in the top-right -to quickly set up a free account. Once inside, click on your username (top-right), -then "Account Settings". On the bottom, there is a section called "API Access". -If you don't have this set up already, create a new token and use `cargo login` -to set it up. This will now authenticate you with the `cargo` cli tool and allow -you to publish. - -### Uploading - -Once this is set up, make sure you commit the current state you want to publish. -Then try `cargo publish --dry-run`. If that works well, review the files that -will be published via `cargo package --list`. If you are satisfied, you can now -officially publish it via `cargo publish`. - -Congratulations, your package is public to the world. - -### Sharing - -Once you have published your package, people can now find it by -[searching for "cw-" on crates.io](https://crates.io/search?q=cw). -But that isn't exactly the simplest way. To make things easier and help -keep the ecosystem together, we suggest making a PR to add your package -to the [`cawesome-wasm`](https://github.com/cosmwasm/cawesome-wasm) list. - -### Organizations - -Many times you are writing a contract not as a solo developer, but rather as -part of an organization. You will want to allow colleagues to upload new -versions of the contract to crates.io when you are on holiday. -[These instructions show how]() you can set up your crate to allow multiple maintainers. - -You can add another owner to the crate by specifying their github user. Note, you will -now both have complete control of the crate, and they can remove you: - -`cargo owner --add ethanfrey` - -You can also add an existing github team inside your organization: - -`cargo owner --add github:confio:developers` - -The team will allow anyone who is currently in the team to publish new versions of the crate. -And this is automatically updated when you make changes on github. However, it will not allow -anyone in the team to add or remove other owners. diff --git a/smart-contracts/contracts/intergamm-bindings-test/README.md b/smart-contracts/contracts/intergamm-bindings-test/README.md index d93368b2f..e69de29bb 100644 --- a/smart-contracts/contracts/intergamm-bindings-test/README.md +++ b/smart-contracts/contracts/intergamm-bindings-test/README.md @@ -1,33 +0,0 @@ -# Intergamm test contract -This contract demonstrates the usage of the intergamm - -## Prerequisites -A local quasard, osmosisd and gaiad binary. -The quasard binary can be installed by running -``` -go install go install ../../../cmd/quasard/ -``` - -For the osmosisd and gaiad, you need to build those from their respective source, which can be found here: -[Osmosis](https://github.com/osmosis-labs/osmosis) -[Gaia](https://github.com/cosmos/gaia) - -## setting up -Run the chains using the [run_all](../../../demos/orion-manual-demo/run_all.sh) script from the orion manual demo in a separate window: -``` -./run_all.sh -``` - -once you see `starting relaying`, in a second terminal run the [create_and_execute](../../../demos/orion-manual-demo/create_and_execute_contract.sh) script - -``` -./create_and_execute.sh -``` - -Now a new contract should be deployed with a registered interchain account. The address of this contract can be found in the output of [create_and_execute](../../../demos/orion-manual-demo/create_and_execute_contract.sh) - -The created contract contains multiple execute messages to use the different intergamm messages from the intergamm-bindings package. The easiest way to get the correct funds on the interchain account address on cosmos is to send funds from alice/bob to the newly created interchain account. -A sample pool can be made using -``` -osmosisd tx gamm create-pool --pool-file ./sample_pool.json --node tcp://localhost:26679 --from bob --chain-id osmosis --gas auto -``` diff --git a/smart-contracts/contracts/intergamm-bindings-test/examples/schema.rs b/smart-contracts/contracts/intergamm-bindings-test/examples/schema.rs deleted file mode 100644 index 21bfcfe76..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/examples/schema.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use intergamm_bindings_test::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/rustfmt.toml b/smart-contracts/contracts/intergamm-bindings-test/rustfmt.toml deleted file mode 100644 index 11a85e6a9..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/rustfmt.toml +++ /dev/null @@ -1,15 +0,0 @@ -# stable -newline_style = "unix" -hard_tabs = false -tab_spaces = 4 - -# unstable... should we require `rustup run nightly cargo fmt` ? -# or just update the style guide when they are stable? -#fn_single_line = true -#format_code_in_doc_comments = true -#overflow_delimited_expr = true -#reorder_impl_items = true -#struct_field_align_threshold = 20 -#struct_lit_single_line = true -#report_todo = "Always" - diff --git a/smart-contracts/contracts/intergamm-bindings-test/schema/execute_msg.json b/smart-contracts/contracts/intergamm-bindings-test/schema/execute_msg.json deleted file mode 100644 index 9fcd1ba27..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/schema/execute_msg.json +++ /dev/null @@ -1,516 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "send_token" - ], - "properties": { - "send_token": { - "type": "object", - "required": [ - "destination_local_zone_id" - ], - "properties": { - "destination_local_zone_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "send_token_ibc" - ], - "properties": { - "send_token_ibc": { - "type": "object", - "required": [ - "amount", - "channel_id", - "to_address" - ], - "properties": { - "amount": { - "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "channel_id": { - "description": "exisiting channel to send the tokens over", - "type": "string" - }, - "to_address": { - "description": "address on the remote chain to receive these tokens", - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deposit" - ], - "properties": { - "deposit": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_interchain_account" - ], - "properties": { - "register_interchain_account": { - "type": "object", - "required": [ - "connection_id" - ], - "properties": { - "connection_id": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "join_pool" - ], - "properties": { - "join_pool": { - "type": "object", - "required": [ - "connection_id", - "pool_id", - "share_out_amount", - "timeout_timestamp", - "token_in_maxs" - ], - "properties": { - "connection_id": { - "type": "string" - }, - "pool_id": { - "$ref": "#/definitions/Uint64" - }, - "share_out_amount": { - "type": "integer", - "format": "int64" - }, - "timeout_timestamp": { - "$ref": "#/definitions/Uint64" - }, - "token_in_maxs": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "exit_pool" - ], - "properties": { - "exit_pool": { - "type": "object", - "required": [ - "connection_id", - "pool_id", - "share_in_amount", - "timeout_timestamp", - "token_out_mins" - ], - "properties": { - "connection_id": { - "type": "string" - }, - "pool_id": { - "$ref": "#/definitions/Uint64" - }, - "share_in_amount": { - "type": "integer", - "format": "int64" - }, - "timeout_timestamp": { - "$ref": "#/definitions/Uint64" - }, - "token_out_mins": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "lock_tokens" - ], - "properties": { - "lock_tokens": { - "type": "object", - "required": [ - "coins", - "connection_id", - "duration", - "timeout_timestamp" - ], - "properties": { - "coins": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "connection_id": { - "type": "string" - }, - "duration": { - "$ref": "#/definitions/Uint64" - }, - "timeout_timestamp": { - "$ref": "#/definitions/Uint64" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "join_swap_extern_amount_in" - ], - "properties": { - "join_swap_extern_amount_in": { - "type": "object", - "required": [ - "connection_id", - "pool_id", - "share_out_min_amount", - "token_in" - ], - "properties": { - "connection_id": { - "type": "string" - }, - "pool_id": { - "$ref": "#/definitions/Uint64" - }, - "share_out_min_amount": { - "type": "integer", - "format": "int64" - }, - "token_in": { - "$ref": "#/definitions/Coin" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "exit_swap_extern_amount_out" - ], - "properties": { - "exit_swap_extern_amount_out": { - "type": "object", - "required": [ - "connection_id", - "pool_id", - "share_in_amount", - "timeout_timestamp", - "token_out_mins" - ], - "properties": { - "connection_id": { - "type": "string" - }, - "pool_id": { - "$ref": "#/definitions/Uint64" - }, - "share_in_amount": { - "type": "integer", - "format": "int64" - }, - "timeout_timestamp": { - "$ref": "#/definitions/Uint64" - }, - "token_out_mins": { - "$ref": "#/definitions/Coin" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "begin_unlocking" - ], - "properties": { - "begin_unlocking": { - "type": "object", - "required": [ - "coins", - "connection_id", - "id", - "timeout_timestamp" - ], - "properties": { - "coins": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "connection_id": { - "type": "string" - }, - "id": { - "$ref": "#/definitions/Uint64" - }, - "timeout_timestamp": { - "$ref": "#/definitions/Uint64" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "test_ica_scenario" - ], - "properties": { - "test_ica_scenario": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ack" - ], - "properties": { - "ack": { - "type": "object", - "required": [ - "sequence_number" - ], - "properties": { - "error": { - "type": [ - "string", - "null" - ] - }, - "response": { - "anyOf": [ - { - "$ref": "#/definitions/AckResponse" - }, - { - "type": "null" - } - ] - }, - "sequence_number": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AckResponse": { - "oneOf": [ - { - "type": "object", - "required": [ - "join_swap_extern_amount_in" - ], - "properties": { - "join_swap_extern_amount_in": { - "type": "object", - "required": [ - "shareOutAmount" - ], - "properties": { - "shareOutAmount": { - "$ref": "#/definitions/Uint256" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "exit_swap_extern_amount_out" - ], - "properties": { - "exit_swap_extern_amount_out": { - "type": "object", - "required": [ - "shareInAmount" - ], - "properties": { - "shareInAmount": { - "$ref": "#/definitions/Uint256" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "join_swap_share_amount_out" - ], - "properties": { - "join_swap_share_amount_out": { - "type": "object", - "required": [ - "tokenInAmount" - ], - "properties": { - "tokenInAmount": { - "$ref": "#/definitions/Uint256" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "exit_swap_share_amount_in" - ], - "properties": { - "exit_swap_share_amount_in": { - "type": "object", - "required": [ - "tokenOutAmount" - ], - "properties": { - "tokenOutAmount": { - "$ref": "#/definitions/Uint256" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "lock_tokens" - ], - "properties": { - "lock_tokens": { - "type": "object", - "required": [ - "ID" - ], - "properties": { - "ID": { - "$ref": "#/definitions/Uint64" - } - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "begin_unlocking" - ], - "properties": { - "begin_unlocking": { - "type": "object", - "required": [ - "Success" - ], - "properties": { - "Success": { - "type": "boolean" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint256": { - "description": "An implementation of u256 that is using strings for JSON encoding/decoding, such that the full u256 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances out of primitive uint types or `new` to provide big endian bytes:\n\n``` # use cosmwasm_std::Uint256; let a = Uint256::from(258u128); let b = Uint256::new([ 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, ]); assert_eq!(a, b); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/schema/instantiate_msg.json b/smart-contracts/contracts/intergamm-bindings-test/schema/instantiate_msg.json deleted file mode 100644 index ab0fcab20..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/schema/instantiate_msg.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "callback_address" - ], - "properties": { - "callback_address": { - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/schema/query_msg.json b/smart-contracts/contracts/intergamm-bindings-test/schema/query_msg.json deleted file mode 100644 index 5f93056d6..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/schema/query_msg.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "pending_acks" - ], - "properties": { - "pending_acks": { - "type": "object" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "acks" - ], - "properties": { - "acks": { - "type": "object" - } - }, - "additionalProperties": false - } - ] -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/src/contract.rs b/smart-contracts/contracts/intergamm-bindings-test/src/contract.rs deleted file mode 100644 index 85834112e..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/src/contract.rs +++ /dev/null @@ -1,341 +0,0 @@ -use cosmwasm_std::{ - entry_point, to_json_binary, Binary, Coin, Deps, DepsMut, Env, IbcMsg, IbcTimeout, MessageInfo, - Order, Reply, Response, StdError, StdResult, Uint64, -}; -use cw2::set_contract_version; -use intergamm_bindings::helper::{ - ack, check_callback_addr, create_intergamm_msg, handle_reply, set_callback_addr, -}; -use intergamm_bindings::msg::IntergammMsg; - -use crate::error::ContractError; -use crate::msg::{AcksResponse, ExecuteMsg, InstantiateMsg, PendingAcksResponse, QueryMsg}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:intergamm-bindings-test"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - set_callback_addr(deps, &msg.callback_address)?; - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> StdResult { - handle_reply(deps.storage, env, msg) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result, ContractError> { - match msg { - ExecuteMsg::SendToken { - destination_local_zone_id, - receiver, - coin, - } => execute_send_token(destination_local_zone_id, receiver, coin), - - ExecuteMsg::SendTokenIbc { - channel_id, - to_address, - amount, - } => execute_send_token_ibc(channel_id, to_address, amount, env), - ExecuteMsg::RegisterIcaOnZone { zone_id } => execute_register_ica_on_zone(zone_id, deps), - ExecuteMsg::JoinSwapExternAmountIn { - connection_id, - pool_id, - share_out_min_amount, - token_in, - } => execute_join_swap_extern_amount_in( - connection_id, - pool_id, - share_out_min_amount, - token_in, - deps, - env, - ), - ExecuteMsg::TestIcaScenario {} => execute_test_scenario("registerIca".to_string()), - ExecuteMsg::Ack { - sequence_number, - error, - response, - } => do_ibc_packet_ack(deps, env, info, sequence_number, error, response), - ExecuteMsg::Deposit {} => execute_deposit(info), - ExecuteMsg::JoinPool { - connection_id, - timeout_timestamp, - pool_id, - share_out_amount, - token_in_maxs, - } => execute_join_pool( - connection_id, - timeout_timestamp, - pool_id, - share_out_amount, - token_in_maxs, - deps, - ), - ExecuteMsg::ExitPool { - connection_id, - timeout_timestamp, - pool_id, - share_in_amount, - token_out_mins, - } => execute_exit_pool( - connection_id, - timeout_timestamp, - pool_id, - share_in_amount, - token_out_mins, - deps, - ), - ExecuteMsg::LockTokens { - connection_id, - timeout_timestamp, - duration, - coins, - } => execute_lock_tokens(connection_id, timeout_timestamp, duration, coins, deps), - ExecuteMsg::ExitSwapExternAmountOut { - connection_id, - timeout_timestamp, - pool_id, - share_in_amount, - token_out_mins, - } => execute_exit_swap_extern_amount_out( - connection_id, - timeout_timestamp, - pool_id, - share_in_amount, - token_out_mins, - deps, - ), - ExecuteMsg::BeginUnlocking { - connection_id, - timeout_timestamp, - id, - coins, - } => execute_begin_unlocking(connection_id, timeout_timestamp, id, coins, deps), - } -} - -pub fn execute_exit_pool( - connection_id: String, - timeout_timestamp: Uint64, - pool_id: Uint64, - share_in_amount: i64, - token_out_mins: Vec, - deps: DepsMut, -) -> Result, ContractError> { - let msg = IntergammMsg::ExitPool { - connection_id, - timeout_timestamp: timeout_timestamp.u64(), - pool_id: pool_id.u64(), - share_in_amount, - token_out_mins, - }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -pub fn execute_join_pool( - connection_id: String, - timeout_timestamp: Uint64, - pool_id: Uint64, - share_out_amount: i64, - token_in_maxs: Vec, - deps: DepsMut, -) -> Result, ContractError> { - let msg = IntergammMsg::JoinPool { - connection_id, - timeout_timestamp: timeout_timestamp.u64(), - pool_id: pool_id.u64(), - share_out_amount, - token_in_maxs, - }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -pub fn execute_lock_tokens( - connection_id: String, - timeout_timestamp: Uint64, - duration: Uint64, - coins: Vec, - deps: DepsMut, -) -> Result, ContractError> { - let msg = IntergammMsg::LockTokens { - connection_id, - timeout_timestamp: timeout_timestamp.u64(), - duration: duration.u64(), - coins, - }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -pub fn execute_begin_unlocking( - connection_id: String, - timeout_timestamp: Uint64, - id: Uint64, - coins: Vec, - deps: DepsMut, -) -> Result, ContractError> { - let msg = IntergammMsg::BeginUnlocking { - connection_id, - timeout_timestamp: timeout_timestamp.u64(), - id: id.u64(), - coins, - }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -pub fn execute_exit_swap_extern_amount_out( - connection_id: String, - timeout_timestamp: Uint64, - pool_id: Uint64, - share_in_amount: i64, - token_out_mins: Coin, - deps: DepsMut, -) -> Result, ContractError> { - let msg = IntergammMsg::ExitSwapExternAmountOut { - connection_id, - timeout_timestamp: timeout_timestamp.u64(), - pool_id: pool_id.u64(), - share_in_amount, - token_out_mins, - }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -pub fn execute_send_token( - destination_local_zone_id: String, - receiver: String, - coin: Coin, -) -> Result, ContractError> { - // receiver is an address on a different chain, so we can't parse it. - Ok(Response::new() - .add_attribute( - "send_tokens", - format!( - "{} {} to {}", - coin.amount, coin.denom, destination_local_zone_id - ), - ) - .add_message(IntergammMsg::SendToken { - destination_local_zone_id, - receiver, - coin, - })) -} - -pub fn execute_send_token_ibc( - channel_id: String, - to_address: String, - amount: Coin, - env: Env, -) -> Result, ContractError> { - // timeout in 600 seconds after current block timestamp - let timeout = IbcTimeout::with_timestamp(env.block.time.plus_seconds(600)); - Ok(Response::new().add_message(IbcMsg::Transfer { - channel_id, - to_address, - amount, - timeout, - })) -} - -pub fn execute_test_scenario(scenario: String) -> Result, ContractError> { - Ok(Response::new().add_message(IntergammMsg::TestScenario { scenario })) -} - -pub fn execute_register_ica_on_zone( - zone_id: String, - deps: DepsMut, -) -> Result, ContractError> { - let msg = IntergammMsg::RegisterIcaOnZone { zone_id }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -// join pool requires us to have a pool on the remote chain and funds in the interchain account of this contract -pub fn execute_join_swap_extern_amount_in( - connection_id: String, - pool_id: Uint64, - share_out_min_amount: i64, - token_in: Coin, - deps: DepsMut, - env: Env, -) -> Result, ContractError> { - let msg = IntergammMsg::JoinSwapExternAmountIn { - connection_id, - // timeout in 10 minutes - timeout_timestamp: env.block.time.plus_seconds(600).nanos(), - pool_id: pool_id.u64(), - share_out_min_amount, - token_in, - }; - create_intergamm_msg(deps.storage, msg).map_err(ContractError::Std) -} - -pub fn execute_deposit(info: MessageInfo) -> Result, ContractError> { - let funds = cw_utils::one_coin(&info)?; - if funds.denom != "uqsr" && funds.denom != "stake" { - return Err(ContractError::PaymentError( - cw_utils::PaymentError::MissingDenom("uqsr/stake".into()), - )); - } - // we dont do anything else with the funds since we solely use them for testing and don't need to deposit - Ok(Response::new() - .add_attribute("deposit_amount", funds.amount) - .add_attribute("deposit_denom", funds.denom)) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Acks {} => to_json_binary(&query_acks(deps)?), - QueryMsg::PendingAcks {} => to_json_binary(&query_pending_acks(deps)?), - } -} - -pub fn query_acks(deps: Deps) -> StdResult { - let acks: Result, StdError> = - intergamm_bindings::state::ACKS - .range(deps.storage, None, None, Order::Ascending) - .collect(); - Ok(AcksResponse { acks: acks? }) -} - -pub fn query_pending_acks(deps: Deps) -> StdResult { - let pending: Result, StdError> = - intergamm_bindings::state::PENDINGACKS - .range(deps.storage, None, None, Order::Ascending) - .collect(); - Ok(PendingAcksResponse { pending: pending? }) -} - -pub fn do_ibc_packet_ack( - deps: DepsMut, - _env: Env, - info: MessageInfo, - sequence: u64, - error: Option, - response: Option, -) -> Result, ContractError> { - check_callback_addr(deps.as_ref(), info.sender)?; - ack(deps, sequence, &error, &response)?; - // Insert any further neede logic to handle acks here - Ok(Response::new() - .add_attribute("error", error.unwrap_or_else(|| "none".into())) - .add_attribute("response", format!("{response:?}"))) -} - -#[cfg(test)] -mod tests {} diff --git a/smart-contracts/contracts/intergamm-bindings-test/src/error.rs b/smart-contracts/contracts/intergamm-bindings-test/src/error.rs deleted file mode 100644 index 71e1bd749..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/src/error.rs +++ /dev/null @@ -1,22 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("{0}")] - PaymentError(#[from] cw_utils::PaymentError), - - #[error("bindings {0}")] - Bindings(#[from] intergamm_bindings::error::ContractError), - - #[error("Custom Error val: {val:?}")] - CustomError { val: String }, - // Add any other custom errors you like here. - // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details. -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/src/integration_tests.rs b/smart-contracts/contracts/intergamm-bindings-test/src/integration_tests.rs deleted file mode 100644 index ae09e2d44..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/src/integration_tests.rs +++ /dev/null @@ -1,70 +0,0 @@ -#[cfg(test)] -mod tests { - use crate::msg::InstantiateMsg; - use cosmwasm_std::{Addr, Coin, Empty, Uint128}; - use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper, Executor}; - - pub fn contract_template() -> Box> { - let contract = ContractWrapper::new( - crate::contract::execute, - crate::contract::instantiate, - crate::contract::query, - ); - Box::new(contract) - } - - const USER: &str = "USER"; - const ADMIN: &str = "ADMIN"; - const NATIVE_DENOM: &str = "denom"; - - fn mock_app() -> App { - AppBuilder::new().build(|router, _, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked(USER), - vec![Coin { - denom: NATIVE_DENOM.to_string(), - amount: Uint128::new(1), - }], - ) - .unwrap(); - }) - } - - fn proper_instantiate() -> (App, CwTemplateContract) { - let mut app = mock_app(); - let cw_template_id = app.store_code(contract_template()); - - let msg = InstantiateMsg { }; - let cw_template_contract_addr = app - .instantiate_contract( - cw_template_id, - Addr::unchecked(ADMIN), - &msg, - &[], - "test", - None, - ) - .unwrap(); - - let cw_template_contract = CwTemplateContract(cw_template_contract_addr); - - (app, cw_template_contract) - } - - mod count { - use super::*; - use crate::msg::ExecuteMsg; - - #[test] - fn count() { - let (mut app, cw_template_contract) = proper_instantiate(); - - let msg = ExecuteMsg::Increment {}; - let cosmos_msg = cw_template_contract.call(msg).unwrap(); - app.execute(Addr::unchecked(USER), cosmos_msg).unwrap(); - } - } -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/src/lib.rs b/smart-contracts/contracts/intergamm-bindings-test/src/lib.rs deleted file mode 100644 index dfedc9dc6..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod contract; -mod error; -pub mod msg; -pub mod state; - -pub use crate::error::ContractError; diff --git a/smart-contracts/contracts/intergamm-bindings-test/src/msg.rs b/smart-contracts/contracts/intergamm-bindings-test/src/msg.rs deleted file mode 100644 index 6c2bb1b0c..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/src/msg.rs +++ /dev/null @@ -1,98 +0,0 @@ -use cosmwasm_std::{Coin, Uint64}; -use intergamm_bindings::msg::IntergammMsg; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct InstantiateMsg { - pub callback_address: String, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ExecuteMsg { - SendToken { - destination_local_zone_id: String, - receiver: String, - coin: Coin, - }, - SendTokenIbc { - /// exisiting channel to send the tokens over - channel_id: String, - /// address on the remote chain to receive these tokens - to_address: String, - /// packet data only supports one coin - /// https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20 - amount: Coin, - // when packet times out, measured on remote chain, for now we hardcode the timeout - // timeout: IbcTimeout, - }, - Deposit {}, - RegisterIcaOnZone { - zone_id: String, - }, - JoinPool { - connection_id: String, - timeout_timestamp: Uint64, - pool_id: Uint64, - share_out_amount: i64, - token_in_maxs: Vec, - }, - ExitPool { - connection_id: String, - timeout_timestamp: Uint64, - pool_id: Uint64, - share_in_amount: i64, - token_out_mins: Vec, - }, - LockTokens { - connection_id: String, - timeout_timestamp: Uint64, - duration: Uint64, - coins: Vec, - }, - JoinSwapExternAmountIn { - connection_id: String, - pool_id: Uint64, - share_out_min_amount: i64, - token_in: Coin, - }, - ExitSwapExternAmountOut { - connection_id: String, - timeout_timestamp: Uint64, - pool_id: Uint64, - share_in_amount: i64, - token_out_mins: Coin, - }, - BeginUnlocking { - connection_id: String, - timeout_timestamp: Uint64, - id: Uint64, - coins: Vec, - }, - TestIcaScenario {}, - Ack { - sequence_number: u64, - error: Option, - response: Option, - }, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum QueryMsg { - PendingAcks {}, - Acks {}, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct AcksResponse { - pub acks: Vec<(u64, intergamm_bindings::msg::AckValue)>, -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub struct PendingAcksResponse { - pub pending: Vec<(u64, IntergammMsg)>, -} diff --git a/smart-contracts/contracts/intergamm-bindings-test/src/state.rs b/smart-contracts/contracts/intergamm-bindings-test/src/state.rs deleted file mode 100644 index 0c9da70e7..000000000 --- a/smart-contracts/contracts/intergamm-bindings-test/src/state.rs +++ /dev/null @@ -1,23 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::Addr; -use cw_storage_plus::Item; - -use crate::ContractError; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct State { - pub count: i32, - pub owner: Addr, -} - -pub const ACKTRIGGERED: Item = Item::new("ack_triggered"); -pub enum Status { - Succes, - // TODO saving the error as part of the sequence might not be desirable for the future - Error { reason: ContractError }, - InProgress, -} - -pub const STATE: Item = Item::new("state"); diff --git a/smart-contracts/contracts/intergamm-bindings-test/test.sh b/smart-contracts/contracts/intergamm-bindings-test/test.sh deleted file mode 100644 index e69de29bb..000000000 diff --git a/smart-contracts/contracts/lp-strategy/.cargo/config b/smart-contracts/contracts/lp-strategy/.cargo/config deleted file mode 100644 index dba2c3f7a..000000000 --- a/smart-contracts/contracts/lp-strategy/.cargo/config +++ /dev/null @@ -1,5 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" -lint = "clippy -- -D warnings" \ No newline at end of file diff --git a/smart-contracts/contracts/lp-strategy/CHANGELOG.md b/smart-contracts/contracts/lp-strategy/CHANGELOG.md deleted file mode 100644 index 19336e815..000000000 --- a/smart-contracts/contracts/lp-strategy/CHANGELOG.md +++ /dev/null @@ -1,64 +0,0 @@ -# CHANGELOG - -## Unreleased - -### Dependencies - -### API breaking - -### State breaking - -- Delete old pending acks from the state -- Delete failed traps from the state - -### Improvements - -- Add bond queue duplicate key check -- Add testing to try_icq -- Remove unnecessary load from try_icq -- Changed the locking on the execute calls to lock correctly depending on queue state -- Delete pending ack entry after succesful ack handling -- Added some doc comments -- Created execute.rs file and created retry exit pool fn there -- Added proptests for retry join pool - -### Features - -- Added permission-less retry entrypoint to handle exit pool errors -- Added permission-less retry entrypoint to handle join pool errors - -### Bugfixes - -- divide quote denom by spotprice instead of multiply with spotprice -- readd proper lock behaviour -- Do not allow opentry messages to clog up our state -- Compare users' shares to their owned amount of queued shares instead of all queued shares -- make it so that the primitive compounds -- using only the unbonds amount to calculate slippage (previously using total shares amount) -- fixed math on consolidate_exit_pool_amount_into_local_denom - -## V0.1.1 08-05-2023 - -### Dependencies - -### API breaking - -### State breaking - -- Recover user bonds with manual callbacks - -### Improvements - -### Features - -### Bugfixes - -### Notes - -Migrations (branch names) performed with this source: -migration-004/recover-bonds -migration-005/recover-bonds-again - -## V0.1.0 - -### Initial version diff --git a/smart-contracts/contracts/lp-strategy/Cargo.toml b/smart-contracts/contracts/lp-strategy/Cargo.toml deleted file mode 100644 index e5696410e..000000000 --- a/smart-contracts/contracts/lp-strategy/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -authors = ["Laurens Kubat "] -edition = "2021" -name = "lp-strategy" -version = "0.1.1" - -[lib] -crate-type = ["cdylib", "rlib"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[features] -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -prost = { workspace = true } -cw-utils = { workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cw20-base = { workspace = true } -cosmos-sdk-proto = { workspace = true } -serde-json-wasm = { workspace = true } - -uuid = {version = "1.1.2", default-features = false, features = ["v4", "js"]} -quasar-types = {path = "../../packages/quasar-types"} - -[dev-dependencies] -cw-multi-test = { workspace = true } -proptest = "1.0.0" diff --git a/smart-contracts/contracts/lp-strategy/README.md b/smart-contracts/contracts/lp-strategy/README.md deleted file mode 100644 index dcdcb383d..000000000 --- a/smart-contracts/contracts/lp-strategy/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# LP-strategy - -## current state -Currently, the strategy supports receiving funds from a depositor, transferring those funds over a channel to it's own ICA address, joining a predetermined pool with those funds and locking those funds for two weeks - -## to be added -The strategy currently lacks the following that need to be added -- [ ] bookkeeping -- [ ] withdraws (dependant on ibc hooks on quasar, memo field in ibc transfer over ICA) -- [ ] move channel logic to quasar-types - -## how does the contract work -In ibc.rs, we have the cosmwasm entrypoints to setup the different IBC connections, this contract currently supports ICQ and ICA channels, but there is currently no use case for ICQ. - -After channels are setup, users can call the `TransferJoinLock` and `DepositAndLockTokens` execute Msgs, `TransferJoinLock`, transfers funds, joins the pool and locks the tokens, `DepositAndLockTokens` only joins the pool and locks the tokens - -## Testing locally -In demos/orion-manual-demo, `run_all.sh` sets up all chain needed, and `create_and_execute_contract` sets up a contract and starts trying to `TransferJoinLock` for Alice - diff --git a/smart-contracts/contracts/lp-strategy/examples/schema.rs b/smart-contracts/contracts/lp-strategy/examples/schema.rs deleted file mode 100644 index 819abb062..000000000 --- a/smart-contracts/contracts/lp-strategy/examples/schema.rs +++ /dev/null @@ -1,10 +0,0 @@ -use cosmwasm_schema::write_api; -use lp_strategy::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; - -fn main() { - write_api! { - instantiate: InstantiateMsg, - query: QueryMsg, - execute: ExecuteMsg, - } -} diff --git a/smart-contracts/contracts/lp-strategy/migration_primitive1.json b/smart-contracts/contracts/lp-strategy/migration_primitive1.json deleted file mode 100644 index 53f4565dc..000000000 --- a/smart-contracts/contracts/lp-strategy/migration_primitive1.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - {"claim_amount":"28971416","raw_amount":{"local_denom":"6982413"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"13"}, - {"claim_amount":"145064310","raw_amount":{"local_denom":"26615807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"21"}, - {"claim_amount":"4061797","raw_amount":{"local_denom":"745242"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"22"}, - {"claim_amount":"521529251","raw_amount":{"local_denom":"95688056"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"23"}, - {"claim_amount":"5814419","raw_amount":{"local_denom":"1066806"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"24"}, - {"claim_amount":"3953805","raw_amount":{"local_denom":"725428"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"25"}, - {"claim_amount":"409062074","raw_amount":{"local_denom":"75053038"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"26"}, - {"claim_amount":"1503723755","raw_amount":{"local_denom":"79003403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1468"} -] \ No newline at end of file diff --git a/smart-contracts/contracts/lp-strategy/migration_primitive3.json b/smart-contracts/contracts/lp-strategy/migration_primitive3.json deleted file mode 100644 index 3324cacff..000000000 --- a/smart-contracts/contracts/lp-strategy/migration_primitive3.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - {"claim_amount":"43881823","raw_amount":{"local_denom":"32201796"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"20"},{"claim_amount":"88650150","raw_amount":{"local_denom":"65054135"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"21"},{"claim_amount":"2482203","raw_amount":{"local_denom":"1821515"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"22"},{"claim_amount":"315431924","raw_amount":{"local_denom":"231473390"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"23"},{"claim_amount":"2063730","raw_amount":{"local_denom":"1514427"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"25"},{"claim_amount":"248209338","raw_amount":{"local_denom":"182143444"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"26"}, - {"claim_amount":"4043454","raw_amount":{"local_denom":"5877677"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"491"}, - {"claim_amount":"12776164","raw_amount":{"local_denom":"8615945"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"492"}, - {"claim_amount":"2874701","raw_amount":{"local_denom":"1938631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"493"}, - {"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"494"}, - {"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"495"}, - {"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"496"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"497"},{"claim_amount":"89435176","raw_amount":{"local_denom":"60312982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"498"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"499"},{"claim_amount":"4152346","raw_amount":{"local_denom":"2800245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"500"},{"claim_amount":"91351644","raw_amount":{"local_denom":"61605403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"501"},{"claim_amount":"2874702108","raw_amount":{"local_denom":"1938631576"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"502"},{"claim_amount":"37690537","raw_amount":{"local_denom":"25417613"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"503"},{"claim_amount":"2171995","raw_amount":{"local_denom":"1464743"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"504"}, - {"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"505"},{"claim_amount":"1659661350","raw_amount":{"local_denom":"1119236630"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"506"},{"claim_amount":"165455076","raw_amount":{"local_denom":"111579017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"507"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"508"},{"claim_amount":"766586","raw_amount":{"local_denom":"516968"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"509"},{"claim_amount":"6707637","raw_amount":{"local_denom":"4523473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"510"},{"claim_amount":"8943517","raw_amount":{"local_denom":"6031298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"511"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"512"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"513"},{"claim_amount":"5110581","raw_amount":{"local_denom":"3446456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"514"}, - {"claim_amount":"638183866","raw_amount":{"local_denom":"430376209"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"515"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"516"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"517"},{"claim_amount":"11498807","raw_amount":{"local_denom":"7754526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"518"},{"claim_amount":"111155146","raw_amount":{"local_denom":"74960420"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"519"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"520"},{"claim_amount":"63946150","raw_amount":{"local_denom":"43123782"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"521"},{"claim_amount":"44717588","raw_amount":{"local_denom":"30156491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"522"},{"claim_amount":"2427525","raw_amount":{"local_denom":"1637066"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"523"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"524"}, - {"claim_amount":"8240811","raw_amount":{"local_denom":"5557410"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"525"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"526"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"527"},{"claim_amount":"3171575","raw_amount":{"local_denom":"2138836"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"528"},{"claim_amount":"2171995","raw_amount":{"local_denom":"1464743"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"529"},{"claim_amount":"32579955","raw_amount":{"local_denom":"21971157"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"530"},{"claim_amount":"91287761","raw_amount":{"local_denom":"61562322"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"531"},{"claim_amount":"7090930","raw_amount":{"local_denom":"4781957"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"532"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"533"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"534"},{"claim_amount":"8649659","raw_amount":{"local_denom":"5833127"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"535"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"536"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"537"},{"claim_amount":"63818385","raw_amount":{"local_denom":"43037620"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"538"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"539"},{"claim_amount":"638822689","raw_amount":{"local_denom":"430807016"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"540"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"541"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"542"},{"claim_amount":"120098665","raw_amount":{"local_denom":"80991719"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"543"},{"claim_amount":"1149880842","raw_amount":{"local_denom":"775452630"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"544"},{"claim_amount":"12457041","raw_amount":{"local_denom":"8400736"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"545"},{"claim_amount":"25552906","raw_amount":{"local_denom":"17232280"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"546"},{"claim_amount":"8135406967","raw_amount":{"local_denom":"5486327360"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"547"},{"claim_amount":"24914083","raw_amount":{"local_denom":"16801473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"548"},{"claim_amount":"536611060","raw_amount":{"local_denom":"361877894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"549"},{"claim_amount":"1149880842","raw_amount":{"local_denom":"775452630"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"550"},{"claim_amount":"63754504","raw_amount":{"local_denom":"42994540"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"551"},{"claim_amount":"159705672","raw_amount":{"local_denom":"107701754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"552"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"553"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"554"},{"claim_amount":"223524059","raw_amount":{"local_denom":"150739375"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"555"},{"claim_amount":"8304694","raw_amount":{"local_denom":"5600491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"556"},{"claim_amount":"2235878","raw_amount":{"local_denom":"1507824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"557"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"558"},{"claim_amount":"702703","raw_amount":{"local_denom":"473887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"559"},{"claim_amount":"89435176","raw_amount":{"local_denom":"60312982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"560"},{"claim_amount":"287470209","raw_amount":{"local_denom":"193863157"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"561"},{"claim_amount":"30024665","raw_amount":{"local_denom":"20247929"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"562"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"563"},{"claim_amount":"1852585","raw_amount":{"local_denom":"1249340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"564"},{"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"565"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"566"},{"claim_amount":"12712570","raw_amount":{"local_denom":"8573059"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"567"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"568"},{"claim_amount":"82408126","raw_amount":{"local_denom":"55574105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"569"},{"claim_amount":"12073747","raw_amount":{"local_denom":"8142252"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"570"},{"claim_amount":"19036916","raw_amount":{"local_denom":"12838049"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"571"},{"claim_amount":"19036916","raw_amount":{"local_denom":"12838049"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"572"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"573"},{"claim_amount":"19931266","raw_amount":{"local_denom":"13441178"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"574"},{"claim_amount":"45356410","raw_amount":{"local_denom":"30587298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"575"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"576"}, - {"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"577"},{"claim_amount":"45356410","raw_amount":{"local_denom":"30587298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"578"},{"claim_amount":"1788702","raw_amount":{"local_denom":"1206259"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"579"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"580"},{"claim_amount":"3832935","raw_amount":{"local_denom":"2584842"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"581"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"582"},{"claim_amount":"670763","raw_amount":{"local_denom":"452347"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"583"},{"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"584"},{"claim_amount":"702703","raw_amount":{"local_denom":"473887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"585"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"586"},{"claim_amount":"4343993","raw_amount":{"local_denom":"2929487"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"587"},{"claim_amount":"3602959975","raw_amount":{"local_denom":"2429751575"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"588"},{"claim_amount":"6068814","raw_amount":{"local_denom":"4092666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"589"},{"claim_amount":"26830551","raw_amount":{"local_denom":"18093894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"590"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"591"},{"claim_amount":"2005903","raw_amount":{"local_denom":"1352734"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"592"},{"claim_amount":"3066347","raw_amount":{"local_denom":"2067873"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"593"},{"claim_amount":"3066347","raw_amount":{"local_denom":"2067873"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"594"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"595"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"596"},{"claim_amount":"49828169","raw_amount":{"local_denom":"33602947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"597"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"598"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"599"},{"claim_amount":"350713656","raw_amount":{"local_denom":"236513052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"600"},{"claim_amount":"33186838","raw_amount":{"local_denom":"22380424"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"601"},{"claim_amount":"3769053","raw_amount":{"local_denom":"2541761"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"602"},{"claim_amount":"3769053","raw_amount":{"local_denom":"2541761"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"603"},{"claim_amount":"14692921","raw_amount":{"local_denom":"9908561"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"604"},{"claim_amount":"15331743","raw_amount":{"local_denom":"10339368"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"605"},{"claim_amount":"185258579","raw_amount":{"local_denom":"124934034"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"606"},{"claim_amount":"88796353","raw_amount":{"local_denom":"59882175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"607"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"608"},{"claim_amount":"9262927","raw_amount":{"local_denom":"6246701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"609"},{"claim_amount":"98378693","raw_amount":{"local_denom":"66344280"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"610"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"611"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"612"},{"claim_amount":"31621722","raw_amount":{"local_denom":"21324947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"613"},{"claim_amount":"89435176","raw_amount":{"local_denom":"60312982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"614"},{"claim_amount":"3833574967","raw_amount":{"local_denom":"2585272908"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"615"},{"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"616"},{"claim_amount":"38329361","raw_amount":{"local_denom":"25848421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"617"},{"claim_amount":"1750373","raw_amount":{"local_denom":"1180411"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"618"},{"claim_amount":"905850575","raw_amount":{"local_denom":"610884350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"619"},{"claim_amount":"4407875","raw_amount":{"local_denom":"2972568"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"620"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"621"},{"claim_amount":"862409","raw_amount":{"local_denom":"581589"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"622"},{"claim_amount":"35135246","raw_amount":{"local_denom":"23694385"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"623"},{"claim_amount":"5110581","raw_amount":{"local_denom":"3446456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"624"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"625"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"626"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"627"},{"claim_amount":"166093899","raw_amount":{"local_denom":"112009824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"628"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"629"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"630"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"631"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"632"},{"claim_amount":"38329361","raw_amount":{"local_denom":"25848421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"633"},{"claim_amount":"28747019","raw_amount":{"local_denom":"19386315"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"634"},{"claim_amount":"734645","raw_amount":{"local_denom":"495428"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"635"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"636"},{"claim_amount":"1269340685","raw_amount":{"local_denom":"856013542"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"637"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"638"},{"claim_amount":"8815751","raw_amount":{"local_denom":"5945136"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"639"},{"claim_amount":"2874701","raw_amount":{"local_denom":"1938631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"640"},{"claim_amount":"95184580","raw_amount":{"local_denom":"64190245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"641"},{"claim_amount":"1852585","raw_amount":{"local_denom":"1249340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"642"},{"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"643"},{"claim_amount":"633073285","raw_amount":{"local_denom":"426929753"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"644"},{"claim_amount":"28747019","raw_amount":{"local_denom":"19386315"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"645"},{"claim_amount":"9262927","raw_amount":{"local_denom":"6246701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"646"},{"claim_amount":"34496423","raw_amount":{"local_denom":"23263578"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"647"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"648"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"649"},{"claim_amount":"766586","raw_amount":{"local_denom":"516968"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"650"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"651"},{"claim_amount":"37690537","raw_amount":{"local_denom":"25417613"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"652"},{"claim_amount":"204423260","raw_amount":{"local_denom":"137858245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"653"},{"claim_amount":"91798820","raw_amount":{"local_denom":"61906968"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"654"},{"claim_amount":"41523474","raw_amount":{"local_denom":"28002456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"655"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"656"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"657"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"658"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"659"},{"claim_amount":"81130481","raw_amount":{"local_denom":"54712491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"660"},{"claim_amount":"23317028","raw_amount":{"local_denom":"15724456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"661"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"662"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"663"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"664"},{"claim_amount":"1852585","raw_amount":{"local_denom":"1249340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"665"},{"claim_amount":"22358793","raw_amount":{"local_denom":"15078245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"666"},{"claim_amount":"241474976","raw_amount":{"local_denom":"162845052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"667"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"668"},{"claim_amount":"73464608","raw_amount":{"local_denom":"49542806"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"669"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"670"},{"claim_amount":"1128799693","raw_amount":{"local_denom":"761235998"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"671"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"672"},{"claim_amount":"3609347","raw_amount":{"local_denom":"2434059"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"673"},{"claim_amount":"5704685","raw_amount":{"local_denom":"3847106"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"674"},{"claim_amount":"14692921","raw_amount":{"local_denom":"9908561"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"675"},{"claim_amount":"11179395","raw_amount":{"local_denom":"7539122"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"676"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"677"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"678"},{"claim_amount":"639142101","raw_amount":{"local_denom":"431022420"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"679"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"680"},{"claim_amount":"241794387","raw_amount":{"local_denom":"163060455"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"681"},{"claim_amount":"585800406","raw_amount":{"local_denom":"395050034"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"682"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"683"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"684"},{"claim_amount":"670763","raw_amount":{"local_denom":"452347"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"685"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"686"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"687"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"688"},{"claim_amount":"1427129890","raw_amount":{"local_denom":"962422875"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"689"},{"claim_amount":"5781344","raw_amount":{"local_denom":"3898803"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"690"},{"claim_amount":"141818636","raw_amount":{"local_denom":"95639157"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"691"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"692"},{"claim_amount":"1149879","raw_amount":{"local_denom":"775452"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"693"},{"claim_amount":"95823402","raw_amount":{"local_denom":"64621052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"694"},{"claim_amount":"56855218","raw_amount":{"local_denom":"38341824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"695"},{"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"696"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"697"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"698"},{"claim_amount":"65287678","raw_amount":{"local_denom":"44028477"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"699"},{"claim_amount":"15331743","raw_amount":{"local_denom":"10339368"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"700"},{"claim_amount":"14373509","raw_amount":{"local_denom":"9693157"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"701"}, - {"claim_amount":"12648687","raw_amount":{"local_denom":"8529978"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"702"},{"claim_amount":"85921650","raw_amount":{"local_denom":"57943543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"703"},{"claim_amount":"15331743","raw_amount":{"local_denom":"10339368"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"704"},{"claim_amount":"11498807","raw_amount":{"local_denom":"7754526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"705"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"706"},{"claim_amount":"159066849","raw_amount":{"local_denom":"107270947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"707"},{"claim_amount":"258723188","raw_amount":{"local_denom":"174476841"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"708"},{"claim_amount":"38329361","raw_amount":{"local_denom":"25848421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"709"},{"claim_amount":"1022115","raw_amount":{"local_denom":"689291"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"710"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"711"},{"claim_amount":"19484092","raw_amount":{"local_denom":"13139614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"712"},{"claim_amount":"11498807","raw_amount":{"local_denom":"7754526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"713"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"714"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"715"},{"claim_amount":"11498807","raw_amount":{"local_denom":"7754526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"716"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"717"},{"claim_amount":"159577906","raw_amount":{"local_denom":"107615592"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"718"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"719"},{"claim_amount":"479117017","raw_amount":{"local_denom":"323105262"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"720"},{"claim_amount":"3960699","raw_amount":{"local_denom":"2671003"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"721"}, - {"claim_amount":"41204062","raw_amount":{"local_denom":"27787052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"722"},{"claim_amount":"958234035","raw_amount":{"local_denom":"646210525"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"723"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"724"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"725"},{"claim_amount":"686734392","raw_amount":{"local_denom":"463117543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"726"},{"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"727"},{"claim_amount":"245946735","raw_amount":{"local_denom":"165860701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"728"},{"claim_amount":"670763","raw_amount":{"local_denom":"452347"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"729"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"730"},{"claim_amount":"64904384","raw_amount":{"local_denom":"43769992"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"731"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"732"},{"claim_amount":"63818385","raw_amount":{"local_denom":"43037620"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"733"},{"claim_amount":"1469291","raw_amount":{"local_denom":"990856"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"734"},{"claim_amount":"577712911","raw_amount":{"local_denom":"389596017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"735"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"736"},{"claim_amount":"1597055","raw_amount":{"local_denom":"1077017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"737"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"738"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"739"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"740"},{"claim_amount":"3199224034","raw_amount":{"local_denom":"2157481540"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"741"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"742"},{"claim_amount":"79214013","raw_amount":{"local_denom":"53420070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"743"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"744"},{"claim_amount":"15651154","raw_amount":{"local_denom":"10554771"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"745"},{"claim_amount":"2874701","raw_amount":{"local_denom":"1938631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"746"},{"claim_amount":"8943517","raw_amount":{"local_denom":"6031298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"747"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"748"},{"claim_amount":"19164679","raw_amount":{"local_denom":"12924210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"749"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"750"},{"claim_amount":"82216480","raw_amount":{"local_denom":"55444863"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"752"},{"claim_amount":"42801120","raw_amount":{"local_denom":"28864070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"753"},{"claim_amount":"40884652","raw_amount":{"local_denom":"27571649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"754"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"755"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"756"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"757"},{"claim_amount":"36540657","raw_amount":{"local_denom":"24642161"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"758"},{"claim_amount":"21719970","raw_amount":{"local_denom":"14647438"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"759"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"760"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"761"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"762"},{"claim_amount":"70909317","raw_amount":{"local_denom":"47819578"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"763"},{"claim_amount":"2171995","raw_amount":{"local_denom":"1464743"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"764"},{"claim_amount":"10859985","raw_amount":{"local_denom":"7323719"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"765"},{"claim_amount":"894350","raw_amount":{"local_denom":"603129"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"766"},{"claim_amount":"9582339","raw_amount":{"local_denom":"6462105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"767"},{"claim_amount":"3832935","raw_amount":{"local_denom":"2584842"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"768"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"769"},{"claim_amount":"6068814","raw_amount":{"local_denom":"4092666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"770"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"771"},{"claim_amount":"86879885","raw_amount":{"local_denom":"58589754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"772"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"773"},{"claim_amount":"9582339","raw_amount":{"local_denom":"6462105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"774"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"775"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"776"},{"claim_amount":"141818636","raw_amount":{"local_denom":"95639157"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"777"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"778"},{"claim_amount":"5110581","raw_amount":{"local_denom":"3446456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"779"},{"claim_amount":"127125714","raw_amount":{"local_denom":"85730596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"780"},{"claim_amount":"8943517","raw_amount":{"local_denom":"6031298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"781"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"782"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"783"},{"claim_amount":"31302310","raw_amount":{"local_denom":"21109543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"784"},{"claim_amount":"318133699","raw_amount":{"local_denom":"214541894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"785"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"786"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"787"},{"claim_amount":"2108114","raw_amount":{"local_denom":"1421663"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"788"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"789"},{"claim_amount":"19803502","raw_amount":{"local_denom":"13355017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"790"},{"claim_amount":"25552906","raw_amount":{"local_denom":"17232280"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"791"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"792"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"793"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"794"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"795"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"796"},{"claim_amount":"670763","raw_amount":{"local_denom":"452347"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"797"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"798"},{"claim_amount":"5110581","raw_amount":{"local_denom":"3446456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"799"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"800"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"801"},{"claim_amount":"2874701","raw_amount":{"local_denom":"1938631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"802"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"803"},{"claim_amount":"3385759","raw_amount":{"local_denom":"2283277"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"804"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"805"},{"claim_amount":"49828169","raw_amount":{"local_denom":"33602947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"806"},{"claim_amount":"31941133","raw_amount":{"local_denom":"21540350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"807"},{"claim_amount":"17887034","raw_amount":{"local_denom":"12062596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"808"},{"claim_amount":"27469374","raw_amount":{"local_denom":"18524701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"809"},{"claim_amount":"44078765","raw_amount":{"local_denom":"29725684"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"810"},{"claim_amount":"3832935","raw_amount":{"local_denom":"2584842"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"811"},{"claim_amount":"22358793","raw_amount":{"local_denom":"15078245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"812"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"813"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"814"},{"claim_amount":"98378693","raw_amount":{"local_denom":"66344280"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"815"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"817"},{"claim_amount":"9422633","raw_amount":{"local_denom":"6354403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"818"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"819"},{"claim_amount":"82408126","raw_amount":{"local_denom":"55574105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"820"},{"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"821"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"822"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"823"},{"claim_amount":"86241062","raw_amount":{"local_denom":"58158947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"824"},{"claim_amount":"12712570","raw_amount":{"local_denom":"8573059"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"825"},{"claim_amount":"60688154","raw_amount":{"local_denom":"40926666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"826"},{"claim_amount":"3832935","raw_amount":{"local_denom":"2584842"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"827"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"828"},{"claim_amount":"28747019","raw_amount":{"local_denom":"19386315"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"829"},{"claim_amount":"141754755","raw_amount":{"local_denom":"95596077"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"830"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"831"}, - {"claim_amount":"2491407","raw_amount":{"local_denom":"1680147"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"832"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"833"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"834"},{"claim_amount":"3162171","raw_amount":{"local_denom":"2132494"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"835"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"836"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"837"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"838"},{"claim_amount":"47911701","raw_amount":{"local_denom":"32310526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"839"},{"claim_amount":"77297545","raw_amount":{"local_denom":"52127649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"840"},{"claim_amount":"1277645380","raw_amount":{"local_denom":"861614033"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"841"},{"claim_amount":"5110581","raw_amount":{"local_denom":"3446456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"842"},{"claim_amount":"62604622","raw_amount":{"local_denom":"42219087"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"843"},{"claim_amount":"27469374","raw_amount":{"local_denom":"18524701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"844"},{"claim_amount":"42149521","raw_amount":{"local_denom":"28424647"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"845"},{"claim_amount":"127125714","raw_amount":{"local_denom":"85730596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"846"},{"claim_amount":"124570424","raw_amount":{"local_denom":"84007368"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"847"},{"claim_amount":"19739619","raw_amount":{"local_denom":"13311936"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"848"},{"claim_amount":"10859985","raw_amount":{"local_denom":"7323719"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"849"},{"claim_amount":"67076381","raw_amount":{"local_denom":"45234736"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"850"},{"claim_amount":"412040634","raw_amount":{"local_denom":"277870525"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"851"},{"claim_amount":"638183866","raw_amount":{"local_denom":"430376209"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"852"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"853"},{"claim_amount":"1245703","raw_amount":{"local_denom":"840073"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"854"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"855"},{"claim_amount":"40884652","raw_amount":{"local_denom":"27571649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"856"},{"claim_amount":"2235878","raw_amount":{"local_denom":"1507824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"857"},{"claim_amount":"1852585","raw_amount":{"local_denom":"1249340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"858"},{"claim_amount":"8879634","raw_amount":{"local_denom":"5988217"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"859"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"860"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"861"},{"claim_amount":"6260461","raw_amount":{"local_denom":"4221908"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"862"},{"claim_amount":"20442325","raw_amount":{"local_denom":"13785824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"863"},{"claim_amount":"3705170","raw_amount":{"local_denom":"2498680"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"864"},{"claim_amount":"41459592","raw_amount":{"local_denom":"27959375"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"865"},{"claim_amount":"3130230","raw_amount":{"local_denom":"2110954"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"866"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"867"},{"claim_amount":"785750","raw_amount":{"local_denom":"529892"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"868"},{"claim_amount":"10221162","raw_amount":{"local_denom":"6892912"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"869"},{"claim_amount":"9582339","raw_amount":{"local_denom":"6462105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"870"},{"claim_amount":"1248898360","raw_amount":{"local_denom":"842227718"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"871"},{"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"872"},{"claim_amount":"63946150","raw_amount":{"local_denom":"43123782"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"873"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"874"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"875"},{"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"876"},{"claim_amount":"50466992","raw_amount":{"local_denom":"34033754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"877"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"878"},{"claim_amount":"1788702","raw_amount":{"local_denom":"1206259"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"879"},{"claim_amount":"319347462","raw_amount":{"local_denom":"215360427"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"880"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"881"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"882"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"883"},{"claim_amount":"31302310","raw_amount":{"local_denom":"21109543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"884"},{"claim_amount":"1290421","raw_amount":{"local_denom":"870230"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"885"},{"claim_amount":"638183866","raw_amount":{"local_denom":"430376209"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"886"},{"claim_amount":"159386260","raw_amount":{"local_denom":"107486350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"888"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"889"},{"claim_amount":"702703","raw_amount":{"local_denom":"473887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"890"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"891"},{"claim_amount":"4407875","raw_amount":{"local_denom":"2972568"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"892"},{"claim_amount":"3832935","raw_amount":{"local_denom":"2584842"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"893"},{"claim_amount":"3513523","raw_amount":{"local_denom":"2369438"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"894"},{"claim_amount":"318772522","raw_amount":{"local_denom":"214972701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"895"},{"claim_amount":"159705672","raw_amount":{"local_denom":"107701754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"896"},{"claim_amount":"43439942","raw_amount":{"local_denom":"29294877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"897"},{"claim_amount":"13351393","raw_amount":{"local_denom":"9003866"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"898"},{"claim_amount":"13415275","raw_amount":{"local_denom":"9046947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"899"},{"claim_amount":"320018226","raw_amount":{"local_denom":"215812775"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"900"},{"claim_amount":"2874701","raw_amount":{"local_denom":"1938631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"901"},{"claim_amount":"37051714","raw_amount":{"local_denom":"24986806"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"902"},{"claim_amount":"17887034","raw_amount":{"local_denom":"12062596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"903"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"904"},{"claim_amount":"753810","raw_amount":{"local_denom":"508352"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"905"},{"claim_amount":"79852836","raw_amount":{"local_denom":"53850877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"906"},{"claim_amount":"1279561848","raw_amount":{"local_denom":"862906454"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"907"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"908"},{"claim_amount":"7985282","raw_amount":{"local_denom":"5385087"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"909"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"910"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"911"},{"claim_amount":"1277645380","raw_amount":{"local_denom":"861614033"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"912"},{"claim_amount":"8879634","raw_amount":{"local_denom":"5988217"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"913"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"914"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"915"},{"claim_amount":"2235878","raw_amount":{"local_denom":"1507824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"916"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"917"},{"claim_amount":"63818385","raw_amount":{"local_denom":"43037620"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"918"},{"claim_amount":"2407721","raw_amount":{"local_denom":"1623711"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"919"},{"claim_amount":"56216396","raw_amount":{"local_denom":"37911017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"920"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"921"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"922"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"923"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"924"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"925"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"926"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"927"},{"claim_amount":"1852585","raw_amount":{"local_denom":"1249340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"928"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"929"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"930"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"931"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"932"},{"claim_amount":"8943517","raw_amount":{"local_denom":"6031298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"933"},{"claim_amount":"6068814","raw_amount":{"local_denom":"4092666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"934"},{"claim_amount":"11434925","raw_amount":{"local_denom":"7711445"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"935"},{"claim_amount":"1252091","raw_amount":{"local_denom":"844381"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"936"},{"claim_amount":"13415275","raw_amount":{"local_denom":"9046947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"937"},{"claim_amount":"24275261","raw_amount":{"local_denom":"16370666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"938"},{"claim_amount":"142457458","raw_amount":{"local_denom":"96069964"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"939"},{"claim_amount":"1341526","raw_amount":{"local_denom":"904694"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"940"},{"claim_amount":"2414110948","raw_amount":{"local_denom":"1628019717"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"941"},{"claim_amount":"97420460","raw_amount":{"local_denom":"65698070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"942"},{"claim_amount":"6707637","raw_amount":{"local_denom":"4523473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"943"},{"claim_amount":"395431244","raw_amount":{"local_denom":"266669543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"944"},{"claim_amount":"19036916","raw_amount":{"local_denom":"12838049"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"945"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"946"},{"claim_amount":"79533424","raw_amount":{"local_denom":"53635473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"947"},{"claim_amount":"1641774","raw_amount":{"local_denom":"1107174"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"948"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"949"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"950"},{"claim_amount":"4343993","raw_amount":{"local_denom":"2929487"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"951"},{"claim_amount":"6260461","raw_amount":{"local_denom":"4221908"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"952"},{"claim_amount":"76594840","raw_amount":{"local_denom":"51653761"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"953"},{"claim_amount":"3769053","raw_amount":{"local_denom":"2541761"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"954"},{"claim_amount":"205062083","raw_amount":{"local_denom":"138289052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"955"}, - {"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"956"},{"claim_amount":"38329361","raw_amount":{"local_denom":"25848421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"957"},{"claim_amount":"75381076","raw_amount":{"local_denom":"50835227"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"958"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"959"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"960"},{"claim_amount":"31941133","raw_amount":{"local_denom":"21540350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"961"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"962"},{"claim_amount":"766586","raw_amount":{"local_denom":"516968"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"963"},{"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"964"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"965"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"966"}, - {"claim_amount":"127125714","raw_amount":{"local_denom":"85730596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"967"},{"claim_amount":"1533173","raw_amount":{"local_denom":"1033936"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"968"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"969"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"970"},{"claim_amount":"109238678","raw_amount":{"local_denom":"73667999"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"971"},{"claim_amount":"31941133","raw_amount":{"local_denom":"21540350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"972"},{"claim_amount":"44717588","raw_amount":{"local_denom":"30156491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"973"},{"claim_amount":"1533173","raw_amount":{"local_denom":"1033936"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"974"},{"claim_amount":"59410509","raw_amount":{"local_denom":"40065052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"975"},{"claim_amount":"683539","raw_amount":{"local_denom":"460963"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"976"},{"claim_amount":"10540573","raw_amount":{"local_denom":"7108315"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"977"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"978"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"979"},{"claim_amount":"42801120","raw_amount":{"local_denom":"28864070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"980"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"981"},{"claim_amount":"79852836","raw_amount":{"local_denom":"53850877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"982"},{"claim_amount":"19164679","raw_amount":{"local_denom":"12924210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"983"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"984"},{"claim_amount":"1724819","raw_amount":{"local_denom":"1163178"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"985"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"986"},{"claim_amount":"31302310","raw_amount":{"local_denom":"21109543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"987"},{"claim_amount":"2491407","raw_amount":{"local_denom":"1680147"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"988"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"989"},{"claim_amount":"89435176","raw_amount":{"local_denom":"60312982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"990"},{"claim_amount":"8943517","raw_amount":{"local_denom":"6031298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"991"},{"claim_amount":"8943517","raw_amount":{"local_denom":"6031298"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"992"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"993"},{"claim_amount":"167946484","raw_amount":{"local_denom":"113259164"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"994"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"995"},{"claim_amount":"376266563","raw_amount":{"local_denom":"253745332"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"996"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"997"},{"claim_amount":"35135246","raw_amount":{"local_denom":"23694385"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"998"},{"claim_amount":"175676239","raw_amount":{"local_denom":"118471929"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"999"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1000"},{"claim_amount":"702703","raw_amount":{"local_denom":"473887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1001"},{"claim_amount":"12712570","raw_amount":{"local_denom":"8573059"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1002"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1003"},{"claim_amount":"78575190","raw_amount":{"local_denom":"52989263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1004"},{"claim_amount":"3513523","raw_amount":{"local_denom":"2369438"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1005"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1006"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1007"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1008"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1009"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1010"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1011"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1013"},{"claim_amount":"12776453","raw_amount":{"local_denom":"8616140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1014"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1015"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1016"},{"claim_amount":"7346459","raw_amount":{"local_denom":"4954280"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1017"},{"claim_amount":"7985282","raw_amount":{"local_denom":"5385087"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1018"},{"claim_amount":"734645","raw_amount":{"local_denom":"495428"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1019"},{"claim_amount":"5749403","raw_amount":{"local_denom":"3877263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1020"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1021"},{"claim_amount":"7665871","raw_amount":{"local_denom":"5169684"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1022"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1023"},{"claim_amount":"191646807","raw_amount":{"local_denom":"129242105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1024"},{"claim_amount":"5493874","raw_amount":{"local_denom":"3704940"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1025"},{"claim_amount":"127445125","raw_amount":{"local_denom":"85945999"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1026"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1027"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1028"},{"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1029"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1030"},{"claim_amount":"318772522","raw_amount":{"local_denom":"214972701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1031"},{"claim_amount":"114988084","raw_amount":{"local_denom":"77545263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1032"},{"claim_amount":"56855218","raw_amount":{"local_denom":"38341824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1033"},{"claim_amount":"1724819","raw_amount":{"local_denom":"1163178"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1034"},{"claim_amount":"641377981","raw_amount":{"local_denom":"432530245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1035"},{"claim_amount":"11498807","raw_amount":{"local_denom":"7754526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1036"},{"claim_amount":"66437558","raw_amount":{"local_denom":"44803929"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1037"},{"claim_amount":"2191161","raw_amount":{"local_denom":"1477668"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1038"},{"claim_amount":"28683138","raw_amount":{"local_denom":"19343235"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1039"},{"claim_amount":"2427525","raw_amount":{"local_denom":"1637066"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1040"},{"claim_amount":"10859985","raw_amount":{"local_denom":"7323719"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1041"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1042"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1043"},{"claim_amount":"2389196863","raw_amount":{"local_denom":"1611218243"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1044"},{"claim_amount":"127125714","raw_amount":{"local_denom":"85730596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1045"},{"claim_amount":"89435176","raw_amount":{"local_denom":"60312982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1046"},{"claim_amount":"6260461","raw_amount":{"local_denom":"4221908"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1047"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1048"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1049"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1050"},{"claim_amount":"95823402","raw_amount":{"local_denom":"64621052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1051"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1052"},{"claim_amount":"12073747","raw_amount":{"local_denom":"8142252"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1053"},{"claim_amount":"5429991","raw_amount":{"local_denom":"3661859"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1054"},{"claim_amount":"33793720","raw_amount":{"local_denom":"22789691"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1055"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1056"},{"claim_amount":"926292","raw_amount":{"local_denom":"624670"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1057"},{"claim_amount":"31877252","raw_amount":{"local_denom":"21497270"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1058"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1059"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1060"},{"claim_amount":"574940421","raw_amount":{"local_denom":"387726315"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1061"},{"claim_amount":"17887034","raw_amount":{"local_denom":"12062596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1062"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1063"},{"claim_amount":"82855302","raw_amount":{"local_denom":"55875670"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1064"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1065"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1066"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1067"},{"claim_amount":"25552906","raw_amount":{"local_denom":"17232280"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1068"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1069"},{"claim_amount":"3130230","raw_amount":{"local_denom":"2110954"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1070"},{"claim_amount":"791501312","raw_amount":{"local_denom":"533769893"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1071"},{"claim_amount":"7665871","raw_amount":{"local_denom":"5169684"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1072"},{"claim_amount":"12457041","raw_amount":{"local_denom":"8400736"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1073"},{"claim_amount":"1597055","raw_amount":{"local_denom":"1077017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1074"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1075"},{"claim_amount":"574940421","raw_amount":{"local_denom":"387726315"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1076"},{"claim_amount":"7665871","raw_amount":{"local_denom":"5169684"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1077"},{"claim_amount":"1022115","raw_amount":{"local_denom":"689291"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1078"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1079"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1080"},{"claim_amount":"89051882","raw_amount":{"local_denom":"60054498"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1081"},{"claim_amount":"7665871","raw_amount":{"local_denom":"5169684"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1082"},{"claim_amount":"125145364","raw_amount":{"local_denom":"84395094"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1083"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1084"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1085"}, - {"claim_amount":"1245703","raw_amount":{"local_denom":"840073"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1086"},{"claim_amount":"5941050","raw_amount":{"local_denom":"4006505"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1087"},{"claim_amount":"6707637","raw_amount":{"local_denom":"4523473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1088"},{"claim_amount":"44653705","raw_amount":{"local_denom":"30113410"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1089"},{"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1090"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1091"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1092"},{"claim_amount":"76658722","raw_amount":{"local_denom":"51696842"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1093"},{"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1094"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1095"},{"claim_amount":"3130230","raw_amount":{"local_denom":"2110954"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1096"},{"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1097"},{"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1098"},{"claim_amount":"22997615","raw_amount":{"local_denom":"15509052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1099"},{"claim_amount":"127690862","raw_amount":{"local_denom":"86111718"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1100"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1101"},{"claim_amount":"40884652","raw_amount":{"local_denom":"27571649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1102"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1103"},{"claim_amount":"318772522","raw_amount":{"local_denom":"214972701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1104"},{"claim_amount":"6707637","raw_amount":{"local_denom":"4523473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1105"},{"claim_amount":"239558508","raw_amount":{"local_denom":"161552631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1106"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1107"},{"claim_amount":"8304694","raw_amount":{"local_denom":"5600491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1108"},{"claim_amount":"2317009899","raw_amount":{"local_denom":"1562537050"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1109"},{"claim_amount":"15970566","raw_amount":{"local_denom":"10770175"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1110"}, - {"claim_amount":"7027049","raw_amount":{"local_denom":"4738877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1111"},{"claim_amount":"63243445","raw_amount":{"local_denom":"42649894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1112"},{"claim_amount":"6707637","raw_amount":{"local_denom":"4523473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1113"},{"claim_amount":"1012708","raw_amount":{"local_denom":"682947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1114"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1115"},{"claim_amount":"3769053","raw_amount":{"local_denom":"2541761"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1116"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1117"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1118"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1119"},{"claim_amount":"3513523","raw_amount":{"local_denom":"2369438"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1120"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1121"},{"claim_amount":"14054098","raw_amount":{"local_denom":"9477754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1122"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1123"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1124"},{"claim_amount":"702703","raw_amount":{"local_denom":"473887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1125"},{"claim_amount":"19100797","raw_amount":{"local_denom":"12881129"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1126"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1127"},{"claim_amount":"702703","raw_amount":{"local_denom":"473887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1128"},{"claim_amount":"5685521","raw_amount":{"local_denom":"3834182"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1129"},{"claim_amount":"3513523","raw_amount":{"local_denom":"2369438"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1130"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1131"},{"claim_amount":"76019900","raw_amount":{"local_denom":"51266035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1132"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1133"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1134"},{"claim_amount":"2235878","raw_amount":{"local_denom":"1507824"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1135"},{"claim_amount":"63882269087","raw_amount":{"local_denom":"43080701693"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1136"},{"claim_amount":"16289977","raw_amount":{"local_denom":"10985578"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1137"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1138"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1139"},{"claim_amount":"894350","raw_amount":{"local_denom":"603129"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1140"},{"claim_amount":"78575190","raw_amount":{"local_denom":"52989263"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1141"},{"claim_amount":"172482125","raw_amount":{"local_denom":"116317894"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1142"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1143"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1144"},{"claim_amount":"22358793","raw_amount":{"local_denom":"15078245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1145"},{"claim_amount":"3130230","raw_amount":{"local_denom":"2110954"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1146"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1147"},{"claim_amount":"8304694","raw_amount":{"local_denom":"5600491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1148"},{"claim_amount":"2491407","raw_amount":{"local_denom":"1680147"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1149"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1150"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1151"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1152"},{"claim_amount":"4212396822","raw_amount":{"local_denom":"2840741469"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1153"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1154"},{"claim_amount":"4471758","raw_amount":{"local_denom":"3015649"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1155"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1156"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1157"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1158"},{"claim_amount":"2529736","raw_amount":{"local_denom":"1705995"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1159"},{"claim_amount":"4791169","raw_amount":{"local_denom":"3231052"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1160"},{"claim_amount":"58771686","raw_amount":{"local_denom":"39634245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1161"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1162"},{"claim_amount":"47272878","raw_amount":{"local_denom":"31879719"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1163"},{"claim_amount":"37690537","raw_amount":{"local_denom":"25417613"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1164"},{"claim_amount":"3066347","raw_amount":{"local_denom":"2067873"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1165"},{"claim_amount":"734645","raw_amount":{"local_denom":"495428"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1166"},{"claim_amount":"14692921","raw_amount":{"local_denom":"9908561"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1167"},{"claim_amount":"13415275","raw_amount":{"local_denom":"9046947"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1168"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1169"},{"claim_amount":"12457041","raw_amount":{"local_denom":"8400736"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1170"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1171"},{"claim_amount":"2491407","raw_amount":{"local_denom":"1680147"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1172"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1173"},{"claim_amount":"14054098","raw_amount":{"local_denom":"9477754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1174"},{"claim_amount":"11179395","raw_amount":{"local_denom":"7539122"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1175"},{"claim_amount":"16258036","raw_amount":{"local_denom":"10964038"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1176"},{"claim_amount":"1916467","raw_amount":{"local_denom":"1292421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1177"},{"claim_amount":"6356284","raw_amount":{"local_denom":"4286529"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1178"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1179"},{"claim_amount":"97739870","raw_amount":{"local_denom":"65913473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1180"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1181"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1182"},{"claim_amount":"102658805","raw_amount":{"local_denom":"69230687"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1183"},{"claim_amount":"14692921","raw_amount":{"local_denom":"9908561"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1184"},{"claim_amount":"44717588","raw_amount":{"local_denom":"30156491"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1185"},{"claim_amount":"2427525","raw_amount":{"local_denom":"1637066"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1186"},{"claim_amount":"1149879","raw_amount":{"local_denom":"775452"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1187"},{"claim_amount":"3194113","raw_amount":{"local_denom":"2154035"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1188"},{"claim_amount":"5642720827","raw_amount":{"local_denom":"3805318380"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1189"},{"claim_amount":"30982900","raw_amount":{"local_denom":"20894140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1190"},{"claim_amount":"38329361","raw_amount":{"local_denom":"25848421"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1191"},{"claim_amount":"9837869","raw_amount":{"local_denom":"6634428"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1192"},{"claim_amount":"72186962","raw_amount":{"local_denom":"48681192"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1193"},{"claim_amount":"929487014","raw_amount":{"local_denom":"626824209"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1194"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1195"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1196"},{"claim_amount":"6068814","raw_amount":{"local_denom":"4092666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1197"},{"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1198"},{"claim_amount":"60049332","raw_amount":{"local_denom":"40495859"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1199"},{"claim_amount":"14629038","raw_amount":{"local_denom":"9865480"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1200"},{"claim_amount":"2523348","raw_amount":{"local_denom":"1701687"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1201"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1202"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1203"},{"claim_amount":"2491407","raw_amount":{"local_denom":"1680147"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1204"},{"claim_amount":"82791420","raw_amount":{"local_denom":"55832589"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1205"},{"claim_amount":"7665871","raw_amount":{"local_denom":"5169684"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1206"},{"claim_amount":"32579955","raw_amount":{"local_denom":"21971157"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1207"},{"claim_amount":"4407875","raw_amount":{"local_denom":"2972568"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1208"},{"claim_amount":"14692921","raw_amount":{"local_denom":"9908561"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1209"},{"claim_amount":"1054056","raw_amount":{"local_denom":"710831"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1210"},{"claim_amount":"23317028","raw_amount":{"local_denom":"15724456"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1211"},{"claim_amount":"9422633","raw_amount":{"local_denom":"6354403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1212"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1213"},{"claim_amount":"436315897","raw_amount":{"local_denom":"294241192"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1214"},{"claim_amount":"31877252","raw_amount":{"local_denom":"21497270"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1215"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1216"},{"claim_amount":"45931350","raw_amount":{"local_denom":"30975024"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1217"},{"claim_amount":"2555290","raw_amount":{"local_denom":"1723228"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1218"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1219"},{"claim_amount":"1277645","raw_amount":{"local_denom":"861614"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1220"},{"claim_amount":"16609389","raw_amount":{"local_denom":"11200982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1221"},{"claim_amount":"31302310","raw_amount":{"local_denom":"21109543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1222"},{"claim_amount":"2986304432","raw_amount":{"local_denom":"2013893562"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1223"},{"claim_amount":"57494041","raw_amount":{"local_denom":"38772631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1224"},{"claim_amount":"70909317","raw_amount":{"local_denom":"47819578"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1225"}, - {"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1226"},{"claim_amount":"830469","raw_amount":{"local_denom":"560049"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1227"},{"claim_amount":"9582339","raw_amount":{"local_denom":"6462105"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1228"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1229"},{"claim_amount":"213366777","raw_amount":{"local_denom":"143889543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1230"},{"claim_amount":"31941133","raw_amount":{"local_denom":"21540350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1231"},{"claim_amount":"12137630","raw_amount":{"local_denom":"8185333"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1232"},{"claim_amount":"14054098","raw_amount":{"local_denom":"9477754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1233"},{"claim_amount":"37371126","raw_amount":{"local_denom":"25202210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1234"},{"claim_amount":"111155146","raw_amount":{"local_denom":"74960420"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1235"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1236"},{"claim_amount":"18525857","raw_amount":{"local_denom":"12493403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1237"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1238"},{"claim_amount":"6388226","raw_amount":{"local_denom":"4308070"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1239"},{"claim_amount":"16609389","raw_amount":{"local_denom":"11200982"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1240"},{"claim_amount":"6324343","raw_amount":{"local_denom":"4264989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1241"},{"claim_amount":"32899368","raw_amount":{"local_denom":"22186561"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1242"},{"claim_amount":"17887034","raw_amount":{"local_denom":"12062596"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1243"}, - {"claim_amount":"1852585","raw_amount":{"local_denom":"1249340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1244"},{"claim_amount":"60688154","raw_amount":{"local_denom":"40926666"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1245"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1246"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1247"},{"claim_amount":"31302310","raw_amount":{"local_denom":"21109543"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1248"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1249"},{"claim_amount":"1597055","raw_amount":{"local_denom":"1077017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1250"},{"claim_amount":"958233","raw_amount":{"local_denom":"646210"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1251"},{"claim_amount":"93906934","raw_amount":{"local_denom":"63328631"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1252"},{"claim_amount":"1213762","raw_amount":{"local_denom":"818533"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1253"},{"claim_amount":"555775739","raw_amount":{"local_denom":"374802104"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1254"},{"claim_amount":"47911701","raw_amount":{"local_denom":"32310526"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1255"},{"claim_amount":"18845267","raw_amount":{"local_denom":"12708806"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1256"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1257"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1258"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1259"},{"claim_amount":"204103848","raw_amount":{"local_denom":"137642841"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1260"},{"claim_amount":"20059032","raw_amount":{"local_denom":"13527340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1261"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1262"},{"claim_amount":"63882268","raw_amount":{"local_denom":"43080701"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1263"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1264"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1265"},{"claim_amount":"638822","raw_amount":{"local_denom":"430807"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1266"},{"claim_amount":"14054098","raw_amount":{"local_denom":"9477754"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1267"},{"claim_amount":"753171951","raw_amount":{"local_denom":"507921472"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1268"} -] \ No newline at end of file diff --git a/smart-contracts/contracts/lp-strategy/proptest-regressions/icq.txt b/smart-contracts/contracts/lp-strategy/proptest-regressions/icq.txt deleted file mode 100644 index 59fc9c668..000000000 --- a/smart-contracts/contracts/lp-strategy/proptest-regressions/icq.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 2b300d09f5f1856b156f41658fdd276b8a378e67da0908c4c158b8d7730d81b9 # shrinks to ica_balance = 1, base_amount = 1, quote_amount = 327625762938489495774, spot_price = 1 -cc 6448d8264198d301ef2dbab1d66ec3e06a1e912fa9bcd78bcd518cc776a91c06 # shrinks to ica_balance = 58306639683943076671774772009787831350, base_amount = 281975727236995386788616564490221065989, quote_amount = 193186435338440089613902032006337132281, spot_price = 1 diff --git a/smart-contracts/contracts/lp-strategy/proptest-regressions/proptests.txt b/smart-contracts/contracts/lp-strategy/proptest-regressions/proptests.txt deleted file mode 100644 index f97783546..000000000 --- a/smart-contracts/contracts/lp-strategy/proptest-regressions/proptests.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 18cce7ef7418ba2e32c0dc974cce3839ed3afdd23c44eeff10c7cd502b664e52 # shrinks to (claim_amount, raw_amount, owner, bond_id) = ([0, 0, 0, 0, 0, 0, 0, 0, 11673845048084930547460394097995684, 38681151403059791997234025049684207626, 275054852874891480362198002940302056891, 248004106615233309637537480600637151515, 12165567352195846609387282639635621409, 260605945814629129877776296832005137162, 332498733738228587954824791897661214933, 220466759761543005181347682445321394851, 276955038478825658651724087112112977189, 327002931333860120384022494611419106764, 147064090442518249001596779703329850197, 39564122707571826747255339378284677948, 17245431880610274106465508916866826111, 26339003119474933218657724991629946399, 82276117695411068556044142010840638542, 295008677415348915376590468404000416830, 151554982649645368787246484795119526682, 180975261261844223519603233989024384027, 168751969190378588139721758050330892898, 131638036830868649013316482547580628713, 220442041130371752953825283455113893493, 65440179817723704813041205675233168717, 302341085874258666373729283438827979429, 59484899708101852479526669734567026566, 167625816230803446734600484639624676839, 223247288265999841840523557165498328548, 271205220985832846755417320083279796734, 188428825985446459356920011698020643141, 55914548276615285259550848482812446934, 102195989075020376935386609445353607918, 121781350805295556121749379931595727418, 49381516483748229739304062049605408686, 329483797478926557991409582759842888536, 25050877269533561643188662513251020289, 184084971816401394199792095345498654512, 314553285012672846226294513049818847532, 118214012495816784551227736304553654376, 331325951165181232595902138691158403353, 229895801368881505703484862144444531032, 217114635620378362608851676834552215349, 159876936511935302157126642045367287856, 135181955021589654255626347995453150573], [227365969172255363624507819951096565724, 301233924106392053527349799565535715008, 215189084033479621725931318636708931919, 269766051904425953113532064070452847870, 61626890029710227563630958944174916236, 121643162891773300986476522338839386555, 157890849575919296860121842741320755656, 318428887894696259998226374343390699537, 150429733389995246829353939053231673536, 1309984178131570546375402682674361514, 288596204117498775793769566300644324747, 221239221463166352388729594400491553656, 148978909380753273521137273830591697007, 275538702349313158916849577919121729747, 163713187093681229043970290243259360890, 151924563830510961661700273092653868361, 148155351515033332222116696976228855043, 23040063650194206500661391710955447418, 13976091836981510172184743689715944696, 185666796634122241421163204703768333325, 31949197993783774617668624979640684182, 44236163852815662641567703574148698704, 47478877286618988935887578375249136659, 70426128900427005954075445206391113470, 140906409014291614293719794814848067102, 107269575146883060322539137018471008849, 296995157204714311405805419068824989229, 161750435276928235606415971917746751228, 130756986618466217781348998859419151606, 105073686713080197476347255702114582082, 129373854793859197217362919487938017347, 285793942650403489640653646346783262704, 176448516216785083528112658599394780511, 200568359946301769234774760267636045793, 27117563929292709236084290248168245624, 132398191031838449046483348706831060869, 57516945481821405412092628600363321519, 197427381802548279413420705792351222501, 222846337535771089032432325957371072165, 79516707543765823940780266761219013517, 332746313329984099982163571762137691017, 297346398595796224323092462643166162137, 337071417935433974216532431467712569575, 41085095792457838701721359791557450918, 702470706316076453758134797401550118, 100190323026370930887276274578630211218, 54132925651950671821377657598243746105, 160055808294617960457289618967505797919, 112719553546396289399469348203275740183, 242448663799866037822921626508547285315], ["pelxgcgce", "eypufagrnmxaahmtwbz", "cksckqcgu", "johwpajdhxxdilpdqrskizhddv", "ecdyivkeowdhfpw", "ueuajshhjamecwhwunb", "ytwfxzlqv", "hbbmwqnofuhemyeziytmbdf", "ygqznvztityjg", "ntflh", "mivqrepqpwb", "gdvidjpuxwlrrqbr", "xjarmvwsgdwvwbblsooirfpcc", "zepkhzdkhvuakrhxsevrtdmbethihul", "ifrbn", "mersihvlcbvl", "ofyoghkarnxgpkorimi", "drdnbwlazpjrnmjpsksn", "mlppcbqtffsanomjokhth", "rxvlxdmxxlhckfklgd", "abf", "xltocqunoj", "ivsethz", "nzxsbgopozgqdxdmjmahmlglzwppoqg", "tkfsavgckbbzenoy", "sszuzdirsyfcwqogzhcnoaku", "rqnynflkonzpf", "kxlbd", "sylpzasamyg", "arbxqxavnptpewgb", "zovsuusznqywcnmqjppgzhwlcl", "pvjqbwupe", "xlnxdjtvxpd", "", "xbdygipeqfbazl", "j", "mdxudvywbvbfxkhnq", "ijrbpwsmvhzksyztnbqctyfqoiwkcy", "dqthiwptekttiplbhttgiuj", "twqkimydeuvacaelnklsxsbavmobuiqk", "qixstkpwyugrfwxsgohjpvtaa", "rvsiw", "ghwgcnggijoyapcaadxjk", "vkjv", "icpqzohhbpiywrdonllmzadjmffin", "ridgzcfb", "xbeunufvpqzytneqr", "cgoazeqiogbsv", "pprfeonetfysfbylr", "w"], [245156543980833747090242765144329311038, 194567896024102730141520967076722737253, 78321590831082444086273322095061857666, 46234274478596011116062623468273869668, 263465158450098859717724367516067905975, 100752541069266103352244815706779144613, 246329798443977159630785364311541203165, 89071066193382807867647247777458784703, 89680324833787488426590379191240982648, 326751368326903363754619742229709084471, 81949509939543357493869595004811069397, 320435057684033242953952509794605645127, 133212895719388354112667050350502201843, 262256541475020683812327300478510544022, 68423813730476634270402958635073934367, 156738226689669755944851331748791005616, 165800725532545879609977936210035055040, 172018455739485735148072644379216290447, 230951541362177602359868002660805912181, 152287027695533706215823402052033189960, 185057933550094735087283806786823061589, 122688000701961209416344853008164886381, 134958802702793640081845590040343954920, 234580960409424622564273814575333116288, 183739892098724792237695657764961499807, 39015994699012683337617007960068058843, 324137172833870104374658339409853260398, 156871594659100780158350555737480367369, 76549132260116470292478935610594931831, 206367556367473756044436720233354369995, 242121355820534272849028361122887112128, 188631998326034004600861498586852938791, 216069174770114465624174207718872444354, 307944890529036529511929496919799050224, 316346783727245703493409702940347462603, 232794123719215275741536507199048918940, 230699271415462493000400243339292494907, 215746109799468672448745109724428767505, 10735964370838476891653111627115651590, 177546680977013945994944742461442930075, 48188853863336799882618830643360361251, 123072710083781474823580256603344815581, 53696605966638634884824007767847163895, 244813750508221881267886759962353770844, 138389416756738828485107907845869178387, 28787808414027521881066099129863372506, 208960876676490369283588392054850944689, 291922470923877549823217120675909351267, 115223001020919711020256788413332787629, 309151305555635829791059270121082705015]) -cc ed5adefd853fbe7386e63b9d852d81fcfb66fd30eb1ee0ac95f4915dc32af26d # shrinks to (claim_amount, raw_amount, owner, bond_id) = ([0, 0], [5567553736818050811761864155695314435, 334714813184120412651612743276072882021], ["", ""], [0, 0]) -cc bb29a873ab429224989abbadbb61fd8492c0c147fcbfdd7c03eb64d853c254db # shrinks to (claim_amount, raw_amount, owner, bond_id) = ([], [], [], []), (amount_pd, owner_pd, bond_id_pd) = ([], [], []), raw_balalance_rq = 0, quote_balance_rq = 0, lp_balance_rq = 0, join_pool_rq = 0, exit_pool_base_rq = 0, exit_pool_quote_rq = 0, spot_price_rq = 0 -cc 34775cc5f6b44bd958d663493908f0e5546434ed9156d1ebe18a1503b4166df0 # shrinks to (claim_amount, raw_amount, owner, bond_id) = ([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 83553156567498, 11808849592816811342, 8130787376546610459, 14980519244902503230, 14234410997718520343, 10225549382265082313, 14258484066235613374, 16132509078925444533, 12496179773926113447, 5163701959177179557, 6115732151642180644, 16014557328226574517, 17910735935150482215, 15905882731006320604, 6938858134545344839, 311364060211843560, 8464979079766962920, 8688102988532725869, 6950140404087665517, 61793720827537470, 15697647606715928957, 6549806696217709345, 6362990510017777241, 10957519013857898322, 12513697704065533392, 10682377085392477145, 11467648984684906402, 6914635055688605728, 6355149797117565939, 3759358825474970803, 1512101291444601349, 12542255319701031943, 7005223357316672524, 11709985910294196329, 16431675148878993558, 18088527547444258371, 18128405577901023348, 533460672940784407, 6547510708312023640, 12866793111322861531, 8672995590736397231, 14424622615502074446, 2307613407971382985, 17441942398532076118], [15826457340195732357, 3704826055518850654, 7534652765877672533, 17446234302595466983, 6161974760894201947, 14625587653503619871, 6368026972723040756, 9429109580945985830, 2272938497016214323, 3904354027872436016, 11765354634249073970, 5206622489089162589, 6352158132024455001, 10360948853066292607, 16091076371184297087, 10686302784989918058, 522004517581656444, 4357444334841157825, 8752957838480279932, 1966713813215548561, 16954393754388505823, 984025542946232675, 13665913500959464705, 4955554490241156322, 7294307173539117479, 938763324680373732, 492520615853963630, 14849790482556102869, 13517356408982302285, 12639950288329634165, 13393035703502329928, 16572484674960023979, 6573211058722160462, 14412302373624951367, 6188123385003315881, 11715869108671089008, 5648724300247408734, 5413705664772579881, 5998831249611394040, 1220625596522501898, 1377604803059093507, 141220414108167420, 120942024884388456, 15465952658707590747, 14335606127926440686, 16175674822280915491, 8695491072012231849, 1853068128626976492, 11227189535675615227, 4960793297193568795, 7850650787850785584, 2911908877680041078, 9878681945393343004, 7725132537583460349, 5630970625065211239, 15588629860098892381, 9561298833016379036, 17094307055106940528, 6013650033902031667, 8259839850861701315], ["dgrqiyjcovaookyblrg", "ztmagivlipvydahetyhpdwayykzjj", "tfdbxmfojhsbmzgumapeoz", "gxezjehqzrkzutmghdlqaxfduyvdtmmd", "fhsdpym", "wudbifslwjvruodwlokezlrkouqarvt", "zpnihv", "e", "vkyycuyhdzzdeemvpigsb", "plvetqyxmjjhsgtuysxqqymj", "inwzsdwpbdoerg", "zfwpkflklyt", "mnbfxebcyiailqsrfqowr", "mupbksylxtjtgqalnitlqjitlnzks", "qpjyoai", "bzskbtibcesvxnfgbvuzhzgtycy", "opjjotortcawlyttck", "mgftscgljwawrffmgsffsxleujngatbi", "atofntcuqdxmzqyaykhwyuwzy", "bkehgtfwnxphyxfaryescclprn", "moaianym", "hufolvhlfdjbeogauquuv", "dpkoobsneuuktmrxabwhk", "fxkeasrmkldatftoxaxtrow", "ynqjoxyleuoo", "dmjobjvtdxvfaiiicbjjpmhrke", "rpqahmnaflpqteyeyzfbhuab", "qgxytkazzaowoahejafngnnmoyuwq", "mctubnxzqodnwqxlhfhcrmtnoqaav", "nhjqjrktvc", "ysyqcjioyrfhutkaueaoocfxnctqazeq", "clxcviqulqfkm", "rtnwqgagvt", "jmqaltldcjcvfmdj", "nnlnpocqf", "pptjwiqwjbxfetnztectxrainddacm", "onxfua", "jngvifuoigb", "scmknna", "splnseom", "onqlrofyfmycjjdz", "fifjawebeqjtnbvoeioyimxvjjl", "ovqeftnbpqwp", "sk", "zidmgenlzppemiofhewmlsefjzdo", "rweenuisuhqk", "hop", "hpnyurozekfedbxhzidxbfihcypeljuf", "x", "ttpwuzzlnw", "defee", "pszdtgzfkzdxldlcrbr", "hqqnyylxmm", "ytwhdpgbqqluofeimednsepsvkxhaae", "uwlzmmgbadlymz", "ilpfthwgblxrlcwt", "trxqrxeii", "nklgitkbqdgbuiykweimoxxbus", "wsnxygctcnomzgjywfvtu", "bfcglnnizuhprogakd"], [17564701645947559694, 10684717952737285943, 10219761788279915146, 2109710357599859391, 10487310863879864593, 15822884041780719907, 11848105584455790133, 17931449780282279864, 8909590184269171323, 2959034442329770038, 16596193355103071593, 15485371830524286297, 15155403646891693209, 16618642512816226160, 11042324674626444498, 11974407949461512535, 1763186450440707960, 18290373659633014915, 15628661186771988252, 16836233893596365339, 16156643523011845388, 6812953976141217730, 3685585248911984394, 810033298279336584, 9998175313336111059, 8687288352342553603, 3098556134784640099, 3864774701428716149, 15051486419399376922, 2190077543700623599, 16012320347463077713, 16833307165034632153, 2395940186996495483, 4130047742181157138, 398807872624232724, 5593681726988201550, 17694081960095301824, 15985889760645175226, 16376128475035724969, 4026056742303909744, 15014143413475248664, 3995771739911710916, 1941983340358743336, 13206881376468297167, 14576866369417099042, 11358921675486065870, 2026942581626530092, 3182543356739401115, 13832536031591260330, 10929954346159679353, 17226923001376597991, 14359302255407025404, 15604591261117489966, 4652729393292511177, 14178413536313939160, 8962255765512619945, 11954228840537278358, 7081160827464255778, 12740476215904686133, 901276637696619765]), (amount_pd, owner_pd, bond_id_pd) = ([], [], []), raw_balalance_rq = 3906736672086151414, quote_balance_rq = 5260586167652135091, lp_balance_rq = 47453939318407458, join_pool_rq = 17437550474192041343, exit_pool_base_rq = 12672570040552928040, exit_pool_quote_rq = 261663182347622709, spot_price_rq = 10002155156807470437 diff --git a/smart-contracts/contracts/lp-strategy/src/admin.rs b/smart-contracts/contracts/lp-strategy/src/admin.rs deleted file mode 100644 index 23b5972cd..000000000 --- a/smart-contracts/contracts/lp-strategy/src/admin.rs +++ /dev/null @@ -1,158 +0,0 @@ -use cosmwasm_std::{Addr, Empty, Env, QuerierWrapper, Storage}; - -use crate::{ - error::ContractError, - helpers::is_contract_admin, - state::{DEPOSITOR, LOCK_ADMIN}, -}; - -// check if sender is the admin -pub fn check_depositor(storage: &mut dyn Storage, sender: &Addr) -> Result { - let depositor = DEPOSITOR.load(storage)?; - Ok(depositor == sender) -} - -pub fn add_lock_admin( - storage: &mut dyn Storage, - querier: &QuerierWrapper, - env: &Env, - sender: Addr, - to_add: Addr, -) -> Result<(), ContractError> { - is_contract_admin(querier, env, &sender)?; - LOCK_ADMIN.save(storage, &to_add, &Empty::default())?; - Ok(()) -} - -pub fn remove_lock_admin( - storage: &mut dyn Storage, - querier: &QuerierWrapper, - env: &Env, - sender: Addr, - to_remove: Addr, -) -> Result<(), ContractError> { - is_contract_admin(querier, env, &sender)?; - LOCK_ADMIN.remove(storage, &to_remove); - Ok(()) -} - -pub fn is_lock_admin( - storage: &mut dyn Storage, - querier: &QuerierWrapper, - env: &Env, - sender: &Addr, -) -> Result<(), ContractError> { - // if the may load is none, we check the contract admin status, if that errors, then the sender is neither contract - // admin or a lock admin - let lock = LOCK_ADMIN.may_load(storage, sender)?; - match lock { - Some(_) => Ok(()), - None => is_contract_admin(querier, env, sender), - } -} - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, MockQuerier}, - to_json_binary, ContractInfoResponse, ContractResult, QuerierResult, WasmQuery, - }; - - #[test] - fn test_lock_admin() { - let mut deps = mock_dependencies(); - let admin = "bob"; - let admin1 = "alice"; - let admin2: &str = "eve"; - let env = mock_env(); - - let mut info = ContractInfoResponse::default(); - info.admin = Some(admin.to_string()); - let mut q = MockQuerier::default(); - q.update_wasm(move |q: &WasmQuery| -> QuerierResult { - match q { - WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Ok(ContractResult::Ok(to_json_binary(&info).unwrap())) - } - _ => unreachable!(), - } - }); - let querier: QuerierWrapper = QuerierWrapper::new(&q); - - // add the extra admin - add_lock_admin( - deps.as_mut().storage, - &querier, - &env, - Addr::unchecked(admin), - Addr::unchecked(admin1), - ) - .unwrap(); - is_lock_admin( - deps.as_mut().storage, - &querier, - &env, - &Addr::unchecked(admin), - ) - .unwrap(); - is_lock_admin( - deps.as_mut().storage, - &querier, - &env, - &Addr::unchecked(admin1), - ) - .unwrap(); - is_lock_admin( - deps.as_mut().storage, - &querier, - &env, - &Addr::unchecked(admin2), - ) - .unwrap_err(); - add_lock_admin( - deps.as_mut().storage, - &querier, - &env, - Addr::unchecked(admin), - Addr::unchecked(admin2), - ) - .unwrap(); - is_lock_admin( - deps.as_mut().storage, - &querier, - &env, - &Addr::unchecked(admin2), - ) - .unwrap(); - - remove_lock_admin( - deps.as_mut().storage, - &querier, - &env, - Addr::unchecked(admin), - Addr::unchecked(admin2), - ) - .unwrap(); - // check that we fail once removed - is_lock_admin( - deps.as_mut().storage, - &querier, - &env, - &Addr::unchecked(admin2), - ) - .unwrap_err(); - } - - #[test] - fn test_admin() { - let mut deps = mock_dependencies(); - let sender1 = Addr::unchecked("alice"); - let sender2 = Addr::unchecked("eve"); - - DEPOSITOR.save(deps.as_mut().storage, &sender1).unwrap(); - assert!(check_depositor(deps.as_mut().storage, &sender1).unwrap()); - assert_eq!(check_depositor(deps.as_mut().storage, &sender1), Ok(true)); - assert_eq!(check_depositor(deps.as_mut().storage, &sender2), Ok(false)); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/bond.rs b/smart-contracts/contracts/lp-strategy/src/bond.rs deleted file mode 100644 index a63a73c68..000000000 --- a/smart-contracts/contracts/lp-strategy/src/bond.rs +++ /dev/null @@ -1,554 +0,0 @@ -use std::cmp::Ordering; - -use cosmwasm_std::{Addr, Env, QuerierWrapper, StdResult, Storage, SubMsg, Uint128}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::{ - error::ContractError, - helpers::{get_ica_address, get_total_primitive_shares}, - ibc_util::do_transfer, - icq::try_icq, - state::{ - OngoingDeposit, RawAmount, BONDING_CLAIMS, BOND_QUEUE, CONFIG, FAILED_JOIN_QUEUE, - ICA_CHANNEL, PENDING_BOND_QUEUE, REJOIN_QUEUE, SHARES, - }, -}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct Bond { - pub amount: Uint128, - pub owner: Addr, - pub bond_id: String, -} - -// A deposit starts of by querying the state of the ica counterparty contract -pub fn do_bond( - storage: &mut dyn Storage, - querier: QuerierWrapper, - env: Env, - amount: Uint128, - sender: Addr, - bond_id: String, -) -> Result, ContractError> { - // check that our bond-id is not a duplicate from a pending bond - let pending: StdResult> = PENDING_BOND_QUEUE.iter(storage)?.collect(); - if pending? - .iter() - .any(|bond| bond.owner == sender && bond_id == bond.bond_id) - { - return Err(ContractError::DuplicateKey); - } - - // check that our bond-id is not a duplicate in the actual bond queue - let pending: StdResult> = BOND_QUEUE.iter(storage)?.collect(); - if pending? - .iter() - .any(|bond| bond.owner == sender && bond_id == bond.bond_id) - { - return Err(ContractError::DuplicateKey); - } - - PENDING_BOND_QUEUE.push_back( - storage, - &Bond { - amount, - owner: sender, - bond_id, - }, - )?; - - // TODO: move this to the execute_bond function - try_icq(storage, querier, env) -} - -// after the balance query, we can calculate the amount of the claim we need to create, we update the claims and transfer the funds -pub fn batch_bond( - storage: &mut dyn Storage, - env: &Env, - total_vault_value: Uint128, -) -> Result, ContractError> { - let transfer_chan = CONFIG.load(storage)?.transfer_channel; - let to_address = get_ica_address(storage, ICA_CHANNEL.load(storage)?)?; - - if let Some((amount, deposits)) = fold_bonds(storage, total_vault_value)? { - if amount.is_zero() { - Ok(None) - } else { - Ok(Some(do_transfer( - storage, - env, - amount, - transfer_chan, - to_address, - deposits, - )?)) - } - } else { - Ok(None) - } -} - -/// fold_bonds folds the queue and attributes shares to the depositors according to the given total value -pub fn fold_bonds( - storage: &mut dyn Storage, - total_balance: Uint128, -) -> Result)>, ContractError> { - let mut total = Uint128::zero(); - let mut deposits: Vec = vec![]; - - if BOND_QUEUE.is_empty(storage)? && FAILED_JOIN_QUEUE.is_empty(storage)? { - return Ok(None); - } - - while !BOND_QUEUE.is_empty(storage)? { - let item: Bond = - BOND_QUEUE - .pop_front(storage)? - .ok_or(ContractError::QueueItemNotFound { - queue: "bond".to_string(), - })?; - let claim_amount = create_claim( - storage, - item.amount, - &item.owner, - &item.bond_id, - total_balance, - )?; - total = total - .checked_add(item.amount) - .map_err(|err| ContractError::TracedOverflowError(err, "fold_bonds".to_string()))?; - deposits.push(OngoingDeposit { - claim_amount, - owner: item.owner, - raw_amount: RawAmount::LocalDenom(item.amount), - bond_id: item.bond_id, - }); - } - - while !FAILED_JOIN_QUEUE.is_empty(storage)? { - let item: Bond = - FAILED_JOIN_QUEUE - .pop_front(storage)? - .ok_or(ContractError::QueueItemNotFound { - queue: "failed_join".to_string(), - })?; - let claim_amount = create_claim( - storage, - item.amount, - &item.owner, - &item.bond_id, - total_balance, - )?; - - REJOIN_QUEUE.push_back( - storage, - &OngoingDeposit { - claim_amount, - owner: item.owner, - raw_amount: RawAmount::LocalDenom(item.amount), - bond_id: item.bond_id, - }, - )?; - } - - Ok(Some((total, deposits))) -} - -// create_claim -pub fn create_claim( - storage: &mut dyn Storage, - user_balance: Uint128, - address: &Addr, - bond_id: &str, - total_balance: Uint128, -) -> Result { - let total_shares = get_total_primitive_shares(storage)?; - - // calculate the correct size of the claim - let claim_amount = calculate_claim(user_balance, total_balance, total_shares)?; - BONDING_CLAIMS.save(storage, (address, bond_id), &claim_amount)?; - Ok(claim_amount) -} - -// create a share and remove the amount from the claim -pub fn create_share( - storage: &mut dyn Storage, - owner: &Addr, - bond_id: &str, - amount: Uint128, -) -> Result { - let claim = BONDING_CLAIMS.load(storage, (owner, bond_id))?; - - match claim.cmp(&amount) { - Ordering::Less => return Err(ContractError::InsufficientClaims), - Ordering::Equal => BONDING_CLAIMS.remove(storage, (owner, bond_id)), - Ordering::Greater => BONDING_CLAIMS.save( - storage, - (owner, bond_id), - &claim.checked_sub(amount).map_err(|err| { - ContractError::TracedOverflowError(err, "create_share".to_string()) - })?, - )?, - } - - // TODO do we want to make shares fungible using cw20? if so, call into the minter and mint shares for the according to the claim - SHARES.update( - storage, - owner.clone(), - |old| -> Result { - if let Some(existing) = old { - Ok(existing.checked_add(amount).map_err(|err| { - ContractError::TracedOverflowError( - err, - "create_share_update_shares".to_string(), - ) - })?) - } else { - Ok(amount) - } - }, - )?; - Ok(claim) -} - -/// calculate the amount of for the claim of the user -/// user_shares = (user_balance / vault_balance) * vault_total_shares = (user_balance * vault_total_shares) / vault_balance -/// if the total_shares are zero, independant of the total_balance, the user shoudl get user_balance amount of shares -/// if the total_balance is zero, what do we do?, for now the same as if total_shares is zero -/// ```rust -/// # use cosmwasm_std::Uint128; -/// # use lp_strategy::bond::calculate_claim; -/// -/// # fn calculate_claim_works() { -/// let val = calculate_claim(Uint128::new(10), Uint128::new(100), Uint128::new(10)).unwrap(); -/// assert_eq!(val, Uint128::one()) -/// # } -/// ``` -pub fn calculate_claim( - user_balance: Uint128, - total_balance: Uint128, - total_shares: Uint128, -) -> Result { - if total_shares == Uint128::zero() || total_balance == Uint128::zero() { - Ok(user_balance) - } else { - Ok(user_balance.checked_multiply_ratio(total_shares, total_balance)?) - } -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, MockQuerier}, - to_json_binary, CosmosMsg, Empty, IbcMsg, IbcTimeout, - }; - - use crate::{ - ibc_lock::Lock, - icq::prepare_full_query, - state::{LpCache, IBC_LOCK, ICQ_CHANNEL, LP_SHARES}, - test_helpers::default_setup, - }; - - use super::*; - - #[test] - fn calculate_claim_works() { - let val = calculate_claim(Uint128::new(10), Uint128::new(100), Uint128::new(10)).unwrap(); - assert_eq!(val, Uint128::one()) - } - - #[test] - fn do_bond_locked_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - let _config = CONFIG.load(deps.as_ref().storage).unwrap(); - let owner = Addr::unchecked("bob"); - - IBC_LOCK - .save(deps.as_mut().storage, &Lock::new().lock_bond()) - .unwrap(); - let id = "my-id"; - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = do_bond( - deps.as_mut().storage, - q, - env, - Uint128::new(1000), - owner, - id.to_string(), - ) - .unwrap(); - assert_eq!(res, None) - } - - #[test] - fn do_bond_unlocked_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - let _config = CONFIG.load(deps.as_ref().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - - LP_SHARES - .save( - deps.as_mut().storage, - &LpCache { - locked_shares: Uint128::new(100), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = do_bond( - deps.as_mut().storage, - q, - env.clone(), - Uint128::new(1000), - owner, - id.to_string(), - ) - .unwrap(); - assert!(res.is_some()); - - // mocking the pending bonds is real ugly here - let packet = prepare_full_query( - deps.as_mut().storage, - env.clone(), - Uint128::new(1000), - Uint128::zero(), - ) - .unwrap(); - - let icq_msg = CosmosMsg::Ibc(IbcMsg::SendPacket { - channel_id: ICQ_CHANNEL.load(deps.as_mut().storage).unwrap(), - data: to_json_binary(&packet).unwrap(), - timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(7200)), - }); - - assert_eq!(res.unwrap().msg, icq_msg) - } - - #[test] - fn do_bond_duplicate_id_fails() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - let _config = CONFIG.load(deps.as_ref().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - - LP_SHARES - .save( - deps.as_mut().storage, - &LpCache { - locked_shares: Uint128::new(100), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = do_bond( - deps.as_mut().storage, - q, - env.clone(), - Uint128::new(1000), - owner.clone(), - id.to_string(), - ) - .unwrap(); - assert!(res.is_some()); - - // bond with a duplicate id, we expect this to error - let err = do_bond( - deps.as_mut().storage, - q, - env, - Uint128::new(1000), - owner, - id.to_string(), - ) - .unwrap_err(); - assert_eq!(err, ContractError::DuplicateKey) - } - - #[test] - fn create_claim_works() { - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let user_balance = Uint128::new(10); - let total_balance = Uint128::new(100); - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(100)) - .unwrap(); - - let claim_amount = create_claim( - deps.as_mut().storage, - user_balance, - &owner, - id, - total_balance, - ) - .unwrap(); - assert_eq!(claim_amount, Uint128::new(10)); - assert_eq!( - BONDING_CLAIMS - .load(deps.as_ref().storage, (&owner, id)) - .unwrap(), - claim_amount - ); - } - - #[test] - fn create_exact_share_works() { - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let amount = Uint128::new(100); - - BONDING_CLAIMS - .save(deps.as_mut().storage, (&owner, id), &amount) - .unwrap(); - - create_share(deps.as_mut().storage, &owner, id, amount).unwrap(); - // the claim in BONDING_CLAIMS should have been deleted - assert_eq!( - BONDING_CLAIMS - .may_load(deps.as_ref().storage, (&owner, id)) - .unwrap(), - None - ); - - // we should have minted exactly 100 shares by now, - // we should have minted exactly 100 shares by now, - assert_eq!(SHARES.load(deps.as_ref().storage, owner).unwrap(), amount); - } - - #[test] - fn create_less_shares_works() { - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let amount = Uint128::new(100); - let smaller_amount = Uint128::new(99); - - BONDING_CLAIMS - .save(deps.as_mut().storage, (&owner, id), &amount) - .unwrap(); - - create_share(deps.as_mut().storage, &owner, id, smaller_amount).unwrap(); - // the claim in BONDING_CLAIMS should have been deleted - assert_eq!( - BONDING_CLAIMS - .may_load(deps.as_ref().storage, (&owner, id)) - .unwrap(), - Some(Uint128::one()) - ); - // we should have amount shares by now - assert_eq!( - SHARES.load(deps.as_ref().storage, owner).unwrap(), - smaller_amount - ); - } - - #[test] - fn create_too_many_shares_fails() { - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let amount = Uint128::new(100); - let incorrect_amount = Uint128::new(101); - - BONDING_CLAIMS - .save(deps.as_mut().storage, (&owner, id), &amount) - .unwrap(); - - let err = create_share(deps.as_mut().storage, &owner, id, incorrect_amount).unwrap_err(); - // we should not have created shares - assert_eq!(err, ContractError::InsufficientClaims); - // our bonding claim should still exist - assert_eq!( - BONDING_CLAIMS - .load(deps.as_ref().storage, (&owner, id)) - .unwrap(), - amount - ) - } - - #[test] - fn empty_fold_bonds_works() { - let mut deps = mock_dependencies(); - let total_balance = Uint128::new(150); - // we don't have any bonds to setup - - let res = fold_bonds(deps.as_mut().storage, total_balance).unwrap(); - assert_eq!(res, None) - } - - #[test] - fn filled_fold_bonds_works() { - let mut deps = mock_dependencies(); - let total_balance = Uint128::new(150); - let bonds = vec![ - Bond { - amount: Uint128::new(34), - owner: Addr::unchecked("person1"), - bond_id: "id1".to_string(), - }, - Bond { - amount: Uint128::new(50), - owner: Addr::unchecked("person2"), - bond_id: "id2".to_string(), - }, - Bond { - amount: Uint128::new(2), - owner: Addr::unchecked("person3"), - bond_id: "id3".to_string(), - }, - Bond { - amount: Uint128::new(7), - owner: Addr::unchecked("person4"), - bond_id: "id4".to_string(), - }, - Bond { - amount: Uint128::new(57), - owner: Addr::unchecked("person5"), - bond_id: "id5".to_string(), - }, - ]; - for b in &bonds { - BOND_QUEUE.push_back(deps.as_mut().storage, b).unwrap(); - } - - let (total, ongoing) = fold_bonds(deps.as_mut().storage, total_balance) - .unwrap() - .unwrap(); - assert_eq!(total_balance, total); - for (i, b) in bonds.iter().enumerate() { - assert_eq!(ongoing[i].bond_id, b.bond_id); - assert_eq!(ongoing[i].owner, b.owner); - - assert_eq!(ongoing[i].claim_amount, b.amount) - } - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/contract.rs b/smart-contracts/contracts/lp-strategy/src/contract.rs deleted file mode 100644 index 3466a5ec3..000000000 --- a/smart-contracts/contracts/lp-strategy/src/contract.rs +++ /dev/null @@ -1,1331 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - from_json, Attribute, DepsMut, Env, IbcMsg, IbcPacketAckMsg, MessageInfo, QuerierWrapper, - Reply, Response, Storage, Uint128, -}; -use cw2::set_contract_version; -use cw_utils::{must_pay, nonpayable}; - -use quasar_types::ibc::IcsAck; - -use crate::admin::{add_lock_admin, check_depositor, is_lock_admin, remove_lock_admin}; -use crate::bond::do_bond; -use crate::error::{ContractError, Trap}; -use crate::execute::execute_retry; -use crate::helpers::{create_callback_submsg, is_contract_admin, lock_try_icq, SubMsgKind}; -use crate::ibc::{handle_failing_ack, handle_succesful_ack, on_packet_timeout}; -use crate::ibc_lock::{IbcLock, Lock}; -use crate::ibc_util::{do_ibc_join_pool_swap_extern_amount_in, do_transfer}; -use crate::icq::try_icq; -use crate::msg::{ExecuteMsg, InstantiateMsg, LockOnly, MigrateMsg, UnlockOnly}; -use crate::reply::{handle_ack_reply, handle_callback_reply, handle_ibc_reply}; -use crate::start_unbond::{do_start_unbond, StartUnbond}; -use crate::state::{ - Config, LpCache, OngoingDeposit, PendingBond, RawAmount, ADMIN, BOND_QUEUE, CONFIG, DEPOSITOR, - FAILED_JOIN_QUEUE, IBC_LOCK, ICA_CHANNEL, LP_SHARES, PENDING_ACK, REPLIES, RETURNING, - START_UNBOND_QUEUE, TIMED_OUT, TOTAL_VAULT_BALANCE, TRAPS, UNBOND_QUEUE, -}; -use crate::unbond::{do_unbond, finish_unbond, PendingReturningUnbonds}; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:lp-strategy"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - _env: Env, - info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // check valid token info - msg.validate()?; - - // ADMIN here is only used to decide who can deposit - ADMIN.save(deps.storage, &info.sender)?; - - CONFIG.save( - deps.storage, - &Config { - lock_period: msg.lock_period, - pool_id: msg.pool_id, - pool_denom: msg.pool_denom, - base_denom: msg.base_denom, - local_denom: msg.local_denom, - quote_denom: msg.quote_denom, - return_source_channel: msg.return_source_channel, - transfer_channel: msg.transfer_channel, - expected_connection: msg.expected_connection, - }, - )?; - - IBC_LOCK.save(deps.storage, &Lock::new())?; - - // OSMO_LOCK.save(deps.storage, &u64::MAX)?; - - LP_SHARES.save( - deps.storage, - &LpCache { - locked_shares: Uint128::zero(), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - )?; - - TOTAL_VAULT_BALANCE.save(deps.storage, &Uint128::zero())?; - - TIMED_OUT.save(deps.storage, &false)?; - - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - // Save the ibc message together with the sequence number, to be handled properly later at the ack, we can pass the ibc_kind one to one - // TODO this needs and error check and error handling - let reply = REPLIES.load(deps.storage, msg.id)?; - match reply { - SubMsgKind::Ibc(pending, channel) => handle_ibc_reply(deps, msg, pending, channel), - SubMsgKind::Ack(seq, channel) => handle_ack_reply(deps, msg, seq, channel), - SubMsgKind::Callback(_callback) => handle_callback_reply(deps, msg, _callback), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Bond { id } => execute_bond(deps, env, info, id), - ExecuteMsg::StartUnbond { id, share_amount } => { - execute_start_unbond(deps, env, info, id, share_amount) - } - ExecuteMsg::Unbond { id } => execute_unbond(deps, env, info, id), - ExecuteMsg::AcceptReturningFunds { id, pending } => { - execute_accept_returning_funds(deps.storage, deps.querier, info, id, pending) - } - ExecuteMsg::CloseChannel { channel_id } => execute_close_channel(deps, channel_id), - ExecuteMsg::Ack { ack } => execute_ack(deps, env, info, ack), - ExecuteMsg::TryIcq {} => execute_try_icq(deps, env), - ExecuteMsg::SetDepositor { depositor } => execute_set_depositor(deps, info, depositor), - ExecuteMsg::Unlock { unlock_only } => execute_unlock(deps, env, info, unlock_only), - ExecuteMsg::Lock { lock_only } => execute_lock(deps, env, info, lock_only), - ExecuteMsg::ManualTimeout { - seq, - channel, - should_unlock, - } => manual_timeout(deps, env, info, seq, channel, should_unlock), - ExecuteMsg::AddLockAdmin { to_add } => execute_add_lock_admin(deps, env, info, to_add), - ExecuteMsg::RemoveLockAdmin { to_remove } => { - execute_remove_lock_admin(deps, env, info, to_remove) - } - ExecuteMsg::Retry { seq, channel } => execute_retry(deps, env, info, seq, channel), - } -} - -pub fn execute_add_lock_admin( - deps: DepsMut, - env: Env, - info: MessageInfo, - to_add: String, -) -> Result { - add_lock_admin( - deps.storage, - &deps.querier, - &env, - info.sender, - deps.api.addr_validate(to_add.as_str())?, - )?; - Ok(Response::new() - .add_attribute("action", "add_lock_admin") - .add_attribute("lock_admin", to_add)) -} - -pub fn execute_remove_lock_admin( - deps: DepsMut, - env: Env, - info: MessageInfo, - to_add: String, -) -> Result { - remove_lock_admin( - deps.storage, - &deps.querier, - &env, - info.sender, - deps.api.addr_validate(to_add.as_str())?, - )?; - Ok(Response::new() - .add_attribute("action", "remove_lock_admin") - .add_attribute("lock_admin", to_add)) -} - -pub fn execute_lock( - deps: DepsMut, - env: Env, - info: MessageInfo, - lock_only: LockOnly, -) -> Result { - is_lock_admin(deps.storage, &deps.querier, &env, &info.sender)?; - let mut lock = IBC_LOCK.load(deps.storage)?; - - match lock_only { - LockOnly::Bond => lock = lock.lock_bond(), - LockOnly::StartUnbond => lock = lock.lock_start_unbond(), - LockOnly::Unbond => lock = lock.lock_unbond(), - LockOnly::Migration => lock = lock.lock_migration(), - }; - IBC_LOCK.save(deps.storage, &lock)?; - - Ok(Response::new().add_attribute("lock_only", lock_only.to_string())) -} - -pub fn execute_unlock( - deps: DepsMut, - env: Env, - info: MessageInfo, - unlock_only: UnlockOnly, -) -> Result { - is_lock_admin(deps.storage, &deps.querier, &env, &info.sender)?; - let mut lock = IBC_LOCK.load(deps.storage)?; - - match unlock_only { - UnlockOnly::Bond => lock = lock.unlock_bond(), - UnlockOnly::StartUnbond => lock = lock.unlock_start_unbond(), - UnlockOnly::Unbond => lock = lock.unlock_unbond(), - UnlockOnly::Migration => lock = lock.unlock_migration(), - }; - IBC_LOCK.save(deps.storage, &lock)?; - - Ok(Response::new().add_attribute("unlock_only", unlock_only.to_string())) -} - -pub fn manual_timeout( - deps: DepsMut, - env: Env, - info: MessageInfo, - sequence: u64, - channel: String, - should_unlock: bool, -) -> Result { - is_contract_admin(&deps.querier, &env, &info.sender)?; - - let response = on_packet_timeout( - deps, - sequence, - channel, - "timeout".to_string(), - should_unlock, - )?; - - Ok(Response::new() - .add_attributes(response.attributes) - .add_events(response.events) - .add_submessages(response.messages)) -} - -pub fn execute_set_depositor( - deps: DepsMut, - info: MessageInfo, - depositor: String, -) -> Result { - if info.sender == ADMIN.load(deps.storage)? { - let depositor_addr = deps.api.addr_validate(depositor.as_str())?; - DEPOSITOR.save(deps.storage, &depositor_addr)?; - Ok(Response::new().add_attribute("set-depositor", depositor)) - } else { - Err(ContractError::Unauthorized) - } -} - -pub fn execute_try_icq(deps: DepsMut, env: Env) -> Result { - // if we're unlocked, we can empty the queues and send the submessages - let mut lock = IBC_LOCK.load(deps.storage)?; - let sub_msg = try_icq(deps.storage, deps.querier, env)?; - let mut res = Response::new(); - - if let Some(sub_msg) = sub_msg { - if !BOND_QUEUE.is_empty(deps.storage)? { - lock.bond = IbcLock::Locked; - res = res.add_attribute("bond_queue", "locked"); - } else if !START_UNBOND_QUEUE.is_empty(deps.storage)? { - lock = lock.lock_start_unbond(); - res = res.add_attribute("start_unbond_queue", "locked"); - } else if !UNBOND_QUEUE.is_empty(deps.storage)? { - lock = lock.lock_unbond(); - res = res.add_attribute("unbond_queue", "locked"); - } - if lock.is_unlocked() { - res = res.add_attribute("IBC_LOCK", "unlocked"); - } - IBC_LOCK.save(deps.storage, &lock)?; - res = res.add_submessage(sub_msg); - } else { - res = res.add_attribute("IBC_LOCK", "locked"); - } - Ok(res) -} - -pub fn execute_ack( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: IbcPacketAckMsg, -) -> Result { - if env.contract.address != info.sender { - return Err(ContractError::Unauthorized); - } - - // TODO: trap error like in receive? - // pro's acks happen anyway, cons? - let ack: IcsAck = from_json(&msg.acknowledgement.data)?; - match ack { - IcsAck::Result(val) => handle_succesful_ack(deps, env, msg, val), - IcsAck::Error(err) => handle_failing_ack(deps, env, msg, err), - } -} - -pub fn execute_accept_returning_funds( - storage: &mut dyn Storage, - querier: QuerierWrapper, - info: MessageInfo, - id: u64, - pending: PendingReturningUnbonds, -) -> Result { - let returning_amount = RETURNING - .may_load(storage, id)? - .ok_or(ContractError::ReturningTransferNotFound)?; - - let amount = must_pay(&info, CONFIG.load(storage)?.local_denom.as_str())?; - if amount != returning_amount { - return Err(ContractError::ReturningTransferIncorrectAmount); - } - - let mut callback_submsgs = vec![]; - for unbond in pending.unbonds.iter() { - let cosmos_msg = finish_unbond(storage, querier, unbond)?; - callback_submsgs.push(create_callback_submsg( - storage, - cosmos_msg, - unbond.owner.clone(), - unbond.id.clone(), - )?) - } - - Ok(Response::new() - .add_attribute("callback-submsgs", callback_submsgs.len().to_string()) - .add_attribute("returning-transfer", id.to_string()) - .add_attribute("success", "true") - .add_submessages(callback_submsgs)) -} - -pub fn execute_bond( - deps: DepsMut, - env: Env, - info: MessageInfo, - id: String, -) -> Result { - if !check_depositor(deps.storage, &info.sender)? { - return Err(ContractError::Unauthorized); - } - - let amount = must_pay(&info, &CONFIG.load(deps.storage)?.local_denom)?; - - let msg = do_bond( - deps.storage, - deps.querier, - env, - amount, - info.sender.clone(), - id, - )?; - - // if msg is some, we are dispatching an icq - let attributes = vec![ - Attribute::new("action", "bond"), - Attribute::new("sender", info.sender), - Attribute::new("token_amount", amount), - ]; - - let res = lock_try_icq(deps, msg)?; - Ok(res.add_attributes(attributes)) -} - -pub fn execute_start_unbond( - deps: DepsMut, - env: Env, - info: MessageInfo, - id: String, - share_amount: Uint128, -) -> Result { - nonpayable(&info)?; - - if !check_depositor(deps.storage, &info.sender)? { - return Err(ContractError::Unauthorized); - } - - do_start_unbond( - deps.storage, - StartUnbond { - owner: info.sender.clone(), - id: id.clone(), - primitive_shares: share_amount, - }, - )?; - - let msg = try_icq(deps.storage, deps.querier, env)?; - - let attributes = vec![ - Attribute::new("action", "start-unbond"), - Attribute::new("sender", info.sender), - Attribute::new("prim_share_amount", share_amount), - Attribute::new("unbond_id", id), - ]; - - let res = lock_try_icq(deps, msg)?; - Ok(res.add_attributes(attributes)) -} - -pub fn execute_unbond( - deps: DepsMut, - env: Env, - info: MessageInfo, - id: String, -) -> Result { - nonpayable(&info)?; - - if !check_depositor(deps.storage, &info.sender)? { - return Err(ContractError::Unauthorized); - } - - do_unbond(deps.storage, &env, info.sender.clone(), id.clone())?; - - let msg = try_icq(deps.storage, deps.querier, env)?; - - let attributes = vec![ - Attribute::new("action", "unbond"), - Attribute::new("sender", info.sender), - Attribute::new("unbond_id", id), - ]; - - let res = lock_try_icq(deps, msg)?; - Ok(res.add_attributes(attributes)) -} - -// transfer funds sent to the contract to an address on osmosis, this call ignores the lock system -pub fn execute_transfer( - deps: DepsMut, - env: Env, - info: MessageInfo, - channel: String, - to_address: String, -) -> Result { - let amount = must_pay(&info, &CONFIG.load(deps.storage)?.local_denom)?; - - let transfer = do_transfer( - deps.storage, - &env, - amount, - channel.clone(), - to_address.clone(), - // add a dummy ongoing deposit, actual ongoing deposit should calculate the claim using the total balance - vec![OngoingDeposit { - claim_amount: amount, - owner: info.sender, - raw_amount: RawAmount::LocalDenom(amount), - bond_id: "id".to_string(), - }], - )?; - - Ok(Response::new() - .add_submessage(transfer) - .add_attribute("ibc-tranfer-channel", channel) - .add_attribute("ibc-transfer-receiver", to_address)) -} - -pub fn execute_join_pool( - deps: DepsMut, - env: Env, - info: MessageInfo, - pool_id: u64, - denom: String, - amount: Uint128, - share_out_min_amount: Uint128, -) -> Result { - let join = do_ibc_join_pool_swap_extern_amount_in( - deps.storage, - env, - pool_id, - denom.clone(), - amount, - share_out_min_amount, - // add a dummy ongoing deposit, actual ongoing deposit should calculate the claim using the total balance - vec![OngoingDeposit { - claim_amount: amount, - owner: info.sender, - raw_amount: RawAmount::LocalDenom(amount), - bond_id: "id".to_string(), - }], - )?; - - Ok(Response::new() - .add_submessage(join) - .add_attribute("denom", denom)) -} - -pub fn execute_close_channel(deps: DepsMut, channel_id: String) -> Result { - if TIMED_OUT.load(deps.storage)? && channel_id == ICA_CHANNEL.load(deps.storage)? { - Ok(Response::new().add_message(IbcMsg::CloseChannel { channel_id })) - } else { - Err(ContractError::IcaChannelAlreadySet) - } -} - -// It's recommended to migrate either pending acks or traps, not both at the same time! -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { - // remove old traps - for key in msg.delete_traps.clone() { - TRAPS.remove(deps.storage, key) - } - - // remove old pending acks - for key in msg.delete_pending_acks.clone() { - PENDING_ACK.remove(deps.storage, key) - } - - // add a new fresh unlocked ibc lock - IBC_LOCK.save(deps.storage, &Lock::new())?; - - let mut fjq = vec![]; - while !FAILED_JOIN_QUEUE.is_empty(deps.storage)? { - let fj = FAILED_JOIN_QUEUE.pop_front(deps.storage)?; - fjq.push(fj.unwrap()); - } - - if !fjq.is_empty() { - TRAPS.save( - deps.storage, - (1, "undefined-purge".to_string()), - &Trap { - error: "rejoin purge".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: fjq - .into_iter() - .map(|b| OngoingDeposit { - claim_amount: Uint128::new(1), - raw_amount: RawAmount::LocalDenom(b.amount), - owner: b.owner, - bond_id: b.bond_id, - }) - .collect(), - }), - ), - last_succesful: false, - }, - )?; - } - - Ok(Response::new() - .add_attribute("migrate", CONTRACT_NAME) - .add_attribute("success", "true") - .add_attribute("deleted_traps", msg.delete_traps.len().to_string()) - .add_attribute( - "deleted_pending_acks", - msg.delete_pending_acks.len().to_string(), - )) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - attr, coins, - testing::{mock_dependencies, mock_env, mock_info, MockQuerier}, - to_json_binary, Addr, ContractInfoResponse, ContractResult, QuerierResult, Timestamp, - WasmQuery, - }; - use cw_utils::PaymentError; - - use crate::{ - bond::Bond, - error::Trap, - queries::handle_trapped_errors_query, - state::{PendingBond, Unbond, LOCK_ADMIN, SHARES, UNBONDING_CLAIMS}, - test_helpers::default_setup, - }; - - use super::*; - - #[test] - fn migrate_purges_queue() { - let env = mock_env(); - let mut deps = mock_dependencies(); - - FAILED_JOIN_QUEUE - .push_back( - deps.as_mut().storage, - &Bond { - amount: Uint128::new(101), - owner: Addr::unchecked("vault"), - bond_id: "1".to_string(), - }, - ) - .unwrap(); - FAILED_JOIN_QUEUE - .push_back( - deps.as_mut().storage, - &Bond { - amount: Uint128::new(101), - owner: Addr::unchecked("vault"), - bond_id: "1".to_string(), - }, - ) - .unwrap(); - FAILED_JOIN_QUEUE - .push_back( - deps.as_mut().storage, - &Bond { - amount: Uint128::new(101), - owner: Addr::unchecked("vault"), - bond_id: "1".to_string(), - }, - ) - .unwrap(); - - let msg = MigrateMsg { - delete_traps: vec![], - delete_pending_acks: vec![], - }; - - migrate(deps.as_mut(), env, msg).unwrap(); - assert!(FAILED_JOIN_QUEUE.is_empty(deps.as_mut().storage).unwrap()); - assert_eq!( - handle_trapped_errors_query(deps.as_ref()) - .unwrap() - .errors - .len(), - 1 - ); - } - - #[test] - fn migrate_msg_works_for_pending_acks() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let entries = vec![ - ( - (1, "channel-1".to_string()), - crate::helpers::IbcMsgKind::Ica(crate::helpers::IcaMessages::ExitPool( - PendingReturningUnbonds { unbonds: vec![] }, - )), - ), - ( - (2, "channel-1".to_string()), - crate::helpers::IbcMsgKind::Ica(crate::helpers::IcaMessages::ExitPool( - PendingReturningUnbonds { unbonds: vec![] }, - )), - ), - ( - (1, "channel-3".to_string()), - crate::helpers::IbcMsgKind::Ica(crate::helpers::IcaMessages::ExitPool( - PendingReturningUnbonds { unbonds: vec![] }, - )), - ), - ( - (1, "channel-1".to_string()), - crate::helpers::IbcMsgKind::Icq, - ), - ( - (1, "channel-2".to_string()), - crate::helpers::IbcMsgKind::Icq, - ), - ( - (1, "channel-4".to_string()), - crate::helpers::IbcMsgKind::Icq, - ), - ]; - - for (key, value) in entries.clone() { - PENDING_ACK - .save(deps.as_mut().storage, key, &value) - .unwrap(); - } - - let msg = MigrateMsg { - delete_traps: vec![], - delete_pending_acks: entries.iter().map(|(key, _)| key.clone()).collect(), - }; - - let res = migrate(deps.as_mut(), env, msg.clone()).unwrap(); - assert!(PENDING_ACK.is_empty(deps.as_ref().storage)); - assert_eq!(res.attributes[2].value, "0".to_string()); - assert_eq!( - res.attributes[3].value, - msg.delete_pending_acks.len().to_string() - ); - } - - #[test] - fn migrate_msg_works_for_traps() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let entries = vec![ - ( - (1, "channel-1".to_string()), - Trap { - error: "some_error".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: vec![], - }), - ), - last_succesful: true, - }, - ), - ( - (2, "channel-10".to_string()), - Trap { - error: "some_error".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: vec![OngoingDeposit { - claim_amount: Uint128::new(100), - owner: Addr::unchecked("juan".to_string()), - raw_amount: RawAmount::LocalDenom(Uint128::new(100)), - bond_id: "bond_id_1".to_string(), - }], - }), - ), - last_succesful: true, - }, - ), - ( - (3, "channel-100".to_string()), - Trap { - error: "some_error".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: vec![OngoingDeposit { - claim_amount: Uint128::new(100), - owner: Addr::unchecked("juan".to_string()), - raw_amount: RawAmount::LocalDenom(Uint128::new(100)), - bond_id: "bond_id_1".to_string(), - }], - }), - ), - last_succesful: false, - }, - ), - ]; - - for (key, value) in entries.clone() { - TRAPS.save(deps.as_mut().storage, key, &value).unwrap(); - } - - let msg = MigrateMsg { - delete_traps: entries.iter().map(|(key, _)| key.clone()).collect(), - delete_pending_acks: vec![], - }; - - let res = migrate(deps.as_mut(), env, msg.clone()).unwrap(); - assert!(TRAPS.is_empty(deps.as_ref().storage)); - assert_eq!(res.attributes[2].value, msg.delete_traps.len().to_string()); - assert_eq!(res.attributes[3].value, "0".to_string()); - } - - #[test] - fn migrate_msg_works_for_traps_and_pending_acks_combined() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let pending_acks_entries = vec![ - ( - (1, "channel-1".to_string()), - crate::helpers::IbcMsgKind::Ica(crate::helpers::IcaMessages::ExitPool( - PendingReturningUnbonds { unbonds: vec![] }, - )), - ), - ( - (2, "channel-1".to_string()), - crate::helpers::IbcMsgKind::Ica(crate::helpers::IcaMessages::ExitPool( - PendingReturningUnbonds { unbonds: vec![] }, - )), - ), - ( - (1, "channel-3".to_string()), - crate::helpers::IbcMsgKind::Ica(crate::helpers::IcaMessages::ExitPool( - PendingReturningUnbonds { unbonds: vec![] }, - )), - ), - ( - (1, "channel-1".to_string()), - crate::helpers::IbcMsgKind::Icq, - ), - ( - (1, "channel-2".to_string()), - crate::helpers::IbcMsgKind::Icq, - ), - ( - (1, "channel-4".to_string()), - crate::helpers::IbcMsgKind::Icq, - ), - ]; - - for (key, value) in pending_acks_entries.clone() { - PENDING_ACK - .save(deps.as_mut().storage, key, &value) - .unwrap(); - } - - let trap_entries = vec![ - ( - (1, "channel-1".to_string()), - Trap { - error: "some_error".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: vec![], - }), - ), - last_succesful: true, - }, - ), - ( - (2, "channel-10".to_string()), - Trap { - error: "some_error".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: vec![OngoingDeposit { - claim_amount: Uint128::new(100), - owner: Addr::unchecked("juan".to_string()), - raw_amount: RawAmount::LocalDenom(Uint128::new(100)), - bond_id: "bond_id_1".to_string(), - }], - }), - ), - last_succesful: true, - }, - ), - ( - (3, "channel-100".to_string()), - Trap { - error: "some_error".to_string(), - step: crate::helpers::IbcMsgKind::Ica( - crate::helpers::IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: vec![OngoingDeposit { - claim_amount: Uint128::new(100), - owner: Addr::unchecked("juan".to_string()), - raw_amount: RawAmount::LocalDenom(Uint128::new(100)), - bond_id: "bond_id_1".to_string(), - }], - }), - ), - last_succesful: false, - }, - ), - ]; - - for (key, value) in trap_entries.clone() { - TRAPS.save(deps.as_mut().storage, key, &value).unwrap(); - } - - let msg = MigrateMsg { - delete_traps: trap_entries.iter().map(|(key, _)| key.clone()).collect(), - delete_pending_acks: pending_acks_entries - .iter() - .map(|(key, _)| key.clone()) - .collect(), - }; - - let res = migrate(deps.as_mut(), env, msg.clone()).unwrap(); - assert!(TRAPS.is_empty(deps.as_ref().storage)); - assert_eq!(res.attributes[2].value, msg.delete_traps.len().to_string()); - assert_eq!( - res.attributes[3].value, - msg.delete_pending_acks.len().to_string() - ); - } - - #[test] - fn test_execute_try_icq_ibc_locked() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new().lock_bond().lock_start_unbond().lock_unbond(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - let res = execute_try_icq(deps.as_mut(), env).unwrap(); - - assert_eq!(res.attributes[0], attr("IBC_LOCK", "locked")); - assert!(res.messages.is_empty()); - assert!(IBC_LOCK.load(&deps.storage).unwrap().is_locked()); - } - - #[test] - fn test_execute_try_icq_ibc_unlocked_all_queues_empty() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - - let res = execute_try_icq(deps.as_mut(), env).unwrap(); - - assert_eq!(res.attributes[0], attr("IBC_LOCK", "unlocked")); - assert!(IBC_LOCK.load(&deps.storage).unwrap().is_unlocked()); - } - - #[test] - fn test_execute_try_icq_ibc_locked_all_queues_filled() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new().lock_bond().lock_start_unbond().lock_unbond(); - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - BOND_QUEUE - .push_back( - &mut deps.storage, - &Bond { - amount: Uint128::one(), - owner: Addr::unchecked("juan".to_string()), - bond_id: "bond_id_1".to_string(), - }, - ) - .unwrap(); - START_UNBOND_QUEUE - .push_back( - &mut deps.storage, - &StartUnbond { - owner: Addr::unchecked("pepe".to_string()), - id: "bond_id_10".to_string(), - primitive_shares: Uint128::new(10), - }, - ) - .unwrap(); - UNBOND_QUEUE - .push_back( - &mut deps.storage, - &Unbond { - owner: Addr::unchecked("pedro".to_string()), - id: "bond_id_100".to_string(), - lp_shares: Uint128::new(1000), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - }, - ) - .unwrap(); - - let res = execute_try_icq(deps.as_mut(), env).unwrap(); - - assert_eq!(res.attributes[0], attr("IBC_LOCK", "locked")); - assert!(IBC_LOCK.load(&deps.storage).unwrap().is_locked()); - assert!(res.messages.is_empty()); - } - - #[test] - fn test_execute_try_icq_ibc_unlocked_bond_queue_full() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new(); - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - BOND_QUEUE - .push_back( - &mut deps.storage, - &Bond { - amount: Uint128::one(), - owner: Addr::unchecked("juan".to_string()), - bond_id: "bond_id_1".to_string(), - }, - ) - .unwrap(); - - let res = execute_try_icq(deps.as_mut(), env).unwrap(); - assert_eq!(res.attributes[0], attr("bond_queue", "locked")); - let lock = IBC_LOCK.load(&deps.storage).unwrap(); - assert!(lock.bond.is_locked()); - assert!(lock.start_unbond.is_unlocked()); - assert!(lock.unbond.is_unlocked()); - } - - #[test] - fn test_execute_try_icq_ibc_bond_queue_empty() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new(); - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - START_UNBOND_QUEUE - .push_back( - &mut deps.storage, - &StartUnbond { - owner: Addr::unchecked("pepe".to_string()), - id: "bond_id_10".to_string(), - primitive_shares: Uint128::new(10), - }, - ) - .unwrap(); - UNBOND_QUEUE - .push_back( - &mut deps.storage, - &Unbond { - owner: Addr::unchecked("pedro".to_string()), - id: "bond_id_100".to_string(), - lp_shares: Uint128::new(1000), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - }, - ) - .unwrap(); - - let res = execute_try_icq(deps.as_mut(), env).unwrap(); - assert_eq!(res.attributes[0], attr("start_unbond_queue", "locked")); - let lock = IBC_LOCK.load(&deps.storage).unwrap(); - assert!(lock.bond.is_unlocked()); - assert!(lock.start_unbond.is_locked()); - assert!(lock.unbond.is_unlocked()); - } - - #[test] - fn test_execute_unbond_filled_queues() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new(); - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - BOND_QUEUE - .push_back( - &mut deps.storage, - &Bond { - amount: Uint128::new(1000), - owner: Addr::unchecked("alice"), - bond_id: "3".to_string(), - }, - ) - .unwrap(); - START_UNBOND_QUEUE - .push_back( - &mut deps.storage, - &StartUnbond { - owner: Addr::unchecked("pepe".to_string()), - id: "bond_id_10".to_string(), - primitive_shares: Uint128::new(10), - }, - ) - .unwrap(); - - let id = "2".to_string(); - let owner = Addr::unchecked("bob"); - DEPOSITOR.save(deps.as_mut().storage, &owner).unwrap(); - - // unbond number are abitrary for this test - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (owner.clone(), id.clone()), - &Unbond { - lp_shares: Uint128::new(100), - unlock_time: env.block.time, - attempted: true, - owner: owner.clone(), - id: id.clone(), - }, - ) - .unwrap(); - - let res = execute_unbond( - deps.as_mut(), - env, - MessageInfo { - sender: owner, - funds: vec![], - }, - id, - ) - .unwrap(); - assert_eq!(res.attributes[0], attr("bond_queue", "locked")); - let lock = IBC_LOCK.load(&deps.storage).unwrap(); - assert!(lock.bond.is_locked()); - assert!(lock.start_unbond.is_unlocked()); - assert!(lock.unbond.is_unlocked()); - } - - #[test] - fn test_execute_unbond_filled_start_unbond_queue() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new(); - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - START_UNBOND_QUEUE - .push_back( - &mut deps.storage, - &StartUnbond { - owner: Addr::unchecked("pepe".to_string()), - id: "bond_id_10".to_string(), - primitive_shares: Uint128::new(10), - }, - ) - .unwrap(); - - let id = "2".to_string(); - let owner = Addr::unchecked("bob"); - DEPOSITOR.save(deps.as_mut().storage, &owner).unwrap(); - - // unbond number are abitrary for this test - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (owner.clone(), id.clone()), - &Unbond { - lp_shares: Uint128::new(100), - unlock_time: env.block.time, - attempted: true, - owner: owner.clone(), - id: id.clone(), - }, - ) - .unwrap(); - - let res = execute_unbond( - deps.as_mut(), - env, - MessageInfo { - sender: owner, - funds: vec![], - }, - id, - ) - .unwrap(); - assert_eq!(res.attributes[0], attr("start_unbond_queue", "locked")); - let lock = IBC_LOCK.load(&deps.storage).unwrap(); - assert!(lock.bond.is_unlocked()); - assert!(lock.start_unbond.is_locked()); - assert!(lock.unbond.is_unlocked()); - } - - #[test] - fn test_execute_start_unbond_filled_queues() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let mock_lock = Lock::new(); - default_setup(deps.as_mut().storage).unwrap(); - let lp_cache = LpCache { - locked_shares: Uint128::new(10), - w_unlocked_shares: Uint128::new(10), - d_unlocked_shares: Uint128::new(10), - }; - LP_SHARES.save(deps.as_mut().storage, &lp_cache).unwrap(); - IBC_LOCK.save(&mut deps.storage, &mock_lock).unwrap(); - - BOND_QUEUE - .push_back( - &mut deps.storage, - &Bond { - amount: Uint128::new(1000), - owner: Addr::unchecked("alice"), - bond_id: "3".to_string(), - }, - ) - .unwrap(); - UNBOND_QUEUE - .push_back( - &mut deps.storage, - &Unbond { - owner: Addr::unchecked("pedro".to_string()), - id: "bond_id_100".to_string(), - lp_shares: Uint128::new(1000), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - }, - ) - .unwrap(); - - let id = "2".to_string(); - let owner = Addr::unchecked("bob"); - DEPOSITOR.save(deps.as_mut().storage, &owner).unwrap(); - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(1000)) - .unwrap(); - - let res = execute_start_unbond( - deps.as_mut(), - env, - MessageInfo { - sender: owner, - funds: vec![], - }, - id, - Uint128::new(100), - ) - .unwrap(); - - assert_eq!(res.attributes[0], attr("bond_queue", "locked")); - let lock = IBC_LOCK.load(&deps.storage).unwrap(); - assert!(lock.bond.is_locked()); - assert!(lock.start_unbond.is_unlocked()); - assert!(lock.unbond.is_unlocked()); - } - - #[test] - fn test_start_unbond_with_funds() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let info = mock_info("pepe", &coins(420, "uqsr")); - let msg = ExecuteMsg::StartUnbond { - id: "bond_id_1".to_string(), - share_amount: Uint128::new(69), - }; - - let res = execute(deps.as_mut(), env, info, msg); - assert_eq!(res.unwrap_err(), PaymentError::NonPayable {}.into()); - } - - #[test] - fn test_unbond_with_funds() { - let mut deps = mock_dependencies(); - let env = mock_env(); - let info = mock_info("addr0000", &coins(420, "uqsr")); - let msg = ExecuteMsg::Unbond { - id: "unbond_id".to_string(), - }; - - let res = execute(deps.as_mut(), env, info, msg); - assert_eq!(res.unwrap_err(), PaymentError::NonPayable {}.into()); - } - - #[test] - fn test_execute_add_lock_admin() { - let admin = "bob"; - - let mut info = ContractInfoResponse::default(); - info.admin = Some(admin.to_string()); - let mut q = MockQuerier::default(); - q.update_wasm(move |q: &WasmQuery| -> QuerierResult { - match q { - WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Ok(ContractResult::Ok(to_json_binary(&info).unwrap())) - } - _ => unreachable!(), - } - }); - - let mut deps = mock_dependencies(); - deps.querier = q; - - let env = mock_env(); - - let info = MessageInfo { - sender: Addr::unchecked(admin), - funds: vec![], - }; - - let msg = ExecuteMsg::AddLockAdmin { - to_add: "alice".to_string(), - }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - let _ = LOCK_ADMIN - .load(deps.as_mut().storage, &Addr::unchecked("alice")) - .unwrap(); - assert_eq!( - res.attributes, - vec![("action", "add_lock_admin"), ("lock_admin", "alice")] - ) - } - - #[test] - fn test_execute_remove_lock_admin() { - let admin = "bob"; - - let mut info = ContractInfoResponse::default(); - info.admin = Some(admin.to_string()); - let mut q = MockQuerier::default(); - q.update_wasm(move |q: &WasmQuery| -> QuerierResult { - match q { - WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Ok(ContractResult::Ok(to_json_binary(&info).unwrap())) - } - _ => unreachable!(), - } - }); - - let mut deps = mock_dependencies(); - deps.querier = q; - - let env = mock_env(); - - let info = MessageInfo { - sender: Addr::unchecked(admin), - funds: vec![], - }; - - let msg = ExecuteMsg::AddLockAdmin { - to_add: "alice".to_string(), - }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - let _ = LOCK_ADMIN - .load(deps.as_mut().storage, &Addr::unchecked("alice")) - .unwrap(); - assert_eq!( - res.attributes, - vec![("action", "add_lock_admin"), ("lock_admin", "alice")] - ); - - let msg = ExecuteMsg::RemoveLockAdmin { - to_remove: "alice".to_string(), - }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - assert_eq!( - res.attributes, - vec![("action", "remove_lock_admin"), ("lock_admin", "alice")] - ) - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/error.rs b/smart-contracts/contracts/lp-strategy/src/error.rs deleted file mode 100644 index 48b2ba4cf..000000000 --- a/smart-contracts/contracts/lp-strategy/src/error.rs +++ /dev/null @@ -1,141 +0,0 @@ -use cosmwasm_std::{CheckedMultiplyRatioError, DivideByZeroError, OverflowError, StdError}; -use quasar_types::error::Error as QError; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt::Debug; - -use crate::helpers::IbcMsgKind; -use std::str::Utf8Error; -use thiserror::Error; - -/// Never is a placeholder to ensure we don't return any errors -#[derive(Error, Debug)] -pub enum Never {} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct Trap { - // A string describing the trapped error - pub error: String, - // the failed step and underlying values - pub step: IbcMsgKind, - // last_succesful notes whether the IbcMsg of step was succesful on the counterparty chain - pub last_succesful: bool, -} - -#[derive(Error, Debug, PartialEq)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Base(#[from] cw20_base::ContractError), - - #[error("{0}")] - QError(#[from] QError), - - #[error("map has duplicate key while no key should be present")] - DuplicateKey, - - #[error("caller is unauthorized")] - Unauthorized, - - #[error("{0}")] - PaymentError(#[from] cw_utils::PaymentError), - - #[error("not enough claims")] - InsufficientClaims, - - #[error("not enough funds")] - InsufficientFunds, - - #[error("base denom not found")] - BaseDenomNotFound, - - #[error("quote denom not found")] - QuoteDenomNotFound, - - #[error("No item in the queue {} while an item was expected", queue)] - QueueItemNotFound { queue: String }, - - #[error("no counterpart ica address found")] - NoCounterpartyIcaAddress, - - #[error("ica channel is already set while it should be unset")] - IcaChannelAlreadySet, - - #[error("channel is not an ica channel")] - NoIcaChannel, - - #[error("channel is not an icq channel")] - NoIcqChannel, - - #[error("no connection is found")] - NoConnectionFound, - - #[error("incorrect connection id")] - IncorrectConnection, - - #[error("incorrect channel open type, should be OpenInit")] - IncorrectChannelOpenType, - - #[error("raw ack in recovery could not be handled")] - IncorrectRecoveryAck, - - #[error("no timestamp time found for ibc packets")] - NoTimestampTime, - - #[error("reply data not found")] - NoReplyData, - - #[error("Could not deserialize ack: {err}, payload was {b64_bin}")] - DeserializeIcaAck { b64_bin: String, err: String }, - - #[error("Could not find returning transfer")] - ReturningTransferNotFound, - - #[error("amount of returning transfer is not the same as the expected amount")] - ReturningTransferIncorrectAmount, - - #[error("Shares are still unbonding")] - SharesNotYetUnbonded, - - #[error("found incorrect raw amount type")] - IncorrectRawAmount, - - #[error("{0}")] - DecodeError(#[from] prost::DecodeError), - - #[error("parse int error: {error} caused by {value}")] - ParseIntError { error: String, value: String }, - - #[error("parse int error: {error} caused by {value}")] - ParseDecError { error: StdError, value: String }, - - #[error("{0}")] - OverflowError(#[from] OverflowError), - - #[error("{0}, location {1}")] - TracedOverflowError(OverflowError, String), - - #[error("{0}")] - DivideByZeroError(#[from] DivideByZeroError), - - #[error("{0}")] - CheckedMultiplyRatioError(#[from] CheckedMultiplyRatioError), - - #[error("{0}")] - Utf8Error(#[from] Utf8Error), - - #[error("{0}")] - SerdeJsonDe(#[from] serde_json_wasm::de::Error), - - #[error("could not serialize to json")] - SerdeJsonSer, - - #[error("The Callback has no amount set")] - CallbackHasNoAmount, - - #[error("No pending unbonds found")] - NoPendingUnbonds, -} diff --git a/smart-contracts/contracts/lp-strategy/src/error_recovery.rs b/smart-contracts/contracts/lp-strategy/src/error_recovery.rs deleted file mode 100644 index fe5e9267b..000000000 --- a/smart-contracts/contracts/lp-strategy/src/error_recovery.rs +++ /dev/null @@ -1,298 +0,0 @@ -use cosmwasm_std::{ - from_json, Addr, DepsMut, Env, IbcAcknowledgement, Response, Storage, SubMsg, Uint128, -}; -use osmosis_std::types::osmosis::gamm::v1beta1::MsgJoinSwapExternAmountInResponse; -use quasar_types::{ - ibc::IcsAck, - ica::{packet::AckBody, traits::Unpack}, -}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::{ - error::ContractError, - helpers::{create_ibc_ack_submsg, IbcMsgKind, IcaMessages}, - ibc_util::calculate_token_out_min_amount, - state::{ - FundPath, LpCache, PendingBond, RawAmount, CONFIG, ICA_CHANNEL, LP_SHARES, RECOVERY_ACK, - TRAPS, - }, - unbond::do_exit_swap, -}; - -// start_recovery fetches an error from the TRAPPED_ERRORS and start the appropriate recovery from there -pub fn _start_recovery( - deps: DepsMut, - env: &Env, - error_sequence: u64, - channel: String, -) -> Result { - let error = TRAPS.load(deps.storage, (error_sequence, channel.clone()))?; - match error.last_succesful { - true => { - match error.step { - // if the transfer failed. The funds in pending are still located on Quasar, meaning we - crate::helpers::IbcMsgKind::Transfer { pending, amount } => { - // cleanup error state to prevent multiple error recoveries - TRAPS.remove(deps.storage, (error_sequence, channel)); - let msg = handle_transfer_recovery( - deps.storage, - env, - pending, - amount, - error_sequence, - )?; - Ok(Response::new() - .add_submessage(msg) - .add_attribute("error-recover-sequence", error_sequence.to_string()) - .add_attribute("error-recovery-value", error.last_succesful.to_string())) - } - crate::helpers::IbcMsgKind::Ica(_ica) => todo!(), - // if ICQ was the last successful step, all we failed trying to empty our queues and dispatching any following - // IBC messages, meaning we don't have to do anything with a seperate try_icq endpoint - crate::helpers::IbcMsgKind::Icq => unimplemented!(), - } - } - false => { - todo!() - } - } -} - -// amount is the total amount we will try to transfer back to quasar, pending bond is the users the funds should return back to -#[allow(dead_code)] -fn handle_transfer_recovery( - storage: &mut dyn Storage, - _env: &Env, - bonds: PendingBond, - _amount: Uint128, - trapped_id: u64, -) -> Result { - let _config = CONFIG.load(storage)?; - let returning: Result, ContractError> = bonds - .bonds - .iter() - .map(|bond| { - if let RawAmount::LocalDenom(val) = bond.raw_amount { - Ok(ReturningRecovery { - amount: RawAmount::LocalDenom(val), - owner: bond.owner.clone(), - id: FundPath::Bond { - id: bond.bond_id.clone(), - }, - }) - } else { - Err(ContractError::ReturningTransferIncorrectAmount) - } - }) - .collect(); - - let _returning = PendingReturningRecovery { - returning: returning?, - trapped_id, - }; - - // big TODO here, below should be modified for error recovery criteria - // leaving as todo because this code is not live yet. - // we want to call do_transfer_batch_unbond with the returning unbonds but in the context of error recovery - - // let msg = todo!(); - // Ok(create_ibc_ack_submsg( - // storage, - // IbcMsgKind::Ica(IcaMessages::RecoveryReturnTransfer(returning)), - // msg, - // _config.transfer_channel, - // )?) - todo!() -} - -fn _handle_last_succesful_ica_recovery( - storage: &mut dyn Storage, - env: &Env, - ica: IcaMessages, - _last_succesful: bool, - trapped_id: u64, -) -> Result { - match ica { - // in every succesful ica recovery, our last message was succesful, but our pending state is not, - // For a join swap, we need to exit all shares - IcaMessages::JoinSwapExternAmountIn(pending) => { - handle_join_swap_recovery(storage, env, pending, trapped_id) - } - IcaMessages::LockTokens(_, _) => todo!(), - IcaMessages::BeginUnlocking(_, _) => todo!(), - IcaMessages::ExitPool(_) => todo!(), - IcaMessages::ReturnTransfer(_) => todo!(), - IcaMessages::RecoveryExitPool(_) => todo!(), - IcaMessages::RecoveryReturnTransfer(_) => todo!(), - } -} -fn _handle_last_failed_ica_recovery( - _storage: &mut dyn Storage, - _env: &Env, - ica: IcaMessages, - _trapped_id: u64, -) -> Result { - match ica { - // recover by sending funds back - // since the ica failed, we should transfer the funds back, we do not yet expect a raw amount to be set to lp shares - // how do we know how much to return here? - IcaMessages::JoinSwapExternAmountIn(_pending) => { - todo!() - } - IcaMessages::LockTokens(_, _) => todo!(), - // if BeginUnlocking followup failed, our tokens, the amount of tokens in the request was actually succesful, - // so we continue to a recovery exit swap - IcaMessages::BeginUnlocking(_, _) => todo!(), - // if the exit pool was actually succesful, we need to deserialize the saved ack result again to get the amount of tokens - // users should get - // TODO, can they get rejoined to the lp pool here? Maybe???? - // probably gets compounded back again, how do we know here?, do we know at all? - // we let the exit pool get autocompounded by the contract again, to recover from here, we start a start_unlock for all stuck funds - IcaMessages::ExitPool(_pending) => { - todo!() - // let msg = do_begin_unlocking(storage, env, to_unbond)?; - } - // we just retry the transfer here - IcaMessages::ReturnTransfer(_) => todo!(), - // same as regular exit pool recovery - IcaMessages::RecoveryExitPool(_) => todo!(), - // same as regular transfer recovery - IcaMessages::RecoveryReturnTransfer(_) => todo!(), - } -} - -// kinda messed up that we create duplicate code here, should be solved with a single unpacking function that accepts -// a closure for IcsAck::Result and IcsAck::Error -#[allow(dead_code)] -fn de_succcesful_join( - ack_bin: IbcAcknowledgement, -) -> Result { - let ack: IcsAck = from_json(ack_bin.data)?; - if let IcsAck::Result(val) = ack { - let ack_body = AckBody::from_bytes(val.0.as_ref())?.to_any()?; - let ack = MsgJoinSwapExternAmountInResponse::unpack(ack_body)?; - Ok(ack) - } else { - Err(ContractError::IncorrectRecoveryAck) - } -} - -// if the join_swap was succesful, the refund path means we have to -#[allow(dead_code)] -fn handle_join_swap_recovery( - storage: &mut dyn Storage, - env: &Env, - pending: PendingBond, - trapped_id: u64, -) -> Result { - let channel = ICA_CHANNEL.load(storage)?; - let ack_bin = RECOVERY_ACK.load(storage, (trapped_id, channel.clone()))?; - // in this case the recovery ack should contain a joinswapexternamountin response - // we try to deserialize it - let join_result = de_succcesful_join(ack_bin)?; - - // we expect the total amount here to be in local_denom since, although the join was succesful - // the RawAmount cannot yet have been up updated - let total_lp = pending.bonds.iter().try_fold(Uint128::zero(), |acc, val| { - if let RawAmount::LocalDenom(amount) = val.raw_amount { - Ok(acc.checked_add(amount)?) - } else { - Err(ContractError::IncorrectRawAmount) - } - })?; - // now we need to divide up the lp shares amount our users according to the individual local denom amount - let exits_res: Result, ContractError> = pending - .bonds - .iter() - .map(|val| { - // since the ICA followup failed, we need to figure out how to convert - if let RawAmount::LocalDenom(amount) = val.raw_amount { - Ok(ReturningRecovery { - // lp_shares_i = tokens_i * lp_total / tokens_total - amount: RawAmount::LpShares(amount.checked_mul(total_lp)?.checked_div( - Uint128::new(join_result.share_out_amount.parse().map_err(|err| { - ContractError::ParseIntError { - error: format!("join_swap_recovery:{err}"), - value: join_result.share_out_amount.clone(), - } - })?), - )?), - owner: val.owner.clone(), - // since we are recovering from a join swap, we need do save - // as a Bond for bookkeeping on returned - id: FundPath::Bond { - id: val.bond_id.clone(), - }, - }) - } else { - Err(ContractError::IncorrectRawAmount) - } - }) - .collect(); - - let exits = exits_res?; - let total_exit: Uint128 = exits.iter().try_fold( - Uint128::zero(), - |acc, val| -> Result { - match val.amount { - RawAmount::LocalDenom(_) => unimplemented!(), - RawAmount::LpShares(amount) => Ok(amount.checked_add(acc)?), - } - }, - )?; - - LP_SHARES.update(storage, |mut old| -> Result { - // we remove the amount of shares we are are going to unlock from the locked amount - old.d_unlocked_shares = old.d_unlocked_shares.checked_sub(total_exit)?; - // we add the amount of shares we are going to unlock to the total unlocked - old.w_unlocked_shares = old.w_unlocked_shares.checked_add(total_exit)?; - Ok(old) - })?; - - let token_out_min_amount = calculate_token_out_min_amount(storage).unwrap(); - - let exit = do_exit_swap(storage, env, token_out_min_amount, total_exit)?; - Ok(create_ibc_ack_submsg( - storage, - IbcMsgKind::Ica(IcaMessages::RecoveryExitPool(PendingReturningRecovery { - returning: exits, - trapped_id, - })), - exit, - channel, - )?) -} - -// fn create_recovery_submsg( -// msg: IbcMsg, -// kind: IbcMsgKind -// ) -> Result { - -// } - -fn _handle_lock_recovery() {} - -fn _handle_begin_unlocking_recovery() {} - -fn _handle_exit_pool_recovery() {} - -fn _handle_return_transfer_recovery() {} - -// TODO refactor bonds/unbonds to a single struct item that is bidirectional with a direction enum -// because we did not abstract nicely, we need a separate struct here -// we should feel bad -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub struct PendingReturningRecovery { - pub returning: Vec, - pub trapped_id: u64, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub struct ReturningRecovery { - pub amount: RawAmount, - pub owner: Addr, - pub id: FundPath, -} diff --git a/smart-contracts/contracts/lp-strategy/src/execute.rs b/smart-contracts/contracts/lp-strategy/src/execute.rs deleted file mode 100644 index 2a3fa66cc..000000000 --- a/smart-contracts/contracts/lp-strategy/src/execute.rs +++ /dev/null @@ -1,1007 +0,0 @@ -use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; -use cw_utils::nonpayable; - -use crate::{ - bond::Bond, - error::ContractError, - helpers::{IbcMsgKind, IcaMessages}, - state::{PendingBond, RawAmount, FAILED_JOIN_QUEUE, TRAPS}, - unbond::{do_unbond, PendingReturningUnbonds}, -}; - -/// The retry entry point will be used to retry any failed ICA message given the sequence number and the channel. -/// Depending on the type of ICA message, the contract will handle the retry differently. -/// Funds cannot be sent and, for now, only the lock admin can call retry. -pub fn execute_retry( - deps: DepsMut, - env: Env, - info: MessageInfo, - seq: u64, - channel: String, -) -> Result { - nonpayable(&info)?; - // this endpoint is permissionless in order to allow anyone trigger a retry - let traps = TRAPS.load(deps.storage, (seq, channel.clone()))?; - match traps.step { - IbcMsgKind::Ica(ica_kind) => match ica_kind { - IcaMessages::ExitPool(pending) => { - handle_retry_exit_pool(deps, env, pending, seq, channel) - } - IcaMessages::JoinSwapExternAmountIn(pending) => { - handle_retry_join_pool(deps, env, pending, seq, channel) - } - IcaMessages::BeginUnlocking(pending, to_unbond) => { - handle_retry_begin_unlocking(deps, env, pending, to_unbond) - } - _ => todo!() - }, - _ => todo!(), - } -} - -pub fn handle_retry_join_pool( - deps: DepsMut, - _env: Env, - pending: PendingBond, - seq: u64, - channel: String, -) -> Result { - let mut resp = Response::new() - .add_attribute("action", "retry") - .add_attribute("kind", "join_pool"); - - for ongoing_deposit in pending.bonds { - match ongoing_deposit.raw_amount { - RawAmount::LocalDenom(amount) => { - FAILED_JOIN_QUEUE.push_back( - deps.storage, - &Bond { - amount, - owner: ongoing_deposit.owner.clone(), - bond_id: ongoing_deposit.bond_id.clone(), - }, - )?; - resp = resp - .add_attribute("bond_id", ongoing_deposit.bond_id) - .add_attribute("amount", amount); - } - // We should never have LP shares here - RawAmount::LpShares(_) => return Err(ContractError::IncorrectRawAmount), - } - } - - TRAPS.remove(deps.storage, (seq, channel)); - - Ok(resp) -} - -/// The handle retry exit pool checks that pending unbonds is not empty and then iterates over the pending unbonds vector. -/// For each unbond, it will check that unbond time has expired and push it to the front of the pending unbond queue. -/// A manual TryIcq will be needed to dispatch the IBC message. -pub fn handle_retry_exit_pool( - deps: DepsMut, - env: Env, - pending: PendingReturningUnbonds, - seq: u64, - channel: String, -) -> Result { - if pending.unbonds.is_empty() { - return Err(ContractError::NoPendingUnbonds); - } - - let mut resp = Response::new(); - - for pu in pending.unbonds { - do_unbond(deps.storage, &env, pu.owner.clone(), pu.id.clone())?; - resp = resp - .add_attribute("unbond", pu.owner.clone()) - .add_attribute("unbond_id", pu.id); - } - - resp = resp - .add_attribute("action", "retry") - .add_attribute("kind", "exit_pool"); - - // remove the entry from traps so retrying a single failed tx cannot be triggered twice - TRAPS.remove(deps.storage, (seq, channel)); - - Ok(resp) -} - -#[cfg(test)] -mod tests { - // use cosmos_sdk_proto::tendermint::abci::ResponseQuery; - use cosmwasm_std::{Binary, Coin, CosmosMsg, IbcMsg}; - use osmosis_std::types::cosmos::bank::v1beta1::QueryBalanceResponse; - use osmosis_std::types::{ - cosmos::base::v1beta1::Coin as OsmoCoin, osmosis::lockup::LockedResponse, - }; - - use cosmwasm_std::{ - attr, - testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, StdError, Timestamp, Uint128, - }; - use osmosis_std::types::osmosis::gamm::v1beta1::{ - QueryCalcExitPoolCoinsFromSharesResponse, QueryCalcJoinPoolSharesResponse, - QuerySpotPriceResponse, - }; - use prost::Message; - use quasar_types::icq::{CosmosResponse, InterchainQueryPacketAck}; - - use crate::ibc::handle_icq_ack; - use crate::state::{PENDING_BOND_QUEUE, REJOIN_QUEUE, SIMULATED_JOIN_AMOUNT_IN}; - use crate::test_helpers::{create_query_response, pending_bond_to_bond}; - use crate::{ - contract::execute_try_icq, - error::Trap, - ibc_lock::Lock, - state::{ - OngoingDeposit, RawAmount, Unbond, IBC_LOCK, PENDING_UNBOND_QUEUE, UNBONDING_CLAIMS, - }, - test_helpers::default_setup, - unbond::ReturningUnbond, - }; - - use super::*; - - #[test] - fn test_handle_retry_exit_pool_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(101)), - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(102)), - owner: Addr::unchecked("owner2"), - id: "2".to_string(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(103)), - owner: Addr::unchecked("owner3"), - id: "3".to_string(), - }, - ], - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "exit pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::ExitPool(pending)), - last_succesful: true, - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner1"), "1".to_string()), - &Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner2"), "2".to_string()), - &Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner2"), - id: "2".to_string(), - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner3"), "3".to_string()), - &Unbond { - lp_shares: Uint128::new(103), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner3"), - id: "3".to_string(), - }, - ) - .unwrap(); - - let res = execute_retry( - deps.as_mut(), - env, - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ) - .unwrap(); - - assert!(!TRAPS.has(&deps.storage, (3539, "channel-35".to_string()))); - - assert_eq!( - res.attributes, - vec![ - attr("unbond", "owner1"), - attr("unbond_id", "1"), - attr("unbond", "owner2"), - attr("unbond_id", "2"), - attr("unbond", "owner3"), - attr("unbond_id", "3"), - attr("action", "retry"), - attr("kind", "exit_pool"), - ] - ); - - assert_eq!(PENDING_UNBOND_QUEUE.len(&deps.storage).unwrap(), 3); - assert_eq!( - PENDING_UNBOND_QUEUE.back(&deps.storage).unwrap().unwrap(), - Unbond { - lp_shares: Uint128::new(103), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner3"), - id: "3".to_string(), - } - ); - } - - #[test] - fn test_handle_retry_exit_pool_empty_pending_unbonds_fails() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let pending = PendingReturningUnbonds { unbonds: vec![] }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "exit pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::ExitPool(pending)), - last_succesful: true, - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner1"), "1".to_string()), - &Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ) - .unwrap(); - - let res = execute_retry( - deps.as_mut(), - env, - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ) - .unwrap_err(); - - assert_eq!(res, ContractError::NoPendingUnbonds,); - assert!(PENDING_UNBOND_QUEUE.is_empty(&deps.storage).unwrap()); - } - - #[test] - fn test_handle_retry_exit_pool_without_all_unbonding_claims_fails() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(101)), - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(102)), - owner: Addr::unchecked("owner2"), - id: "2".to_string(), - }, - ], - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "exit pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::ExitPool(pending)), - last_succesful: true, - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner1"), "1".to_string()), - &Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ) - .unwrap(); - - let res = execute_retry( - deps.as_mut(), - env, - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ); - - assert!(res.is_err()); - - // even though the unbonding claim for owner2 is missing, the retry will still add the unbonding claim for owner1 - assert_eq!(PENDING_UNBOND_QUEUE.len(&deps.storage).unwrap(), 1); - assert_eq!( - PENDING_UNBOND_QUEUE.back(&deps.storage).unwrap().unwrap(), - Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - } - ); - } - - #[test] - fn test_handle_retry_exit_pool_with_wrong_seq_channel_fails() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(101)), - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(102)), - owner: Addr::unchecked("owner2"), - id: "2".to_string(), - }, - ], - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "exit pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::ExitPool(pending)), - last_succesful: true, - }, - ) - .unwrap(); - - let res = execute_retry( - deps.as_mut(), - env, - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 0, - "random_channel".to_string(), - ); - - assert!(res.is_err()); - } - - #[test] - fn test_handle_retry_exit_pool_twice_fails() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(101)), - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(102)), - owner: Addr::unchecked("owner2"), - id: "2".to_string(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(103)), - owner: Addr::unchecked("owner3"), - id: "3".to_string(), - }, - ], - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "exit pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::ExitPool(pending)), - last_succesful: true, - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner1"), "1".to_string()), - &Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner1"), - id: "1".to_string(), - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner2"), "2".to_string()), - &Unbond { - lp_shares: Uint128::new(101), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner2"), - id: "2".to_string(), - }, - ) - .unwrap(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (Addr::unchecked("owner3"), "3".to_string()), - &Unbond { - lp_shares: Uint128::new(103), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner3"), - id: "3".to_string(), - }, - ) - .unwrap(); - - let res = execute_retry( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ) - .unwrap(); - - assert!(!TRAPS.has(&deps.storage, (3539, "channel-35".to_string()))); - - assert_eq!( - res.attributes, - vec![ - attr("unbond", "owner1"), - attr("unbond_id", "1"), - attr("unbond", "owner2"), - attr("unbond_id", "2"), - attr("unbond", "owner3"), - attr("unbond_id", "3"), - attr("action", "retry"), - attr("kind", "exit_pool"), - ] - ); - - assert_eq!(PENDING_UNBOND_QUEUE.len(&deps.storage).unwrap(), 3); - assert_eq!( - PENDING_UNBOND_QUEUE.back(&deps.storage).unwrap().unwrap(), - Unbond { - lp_shares: Uint128::new(103), - unlock_time: Timestamp::from_seconds(1000), - attempted: true, - owner: Addr::unchecked("owner3"), - id: "3".to_string(), - } - ); - - // execute retry for same seq & channel should fail - let res = execute_retry( - deps.as_mut(), - env, - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ); - - assert!(res.is_err()); - } - - #[test] - fn test_handle_retry_join_pool_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - default_setup(deps.as_mut().storage).unwrap(); - - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - // mock the failed join pool trap with 3 bonds - let failed = PendingBond { - bonds: vec![ - OngoingDeposit { - claim_amount: Uint128::new(100), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "1".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(99), - raw_amount: RawAmount::LocalDenom(Uint128::new(999)), - owner: Addr::unchecked("address"), - bond_id: "2".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(101), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "3".to_string(), - }, - ], - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "join pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::JoinSwapExternAmountIn(failed)), - last_succesful: true, - }, - ) - .unwrap(); - - // manually trigger retry join pool - let res = execute_retry( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ) - .unwrap(); - - assert!(!TRAPS.has(&deps.storage, (3539, "channel-35".to_string()))); - - assert_eq!( - res.attributes, - vec![ - attr("action", "retry"), - attr("kind", "join_pool"), - attr("bond_id", "1"), - attr("amount", Uint128::new(1000)), - attr("bond_id", "2"), - attr("amount", Uint128::new(999)), - attr("bond_id", "3"), - attr("amount", Uint128::new(1000)), - ] - ); - - // check that the failed join queue has the same mocked bonds - let failed_join_queue: Result, StdError> = - FAILED_JOIN_QUEUE.iter(&deps.storage).unwrap().collect(); - - let failed_bonds = vec![ - Bond { - amount: Uint128::new(1000), - owner: Addr::unchecked("address"), - bond_id: "1".to_string(), - }, - Bond { - amount: Uint128::new(999), - owner: Addr::unchecked("address"), - bond_id: "2".to_string(), - }, - Bond { - amount: Uint128::new(1000), - owner: Addr::unchecked("address"), - bond_id: "3".to_string(), - }, - ]; - - assert_eq!(failed_join_queue.as_ref().unwrap(), &failed_bonds); - - // manually trigger try_icq - let res = execute_try_icq(deps.as_mut(), env.clone()); - assert_eq!(res.unwrap().messages.len(), 1); - - // mocking the ICQ ACK - let raw_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uatom".to_string(), - amount: "1000".to_string(), - }), - } - .encode_to_vec(), - ); - - let quote_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: "1000".to_string(), - }), - } - .encode_to_vec(), - ); - - let lp_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: "1000".to_string(), - }), - } - .encode_to_vec(), - ); - - let join_pool = create_query_response( - QueryCalcJoinPoolSharesResponse { - share_out_amount: "123".to_string(), - tokens_out: vec![OsmoCoin { - denom: "uosmo".to_string(), - amount: "123".to_string(), - }], - } - .encode_to_vec(), - ); - - let exit_pool = create_query_response( - QueryCalcExitPoolCoinsFromSharesResponse { - tokens_out: vec![ - OsmoCoin { - // base denom - denom: "uosmo".to_string(), - amount: "123".to_string(), - }, - OsmoCoin { - // quote denom - denom: "uqsr".to_string(), - amount: "123".to_string(), - }, - ], - } - .encode_to_vec(), - ); - - let spot_price = create_query_response( - QuerySpotPriceResponse { - spot_price: "123".to_string(), - } - .encode_to_vec(), - ); - - let lock = create_query_response(LockedResponse { lock: None }.encode_to_vec()); - - let ibc_ack = InterchainQueryPacketAck { - data: Binary::from( - &CosmosResponse { - responses: vec![ - raw_balance, - quote_balance, - lp_balance, - exit_pool, - spot_price, - join_pool, - lock, - ], - } - .encode_to_vec()[..], - ), - }; - - let res = handle_icq_ack( - deps.as_mut().storage, - env, - to_json_binary(&ibc_ack).unwrap(), - ) - .unwrap(); - - // we do NOT transfer any token here, failed bonds were already transferred to the contract before failing and stay there - // as we do not have any bond_queue items, we return None here - assert!(res.messages.is_empty()); - - assert!(TRAPS.is_empty(deps.as_ref().storage)); - - // FAILED_JOIN_QUEUE should be empty and all bonds moved to REJOIN_QUEUE - assert_eq!(FAILED_JOIN_QUEUE.len(&deps.storage).unwrap(), 0); - assert_eq!(REJOIN_QUEUE.len(&deps.storage).unwrap(), 3); - - assert_eq!( - SIMULATED_JOIN_AMOUNT_IN - .load(deps.as_ref().storage) - .unwrap(), - Uint128::new(1000 + 999 + 1000) - ); - } - - #[test] - fn test_handle_retry_join_pool_with_pending_deposits_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - default_setup(deps.as_mut().storage).unwrap(); - - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - // mock the failed join pool trap with 3 bonds - let failed = PendingBond { - bonds: vec![ - OngoingDeposit { - claim_amount: Uint128::new(1000), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "1".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(999), - raw_amount: RawAmount::LocalDenom(Uint128::new(999)), - owner: Addr::unchecked("address"), - bond_id: "2".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(1000), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "3".to_string(), - }, - ], - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "join pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::JoinSwapExternAmountIn(failed.clone())), - last_succesful: true, - }, - ) - .unwrap(); - - // mock pending deposits and add them to the pending queue - let pending_bonds = vec![ - Bond { - amount: Uint128::new(5_000), - owner: Addr::unchecked("address"), - bond_id: "1".to_string(), - }, - Bond { - amount: Uint128::new(10_000), - owner: Addr::unchecked("address"), - bond_id: "2".to_string(), - }, - ]; - - for bond in pending_bonds.iter() { - PENDING_BOND_QUEUE - .push_back(deps.as_mut().storage, bond) - .unwrap(); - } - - // manually trigger retry join pool - let res = execute_retry( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("not_admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ) - .unwrap(); - - assert!(!TRAPS.has(&deps.storage, (3539, "channel-35".to_string()))); - - // failed bonds amount should not be included in the response as funds are already - // in Osmosis - assert_eq!( - res.attributes, - vec![ - attr("action", "retry"), - attr("kind", "join_pool"), - attr("bond_id", "1"), - attr("amount", Uint128::new(1000)), - attr("bond_id", "2"), - attr("amount", Uint128::new(999)), - attr("bond_id", "3"), - attr("amount", Uint128::new(1000)), - ] - ); - - // check that the failed join queue has the same mocked bonds - let failed_join_queue: Result, StdError> = - FAILED_JOIN_QUEUE.iter(&deps.storage).unwrap().collect(); - assert_eq!(failed_join_queue.unwrap(), pending_bond_to_bond(&failed)); - - // manually trigger try_icq - let res = execute_try_icq(deps.as_mut(), env.clone()); - assert_eq!(res.unwrap().messages.len(), 1); - - // mocking the ICQ ACK - let raw_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uatom".to_string(), - amount: "1000".to_string(), - }), - } - .encode_to_vec(), - ); - - let quote_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: "1000".to_string(), - }), - } - .encode_to_vec(), - ); - - let lp_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: "1000".to_string(), - }), - } - .encode_to_vec(), - ); - - let join_pool = create_query_response( - QueryCalcJoinPoolSharesResponse { - share_out_amount: "123".to_string(), - tokens_out: vec![OsmoCoin { - denom: "uosmo".to_string(), - amount: "123".to_string(), - }], - } - .encode_to_vec(), - ); - - let exit_pool = create_query_response( - QueryCalcExitPoolCoinsFromSharesResponse { - tokens_out: vec![ - OsmoCoin { - // base denom - denom: "uosmo".to_string(), - amount: "123".to_string(), - }, - OsmoCoin { - // quote denom - denom: "uqsr".to_string(), - amount: "123".to_string(), - }, - ], - } - .encode_to_vec(), - ); - - let spot_price = create_query_response( - QuerySpotPriceResponse { - spot_price: "123".to_string(), - } - .encode_to_vec(), - ); - - let lock = create_query_response(LockedResponse { lock: None }.encode_to_vec()); - - let ibc_ack = InterchainQueryPacketAck { - data: Binary::from( - &CosmosResponse { - responses: vec![ - raw_balance, - quote_balance, - lp_balance, - exit_pool, - spot_price, - join_pool, - lock, - ], - } - .encode_to_vec()[..], - ), - }; - - let res = handle_icq_ack( - deps.as_mut().storage, - env, - to_json_binary(&ibc_ack).unwrap(), - ) - .unwrap(); - - // get the pending bonds total amount - let pending_total_amount = pending_bonds - .iter() - .fold(Uint128::zero(), |acc, bond| acc + bond.amount); - - // check that the res amount matches the amount in the pending queue ONLY - match &res.messages[0].msg { - CosmosMsg::Ibc(IbcMsg::Transfer { amount, .. }) => { - assert_eq!( - amount, - &Coin { - denom: "ibc/local_osmo".to_string(), - amount: pending_total_amount, - } - ); - } - _ => panic!("unexpected message type"), - } - - // check that the failed join & pending queues are emptied - assert!(FAILED_JOIN_QUEUE.is_empty(&deps.storage).unwrap()); - assert!(PENDING_BOND_QUEUE.is_empty(&deps.storage).unwrap()); - - // failed bonds should be now in the REJOIN_QUEUE - let rejoin_queue: Result, StdError> = - REJOIN_QUEUE.iter(&deps.storage).unwrap().collect(); - assert_eq!(failed.bonds, rejoin_queue.unwrap()); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/helpers.rs b/smart-contracts/contracts/lp-strategy/src/helpers.rs deleted file mode 100644 index 3990b9041..000000000 --- a/smart-contracts/contracts/lp-strategy/src/helpers.rs +++ /dev/null @@ -1,365 +0,0 @@ -use crate::{ - error::ContractError, - error_recovery::PendingReturningRecovery, - ibc_lock::Lock, - msg::ExecuteMsg, - state::{ - PendingBond, PendingSingleUnbond, RawAmount, BOND_QUEUE, CHANNELS, CONFIG, - FAILED_JOIN_QUEUE, IBC_LOCK, REJOIN_QUEUE, REPLIES, SHARES, START_UNBOND_QUEUE, TRAPS, - UNBOND_QUEUE, - }, - unbond::PendingReturningUnbonds, -}; -use cosmwasm_std::{ - from_json, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, DepsMut, Env, IbcMsg, - IbcPacketAckMsg, Order, QuerierWrapper, Response, StdError, Storage, SubMsg, Uint128, WasmMsg, -}; -use prost::Message; -use quasar_types::{callback::Callback, ibc::MsgTransferResponse}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -pub fn get_total_primitive_shares(storage: &dyn Storage) -> Result { - let mut sum = Uint128::zero(); - for val in SHARES.range(storage, None, None, Order::Ascending) { - sum = sum.checked_add(val?.1)?; - } - Ok(sum) -} - -pub fn get_ica_address(store: &dyn Storage, channel_id: String) -> Result { - let chan = CHANNELS.load(store, channel_id)?; - match chan.channel_type { - quasar_types::ibc::ChannelType::Icq { channel_ty: _ } => Err(ContractError::NoIcaChannel), - quasar_types::ibc::ChannelType::Ica { - channel_ty: _, - counter_party_address, - } => { - if let Some(addr) = counter_party_address { - Ok(addr) - } else { - Err(ContractError::NoCounterpartyIcaAddress) - } - } - quasar_types::ibc::ChannelType::Ics20 { channel_ty: _ } => Err(ContractError::NoIcaChannel), - } -} - -pub fn check_icq_channel(storage: &dyn Storage, channel: String) -> Result<(), ContractError> { - let chan = CHANNELS.load(storage, channel)?; - match chan.channel_type { - quasar_types::ibc::ChannelType::Icq { channel_ty: _ } => Ok(()), - quasar_types::ibc::ChannelType::Ica { - channel_ty: _, - counter_party_address: _, - } => Err(ContractError::NoIcqChannel), - quasar_types::ibc::ChannelType::Ics20 { channel_ty: _ } => Err(ContractError::NoIcqChannel), - } -} - -pub fn create_callback_submsg( - storage: &mut dyn Storage, - cosmos_msg: CosmosMsg, - owner: Addr, - callback_id: String, -) -> Result { - let last = REPLIES.range(storage, None, None, Order::Descending).next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0 + 1; - } - - let local_denom = CONFIG.load(storage)?.local_denom; - let data: SubMsgKind = match &cosmos_msg { - CosmosMsg::Wasm(WasmMsg::Execute { msg, funds, .. }) => { - SubMsgKind::Callback(ContractCallback::Callback { - callback: from_json(msg)?, - // if we send funds, we expect them to be in local denom - amount: funds - .iter() - .find(|c| c.denom == local_denom) - .map(|val| val.amount), - owner, - }) - } - CosmosMsg::Bank(bank_msg) => SubMsgKind::Callback(ContractCallback::Bank { - bank_msg: bank_msg.to_owned(), - unbond_id: callback_id, - }), - _ => return Err(StdError::generic_err("Unsupported WasmMsg")), - }; - - REPLIES.save(storage, id, &data)?; - Ok(SubMsg::reply_always(cosmos_msg, id)) -} - -pub(crate) fn lock_try_icq( - deps: DepsMut, - sub_msg: Option, -) -> Result { - let mut res = Response::new(); - let mut lock = IBC_LOCK.load(deps.storage)?; - - if let Some(sub_msg) = sub_msg { - if !BOND_QUEUE.is_empty(deps.storage)? { - lock = lock.lock_bond(); - res = res.add_attribute("bond_queue", "locked"); - } else if !START_UNBOND_QUEUE.is_empty(deps.storage)? { - lock = lock.lock_start_unbond(); - res = res.add_attribute("start_unbond_queue", "locked"); - } else if !UNBOND_QUEUE.is_empty(deps.storage)? { - lock = lock.lock_unbond(); - res = res.add_attribute("unbond_queue", "locked"); - } - if lock.is_unlocked() { - res = res.add_attribute("IBC_LOCK", "unlocked"); - } - IBC_LOCK.save(deps.storage, &lock)?; - res = res.add_submessage(sub_msg); - res = res.add_attribute("kind", "dispatch"); - } else { - res = res.add_attribute("IBC_LOCK", "locked"); - res = res.add_attribute("kind", "queue"); - } - Ok(res) -} - -pub fn get_usable_compound_balance( - storage: &dyn Storage, - balance: Uint128, -) -> Result { - // two cases where we exclude funds, either transfer succeeded, but not ica, or transfer succeeded and subsequent ica failed - let traps = TRAPS.range(storage, None, None, Order::Ascending); - - let failed_join_queue_amount = FAILED_JOIN_QUEUE.iter(storage)?.try_fold( - Uint128::zero(), - |acc, val| -> Result { Ok(acc + val?.amount) }, - )?; - - let rejoin_queue_amount = REJOIN_QUEUE.iter(storage)?.try_fold( - Uint128::zero(), - |acc, val| -> Result { - match val?.raw_amount { - crate::state::RawAmount::LocalDenom(amount) => Ok(amount + acc), - crate::state::RawAmount::LpShares(_) => Err(ContractError::IncorrectRawAmount), - } - }, - )?; - - let trapped_errors_amount = traps.fold(Uint128::zero(), |acc, wrapped_trap| { - let trap = wrapped_trap.unwrap().1; - if trap.last_succesful { - if let IbcMsgKind::Transfer { pending: _, amount } = trap.step { - acc + amount - } else { - acc - } - // if last msg was not succesful, we did not join the pool, so we have base_denom funds on the - } else if let IbcMsgKind::Ica(IcaMessages::JoinSwapExternAmountIn(pb)) = trap.step { - pb.bonds.iter().fold(acc, |acc2, bond| { - if let RawAmount::LocalDenom(local_denom_amount) = &bond.raw_amount { - acc2 + local_denom_amount - } else { - acc2 - } - }) - } else { - acc - } - }); - - let excluded_funds = failed_join_queue_amount - .checked_add(rejoin_queue_amount)? - .checked_add(trapped_errors_amount)?; - - Ok(balance.saturating_sub(excluded_funds)) -} - -pub fn create_ibc_ack_submsg( - storage: &mut dyn Storage, - pending: IbcMsgKind, - msg: IbcMsg, - channel: String, -) -> Result { - let last = REPLIES.range(storage, None, None, Order::Descending).next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0 + 1; - } - // register the message in the replies for handling - REPLIES.save(storage, id, &SubMsgKind::Ibc(pending, channel))?; - Ok(SubMsg::reply_always(msg, id)) -} - -pub fn ack_submsg( - storage: &mut dyn Storage, - env: Env, - msg: IbcPacketAckMsg, - channel: String, -) -> Result { - let last = REPLIES.range(storage, None, None, Order::Descending).next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0 + 1; - } - - // register the message in the replies for handling - // TODO do we need this state item here? or do we just need the reply hook - REPLIES.save( - storage, - id, - &SubMsgKind::Ack(msg.original_packet.sequence, channel), - )?; - - // TODO for an ack, should the reply hook be always or only on error? Probably only on error - // On succeses, we need to cleanup the state item from REPLIES - Ok(SubMsg::reply_always( - WasmMsg::Execute { - contract_addr: env.contract.address.to_string(), - msg: to_json_binary(&ExecuteMsg::Ack { ack: msg })?, - funds: vec![], - }, - id, - )) -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub enum IbcMsgKind { - Transfer { - pending: PendingBond, - amount: Uint128, - }, - Ica(IcaMessages), - Icq, -} - -// All enums supported by this contract -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub enum IcaMessages { - JoinSwapExternAmountIn(PendingBond), - // pending bonds int the lock and total shares to be locked - // should be gotten from the join pool - LockTokens(PendingBond, Uint128), - BeginUnlocking(Vec, Uint128), - ExitPool(PendingReturningUnbonds), - ReturnTransfer(PendingReturningUnbonds), - RecoveryExitPool(PendingReturningRecovery), - RecoveryReturnTransfer(PendingReturningRecovery), -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum SubMsgKind { - Ibc(IbcMsgKind, String), - Ack(u64, String), - Callback(ContractCallback), // in reply match for callback variant -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum ContractCallback { - Callback { - callback: Callback, - amount: Option, - owner: Addr, - }, - Bank { - bank_msg: BankMsg, - unbond_id: String, - }, -} - -pub fn is_contract_admin( - querier: &QuerierWrapper, - env: &Env, - sus_admin: &Addr, -) -> Result<(), ContractError> { - let contract_admin = querier - .query_wasm_contract_info(&env.contract.address)? - .admin; - if let Some(contract_admin) = contract_admin { - if contract_admin != *sus_admin { - return Err(ContractError::Unauthorized {}); - } - } else { - return Err(ContractError::Unauthorized {}); - } - Ok(()) -} - -pub(crate) fn parse_seq(data: Binary) -> Result { - let resp = MsgTransferResponse::decode(data.0.as_slice())?; - Ok(resp.seq) -} - -pub(crate) fn unlock_on_error( - storage: &mut dyn Storage, - kind: &IbcMsgKind, -) -> Result<(), ContractError> { - match kind { - IbcMsgKind::Transfer { - pending: _, - amount: _, - } => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_bond()) - })?; - Ok(()) - } - IbcMsgKind::Ica(ica) => match ica { - IcaMessages::JoinSwapExternAmountIn(_) => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_bond()) - })?; - Ok(()) - } - IcaMessages::LockTokens(_, _) => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_bond()) - })?; - Ok(()) - } - IcaMessages::BeginUnlocking(_, _) => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_start_unbond()) - })?; - Ok(()) - } - IcaMessages::ExitPool(_) => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_unbond()) - })?; - Ok(()) - } - IcaMessages::ReturnTransfer(_) => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_unbond()) - })?; - Ok(()) - } - IcaMessages::RecoveryExitPool(_) => todo!(), - IcaMessages::RecoveryReturnTransfer(_) => todo!(), - }, - IbcMsgKind::Icq => { - IBC_LOCK.update(storage, |lock| { - Ok::(lock.unlock_bond().unlock_start_unbond().unlock_unbond()) - })?; - Ok(()) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn parse_reply_seq() { - let seq = 35; - let resp = Binary::from(MsgTransferResponse { seq }.encode_to_vec()); - let parsed_seq = parse_seq(resp).unwrap(); - assert_eq!(seq, parsed_seq) - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/ibc.rs b/smart-contracts/contracts/lp-strategy/src/ibc.rs deleted file mode 100644 index 4ab7e6a4a..000000000 --- a/smart-contracts/contracts/lp-strategy/src/ibc.rs +++ /dev/null @@ -1,1179 +0,0 @@ -use crate::bond::{batch_bond, create_share}; -use crate::error::{ContractError, Never, Trap}; - -use crate::helpers::{ - ack_submsg, create_callback_submsg, create_ibc_ack_submsg, get_ica_address, - get_usable_compound_balance, unlock_on_error, IbcMsgKind, IcaMessages, -}; -use crate::ibc_lock::Lock; -use crate::ibc_util::{ - calculate_share_out_min_amount, consolidate_exit_pool_amount_into_local_denom, - do_ibc_join_pool_swap_extern_amount_in, do_ibc_lock_tokens, parse_join_pool, -}; -use crate::icq::calc_total_balance; -use crate::start_unbond::{batch_start_unbond, handle_start_unbond_ack}; -use crate::state::{ - LpCache, PendingBond, CHANNELS, CONFIG, IBC_LOCK, IBC_TIMEOUT_TIME, ICA_CHANNEL, ICQ_CHANNEL, - LP_SHARES, OSMO_LOCK, PENDING_ACK, RECOVERY_ACK, REJOIN_QUEUE, SIMULATED_EXIT_RESULT, - SIMULATED_EXIT_SHARES_IN, SIMULATED_JOIN_AMOUNT_IN, SIMULATED_JOIN_RESULT, TIMED_OUT, - TOTAL_VAULT_BALANCE, TRAPS, USABLE_COMPOUND_BALANCE, -}; -use crate::unbond::{batch_unbond, transfer_batch_unbond, PendingReturningUnbonds}; -use cosmos_sdk_proto::cosmos::bank::v1beta1::QueryBalanceResponse; - -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use osmosis_std::types::cosmos::base::v1beta1::Coin as OsmoCoin; -#[allow(deprecated)] -use osmosis_std::types::osmosis::gamm::v1beta1::QuerySpotPriceResponse; - -use osmosis_std::types::osmosis::gamm::v1beta1::{ - MsgExitSwapShareAmountInResponse, MsgJoinSwapExternAmountInResponse, - QueryCalcExitPoolCoinsFromSharesResponse, QueryCalcJoinPoolSharesResponse, -}; -use osmosis_std::types::osmosis::lockup::{LockedResponse, MsgLockTokensResponse}; -use prost::Message; -use quasar_types::callback::{BondResponse, Callback}; -use quasar_types::error::Error as QError; -use quasar_types::ibc::{enforce_order_and_version, ChannelInfo, ChannelType, HandshakeState}; -use quasar_types::ica::handshake::enforce_ica_order_and_metadata; -use quasar_types::ica::packet::{ica_send, AckBody}; -use quasar_types::ica::traits::Unpack; -use quasar_types::icq::{CosmosResponse, InterchainQueryPacketAck, ICQ_ORDERING}; -use quasar_types::{ibc, ica::handshake::IcaMetadata, icq::ICQ_VERSION}; -use std::str::FromStr; - -use cosmwasm_std::{ - from_json, to_json_binary, Attribute, Binary, Coin, CosmosMsg, Decimal, DepsMut, Env, - IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, - IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, IbcTimeout, - QuerierWrapper, Response, StdError, Storage, SubMsg, Uint128, WasmMsg, -}; - -/// enforces ordering and versioning constraints, this combines ChanOpenInit and ChanOpenTry -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_channel_open( - deps: DepsMut, - _env: Env, - msg: IbcChannelOpenMsg, -) -> Result<(), ContractError> { - // save the channel as an channel in ChanOpenInit, we support inits from icq and ica channels - if msg.channel().version == ICQ_VERSION { - handle_icq_channel(deps, msg.channel().clone())?; - } else { - handle_ica_channel(deps, msg)?; - } - Ok(()) -} - -fn handle_icq_channel(deps: DepsMut, channel: IbcChannel) -> Result<(), ContractError> { - ibc::enforce_order_and_version(&channel, None, &channel.version, channel.order.clone())?; - - // check the connection id vs the expected connection id - let config = CONFIG.load(deps.storage)?; - if config.expected_connection != channel.connection_id { - return Err(ContractError::IncorrectConnection); - } - - // save the channel state here - let info = ChannelInfo { - id: channel.endpoint.channel_id.clone(), - counterparty_endpoint: channel.counterparty_endpoint, - connection_id: channel.connection_id, - channel_type: ChannelType::Icq { - channel_ty: channel.version, - }, - handshake_state: HandshakeState::Init, - }; - - CHANNELS.save(deps.storage, channel.endpoint.channel_id, &info)?; - Ok(()) -} - -fn handle_ica_channel(deps: DepsMut, msg: IbcChannelOpenMsg) -> Result<(), ContractError> { - let channel = msg.channel().clone(); - let metadata: IcaMetadata = serde_json_wasm::from_str(&channel.version).map_err(|error| { - QError::InvalidIcaMetadata { - raw_metadata: channel.version.clone(), - error: error.to_string(), - } - })?; - - enforce_ica_order_and_metadata(&channel, None, &metadata)?; - - // compare the expected connection id to the channel connection-id and the ica metadata connection-id - let config = CONFIG.load(deps.storage)?; - if &config.expected_connection - != metadata - .controller_connection_id() - .as_ref() - .ok_or(ContractError::NoConnectionFound)? - { - return Err(ContractError::IncorrectConnection); - } - if config.expected_connection != channel.connection_id { - return Err(ContractError::IncorrectConnection); - } - // validate that the message is an OpenInit message and not an OpenTry, such that we don't pollute the channel map - // if let IbcChannelOpenMsg::OpenInit(s) = msg { - // return Err(ContractError::InvalidOrder); - // } - match msg { - IbcChannelOpenMsg::OpenInit { channel } => { - // save the current state of the initializing channel - let info = ChannelInfo { - id: channel.endpoint.channel_id.clone(), - counterparty_endpoint: channel.counterparty_endpoint, - connection_id: channel.connection_id, - channel_type: ChannelType::Ica { - channel_ty: metadata, - counter_party_address: None, - }, - handshake_state: HandshakeState::Init, - }; - CHANNELS.save(deps.storage, channel.endpoint.channel_id, &info)?; - Ok(()) - } - IbcChannelOpenMsg::OpenTry { - channel: _, - counterparty_version: _, - } => Err(ContractError::IncorrectChannelOpenType), - } -} - -/// record the channel in CHANNEL_INFO, this combines the ChanOpenAck and ChanOpenConfirm steps -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_channel_connect( - deps: DepsMut, - _env: Env, - msg: IbcChannelConnectMsg, -) -> Result { - // try to fetch the connecting channel, we should error if it does not exist\ - let mut info: ChannelInfo = CHANNELS - .load(deps.storage, msg.channel().endpoint.channel_id.clone()) - .map_err(|err| StdError::GenericErr { - msg: err.to_string(), - })?; - // we need to check the counter party version in try and ack (sometimes here) - // TODO we can wrap this match in a function in our ibc package - - // TODO think of a better datastructure so we dont have to parse ICA channels like this - match info.channel_type { - ChannelType::Icq { ref channel_ty } => { - enforce_order_and_version( - msg.channel(), - msg.counterparty_version(), - channel_ty.as_str(), - ICQ_ORDERING, - )?; - ICQ_CHANNEL.save(deps.storage, &msg.channel().endpoint.channel_id)?; - // TODO save the updated state of the ICQ channel - } - ChannelType::Ica { - channel_ty, - counter_party_address: _, - } => { - let counter_party_metadata = enforce_ica_order_and_metadata( - msg.channel(), - msg.counterparty_version(), - &channel_ty, - )?; - - if counter_party_metadata.is_none() { - return Err(ContractError::QError(QError::NoCounterpartyIcaAddress)); - } - let counter_party = counter_party_metadata.unwrap(); - // at this point, we expect a counterparty address, if it's none, we have to error - if counter_party.address().is_none() { - return Err(ContractError::NoCounterpartyIcaAddress); - } - let addr = counter_party.address(); - if addr.is_none() { - return Err(ContractError::NoCounterpartyIcaAddress); - } - - // once we have an Open ICA channel, save it under ICA channel, - // if a channel already exists, and that channel is not timed out reject incoming OPENS - // if that channel is timed out, we overwrite the previous ICA channel for the new one - let channel = ICA_CHANNEL.may_load(deps.storage)?; - // to reject the msg here, ica should not be timed out - if channel.is_some() && !TIMED_OUT.load(deps.storage)? { - return Err(ContractError::IcaChannelAlreadySet); - } - - // set timed out to false - TIMED_OUT.save(deps.storage, &false)?; - - ICA_CHANNEL.save(deps.storage, &msg.channel().endpoint.channel_id)?; - - info.channel_type = ChannelType::Ica { - channel_ty, - counter_party_address: addr, - }; - CHANNELS.save(deps.storage, info.id.clone(), &info)? - } - ChannelType::Ics20 { channel_ty: _ } => unimplemented!(), - } - - info.handshake_state = HandshakeState::Open; - - CHANNELS.save( - deps.storage, - msg.channel().endpoint.channel_id.clone(), - &info, - )?; - - Ok(IbcBasicResponse::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_channel_close( - _deps: DepsMut, - _env: Env, - channel: IbcChannelCloseMsg, -) -> Result { - // TODO look up the channel, in channels, and update the state to closed - Ok(IbcBasicResponse::new() - .add_attribute("channel", channel.channel().endpoint.channel_id.clone()) - .add_attribute("connection", channel.channel().connection_id.clone())) -} - -/// The lp-strategy cannot receive any packets -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_packet_receive( - _deps: DepsMut, - _env: Env, - _msg: IbcPacketReceiveMsg, -) -> Result { - // Contract does not handle packets/queries. - unimplemented!(); -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_packet_ack( - deps: DepsMut, - env: Env, - msg: IbcPacketAckMsg, -) -> Result { - // We save the ack binary here for error recovery in case of an join pool recovery - // this should be cleaned up from state in the ack submsg Ok case - RECOVERY_ACK.save( - deps.storage, - ( - msg.original_packet.sequence, - msg.original_packet.src.channel_id.clone(), - ), - &msg.acknowledgement, - )?; - let chan = msg.original_packet.src.channel_id.clone(); - Ok(IbcBasicResponse::new().add_submessage(ack_submsg(deps.storage, env, msg, chan)?)) -} - -pub fn handle_succesful_ack( - deps: DepsMut, - env: Env, - pkt: IbcPacketAckMsg, - ack_bin: Binary, -) -> Result { - let kind = PENDING_ACK.load( - deps.storage, - ( - pkt.original_packet.sequence, - pkt.original_packet.src.channel_id.clone(), - ), - )?; - match kind { - // a transfer ack means we have sent funds to the ica address, return transfers are handled by the ICA ack - IbcMsgKind::Transfer { pending, amount } => { - handle_transfer_ack(deps.storage, env, ack_bin, &pkt, pending, amount) - } - IbcMsgKind::Ica(ica_kind) => { - handle_ica_ack(deps.storage, deps.querier, env, ack_bin, &pkt, ica_kind) - } - IbcMsgKind::Icq => handle_icq_ack(deps.storage, env, ack_bin), - } -} - -pub fn handle_transfer_ack( - storage: &mut dyn Storage, - env: Env, - _ack_bin: Binary, - _pkt: &IbcPacketAckMsg, - mut pending: PendingBond, - transferred_amount: Uint128, -) -> Result { - // once the ibc transfer to the ICA account has succeeded, we send the join pool message - // we need to save and fetch - let config = CONFIG.load(storage)?; - - let share_out_min_amount = calculate_share_out_min_amount(storage)?; - - let rejoin_queue_amount = REJOIN_QUEUE.iter(storage)?.try_fold( - Uint128::zero(), - |acc, val| -> Result { - match val?.raw_amount { - crate::state::RawAmount::LocalDenom(amount) => Ok(amount + acc), - crate::state::RawAmount::LpShares(_) => Err(ContractError::IncorrectRawAmount), - } - }, - )?; - - // add in usable base token compound balance to include rewards - // TODO: In an ideal world, I'd also fix share_out_min_amount to adjust for the amount we are compounding - // However, share_out_min_amount is already broken (doens't include failed_bonds_amount), the fix would live in ibc_util.rs L:78 (this would only fix failed_join_amount) - // a better fix would be to get the last state of the pool and do the math on our side to then also be able to include this USABLE_COMPOUND_BALANCE - // howver, if we are going to deprecate this vault, I'd argue it's not worth it - seeing as the compound balance would just be "extra money" for a user anyway - // TODO: remove this comment - let base_token_rewards = USABLE_COMPOUND_BALANCE.load(storage)?; - - let total_amount = transferred_amount + rejoin_queue_amount + base_token_rewards; - - // remove all items from REJOIN_QUEUE & add them to the deposits: Vec - while !REJOIN_QUEUE.is_empty(storage)? { - let rejoin = REJOIN_QUEUE.pop_front(storage)?; - pending.bonds.push(rejoin.unwrap()); - } - - let msg = do_ibc_join_pool_swap_extern_amount_in( - storage, - env, - config.pool_id, - config.base_denom.clone(), - total_amount, - share_out_min_amount, - pending.bonds, - )?; - - // TODO move this update to after the lock - TOTAL_VAULT_BALANCE.update(storage, |old| -> Result { - Ok(old.checked_add(total_amount)?) - })?; - - Ok(Response::new().add_submessage(msg).add_attribute( - "transfer-ack", - format!("{}-{}", &total_amount, config.base_denom), - )) -} - -// TODO move the parsing of the ICQ to it's own function, ideally we'd have a type that is contstructed in create ICQ and is parsed from a proto here -pub fn handle_icq_ack( - storage: &mut dyn Storage, - env: Env, - ack_bin: Binary, -) -> Result { - // todo: query flows should be separated by which flowType we're doing (bond, unbond, startunbond) - - let ack: InterchainQueryPacketAck = from_json(ack_bin)?; - let resp: CosmosResponse = CosmosResponse::decode(ack.data.0.as_ref())?; - - // we have only dispatched on query and a single kind at this point - let raw_balance = QueryBalanceResponse::decode(resp.responses[0].value.as_ref())? - .balance - .ok_or(ContractError::BaseDenomNotFound)? - .amount; - - let base_balance = - Uint128::new( - raw_balance - .parse::() - .map_err(|err| ContractError::ParseIntError { - error: format!("base_balance:{err}"), - value: raw_balance.to_string(), - })?, - ); - - // free base_token osmo side balance but subtracted out anything from trapped_errors, saved for use in transfer ack - let usable_base_token_compound_balance = get_usable_compound_balance(storage, base_balance)?; - USABLE_COMPOUND_BALANCE.save(storage, &usable_base_token_compound_balance)?; - - // TODO the quote balance should be able to be compounded aswell - let _quote_balance = QueryBalanceResponse::decode(resp.responses[1].value.as_ref())? - .balance - .ok_or(ContractError::BaseDenomNotFound)? - .amount; - - // TODO we can make the LP_SHARES cache less error prone here by using the actual state of lp shares - // We then need to query locked shares aswell, since they are not part of balance - let _lp_balance = QueryBalanceResponse::decode(resp.responses[2].value.as_ref())? - .balance - .ok_or(ContractError::BaseDenomNotFound)? - .amount; - - let exit_total_pool = - QueryCalcExitPoolCoinsFromSharesResponse::decode(resp.responses[3].value.as_ref())?; - - #[allow(deprecated)] - let spot_price = QuerySpotPriceResponse::decode(resp.responses[4].value.as_ref())?.spot_price; - - let mut response_idx = 4; - let join_pool = if SIMULATED_JOIN_AMOUNT_IN - .may_load(storage)? - .unwrap_or(0u128.into()) - > 1u128.into() - { - // found, increment response index - response_idx += 1; - // decode result - QueryCalcJoinPoolSharesResponse::decode(resp.responses[response_idx].value.as_ref())? - } else { - QueryCalcJoinPoolSharesResponse { - share_out_amount: "0".to_string(), - tokens_out: vec![], - } - }; - - let config = CONFIG.load(storage)?; - - let locked_lp_shares = match OSMO_LOCK.may_load(storage)? { - Some(_) => { - // found, increment response index - response_idx += 1; - // decode result - let lock = LockedResponse::decode(resp.responses[response_idx].value.as_ref())?.lock; - // parse the locked lp shares on Osmosis, a bit messy - let gamms = if let Some(lock) = lock { - lock.coins - } else { - vec![] - }; - gamms - .into_iter() - .find(|val| val.denom == config.pool_denom) - .unwrap_or(OsmoCoin { - denom: config.pool_denom.clone(), - amount: Uint128::zero().to_string(), - }) - .amount - .parse()? - } - None => Uint128::zero(), - }; - - // update the locked shares in our cache - LP_SHARES.update(storage, |mut cache| -> Result { - cache.locked_shares = locked_lp_shares; - Ok(cache) - })?; - - let exit_pool_unbonds = if SIMULATED_EXIT_SHARES_IN - .may_load(storage)? - .unwrap_or(0u128.into()) - >= 1u128.into() - { - // found, increment response index - response_idx += 1; - - // decode result - QueryCalcExitPoolCoinsFromSharesResponse::decode( - resp.responses[response_idx].value.as_ref(), - )? - } else { - QueryCalcExitPoolCoinsFromSharesResponse { tokens_out: vec![] } - }; - - let spot_price = - Decimal::from_str(spot_price.as_str()).map_err(|err| ContractError::ParseDecError { - error: err, - value: spot_price, - })?; - - let total_balance = calc_total_balance( - storage, - usable_base_token_compound_balance, - &exit_total_pool.tokens_out, - spot_price, - )?; - - TOTAL_VAULT_BALANCE.save(storage, &total_balance)?; - - let parsed_exit_pool_out = consolidate_exit_pool_amount_into_local_denom( - storage, - &exit_pool_unbonds.tokens_out, - spot_price, - )?; - - let parsed_join_pool_out = parse_join_pool(storage, join_pool)?; - - SIMULATED_JOIN_RESULT.save(storage, &parsed_join_pool_out)?; - SIMULATED_EXIT_RESULT.save(storage, &parsed_exit_pool_out)?; - - // todo move this to below into the lock decisions - let bond: Option = batch_bond(storage, &env, total_balance)?; - - let mut msges = Vec::new(); - let mut attrs = Vec::new(); - // if queues had items, msges should be some, so we add the ibc submessage, if there were no items in a queue, we don't have a submsg to add - // if we have a bond, start_unbond or unbond msg, we lock the repsective lock - - // todo rewrite into flat if/else ifs - if let Some(msg) = bond { - msges.push(msg); - attrs.push(Attribute::new("bond-status", "bonding")); - IBC_LOCK.update(storage, |lock| -> Result { - Ok(lock.lock_bond()) - })?; - } else { - attrs.push(Attribute::new("bond-status", "empty")); - if let Some(msg) = batch_start_unbond(storage, &env)? { - msges.push(msg); - attrs.push(Attribute::new("start-unbond-status", "starting-unbond")); - IBC_LOCK.update(storage, |lock| -> Result { - Ok(lock.lock_start_unbond()) - })?; - } else { - attrs.push(Attribute::new("start-unbond-status", "empty")); - if let Some(msg) = batch_unbond(storage, &env)? { - msges.push(msg); - attrs.push(Attribute::new("unbond-status", "unbonding")); - IBC_LOCK.update(storage, |lock| -> Result { - Ok(lock.lock_unbond()) - })?; - } else { - attrs.push(Attribute::new("unbond-status", "empty")); - } - } - } - - Ok(Response::new().add_submessages(msges).add_attributes(attrs)) -} - -pub fn handle_ica_ack( - storage: &mut dyn Storage, - querier: QuerierWrapper, - env: Env, - ack_bin: Binary, - _pkt: &IbcPacketAckMsg, - ica_kind: IcaMessages, -) -> Result { - match ica_kind { - IcaMessages::JoinSwapExternAmountIn(mut data) => { - handle_join_pool(storage, &env, ack_bin, &mut data) - } - IcaMessages::LockTokens(data, lp_shares) => { - handle_lock_tokens_ack(storage, &env, data, lp_shares, ack_bin, querier) - } - IcaMessages::BeginUnlocking(data, total) => { - handle_start_unbond_ack(storage, querier, &env, data, total) - } - IcaMessages::ExitPool(data) => handle_exit_pool_ack(storage, &env, data, ack_bin), - // TODO decide where we unlock the transfer ack unlock, here or in the ibc hooks receive - IcaMessages::ReturnTransfer(data) => handle_return_transfer_ack(storage, querier, data), - // After a RecoveryExitPool, we do a return transfer that should hit RecoveryReturnTransfer - IcaMessages::RecoveryExitPool(_pending) => todo!(), - // After a RecoveryReturnTransfer, we save the funds to a local map, to be claimed by vaults when a users asks - IcaMessages::RecoveryReturnTransfer(_pending) => todo!(), - } -} - -// fn handle_recovery_return_transfer( -// storage: &mut dyn Storage, -// pending: PendingReturningRecovery, - -// ) -> Result { -// // if we have the succesfully received the recovery, we create an entry -// for p in pending.returning { -// if let RawAmount::LocalDenom(val) = p.amount { -// CLAIMABLE_FUNDS.save(storage, (p.owner, p.id), &val)?; -// } else { -// return Err(ContractError::IncorrectRawAmount); -// } -// // remove the error from TRAPS -// TRAPS.remove(storage, (pending.trapped_id, )); -// } -// todo!() -// } - -fn handle_join_pool( - storage: &mut dyn Storage, - env: &Env, - ack_bin: Binary, - data: &mut PendingBond, -) -> Result { - // TODO move the below locking logic to a separate function - // get the ica address of the channel id - let ica_channel = ICA_CHANNEL.load(storage)?; - let ica_addr = get_ica_address(storage, ica_channel.clone())?; - let ack = AckBody::from_bytes(ack_bin.0.as_ref())?.to_any()?; - let resp = MsgJoinSwapExternAmountInResponse::unpack(ack)?; - let shares_out = Uint128::new(resp.share_out_amount.parse::().map_err(|err| { - ContractError::ParseIntError { - error: format!("{err}"), - value: resp.share_out_amount, - } - })?); - - let denom = CONFIG.load(storage)?.pool_denom; - - LP_SHARES.update( - storage, - |mut old: LpCache| -> Result { - old.d_unlocked_shares = old.d_unlocked_shares.checked_add(shares_out)?; - Ok(old) - }, - )?; - - data.update_raw_amount_to_lp(shares_out)?; - - let msg = do_ibc_lock_tokens( - storage, - ica_addr, - vec![Coin { - denom, - amount: shares_out, - }], - )?; - - let channel = ICA_CHANNEL.load(storage)?; - - let outgoing = ica_send( - msg, - ica_channel, - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - )?; - - let msg = create_ibc_ack_submsg( - storage, - IbcMsgKind::Ica(IcaMessages::LockTokens(data.clone(), shares_out)), - outgoing, - channel, - )?; - Ok(Response::new().add_submessage(msg)) -} - -fn handle_lock_tokens_ack( - storage: &mut dyn Storage, - _env: &Env, - data: PendingBond, - total_lp_shares: Uint128, - ack_bin: Binary, - querier: QuerierWrapper, -) -> Result { - let ack = AckBody::from_bytes(ack_bin.0.as_ref())?.to_any()?; - let resp = MsgLockTokensResponse::unpack(ack)?; - - // save the lock id in the contract - OSMO_LOCK.save(storage, &resp.id)?; - - LP_SHARES.update(storage, |mut old| -> Result { - old.d_unlocked_shares = - old.d_unlocked_shares - .checked_sub(total_lp_shares) - .map_err(|err| { - ContractError::TracedOverflowError( - err, - "update_unlocked_deposit_shares".to_string(), - ) - })?; - old.locked_shares = old - .locked_shares - .checked_add(total_lp_shares) - .map_err(|err| { - ContractError::TracedOverflowError(err, "update_locked_shares".to_string()) - })?; - Ok(old) - })?; - - let mut callback_submsgs: Vec = vec![]; - for claim in data.bonds { - let share_amount = create_share(storage, &claim.owner, &claim.bond_id, claim.claim_amount)?; - if querier - .query_wasm_contract_info(claim.owner.as_str()) - .is_ok() - { - let wasm_msg = WasmMsg::Execute { - contract_addr: claim.owner.to_string(), - msg: to_json_binary(&Callback::BondResponse(BondResponse { - share_amount, - bond_id: claim.bond_id.clone(), - }))?, - funds: vec![], - }; - // convert wasm_msg into cosmos_msg to be handled in create_callback_submsg - let cosmos_msg = CosmosMsg::Wasm(wasm_msg); - callback_submsgs.push(create_callback_submsg( - storage, - cosmos_msg, - claim.owner, - claim.bond_id, - )?); - } - } - - // set the bond lock state to unlocked - IBC_LOCK.update(storage, |old| -> Result { - Ok(old.unlock_bond()) - })?; - - // TODO, do we want to also check queue state? and see if we can already start a new execution? - Ok(Response::new() - .add_submessages(callback_submsgs) - .add_attribute("locked_tokens", ack_bin.to_base64()) - .add_attribute("lock_id", resp.id.to_string())) -} - -fn handle_exit_pool_ack( - storage: &mut dyn Storage, - env: &Env, - mut data: PendingReturningUnbonds, - ack_bin: Binary, -) -> Result { - let ack = AckBody::from_bytes(ack_bin.0.as_ref())?.to_any()?; - let msg = MsgExitSwapShareAmountInResponse::unpack(ack)?; - let total_exited_tokens = - Uint128::new(msg.token_out_amount.parse::().map_err(|err| { - ContractError::ParseIntError { - error: format!("{err}"), - value: msg.token_out_amount, - } - })?); - - // we don't need the sum of the lp tokens returned by lp_to_local_denom here - let _ = data.lp_to_local_denom(total_exited_tokens)?; - - let sub_msg = transfer_batch_unbond(storage, env, data, total_exited_tokens)?; - Ok(Response::new() - .add_submessage(sub_msg) - .add_attribute("transfer-funds", total_exited_tokens.to_string())) -} - -fn handle_return_transfer_ack( - storage: &mut dyn Storage, - _querier: QuerierWrapper, - _data: PendingReturningUnbonds, -) -> Result { - IBC_LOCK.update(storage, |lock| -> Result { - Ok(lock.unlock_unbond()) - })?; - - Ok(Response::new().add_attribute("return-transfer", "success")) -} - -pub fn handle_failing_ack( - deps: DepsMut, - _env: Env, - pkt: IbcPacketAckMsg, - error: String, -) -> Result { - // TODO we can expand error handling here to fetch the packet by the ack and add easy retries or something - let step = PENDING_ACK.load( - deps.storage, - ( - pkt.original_packet.sequence, - pkt.original_packet.src.channel_id.clone(), - ), - )?; - unlock_on_error(deps.storage, &step)?; - TRAPS.save( - deps.storage, - ( - pkt.original_packet.sequence, - pkt.original_packet.src.channel_id, - ), - &Trap { - error: format!("packet failure: {error}"), - step, - last_succesful: false, - }, - )?; - Ok(Response::new().add_attribute("ibc-error", error.as_str())) -} - -// if an ICA packet is timed out, we need to reject any further packets (only to the ICA channel or in total -> easiest in total until a new ICA channel is created) -// once time out variable is set, a new ICA channel needs to be able to be opened for the contract to function and the ICA channel val and channels map need to be updated -// what do we do with the trapped errors packets, are they able to be recovered over the new ICA channel? -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn ibc_packet_timeout( - deps: DepsMut, - _env: Env, - msg: IbcPacketTimeoutMsg, -) -> Result { - on_packet_timeout( - deps, - msg.packet.sequence, - msg.packet.src.channel_id, - "timeout".to_string(), - true, - ) -} - -pub(crate) fn on_packet_timeout( - deps: DepsMut, - sequence: u64, - channel: String, - error: String, - should_unlock: bool, -) -> Result { - let step = PENDING_ACK.load(deps.storage, (sequence, channel.clone()))?; - if should_unlock { - unlock_on_error(deps.storage, &step)?; - } - if let IbcMsgKind::Ica(_) = &step { - TIMED_OUT.save(deps.storage, &true)? - } - TRAPS.save( - deps.storage, - (sequence, channel), - &Trap { - error: format!("packet failure: {error}"), - step, - last_succesful: false, - }, - )?; - Ok(IbcBasicResponse::default()) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - state::{Config, LOCK_ADMIN, SIMULATED_JOIN_AMOUNT_IN}, - test_helpers::{create_query_response, default_setup}, - }; - use cosmos_sdk_proto::cosmos::base::v1beta1::Coin as OsmoCoin; - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env}, - Addr, Empty, IbcEndpoint, IbcOrder, - }; - - #[test] - fn handle_icq_ack_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - default_setup(deps.as_mut().storage).unwrap(); - - CONFIG - .save( - deps.as_mut().storage, - &Config { - lock_period: 100, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - base_denom: - "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2" - .to_string(), - quote_denom: - "ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901" - .to_string(), - local_denom: - "ibc/FA0006F056DB6719B8C16C551FC392B62F5729978FC0B125AC9A432DBB2AA1A5" - .to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }, - ) - .unwrap(); - LP_SHARES - .save( - deps.as_mut().storage, - &LpCache { - locked_shares: Uint128::new(1000), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - SIMULATED_JOIN_AMOUNT_IN - .save(deps.as_mut().storage, &Uint128::zero()) - .unwrap(); - - // base64 of '{"data":"Chs6FAoSCgV1b3NtbxIJMTkyODcwODgySNW/pQQKUjpLCkkKRGliYy8yNzM5NEZCMDkyRDJFQ0NENTYxMjNDNzRGMzZFNEMxRjkyNjAwMUNFQURBOUNBOTdFQTYyMkIyNUY0MUU1RUIyEgEwSNW/pQQKGToSChAKC2dhbW0vcG9vbC8xEgEwSNW/pQQKFjoPCgEwEgoKBXVvc21vEgEwSNW/pQQKcTpqClIKRGliYy8yNzM5NEZCMDkyRDJFQ0NENTYxMjNDNzRGMzZFNEMxRjkyNjAwMUNFQURBOUNBOTdFQTYyMkIyNUY0MUU1RUIyEgoxMDg5ODQ5Nzk5ChQKBXVvc21vEgsxNTQyOTM2Mzg2MEjVv6UECh06FgoUMC4wNzA2MzQ3ODUwMDAwMDAwMDBI1b+lBAqMATqEAQqBAQj7u2ISP29zbW8xd212ZXpscHNrNDB6M3pmc3l5ZXgwY2Q4ZHN1bTdnenVweDJxZzRoMHVhdms3dHh3NHNlcXE3MmZrbRoECIrqSSILCICSuMOY/v///wEqJwoLZ2FtbS9wb29sLzESGDEwODE3NDg0NTgwODQ4MDkyOTUyMDU1MUjVv6UE"}' - let ack_bin = Binary::from_base64("eyJkYXRhIjoiQ2xVNlV3cFJDa1JwWW1Ndk1qY3pPVFJHUWpBNU1rUXlSVU5EUkRVMk1USXpRemMwUmpNMlJUUkRNVVk1TWpZd01ERkRSVUZFUVRsRFFUazNSVUUyTWpKQ01qVkdOREZGTlVWQ01oSUpNVEV5TWpFek1qUTNDbFE2VWdwUUNrUnBZbU12UXpFME1FRkdSRFUwTWtGRk56ZENSRGRFUTBNNE0wWXhNMFpFUkRoRE5VVTFRa0k0UXpRNU1qazNPRFZGTmtWRE1rWTBRell6TmtZNU9FWXhOemt3TVJJSU1qWTROekV6TnpRS0tUb25DaVVLRFdkaGJXMHZjRzl2YkM4NE1ETVNGRFkxTURnM05qazBPREF4TURZeU5EWXdNVEE0Q3FzQk9xZ0JDbElLUkdsaVl5OHlOek01TkVaQ01Ea3lSREpGUTBORU5UWXhNak5ETnpSR016WkZORU14UmpreU5qQXdNVU5GUVVSQk9VTkJPVGRGUVRZeU1rSXlOVVkwTVVVMVJVSXlFZ295TlRZNE56QTROelExQ2xJS1JHbGlZeTlETVRRd1FVWkVOVFF5UVVVM04wSkVOMFJEUXpnelJqRXpSa1JFT0VNMVJUVkNRamhETkRreU9UYzROVVUyUlVNeVJqUkROak0yUmprNFJqRTNPVEF4RWdveU1UY3dOVFkxTXpNNENoZzZGZ29VTUM0NE5EVXdNREkxTVRBd01EQXdNREF3TURBS2h3RTZoQUVLZ1FFSTVQVmtFajl2YzIxdk1YZGxlbkZoZG5ZNE5uQjVOSE5tWXpOM1pubDBiVFY1Ym1ONk5YcG1Oakk1Wm10NE4yb3daM0JsTlhwNWRtTnlPVGwwZUhNNWRuWjNjemNhQkFpQjZra2lDd2lBa3JqRG1QNy8vLzhCS2ljS0RXZGhiVzB2Y0c5dmJDODRNRE1TRmpJek5EQXpOVGs0TWpBd09UTTVOVFV6TkRJNU1EUT0ifQ==").unwrap(); - // queues are empty at this point so we just expect a succesful response without anyhting else - handle_icq_ack(deps.as_mut().storage, env, ack_bin).unwrap(); - } - - #[test] - fn handle_ica_channel_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - - let endpoint = IbcEndpoint { - port_id: "wasm.my_addr".to_string(), - channel_id: "channel-1".to_string(), - }; - let counterparty_endpoint = IbcEndpoint { - port_id: "icahost".to_string(), - channel_id: "channel-2".to_string(), - }; - - let version = r#"{"version":"ics27-1","encoding":"proto3","tx_type":"sdk_multi_msg","controller_connection_id":"connection-0","host_connection_id":"connection-0"}"#.to_string(); - let channel = IbcChannel::new( - endpoint, - counterparty_endpoint.clone(), - IbcOrder::Ordered, - version, - "connection-0".to_string(), - ); - - let msg = IbcChannelOpenMsg::OpenInit { - channel: channel.clone(), - }; - - handle_ica_channel(deps.as_mut(), msg).unwrap(); - - let expected = ChannelInfo { - id: channel.endpoint.channel_id.clone(), - counterparty_endpoint, - connection_id: "connection-0".to_string(), - channel_type: ChannelType::Ica { - channel_ty: IcaMetadata::with_connections( - "connection-0".to_string(), - "connection-0".to_string(), - ), - counter_party_address: None, - }, - handshake_state: HandshakeState::Init, - }; - assert_eq!( - CHANNELS - .load(deps.as_ref().storage, channel.endpoint.channel_id) - .unwrap(), - expected - ) - } - - #[test] - fn handle_ica_channel_open_try_errors() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - - let endpoint = IbcEndpoint { - port_id: "wasm.my_addr".to_string(), - channel_id: "channel-1".to_string(), - }; - let counterparty_endpoint = IbcEndpoint { - port_id: "icahost".to_string(), - channel_id: "channel-2".to_string(), - }; - - let version = r#"{"version":"ics27-1","encoding":"proto3","tx_type":"sdk_multi_msg","controller_connection_id":"connection-0","host_connection_id":"connection-0"}"#.to_string(); - let channel = IbcChannel::new( - endpoint, - counterparty_endpoint, - IbcOrder::Ordered, - version, - "connection-0".to_string(), - ); - - let msg = IbcChannelOpenMsg::OpenTry { - channel, - counterparty_version: "1".to_string(), - }; - - let err = handle_ica_channel(deps.as_mut(), msg).unwrap_err(); - assert_eq!(err, ContractError::IncorrectChannelOpenType); - } - - #[test] - fn test_handle_icq_ack() { - let mut deps = mock_dependencies(); - let env = mock_env(); - default_setup(deps.as_mut().storage).unwrap(); - - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - // no osmo lock as we're not sending lock ICQ for simplicity - // OSMO_LOCK.save(deps.as_mut().storage, &1u64).unwrap(); - - LOCK_ADMIN - .save(deps.as_mut().storage, &Addr::unchecked("admin"), &Empty {}) - .unwrap(); - - // mocking the ICQ ACK (some values don't make sense, but we're not using them in this math calculation) - let raw_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uatom".to_string(), - amount: "100".to_string(), - }), - } - .encode_to_vec(), - ); - - let quote_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uqsr".to_string(), - amount: "100".to_string(), - }), - } - .encode_to_vec(), - ); - - let lp_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: "100".to_string(), - }), - } - .encode_to_vec(), - ); - - let exit_pool = create_query_response( - QueryCalcExitPoolCoinsFromSharesResponse { - tokens_out: vec![ - Coin { - // base denom - denom: "uosmo".to_string(), - amount: Uint128::new(100), - } - .into(), - Coin { - // quote denom - denom: "uqsr".to_string(), - amount: Uint128::new(100), - } - .into(), - ], - } - .encode_to_vec(), - ); - - let spot_price = create_query_response( - QuerySpotPriceResponse { - spot_price: "1".to_string(), - } - .encode_to_vec(), - ); - - let join_pool = create_query_response( - QueryCalcJoinPoolSharesResponse { - share_out_amount: "123".to_string(), - tokens_out: vec![Coin { - denom: "uosmo".to_string(), - amount: Uint128::new(100), - } - .into()], - } - .encode_to_vec(), - ); - - let exit_pool_unbonds = create_query_response( - QueryCalcExitPoolCoinsFromSharesResponse { - tokens_out: vec![ - Coin { - denom: "uqsr".to_string(), - amount: Uint128::new(100), - } - .into(), - Coin { - denom: "uosmo".to_string(), - amount: Uint128::new(100), - } - .into(), - ], - } - .encode_to_vec(), - ); - - let ibc_ack = InterchainQueryPacketAck { - data: Binary::from( - &CosmosResponse { - responses: vec![ - raw_balance.clone(), - quote_balance.clone(), - lp_balance.clone(), - exit_pool.clone(), - spot_price, - join_pool.clone(), - //lock, we're not sending lock for simplicity and to test indexing logic without one value works - exit_pool_unbonds, - ], - } - .encode_to_vec()[..], - ), - }; - - // mock the value of shares we had before sending the query - SIMULATED_EXIT_SHARES_IN - .save(deps.as_mut().storage, &Uint128::new(200)) - .unwrap(); - - // mock the value of shares we had before sending the query - SIMULATED_JOIN_AMOUNT_IN - .save(deps.as_mut().storage, &Uint128::new(100)) - .unwrap(); - - // simulate that we received the ICQ ACK, shouldn't return any messages - let _res = handle_icq_ack( - deps.as_mut().storage, - env.clone(), - to_json_binary(&ibc_ack).unwrap(), - ) - .unwrap(); - - assert_eq!( - SIMULATED_EXIT_RESULT - .load(deps.as_ref().storage) - .unwrap() - .u128(), - // base_amount + (quote_amount / spot_price) - 100 + 100 - ); - - // changing some ICQ ACK params to create a different test scenario - let spot_price = create_query_response( - QuerySpotPriceResponse { - spot_price: "5".to_string(), - } - .encode_to_vec(), - ); - - let exit_pool_unbonds = create_query_response( - QueryCalcExitPoolCoinsFromSharesResponse { - tokens_out: vec![ - Coin { - // base denom - denom: "uosmo".to_string(), - amount: Uint128::new(1000), - } - .into(), - Coin { - // quote denom - denom: "uqsr".to_string(), - amount: Uint128::new(5000), - } - .into(), - ], - } - .encode_to_vec(), - ); - - let ibc_ack = InterchainQueryPacketAck { - data: Binary::from( - &CosmosResponse { - responses: vec![ - raw_balance, - quote_balance, - lp_balance, - exit_pool, - spot_price, - join_pool, - //lock, we're not sending lock for simplicity and to test indexing logic without one value works - exit_pool_unbonds, - ], - } - .encode_to_vec()[..], - ), - }; - - // simulate that we received another ICQ ACK, shouldn't return any messages - let _res = handle_icq_ack( - deps.as_mut().storage, - env, - to_json_binary(&ibc_ack).unwrap(), - ) - .unwrap(); - - assert_eq!( - SIMULATED_EXIT_RESULT - .load(deps.as_ref().storage) - .unwrap() - .u128(), - // base_amount + (quote_amount / spot_price) - 1000 + (5000 / 5) - ); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/ibc_lock.rs b/smart-contracts/contracts/lp-strategy/src/ibc_lock.rs deleted file mode 100644 index dd72944cd..000000000 --- a/smart-contracts/contracts/lp-strategy/src/ibc_lock.rs +++ /dev/null @@ -1,192 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct Lock { - pub bond: IbcLock, - pub start_unbond: IbcLock, - pub unbond: IbcLock, - pub recovery: IbcLock, - pub migration: IbcLock, -} - -impl Lock { - pub fn new() -> Self { - Lock { - bond: IbcLock::Unlocked, - start_unbond: IbcLock::Unlocked, - unbond: IbcLock::Unlocked, - recovery: IbcLock::Unlocked, - migration: IbcLock::Unlocked, - } - } - - pub fn unlock_bond(mut self) -> Self { - self.bond = IbcLock::Unlocked; - self - } - - pub fn unlock_start_unbond(mut self) -> Self { - self.start_unbond = IbcLock::Unlocked; - self - } - - pub fn unlock_unbond(mut self) -> Self { - self.unbond = IbcLock::Unlocked; - self - } - - pub fn unlock_migration(mut self) -> Self { - self.migration = IbcLock::Unlocked; - self - } - - pub fn lock_bond(mut self) -> Self { - self.bond = IbcLock::Locked; - self - } - - pub fn lock_start_unbond(mut self) -> Self { - self.start_unbond = IbcLock::Locked; - self - } - - pub fn lock_unbond(mut self) -> Self { - self.unbond = IbcLock::Locked; - self - } - - pub fn lock_migration(mut self) -> Self { - self.migration = IbcLock::Locked; - self - } - - // this doesnt take into account the recovery lock - pub fn is_unlocked(&self) -> bool { - self.bond.is_unlocked() - && self.start_unbond.is_unlocked() - && self.unbond.is_unlocked() - && self.migration.is_unlocked() - } - - // this doesnt take into account the recovery lock - pub fn is_locked(&self) -> bool { - self.bond.is_locked() - || self.start_unbond.is_locked() - || self.unbond.is_locked() - || self.migration.is_locked() - } -} - -impl Default for Lock { - fn default() -> Self { - Self::new() - } -} - -/// IbcLock describes the current state of the contract -/// Upon locking the contract, all current deposits and withdraws are going to be handled, Incoming withdraws are gathered once again gathered into a queue. -/// Once the contract unlocks, if the queue has any deposits and/or withdraws, the contract locks and starts handling all current queries -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum IbcLock { - Locked, - Unlocked, -} - -impl IbcLock { - pub fn is_unlocked(&self) -> bool { - self == &IbcLock::Unlocked - } - - pub fn is_locked(&self) -> bool { - self == &IbcLock::Locked - } -} - -// write tests -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_lock() { - // start from unlocked - let mut lock = Lock::new(); - assert!(lock.is_unlocked()); - assert!(!lock.is_locked()); - - // lock one by one and check - lock = lock.lock_bond(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - lock = lock.lock_start_unbond(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - lock = lock.lock_unbond(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - // manually lock recovery - lock.recovery = IbcLock::Locked; - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - lock = lock.lock_migration(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - // all should be locked - assert!(lock.bond.is_locked()); - assert!(lock.start_unbond.is_locked()); - assert!(lock.unbond.is_locked()); - assert!(lock.recovery.is_locked()); - assert!(lock.migration.is_locked()); - - // none should be unlocked - assert!(!lock.bond.is_unlocked()); - assert!(!lock.start_unbond.is_unlocked()); - assert!(!lock.unbond.is_unlocked()); - assert!(!lock.recovery.is_unlocked()); - assert!(!lock.migration.is_unlocked()); - - // unlock one by one and check - lock = lock.unlock_bond(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - lock = lock.unlock_start_unbond(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - lock = lock.unlock_unbond(); - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - // manually unlock recovery - lock.recovery = IbcLock::Unlocked; - assert!(!lock.is_unlocked()); - assert!(lock.is_locked()); - - lock = lock.unlock_migration(); - assert!(lock.is_unlocked()); - assert!(!lock.is_locked()); - - // all should be unlocked - assert!(lock.bond.is_unlocked()); - assert!(lock.start_unbond.is_unlocked()); - assert!(lock.unbond.is_unlocked()); - assert!(lock.recovery.is_unlocked()); - assert!(lock.migration.is_unlocked()); - - // none should be locked - assert!(!lock.bond.is_locked()); - assert!(!lock.start_unbond.is_locked()); - assert!(!lock.unbond.is_locked()); - assert!(!lock.recovery.is_locked()); - assert!(!lock.migration.is_locked()); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/ibc_util.rs b/smart-contracts/contracts/lp-strategy/src/ibc_util.rs deleted file mode 100644 index e2d77545f..000000000 --- a/smart-contracts/contracts/lp-strategy/src/ibc_util.rs +++ /dev/null @@ -1,397 +0,0 @@ -use cosmwasm_std::{ - Coin, ConversionOverflowError, Decimal, Env, Fraction, IbcMsg, IbcTimeout, StdError, Storage, - SubMsg, Uint128, -}; -use osmosis_std::{ - shim::Duration, - types::{ - cosmos::base::v1beta1::Coin as OsmoCoin, - osmosis::{ - gamm::v1beta1::{MsgJoinSwapExternAmountIn, QueryCalcJoinPoolSharesResponse}, - lockup::MsgLockTokens, - }, - }, -}; - -use quasar_types::ica::packet::ica_send; - -use crate::{ - error::ContractError, - helpers::{create_ibc_ack_submsg, get_ica_address, IbcMsgKind, IcaMessages}, - state::{ - OngoingDeposit, PendingBond, CONFIG, IBC_TIMEOUT_TIME, ICA_CHANNEL, SIMULATED_EXIT_RESULT, - SIMULATED_JOIN_RESULT, - }, -}; - -pub fn do_transfer( - storage: &mut dyn Storage, - env: &Env, - amount: Uint128, - channel_id: String, - to_address: String, - deposits: Vec, -) -> Result { - // todo check denom of funds once we have denom mapping done - - let coin = Coin { - denom: CONFIG.load(storage)?.local_denom, - amount, - }; - - let timeout = IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)); - let transfer = IbcMsg::Transfer { - channel_id: channel_id.clone(), - to_address, - amount: coin, - timeout, - }; - - Ok(create_ibc_ack_submsg( - storage, - IbcMsgKind::Transfer { - pending: PendingBond { bonds: deposits }, - amount, - }, - transfer, - channel_id, - )?) -} - -pub fn parse_join_pool( - _storage: &dyn Storage, - join: QueryCalcJoinPoolSharesResponse, -) -> Result { - let join = match join.share_out_amount.parse::() { - Ok(val) => Ok(val), - Err(err) => { - match err.kind() { - // if the string is empty, we return 0 shares out - std::num::IntErrorKind::Empty => Ok(0), - _ => Err(ContractError::ParseIntError { - error: format!("scale:{err}"), - value: join.share_out_amount, - }), - } - } - }?; - - Ok(Uint128::new(join)) -} - -pub fn consolidate_exit_pool_amount_into_local_denom( - storage: &mut dyn Storage, - exit_pool_unbonds: &[OsmoCoin], - spot_price: Decimal, -) -> Result { - let config = CONFIG.load(storage)?; - - // if we receive no tokens in the response, we can't exit the pool - // todo: Should this error? - if exit_pool_unbonds.is_empty() { - return Ok(Uint128::zero()); - } - - // consolidate exit_pool.tokens_out into a single Uint128 by using spot price to convert the quote_denom to local_denom - let base = exit_pool_unbonds - .iter() - .find(|coin| coin.denom == config.base_denom) - .ok_or(ContractError::BaseDenomNotFound)?; - let quote = exit_pool_unbonds - .iter() - .find(|coin| coin.denom == config.quote_denom) - .ok_or(ContractError::QuoteDenomNotFound)?; - - Ok(Uint128::new( - base.amount - .parse::() - .map_err(|err| ContractError::ParseIntError { - error: format!("base_amount:{err}"), - value: base.amount.clone(), - })?, - ) - .checked_add( - Uint128::new( - quote - .amount - .parse::() - .map_err(|err| ContractError::ParseIntError { - error: format!("quote_amount:{err}"), - value: quote.amount.clone(), - })?, - ) - .checked_multiply_ratio(spot_price.denominator(), spot_price.numerator())?, - )?) -} - -pub fn calculate_share_out_min_amount(storage: &mut dyn Storage) -> Result { - let last_sim_join_pool_result = SIMULATED_JOIN_RESULT.load(storage)?; - - // todo: better dynamic slippage estimation, especially for volatile tokens - // diminish the share_out_amount by 5 percent to allow for slippage of 5% on the swap - Ok(last_sim_join_pool_result.checked_multiply_ratio(95u128, 100u128)?) -} - -// exit shares should never be more than total shares here -pub fn calculate_token_out_min_amount(storage: &dyn Storage) -> Result { - let last_sim_exit_pool_unbonds_result = SIMULATED_EXIT_RESULT.load(storage)?; - - // todo: better dynamic slippage estimation, especially for volatile tokens - // diminish the share_out_amount by 5 percent to allow for slippage of 5% on the swap - Ok(last_sim_exit_pool_unbonds_result.checked_multiply_ratio(95u128, 100u128)?) -} - -/// prepare the submsg for joining the pool -#[allow(clippy::too_many_arguments)] // allowing this is not ideal, but for now we want to keep channel_id and pool_id in there -pub fn do_ibc_join_pool_swap_extern_amount_in( - storage: &mut dyn Storage, - env: Env, - pool_id: u64, - denom: String, - amount: Uint128, - share_out_min_amount: Uint128, - deposits: Vec, -) -> Result { - let ica_channel = ICA_CHANNEL.load(storage)?; - let ica_address = get_ica_address(storage, ica_channel.clone())?; - - // setup the first IBC message to send, and save the entire sequence so we have acces to it on acks - let msg = MsgJoinSwapExternAmountIn { - sender: ica_address, - pool_id, - token_in: Some(OsmoCoin { - denom, - amount: amount.to_string(), - }), - share_out_min_amount: share_out_min_amount.to_string(), - }; - - let pkt = ica_send::( - msg, - ica_channel.clone(), - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - )?; - - Ok(create_ibc_ack_submsg( - storage, - IbcMsgKind::Ica(IcaMessages::JoinSwapExternAmountIn(PendingBond { - bonds: deposits, - })), - pkt, - ica_channel, - )?) -} - -pub fn do_ibc_lock_tokens( - storage: &mut dyn Storage, - owner: String, - coins: Vec, -) -> Result { - let lock_period = CONFIG.load(storage)?.lock_period; - - // TODO move the duration to a package and make it settable - Ok(MsgLockTokens { - owner, - duration: Some(Duration { - // TODO clean up this conversion a bit - seconds: i64::try_from(lock_period).map_err(|_| { - ContractError::Std(StdError::ConversionOverflow { - source: ConversionOverflowError { - source_type: "u64", - target_type: "i64", - value: lock_period.to_string(), - }, - }) - })?, - nanos: 0, - }), - coins: coins - .iter() - .map(|c| OsmoCoin { - denom: c.denom.clone(), - amount: c.amount.to_string(), - }) - .collect(), - }) -} - -#[cfg(test)] -mod tests { - use std::str::FromStr; - - use cosmwasm_std::{ - testing::{mock_dependencies, MockApi, MockQuerier, MockStorage}, - Decimal, Empty, IbcEndpoint, OwnedDeps, Uint128, - }; - - use cw_storage_plus::Map; - - use osmosis_std::types::cosmos::base::v1beta1::Coin; - use quasar_types::{ - ibc::{ChannelInfo, ChannelType, HandshakeState}, - ica::handshake::IcaMetadata, - }; - - use crate::{ - ibc_util::{calculate_token_out_min_amount, consolidate_exit_pool_amount_into_local_denom}, - state::{SIMULATED_EXIT_RESULT, SIMULATED_JOIN_RESULT}, - test_helpers::default_setup, - }; - - use super::calculate_share_out_min_amount; - - fn default_instantiate( - channels: &Map, - ) -> OwnedDeps { - let mut deps = mock_dependencies(); - - // load an ICA channel into the deps - let (chan_id, channel_info) = default_ica_channel(); - // unwrap here since this is a test function - channels - .save(deps.as_mut().storage, chan_id, &channel_info) - .unwrap(); - deps - } - - fn default_ica_channel() -> (String, ChannelInfo) { - let chan_id = String::from("channel-0"); - ( - chan_id.clone(), - ChannelInfo { - id: chan_id, - counterparty_endpoint: IbcEndpoint { - port_id: String::from("ica-host"), - channel_id: String::from("channel-0"), - }, - connection_id: String::from("connection-0"), - channel_type: ChannelType::Ica { - channel_ty: IcaMetadata::with_connections( - String::from("connection-0"), - String::from("connection-0"), - ), - counter_party_address: Some(String::from("osmo")), - }, - handshake_state: HandshakeState::Open, - }, - ) - } - - #[test] - fn default_instantiate_works() { - let channels = Map::new("channels"); - let deps = default_instantiate(&channels); - - let _chan = channels - .load(deps.as_ref().storage, "channel-0".to_string()) - .unwrap(); - } - - #[test] - fn test_calculate_share_out_min_amount() { - let mut deps = mock_dependencies(); - SIMULATED_JOIN_RESULT - .save(deps.as_mut().storage, &Uint128::new(999999)) - .unwrap(); - - let min_amount_out = calculate_share_out_min_amount(deps.as_mut().storage).unwrap(); - - assert_eq!(min_amount_out, Uint128::from(949999u128)); - } - - #[test] - fn test_calculate_token_out_min_amount() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - - let exit_amount_local_denom = consolidate_exit_pool_amount_into_local_denom( - deps.as_mut().storage, - &vec![ - Coin { - denom: "uosmo".to_string(), - amount: "50".to_string(), - }, - Coin { - denom: "uqsr".to_string(), - amount: "50".to_string(), - }, - ], - Decimal::from_str("1.0").unwrap(), - ) - .unwrap(); - - SIMULATED_EXIT_RESULT - .save(deps.as_mut().storage, &exit_amount_local_denom) - .unwrap(); - - let min_amount_out = calculate_token_out_min_amount(deps.as_mut().storage).unwrap(); - - assert_eq!(min_amount_out, Uint128::from(95u128)); - - // now lets test with a different amount of exit shares - let exit_amount_local_denom = consolidate_exit_pool_amount_into_local_denom( - deps.as_mut().storage, - &vec![ - Coin { - denom: "uosmo".to_string(), - amount: "500".to_string(), - }, - Coin { - denom: "uqsr".to_string(), - amount: "50".to_string(), - }, - ], - // 1 uosmos = 10 uqsr -> price = 0.1 osmo for 1 uqsr - Decimal::from_str("0.1").unwrap(), - ) - .unwrap(); - - SIMULATED_EXIT_RESULT - .save(deps.as_mut().storage, &exit_amount_local_denom) - .unwrap(); - - let min_amount_out = calculate_token_out_min_amount(deps.as_mut().storage).unwrap(); - - // (500 uosmo + (50 uqsr / 0.1 osmo / uqsr)) * 0.95 = (500 + 500) * 0.95 uosmo = 950 uosmo - assert_eq!(min_amount_out, Uint128::from(1000u128 * 95u128 / 100u128)); - } - - #[test] - fn test_consolidate_exit_pool_amount_into_local_denom() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - - let exit_pool = vec![ - Coin { - denom: "uosmo".to_string(), // base_denom - amount: "100".to_string(), - }, - Coin { - denom: "uqsr".to_string(), // quote_denom - amount: "100".to_string(), - }, - ]; - - let spot_price = Decimal::from_str("1.0").unwrap(); - - let parsed = consolidate_exit_pool_amount_into_local_denom( - deps.as_mut().storage, - &exit_pool, - spot_price, - ) - .unwrap(); - - assert_eq!(parsed, Uint128::new(200)); - - // this is for when UNBOND_QUEUE is empty - let exit_pool = vec![]; - let parsed = consolidate_exit_pool_amount_into_local_denom( - deps.as_mut().storage, - &exit_pool, - spot_price, - ) - .unwrap(); - - assert_eq!(parsed, Uint128::zero()); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/icq.rs b/smart-contracts/contracts/lp-strategy/src/icq.rs deleted file mode 100644 index 0e4a5fc5d..000000000 --- a/smart-contracts/contracts/lp-strategy/src/icq.rs +++ /dev/null @@ -1,410 +0,0 @@ -use cosmwasm_std::{ - to_json_binary, Decimal, Env, Fraction, IbcMsg, IbcTimeout, QuerierWrapper, Storage, SubMsg, - Uint128, -}; -#[allow(deprecated)] -use osmosis_std::types::osmosis::gamm::v1beta1::QuerySpotPriceRequest; -use osmosis_std::types::{ - cosmos::bank::v1beta1::QueryBalanceRequest, - cosmos::base::v1beta1::Coin as OsmoCoin, - osmosis::{ - gamm::v1beta1::{QueryCalcExitPoolCoinsFromSharesRequest, QueryCalcJoinPoolSharesRequest}, - lockup::LockedRequest, - }, -}; -use prost::Message; -use quasar_types::icq::{InterchainQueryPacketData, Query}; - -use crate::{ - error::ContractError, - helpers::{check_icq_channel, create_ibc_ack_submsg, get_ica_address, IbcMsgKind}, - state::{ - BOND_QUEUE, CONFIG, FAILED_JOIN_QUEUE, IBC_LOCK, ICA_CHANNEL, ICQ_CHANNEL, LP_SHARES, - OSMO_LOCK, PENDING_BOND_QUEUE, PENDING_UNBOND_QUEUE, SIMULATED_EXIT_SHARES_IN, - SIMULATED_JOIN_AMOUNT_IN, UNBOND_QUEUE, - }, -}; - -/// try_icq only does something if the IBC_LOCK is unlocked. When it is unlocked, -/// all pending bonds are moved into the active bond queue. -/// -/// It then prepares the following queries: -/// - ICA balance in base denom. -/// - ICA balance in quote denom. -/// - ICA balance in LP shares. -/// - SimulateJoinPool with the total pending bonds amount to estimate slippage and saves the total pending bonds amount in state. -/// - SimulateExitPool with the entire ICA locked amount to get the total value in lp tokens. -/// - SpotPrice of base denom and quote denom to convert quote denom from exitpool to the base denom. -/// - LockedByID to get the current lock state. -/// -/// It also moves all pending unbonds into the active unbond queue and returns an IBC send packet with the queries as a submessage. -pub fn try_icq( - storage: &mut dyn Storage, - _querier: QuerierWrapper, - env: Env, -) -> Result, ContractError> { - if IBC_LOCK.load(storage)?.is_unlocked() { - // TODO fetching ICQ channel and confirming vs handshake version can be a single function - let icq_channel = ICQ_CHANNEL.load(storage)?; - check_icq_channel(storage, icq_channel.clone())?; - - let mut pending_bonds_value = Uint128::zero(); - // we dump pending bonds into the active bond queue - while !PENDING_BOND_QUEUE.is_empty(storage)? { - let bond = PENDING_BOND_QUEUE.pop_front(storage)?; - if let Some(bond) = bond { - BOND_QUEUE.push_back(storage, &bond)?; - pending_bonds_value = pending_bonds_value.checked_add(bond.amount)?; - } - } - - let failed_join_queue_amount = FAILED_JOIN_QUEUE.iter(storage)?.try_fold( - Uint128::zero(), - |acc, val| -> Result { - Ok(acc + val?.amount) - // We should never have LP shares here - }, - )?; - - // the bonding amount that we want to calculate the slippage for is the amount of funds in new bonds and the amount of funds that have - // previously failed to join the pool. These funds are already located on Osmosis and should not be part of the transfer to Osmosis. - let bonding_amount = pending_bonds_value + failed_join_queue_amount; - - // we dump pending unbonds into the active unbond queue and save the total amount of shares that will be unbonded - let mut pending_unbonds_shares = Uint128::zero(); - while !PENDING_UNBOND_QUEUE.is_empty(storage)? { - let unbond = PENDING_UNBOND_QUEUE.pop_front(storage)?; - if let Some(unbond) = unbond { - UNBOND_QUEUE.push_back(storage, &unbond)?; - pending_unbonds_shares = pending_unbonds_shares.checked_add(unbond.lp_shares)?; - } - } - - // deposit needs to internally rebuild the amount of funds under the smart contract - let packet = - prepare_full_query(storage, env.clone(), bonding_amount, pending_unbonds_shares)?; - - let send_packet_msg = IbcMsg::SendPacket { - channel_id: icq_channel, - data: to_json_binary(&packet)?, - timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(7200)), - }; - - let channel = ICQ_CHANNEL.load(storage)?; - - Ok(Some(create_ibc_ack_submsg( - storage, - IbcMsgKind::Icq, - send_packet_msg, - channel, - )?)) - } else { - Ok(None) - } -} - -pub fn prepare_full_query( - storage: &mut dyn Storage, - _env: Env, - bonding_amount: Uint128, - pending_unbonds_shares: Uint128, -) -> Result { - let ica_channel = ICA_CHANNEL.load(storage)?; - // todo: query flows should be separated by which flowType we're doing (bond, unbond, startunbond) - let address = get_ica_address(storage, ica_channel)?; - let config = CONFIG.load(storage)?; - // we query the current balance on our ica address - let base_balance = QueryBalanceRequest { - address: address.clone(), - denom: config.base_denom.clone(), - }; - let quote_balance = QueryBalanceRequest { - address: address.clone(), - denom: config.quote_denom.clone(), - }; - let lp_balance = QueryBalanceRequest { - address, - denom: config.pool_denom.clone(), - }; - // we simulate the result of a join pool to estimate the slippage we can expect during this deposit - // we use the current balance of local_denom for this query. This is safe because at any point - // a pending deposit will only use the current balance of the vault. QueryCalcJoinPoolSharesRequest - // since we're going to be moving the entire pending bond queue to the bond queue in this icq, we can - // fold the PENDING_BOND_QUEUE - // April 27 2023 - we removed get_usable_bond_balance, but we will have to bring it back when we do error - // recovery for deposits - - // we save the amount to scale the slippage against in the icq ack for other incoming bonds - SIMULATED_JOIN_AMOUNT_IN.save(storage, &bonding_amount)?; - - // we have to check that bonding amount is >= 1u128, because otherwise we get ABCI error code 1 (see osmosis: osmosis/x/gamm/pool-models/stableswap/amm.go:299 for the error we get in stableswap pools) - let checked_join_pool = match bonding_amount >= 1u128.into() { - true => Some(QueryCalcJoinPoolSharesRequest { - pool_id: config.pool_id, - tokens_in: vec![OsmoCoin { - denom: config.base_denom.clone(), - amount: bonding_amount.to_string(), - }], - }), - false => None, - }; - - // we save the amount to scale the slippage against in the icq ack for other incoming unbonds? - SIMULATED_EXIT_SHARES_IN.save(storage, &pending_unbonds_shares)?; - - // we have to check that unbonding amount is >= 1u128, because otherwise we get ABCI error code 1 (see osmosis: osmosis/x/gamm/pool-models/stableswap/amm.go:299 for the error we get in stableswap pools) - let checked_exit_pool_unbonds = match pending_unbonds_shares >= 1u128.into() { - true => Some(QueryCalcExitPoolCoinsFromSharesRequest { - pool_id: config.pool_id, - share_in_amount: pending_unbonds_shares.to_string(), - }), - false => None, - }; - - let shares = LP_SHARES.load(storage)?.locked_shares; - let shares_out = if !shares.is_zero() { - shares - } else { - Uint128::one() - }; - - let exit_total_pool = QueryCalcExitPoolCoinsFromSharesRequest { - pool_id: config.pool_id, - share_in_amount: shares_out.to_string(), - }; - // we query the spot price of our base_denom and quote_denom so we can convert the quote_denom from exitpool to the base_denom - #[allow(deprecated)] - let spot_price = QuerySpotPriceRequest { - pool_id: config.pool_id, - base_asset_denom: config.base_denom, - quote_asset_denom: config.quote_denom, - }; - - // path have to be set manually, should be equal to the proto_queries of osmosis-std types - let mut q = Query::new() - .add_request( - base_balance.encode_to_vec().into(), - "/cosmos.bank.v1beta1.Query/Balance".to_string(), - ) - .add_request( - quote_balance.encode_to_vec().into(), - "/cosmos.bank.v1beta1.Query/Balance".to_string(), - ) - .add_request( - lp_balance.encode_to_vec().into(), - "/cosmos.bank.v1beta1.Query/Balance".to_string(), - ) - .add_request( - exit_total_pool.encode_to_vec().into(), - "/osmosis.gamm.v1beta1.Query/CalcExitPoolCoinsFromShares".to_string(), - ) - .add_request( - spot_price.encode_to_vec().into(), - "/osmosis.gamm.v2.Query/SpotPrice".to_string(), - ); - - if let Some(join_pool) = checked_join_pool { - q = q.add_request( - join_pool.encode_to_vec().into(), - "/osmosis.gamm.v1beta1.Query/CalcJoinPoolShares".to_string(), - ) - } - - // only query LockedByID if we have a lock_id - if let Some(lock_id) = OSMO_LOCK.may_load(storage)? { - let lock_by_id = LockedRequest { lock_id }; - q = q.add_request( - lock_by_id.encode_to_vec().into(), - "/osmosis.lockup.Query/LockedByID".to_string(), - ); - } - - // if there're items in the unbond_queue, we query CalcExitPoolCoinsFromShares for the added share amount - if let Some(exit_pool) = checked_exit_pool_unbonds { - q = q.add_request( - exit_pool.encode_to_vec().into(), - "/osmosis.gamm.v1beta1.Query/CalcExitPoolCoinsFromShares".to_string(), - ) - } - - Ok(q.encode_pkt()) -} - -// TODO add quote denom to base denom conversion -// calculate the total balance of the vault using the query from prepare_total_balance_query() -pub fn calc_total_balance( - storage: &mut dyn Storage, - ica_balance: Uint128, - exit_pool: &[OsmoCoin], - spot_price: Decimal, -) -> Result { - let config = CONFIG.load(storage)?; - // if we receive no tokens in the response, the total balance - if exit_pool.is_empty() { - return Ok(ica_balance); - } - - let base = exit_pool - .iter() - .find(|coin| coin.denom == config.base_denom) - .ok_or(ContractError::BaseDenomNotFound)?; - - let quote = exit_pool - .iter() - .find(|coin| coin.denom == config.quote_denom) - .ok_or(ContractError::QuoteDenomNotFound)?; - // return ica_balance + base_amount + (quote_amount * spot_price) - Ok(ica_balance - .checked_add(Uint128::new(base.amount.parse::().map_err( - |err| ContractError::ParseIntError { - error: format!("ica_balance:{err:?}"), - value: base.amount.clone(), - }, - )?))? - .checked_add( - Uint128::new(quote.amount.parse::().map_err(|err| { - ContractError::ParseIntError { - error: format!("quote_denom:{err:?}"), - value: quote.amount.clone(), - } - })?) - .checked_multiply_ratio(spot_price.denominator(), spot_price.numerator())?, - )?) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, MockQuerier}, - Empty, - }; - - use crate::{ - ibc_lock::Lock, - state::{LpCache, IBC_LOCK}, - test_helpers::default_setup, - }; - - use proptest::prelude::*; - - use super::*; - - proptest! { - #[test] - fn calc_total_balance_works(ica_balance in 1..u64::MAX as u128, base_amount in 1..u64::MAX as u128, quote_amount in 1..u64::MAX as u128, spot_price in 1..u64::MAX as u128) { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let config = CONFIG.load(deps.as_ref().storage).unwrap(); - - let tokens = vec![OsmoCoin{ denom: config.base_denom, amount: base_amount.to_string() }, OsmoCoin{ denom: config.quote_denom, amount: quote_amount.to_string() }]; - let spot = Decimal::raw(spot_price); - let total = calc_total_balance(deps.as_mut().storage, Uint128::new(ica_balance), &tokens, spot).unwrap(); - let expecte_quote = Uint128::new(quote_amount).multiply_ratio(spot.denominator(), spot.numerator()); - prop_assert_eq!(total.u128(), ica_balance + base_amount + expecte_quote.u128()) - } - } - - #[test] - fn try_icq_unlocked_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - - LP_SHARES - .save( - deps.as_mut().storage, - &LpCache { - locked_shares: Uint128::new(100), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - - // lock the ibc lock - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = try_icq(deps.as_mut().storage, q, env.clone()).unwrap(); - - let icq_channel = ICQ_CHANNEL.load(deps.as_mut().storage).unwrap(); - - let pkt = IbcMsg::SendPacket { - channel_id: icq_channel.clone(), - data: to_json_binary( - &prepare_full_query( - deps.as_mut().storage, - env.clone(), - Uint128::new(0), - Uint128::zero(), - ) - .unwrap(), - ) - .unwrap(), - timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(7200)), - }; - - assert_eq!( - res.unwrap().msg, - create_ibc_ack_submsg(deps.as_mut().storage, IbcMsgKind::Icq, pkt, icq_channel) - .unwrap() - .msg - ) - } - - #[test] - fn try_icq_locked_bond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - - // lock the ibc lock - IBC_LOCK - .save(deps.as_mut().storage, &Lock::new().lock_bond()) - .unwrap(); - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = try_icq(deps.as_mut().storage, q, env).unwrap(); - assert_eq!(res, None) - } - - #[test] - fn try_icq_locked_start_unbond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - - // lock the ibc lock - IBC_LOCK - .save(deps.as_mut().storage, &Lock::new().lock_start_unbond()) - .unwrap(); - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = try_icq(deps.as_mut().storage, q, env).unwrap(); - assert_eq!(res, None) - } - - #[test] - fn try_icq_locked_unbond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - - // lock the ibc lock - IBC_LOCK - .save(deps.as_mut().storage, &Lock::new().lock_unbond()) - .unwrap(); - - let qx: MockQuerier = MockQuerier::new(&[]); - let q = QuerierWrapper::new(&qx); - - let res = try_icq(deps.as_mut().storage, q, env).unwrap(); - assert_eq!(res, None) - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/integration_tests.rs b/smart-contracts/contracts/lp-strategy/src/integration_tests.rs deleted file mode 100644 index 7bb2e11be..000000000 --- a/smart-contracts/contracts/lp-strategy/src/integration_tests.rs +++ /dev/null @@ -1,420 +0,0 @@ -#[cfg(test)] -mod tests { - use cosmwasm_std::{attr, Addr, Empty}; - use cw_multi_test::{App, Contract, ContractWrapper, Executor}; - - use crate::{ - contract::{execute, instantiate}, - msg::{ExecuteMsg, InstantiateMsg, LockOnly, LockResponse, QueryMsg, UnlockOnly}, - queries::query, - }; - - #[test] - fn test_execute_lock() { - const ADMIN: &str = "admin"; - const CONTRACT_OWNER: &str = "contract_owner"; - - // returns an object that can be used with cw-multi-test - fn contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query); - Box::new(contract) - } - - // an app object is the blockchain simulator. we send initial balance here too if we need - let mut app = App::new(|_router, _api, _storage| {}); - - // upload the contracts to the blockchain and get back code_id to instantiate the contract later - let contract_code_id = app.store_code(contract()); - - // create the instantiate message - let instantiate_msg = InstantiateMsg { - lock_period: 100, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - local_denom: "ibc/local_osmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }; - - // instantiate the contract - let contract_addr = app - .instantiate_contract( - contract_code_id, - Addr::unchecked(CONTRACT_OWNER), - &instantiate_msg, - &[], - "lp-strategy", - Some(ADMIN.to_owned()), - ) - .unwrap(); - - // lock the contract manually using the migration lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Migration, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!(res.events[1].attributes[1], attr("lock_only", "migration")); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // migration lock should be the only one locked - assert!(res.lock.migration.is_locked()); - assert!(res.lock.bond.is_unlocked()); - assert!(res.lock.start_unbond.is_unlocked()); - assert!(res.lock.unbond.is_unlocked()); - assert!(res.lock.recovery.is_unlocked()); - - // lock the contract manually using the bond lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Bond, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!(res.events[1].attributes[1], attr("lock_only", "bond")); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond & migration lock should be the only ones locked - assert!(res.lock.migration.is_locked()); - assert!(res.lock.bond.is_locked()); - assert!(res.lock.start_unbond.is_unlocked()); - assert!(res.lock.unbond.is_unlocked()); - assert!(res.lock.recovery.is_unlocked()); - - // lock the contract manually using the start unbond lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::StartUnbond, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!( - res.events[1].attributes[1], - attr("lock_only", "start_unbond") - ); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond, start unbond, & migration lock should be the only ones locked - assert!(res.lock.migration.is_locked()); - assert!(res.lock.bond.is_locked()); - assert!(res.lock.start_unbond.is_locked()); - assert!(res.lock.unbond.is_unlocked()); - assert!(res.lock.recovery.is_unlocked()); - - // lock the contract manually using the unbond lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Unbond, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!(res.events[1].attributes[1], attr("lock_only", "unbond")); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond, start unbond, unbond, & migration lock should be the only ones locked - assert!(res.lock.migration.is_locked()); - assert!(res.lock.bond.is_locked()); - assert!(res.lock.start_unbond.is_locked()); - assert!(res.lock.unbond.is_locked()); - assert!(res.lock.recovery.is_unlocked()); - - // trying to lock the contract as a non-admin should fail - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Migration, - }; - let res = app.execute_contract( - Addr::unchecked("not-admin"), - contract_addr, - &execute_msg, - &[], - ); - assert!(res.is_err()); - } - - #[test] - fn test_execute_unlock() { - const ADMIN: &str = "admin"; - const CONTRACT_OWNER: &str = "contract_owner"; - - // returns an object that can be used with cw-multi-test - fn contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query); - Box::new(contract) - } - - // an app object is the blockchain simulator. we send initial balance here too if we need - let mut app = App::new(|_router, _api, _storage| {}); - - // upload the contracts to the blockchain and get back code_id to instantiate the contract later - let contract_code_id = app.store_code(contract()); - - // create the instantiate message - let instantiate_msg = InstantiateMsg { - lock_period: 100, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - local_denom: "ibc/local_osmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }; - - // instantiate the contract - let contract_addr = app - .instantiate_contract( - contract_code_id, - Addr::unchecked(CONTRACT_OWNER), - &instantiate_msg, - &[], - "lp-strategy", - Some(ADMIN.to_owned()), - ) - .unwrap(); - - // lock the contract manually to be able to unlock it later - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Migration, - }; - app.execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - // lock the contract manually using the bond lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Bond, - }; - app.execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - // lock the contract manually using the start unbond lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::StartUnbond, - }; - app.execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - // lock the contract manually using the unbond lock - let execute_msg = ExecuteMsg::Lock { - lock_only: LockOnly::Unbond, - }; - app.execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond, start unbond, unbond, & migration lock should be locked - assert!(res.lock.migration.is_locked()); - assert!(res.lock.bond.is_locked()); - assert!(res.lock.start_unbond.is_locked()); - assert!(res.lock.unbond.is_locked()); - assert!(res.lock.recovery.is_unlocked()); - - // unlock the contract manually using the migration lock - let execute_msg = ExecuteMsg::Unlock { - unlock_only: UnlockOnly::Migration, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!( - res.events[1].attributes[1], - attr("unlock_only", "migration") - ); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond, start unbond, unbond, & migration lock should be the only ones locked - assert!(res.lock.migration.is_unlocked()); - assert!(res.lock.bond.is_locked()); - assert!(res.lock.start_unbond.is_locked()); - assert!(res.lock.unbond.is_locked()); - assert!(res.lock.recovery.is_unlocked()); - - // unlock the contract manually using the bond lock - let execute_msg = ExecuteMsg::Unlock { - unlock_only: UnlockOnly::Bond, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!(res.events[1].attributes[1], attr("unlock_only", "bond")); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond, start unbond, unbond, & migration lock should be the only ones locked - assert!(res.lock.migration.is_unlocked()); - assert!(res.lock.bond.is_unlocked()); - assert!(res.lock.start_unbond.is_locked()); - assert!(res.lock.unbond.is_locked()); - assert!(res.lock.recovery.is_unlocked()); - - // unlock the contract manually using the start unbond lock - let execute_msg = ExecuteMsg::Unlock { - unlock_only: UnlockOnly::StartUnbond, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!( - res.events[1].attributes[1], - attr("unlock_only", "start_unbond") - ); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // bond, start unbond, unbond, & migration lock should be the only ones locked - assert!(res.lock.migration.is_unlocked()); - assert!(res.lock.bond.is_unlocked()); - assert!(res.lock.start_unbond.is_unlocked()); - assert!(res.lock.unbond.is_locked()); - assert!(res.lock.recovery.is_unlocked()); - - // unlock the contract manually using the unbond lock - let execute_msg = ExecuteMsg::Unlock { - unlock_only: UnlockOnly::Unbond, - }; - let res = app - .execute_contract( - Addr::unchecked(ADMIN), - contract_addr.clone(), - &execute_msg, - &[], - ) - .unwrap(); - - assert_eq!(res.events[1].attributes[1], attr("unlock_only", "unbond")); - - // check the lock - let query_msg = QueryMsg::Lock {}; - let res: LockResponse = app - .wrap() - .query_wasm_smart(contract_addr.clone(), &query_msg) - .unwrap(); - - // everything should be unlocked - assert!(res.lock.is_unlocked()); - - // trying to unlock the contract as a non-admin should fail - let execute_msg = ExecuteMsg::Unlock { - unlock_only: UnlockOnly::Migration, - }; - let res = app.execute_contract( - Addr::unchecked("non-admin"), - contract_addr, - &execute_msg, - &[], - ); - assert!(res.is_err()); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/lib.rs b/smart-contracts/contracts/lp-strategy/src/lib.rs deleted file mode 100644 index ea9fccb3f..000000000 --- a/smart-contracts/contracts/lp-strategy/src/lib.rs +++ /dev/null @@ -1,31 +0,0 @@ -mod admin; -pub mod bond; -pub mod contract; -pub mod error; -mod error_recovery; -pub mod execute; -pub mod helpers; -pub mod ibc; -pub mod ibc_lock; -mod ibc_util; -pub mod icq; -pub mod msg; -pub mod queries; -pub mod reply; -pub mod start_unbond; -pub mod state; -pub mod unbond; - -#[cfg(test)] -pub mod integration_tests; -pub mod proptests; -pub mod test_helpers; - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert_eq!(result, 4); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/msg.rs b/smart-contracts/contracts/lp-strategy/src/msg.rs deleted file mode 100644 index 14a82d17b..000000000 --- a/smart-contracts/contracts/lp-strategy/src/msg.rs +++ /dev/null @@ -1,285 +0,0 @@ -use std::{ - collections::HashMap, - fmt::{Display, Formatter}, -}; - -use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Coin, IbcPacketAckMsg, StdResult, Uint128}; - -pub use cw20::BalanceResponse; -use quasar_types::ibc::ChannelInfo; - -use crate::{ - bond::Bond, - error::Trap, - helpers::{IbcMsgKind, SubMsgKind}, - ibc_lock, - start_unbond::StartUnbond, - state::{Config, LpCache, OngoingDeposit, Unbond}, - unbond::PendingReturningUnbonds, -}; - -#[cw_serde] -pub struct InstantiateMsg { - pub lock_period: u64, - pub pool_id: u64, // 2 - pub pool_denom: String, // gamm/pool/2 - // if setup correctly, local_denom on quasar == base_denom on osmosis - pub local_denom: String, // ibc/ED07 - pub base_denom: String, // uosmo - pub quote_denom: String, // uatom - // TODO should this be outgoing_transfer_channel? - pub transfer_channel: String, - // TODO rename to return_transfer_channel - pub return_source_channel: String, - pub expected_connection: String, -} - -impl InstantiateMsg { - pub fn validate(&self) -> StdResult<()> { - Ok(()) - } -} - -#[cw_serde] -pub struct MigrateMsg { - pub delete_pending_acks: Vec<(u64, String)>, - pub delete_traps: Vec<(u64, String)>, -} - -#[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - #[returns(ChannelsResponse)] - Channels {}, - #[returns(ConfigResponse)] - Config {}, - #[returns(IcaAddressResponse)] - Balance { address: String }, - #[returns(BalanceResponse)] - IcaAddress {}, - #[returns(LockResponse)] - Lock {}, - #[returns(LpSharesResponse)] - LpShares {}, - #[returns(PrimitiveSharesResponse)] - PrimitiveShares {}, - #[returns(IcaBalanceResponse)] - IcaBalance {}, - #[returns(IcaChannelResponse)] - IcaChannel {}, - #[returns(TrappedErrorsResponse)] - TrappedErrors {}, - #[returns(UnbondingClaimResponse)] - UnbondingClaim { addr: Addr, id: String }, - #[returns(ListUnbondingClaimsResponse)] - ListUnbondingClaims {}, - #[returns(ListBondingClaimsResponse)] - ListBondingClaims {}, - #[returns(ListPrimitiveSharesResponse)] - ListPrimitiveShares {}, - #[returns(ListPendingAcksResponse)] - ListPendingAcks {}, - #[returns(ListRepliesResponse)] - ListReplies {}, - #[returns(ListClaimableFundsResponse)] - ListClaimableFunds {}, - #[returns(OsmoLockResponse)] - OsmoLock {}, - #[returns(SimulatedJoinResponse)] - SimulatedJoin {}, - #[returns(GetQueuesResponse)] - GetQueues {}, -} - -#[cw_serde] -pub struct GetQueuesResponse { - pub pending_bond_queue: Vec, - pub bond_queue: Vec, - pub start_unbond_queue: Vec, - pub unbond_queue: Vec, - pub failed_join_queue: Vec, - pub rejoin_queue: Vec, - pub pending_unbond_queue: Vec, -} - -#[cw_serde] -pub struct SimulatedJoinResponse { - pub amount: Option, - pub result: Option, -} - -#[cw_serde] -pub struct OsmoLockResponse { - pub lock_id: u64, -} - -#[cw_serde] -pub struct ListBondingClaimsResponse { - pub bonds: HashMap, -} - -#[cw_serde] -pub struct ListRepliesResponse { - pub replies: HashMap, -} - -#[cw_serde] -pub struct ListClaimableFundsResponse { - pub claimable_funds: HashMap, -} - -#[cw_serde] -pub struct ListPrimitiveSharesResponse { - pub shares: HashMap, -} - -#[cw_serde] -pub struct ListPendingAcksResponse { - pub pending: HashMap, -} - -#[cw_serde] -pub struct ListUnbondingClaimsResponse { - pub unbonds: HashMap, - pub pending_unbonds: HashMap, -} - -#[cw_serde] -pub struct UnbondingClaimResponse { - pub unbond: Option, -} - -#[cw_serde] -pub struct ChannelsResponse { - pub channels: Vec, -} - -#[cw_serde] -pub struct TrappedErrorsResponse { - pub errors: HashMap, -} - -#[cw_serde] -pub struct LpSharesResponse { - pub lp_shares: LpCache, -} - -#[cw_serde] -pub struct ConfigResponse { - pub config: Config, -} - -#[cw_serde] -pub struct LockResponse { - pub lock: ibc_lock::Lock, -} - -#[cw_serde] -pub struct IcaAddressResponse { - pub address: String, -} - -#[cw_serde] -pub struct PrimitiveSharesResponse { - pub total: Uint128, -} - -#[cw_serde] -pub struct IcaBalanceResponse { - pub amount: Coin, -} - -#[cw_serde] -pub struct IcaChannelResponse { - pub channel: String, -} - -#[cw_serde] -pub enum UnlockOnly { - Bond, - StartUnbond, - Unbond, - Migration, -} - -impl Display for UnlockOnly { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - UnlockOnly::Bond => write!(f, "bond"), - UnlockOnly::StartUnbond => write!(f, "start_unbond"), - UnlockOnly::Unbond => write!(f, "unbond"), - UnlockOnly::Migration => write!(f, "migration"), - } - } -} - -#[cw_serde] -pub enum LockOnly { - Bond, - StartUnbond, - Unbond, - Migration, -} - -impl Display for LockOnly { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - LockOnly::Bond => write!(f, "bond"), - LockOnly::StartUnbond => write!(f, "start_unbond"), - LockOnly::Unbond => write!(f, "unbond"), - LockOnly::Migration => write!(f, "migration"), - } - } -} - -#[cw_serde] -pub enum ExecuteMsg { - Bond { - id: String, - }, - StartUnbond { - id: String, - share_amount: Uint128, - }, - Unbond { - id: String, - }, - SetDepositor { - depositor: String, - }, - // accept a dispatched transfer from osmosis - AcceptReturningFunds { - id: u64, - pending: PendingReturningUnbonds, - }, - // try to close a channel where a timout occured - CloseChannel { - channel_id: String, - }, - Ack { - ack: IbcPacketAckMsg, - }, - TryIcq {}, - Unlock { - unlock_only: UnlockOnly, - }, - Lock { - lock_only: LockOnly, - }, - AddLockAdmin { - to_add: String, - }, - RemoveLockAdmin { - to_remove: String, - }, - ManualTimeout { - seq: u64, - channel: String, - should_unlock: bool, - }, - Retry { - seq: u64, - channel: String, - }, -} diff --git a/smart-contracts/contracts/lp-strategy/src/proptests.rs b/smart-contracts/contracts/lp-strategy/src/proptests.rs deleted file mode 100644 index f52017bde..000000000 --- a/smart-contracts/contracts/lp-strategy/src/proptests.rs +++ /dev/null @@ -1,291 +0,0 @@ -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - attr, - testing::{mock_dependencies, mock_env}, - to_json_binary, Addr, Binary, Coin, CosmosMsg, Empty, IbcMsg, MessageInfo, StdError, - Uint128, - }; - use proptest::prelude::*; - use prost::Message; - use quasar_types::icq::{CosmosResponse, InterchainQueryPacketAck}; - - use crate::{ - bond::Bond, - contract::execute_try_icq, - error::Trap, - execute::execute_retry, - helpers::{IbcMsgKind, IcaMessages}, - ibc::handle_icq_ack, - ibc_lock::Lock, - state::{ - OngoingDeposit, PendingBond, RawAmount, FAILED_JOIN_QUEUE, IBC_LOCK, LOCK_ADMIN, - PENDING_BOND_QUEUE, REJOIN_QUEUE, TRAPS, - }, - test_helpers::{create_query_response, default_setup, pending_bond_to_bond}, - }; - use osmosis_std::types::cosmos::base::v1beta1::Coin as OsmoCoin; - use osmosis_std::types::{ - cosmos::bank::v1beta1::QueryBalanceResponse, - osmosis::gamm::v1beta1::{ - QueryCalcExitPoolCoinsFromSharesResponse, QueryCalcJoinPoolSharesResponse, - QuerySpotPriceResponse, - }, - }; - use proptest::collection::vec; - - proptest! { - - #[test] - fn test_handle_retry_join_pool_with_pending_deposits_works( - // values to mock failed join pool - (claim_amount, raw_amount, owner, bond_id) in (0usize..100).prop_flat_map(|size| - ( - // to avoid overflows, we limit the amounts to u64. also force amounts & bond_ids to be >= 1 - vec(any::().prop_map(|x| (x as u128).max(1)), size..=size), - vec(any::().prop_map(|x| (x as u128).max(1)), size..=size), - vec("[a-z]+", size..=size), - vec(any::().prop_map(|x| (x as u128).max(1)), size..=size), - ) - ), - // values to mock pending deposits - (amount_pd, owner_pd, bond_id_pd) in (0usize..100).prop_flat_map(|size| - ( - // to avoid overflows, we limit the amounts to u64. also force amounts & bond_ids to be >= 1 - vec(any::().prop_map(|x| (x as u128).max(1)), size..=size), - vec("[a-z]+", size..=size), - vec(any::().prop_map(|x| (x as u128).max(1)), size..=size), - ) - ), - // values to mock ICQ ACK - raw_balalance_rq in any::(), - quote_balance_rq in any::(), - lp_balance_rq in any::(), - join_pool_rq in any::(), - exit_pool_base_rq in any::(), - exit_pool_quote_rq in any::(), - spot_price_rq in any::(), - ) { - let mut deps = mock_dependencies(); - let env = mock_env(); - default_setup(deps.as_mut().storage).unwrap(); - - IBC_LOCK.save(deps.as_mut().storage, &Lock::new()).unwrap(); - - LOCK_ADMIN - .save(deps.as_mut().storage, &Addr::unchecked("admin"), &Empty {}) - .unwrap(); - - // mock the failed join pool trap with 3 bonds - let failed = PendingBond { - bonds: claim_amount.iter().zip(&raw_amount).zip(&owner).zip(&bond_id).map(|(((_claim, raw), owner), id)| { - OngoingDeposit { - claim_amount: Uint128::new(*raw), - raw_amount: RawAmount::LocalDenom(Uint128::new(*raw)), - owner: Addr::unchecked(owner), - bond_id: id.to_string(), - } - }).collect(), - }; - - TRAPS - .save( - deps.as_mut().storage, - (3539, "channel-35".to_string()), - &Trap { - error: "join pool failed on osmosis".to_string(), - step: IbcMsgKind::Ica(IcaMessages::JoinSwapExternAmountIn(failed.clone())), - last_succesful: true, - }, - ) - .unwrap(); - - // mock pending deposits and add them to the pending queue - let pending_bonds: Vec = amount_pd.iter().zip(&owner_pd).zip(&bond_id_pd).map(|((amount, owner), id)| { - Bond { - amount: Uint128::new(*amount), - owner: Addr::unchecked(owner), - bond_id: id.to_string(), - } - }).collect(); - - for bond in pending_bonds.iter() { - PENDING_BOND_QUEUE - .push_back(deps.as_mut().storage, bond) - .unwrap(); - } - - // manually trigger retry join pool - let res = execute_retry( - deps.as_mut(), - env.clone(), - MessageInfo { - sender: Addr::unchecked("admin"), - funds: vec![], - }, - 3539, - "channel-35".to_string(), - ) - .unwrap(); - - prop_assert!(!TRAPS.has(&deps.storage, (3539, "channel-35".to_string()))); - - let mut attributes = vec![ - attr("action", "retry"), - attr("kind", "join_pool"), - ]; - - for bond in &failed.bonds { - if let RawAmount::LocalDenom(amount) = bond.raw_amount { - attributes.push(attr("bond_id", &bond.bond_id)); - attributes.push(attr("amount", amount)); - } - } - - prop_assert_eq!( - res.attributes, - attributes - ); - - // check that the failed join queue has the same mocked bonds - let failed_join_queue: Result, StdError> = - FAILED_JOIN_QUEUE.iter(&deps.storage).unwrap().collect(); - prop_assert_eq!(failed_join_queue.unwrap(), pending_bond_to_bond(&failed)); - - - // manually trigger try_icq - let res = execute_try_icq(deps.as_mut(), env.clone()); - prop_assert_eq!(res.unwrap().messages.len(), 1); - - // mocking the ICQ ACK - let raw_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uatom".to_string(), - amount: raw_balalance_rq.to_string(), - }), - } - .encode_to_vec(), - ); - - let quote_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: quote_balance_rq.to_string(), - }), - } - .encode_to_vec(), - ); - - let lp_balance = create_query_response( - QueryBalanceResponse { - balance: Some(OsmoCoin { - denom: "uosmo".to_string(), - amount: lp_balance_rq.to_string(), - }), - } - .encode_to_vec(), - ); - - let exit_pool = create_query_response( - QueryCalcExitPoolCoinsFromSharesResponse { - tokens_out: vec![ - OsmoCoin { - // base denom - denom: "uosmo".to_string(), - amount: exit_pool_base_rq.to_string(), - }, - OsmoCoin { - // quote denom - denom: "uqsr".to_string(), - amount: exit_pool_quote_rq.to_string(), - }, - ], - } - .encode_to_vec(), - ); - - let spot_price = create_query_response( - QuerySpotPriceResponse { - spot_price: (spot_price_rq+1).to_string(), - } - .encode_to_vec(), - ); - - let join_pool = create_query_response( - QueryCalcJoinPoolSharesResponse { - share_out_amount: "123".to_string(), - tokens_out: vec![OsmoCoin { - denom: "uosmo".to_string(), - amount: join_pool_rq.to_string(), - }], - } - .encode_to_vec(), - ); - - // LockResponse is fixed to None in this test for simplicity - // let lock = create_query_response(LockedResponse { lock: None }.encode_to_vec()); - - let ibc_ack = InterchainQueryPacketAck { - data: Binary::from( - &CosmosResponse { - responses: vec![ - raw_balance, - quote_balance, - lp_balance, - exit_pool, - spot_price, - join_pool, - // lock, - ], - } - .encode_to_vec()[..], - ), - }; - - // simulate that we received the ICQ ACK - let res = handle_icq_ack(deps.as_mut().storage, env, to_json_binary(&ibc_ack).unwrap()).unwrap(); - - // get the pending bonds total amount - let pending_total_amount = pending_bonds.iter().fold(Uint128::zero(), |acc, bond| { - acc + bond.amount - }); - - // check that the res amount matches the amount in the pending queue ONLY - // only if there are messages - if !res.messages.is_empty() { - match &res.messages[0].msg { - CosmosMsg::Ibc(IbcMsg::Transfer { amount, .. }) => { - assert_eq!( - amount, - &Coin { - denom: "ibc/local_osmo".to_string(), - amount: pending_total_amount, - } - ); - } - _ => panic!("unexpected message type"), - }; - } - - - // if BOND_QUEUE & REJOIN_QUEUE are empty FAILED_JOIN_QUEUE items are not moved to REJOIN_QUEUE - if !pending_bonds.is_empty() && !failed.bonds.is_empty() { - prop_assert!(FAILED_JOIN_QUEUE.is_empty(&deps.storage).unwrap()); - } - - // PENDING_BOND_QUEUE should be empty - prop_assert!(PENDING_BOND_QUEUE.is_empty(&deps.storage).unwrap()); - - // failed bonds should be now in the REJOIN_QUEUE - let rejoin_queue: Result, StdError> = - REJOIN_QUEUE.iter(&deps.storage).unwrap().collect(); - - // only check when there's pending bonds & failed bonds - if !pending_bonds.is_empty() && !failed.bonds.is_empty() { - assert_eq!(failed.bonds, rejoin_queue.unwrap()); - } - } - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/queries.rs b/smart-contracts/contracts/lp-strategy/src/queries.rs deleted file mode 100644 index f8e1675e9..000000000 --- a/smart-contracts/contracts/lp-strategy/src/queries.rs +++ /dev/null @@ -1,336 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cw20::BalanceResponse; -use std::collections::HashMap; - -use cosmwasm_std::{ - to_json_binary, Addr, Binary, Coin, Deps, Env, Order, StdError, StdResult, Uint128, -}; -use quasar_types::ibc::ChannelInfo; - -use crate::{ - bond::Bond, - error::Trap, - helpers::{get_ica_address, get_total_primitive_shares, IbcMsgKind, SubMsgKind}, - msg::{ - ChannelsResponse, ConfigResponse, GetQueuesResponse, IcaAddressResponse, - IcaBalanceResponse, IcaChannelResponse, ListBondingClaimsResponse, - ListClaimableFundsResponse, ListPendingAcksResponse, ListPrimitiveSharesResponse, - ListRepliesResponse, ListUnbondingClaimsResponse, LockResponse, LpSharesResponse, - OsmoLockResponse, PrimitiveSharesResponse, QueryMsg, SimulatedJoinResponse, - TrappedErrorsResponse, UnbondingClaimResponse, - }, - start_unbond::StartUnbond, - state::{ - FundPath, OngoingDeposit, Unbond, BONDING_CLAIMS, BOND_QUEUE, CHANNELS, CLAIMABLE_FUNDS, - CONFIG, FAILED_JOIN_QUEUE, IBC_LOCK, ICA_CHANNEL, LP_SHARES, OSMO_LOCK, PENDING_ACK, - PENDING_BOND_QUEUE, PENDING_UNBONDING_CLAIMS, PENDING_UNBOND_QUEUE, REJOIN_QUEUE, REPLIES, - SHARES, SIMULATED_JOIN_AMOUNT_IN, SIMULATED_JOIN_RESULT, START_UNBOND_QUEUE, - TOTAL_VAULT_BALANCE, TRAPS, UNBONDING_CLAIMS, UNBOND_QUEUE, - }, -}; - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { - match msg { - QueryMsg::Channels {} => to_json_binary(&handle_channels_query(deps)?), - QueryMsg::Config {} => to_json_binary(&handle_config_query(deps)?), - QueryMsg::IcaAddress {} => to_json_binary(&handle_ica_address_query(deps)?), - QueryMsg::Balance { address } => to_json_binary(&handle_balance_query(deps, &address)?), - QueryMsg::PrimitiveShares {} => to_json_binary(&handle_primitive_shares(deps)?), - QueryMsg::IcaBalance {} => to_json_binary(&handle_ica_balance(deps)?), - QueryMsg::IcaChannel {} => to_json_binary(&handle_ica_channel(deps)?), - QueryMsg::Lock {} => to_json_binary(&handle_lock(deps)?), - QueryMsg::LpShares {} => to_json_binary(&handle_lp_shares_query(deps)?), - QueryMsg::TrappedErrors {} => to_json_binary(&handle_trapped_errors_query(deps)?), - QueryMsg::ListUnbondingClaims {} => to_json_binary(&handle_list_unbonding_claims(deps)?), - QueryMsg::UnbondingClaim { addr, id } => { - to_json_binary(&handle_unbonding_claim_query(deps, addr, id)?) - } - QueryMsg::ListBondingClaims {} => to_json_binary(&handle_list_bonding_claims(deps)?), - QueryMsg::ListPrimitiveShares {} => to_json_binary(&handle_list_primitive_shares(deps)?), - QueryMsg::ListPendingAcks {} => to_json_binary(&handle_list_pending_acks(deps)?), - QueryMsg::ListReplies {} => to_json_binary(&handle_list_replies(deps)?), - QueryMsg::ListClaimableFunds {} => to_json_binary(&handle_list_claimable_funds(deps)?), - QueryMsg::OsmoLock {} => to_json_binary(&handle_osmo_lock(deps)?), - QueryMsg::SimulatedJoin {} => to_json_binary(&handle_simulated_join(deps)?), - QueryMsg::GetQueues {} => to_json_binary(&handle_get_queues(deps)?), - } -} - -pub fn handle_get_queues(deps: Deps) -> StdResult { - let pbq: Result, StdError> = PENDING_BOND_QUEUE.iter(deps.storage)?.collect(); - let bq: Result, StdError> = BOND_QUEUE.iter(deps.storage)?.collect(); - let suq: Result, StdError> = START_UNBOND_QUEUE.iter(deps.storage)?.collect(); - let uq: Result, StdError> = UNBOND_QUEUE.iter(deps.storage)?.collect(); - let fjq: Result, StdError> = FAILED_JOIN_QUEUE.iter(deps.storage)?.collect(); - let rj: Result, StdError> = REJOIN_QUEUE.iter(deps.storage)?.collect(); - let puq: Result, StdError> = PENDING_UNBOND_QUEUE.iter(deps.storage)?.collect(); - Ok(GetQueuesResponse { - pending_bond_queue: pbq?, - bond_queue: bq?, - start_unbond_queue: suq?, - unbond_queue: uq?, - failed_join_queue: fjq?, - rejoin_queue: rj?, - pending_unbond_queue: puq?, - }) -} - -pub fn handle_simulated_join(deps: Deps) -> StdResult { - Ok(SimulatedJoinResponse { - amount: SIMULATED_JOIN_AMOUNT_IN.may_load(deps.storage)?, - result: SIMULATED_JOIN_RESULT.may_load(deps.storage)?, - }) -} - -pub fn handle_osmo_lock(deps: Deps) -> StdResult { - Ok(OsmoLockResponse { - lock_id: OSMO_LOCK.load(deps.storage)?, - }) -} - -pub fn handle_list_unbonding_claims(deps: Deps) -> StdResult { - let unbonds: StdResult> = UNBONDING_CLAIMS - .range(deps.storage, None, None, Order::Ascending) - .map(|res| { - let val = res?; - Ok((val.0 .0, (val.0 .1, val.1))) - }) - .collect(); - let pending_unbonds: StdResult> = PENDING_UNBONDING_CLAIMS - .range(deps.storage, None, None, Order::Ascending) - .map(|res| { - let val = res?; - Ok((val.0 .0, (val.0 .1, val.1))) - }) - .collect(); - Ok(ListUnbondingClaimsResponse { - unbonds: unbonds?, - pending_unbonds: pending_unbonds?, - }) -} - -pub fn handle_unbonding_claim_query( - deps: Deps, - addr: Addr, - id: String, -) -> StdResult { - Ok(UnbondingClaimResponse { - unbond: UNBONDING_CLAIMS.may_load(deps.storage, (addr, id))?, - }) -} - -pub fn handle_trapped_errors_query(deps: Deps) -> StdResult { - let trapped: StdResult> = TRAPS - .range(deps.storage, None, None, Order::Ascending) - .map(|res| { - let ((seq, chan), kind) = res?; - Ok((format!("{seq}-{chan}"), kind)) - }) - .collect(); - Ok(TrappedErrorsResponse { errors: trapped? }) -} - -pub fn handle_channels_query(deps: Deps) -> StdResult { - let channels: Vec = CHANNELS - .range(deps.storage, None, None, Order::Ascending) - .map(|kv| kv.unwrap().1) - .collect(); - Ok(ChannelsResponse { channels }) -} - -pub fn handle_lp_shares_query(deps: Deps) -> StdResult { - Ok(LpSharesResponse { - lp_shares: LP_SHARES.load(deps.storage)?, - }) -} - -pub fn handle_config_query(deps: Deps) -> StdResult { - Ok(ConfigResponse { - config: CONFIG.load(deps.storage)?, - }) -} - -pub fn handle_ica_address_query(deps: Deps) -> StdResult { - Ok(IcaAddressResponse { - address: get_ica_address(deps.storage, ICA_CHANNEL.load(deps.storage)?) - .expect("ica address setup correctly"), - }) -} - -pub fn handle_balance_query(deps: Deps, address: &str) -> StdResult { - Ok(BalanceResponse { - balance: SHARES.load(deps.storage, deps.api.addr_validate(address)?)?, - }) -} - -pub fn handle_ica_channel(deps: Deps) -> StdResult { - Ok(IcaChannelResponse { - channel: ICA_CHANNEL.load(deps.storage)?, - }) -} - -pub fn handle_primitive_shares(deps: Deps) -> StdResult { - let total = get_total_primitive_shares(deps.storage).map_err(|err| StdError::GenericErr { - msg: err.to_string(), - })?; - Ok(PrimitiveSharesResponse { total }) -} - -pub fn handle_ica_balance(deps: Deps) -> StdResult { - let amount = TOTAL_VAULT_BALANCE.load(deps.storage)?; - - Ok(IcaBalanceResponse { - amount: Coin { - denom: CONFIG.load(deps.storage)?.local_denom, - amount, - }, - }) -} - -pub fn handle_lock(deps: Deps) -> StdResult { - Ok(LockResponse { - lock: IBC_LOCK - .load(deps.storage) - .map_err(|err| StdError::GenericErr { - msg: err.to_string(), - })?, - }) -} - -pub fn handle_list_bonding_claims(deps: Deps) -> StdResult { - let bonds: StdResult> = BONDING_CLAIMS - .range(deps.storage, None, None, Order::Ascending) - .map(|res| { - let val = res?; - Ok((val.0 .0, (val.0 .1, val.1))) - }) - .collect(); - Ok(ListBondingClaimsResponse { bonds: bonds? }) -} - -pub fn handle_list_primitive_shares(deps: Deps) -> StdResult { - let shares: StdResult> = SHARES - .range(deps.storage, None, None, Order::Ascending) - .collect(); - Ok(ListPrimitiveSharesResponse { shares: shares? }) -} - -pub fn handle_list_pending_acks(deps: Deps) -> StdResult { - let pending: StdResult> = PENDING_ACK - .range(deps.storage, None, None, Order::Ascending) - .map(|res| { - let ((seq, chan), kind) = res?; - Ok((format!("{seq}-{chan}"), kind)) - }) - .collect(); - Ok(ListPendingAcksResponse { pending: pending? }) -} - -pub fn handle_list_replies(deps: Deps) -> StdResult { - let replies: StdResult> = REPLIES - .range(deps.storage, None, None, Order::Ascending) - .collect(); - Ok(ListRepliesResponse { replies: replies? }) -} - -pub fn handle_list_claimable_funds(deps: Deps) -> StdResult { - let funds = CLAIMABLE_FUNDS.range(deps.storage, None, None, Order::Ascending); - - let mut claimable_funds: HashMap = HashMap::new(); - for fund in funds { - let ((addr, fp), amount) = fund?; - let path; - let seq = match fp { - FundPath::Bond { id } => { - path = "bond"; - id - } - FundPath::Unbond { id } => { - path = "unbond"; - id - } - }; - claimable_funds.insert(format!("{addr}-{seq}-{path}"), amount); - } - - Ok(ListClaimableFundsResponse { claimable_funds }) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env}, - }; - - use crate::state::FundPath; - - use super::*; - - #[test] - fn get_trapped_errors_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let q = QueryMsg::TrappedErrors {}; - - TRAPS - .save( - deps.as_mut().storage, - (100, "channel-1".to_string()), - &Trap { - error: "failed to do a thing".to_string(), - step: IbcMsgKind::Icq, - last_succesful: true, - }, - ) - .unwrap(); - - let _res = query(deps.as_ref(), env, q).unwrap(); - } - - #[test] - fn get_trapped_errors_when_empty() { - let deps = mock_dependencies(); - let env = mock_env(); - - let q = QueryMsg::TrappedErrors {}; - - let res: TrappedErrorsResponse = from_json(&query(deps.as_ref(), env, q).unwrap()).unwrap(); - - assert!(res.errors.is_empty()); - } - - #[test] - fn proper_get_claimable_funds() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let q = QueryMsg::ListClaimableFunds {}; - - CLAIMABLE_FUNDS - .save( - deps.as_mut().storage, - ( - Addr::unchecked("somedepositor"), - FundPath::Bond { - id: "channel-1".to_string(), - }, - ), - &Uint128::new(100), - ) - .unwrap(); - - let res = query(deps.as_ref(), env, q).unwrap(); - let claimable_funds: ListClaimableFundsResponse = from_json(&res).unwrap(); - - println!("{claimable_funds:?}"); - assert_eq!(claimable_funds.claimable_funds.len(), 1); - assert_eq!( - claimable_funds.claimable_funds["somedepositor-\u{1}\0channel-1-bond"], - Uint128::new(100) - ); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/reply.rs b/smart-contracts/contracts/lp-strategy/src/reply.rs deleted file mode 100644 index 5b91dd0dd..000000000 --- a/smart-contracts/contracts/lp-strategy/src/reply.rs +++ /dev/null @@ -1,370 +0,0 @@ -use cosmwasm_std::{Addr, BankMsg, StdError}; -use cosmwasm_std::{DepsMut, Reply, Response}; -use quasar_types::callback::Callback; - -use crate::error::{ContractError, Trap}; -use crate::helpers::{parse_seq, unlock_on_error, ContractCallback, IbcMsgKind}; -use crate::state::{FundPath, CLAIMABLE_FUNDS, PENDING_ACK, REPLIES, TRAPS}; - -pub fn handle_ibc_reply( - deps: DepsMut, - msg: Reply, - pending: IbcMsgKind, - channel: String, -) -> Result { - let data = msg - .result - .into_result() - .map_err(|msg| StdError::GenericErr { - msg: format!("submsg error: {msg:?}"), - })? - .data - .ok_or(ContractError::NoReplyData) - .map_err(|_| StdError::NotFound { - kind: "reply-data".to_string(), - })?; - - let seq = parse_seq(data).map_err(|err| StdError::SerializeErr { - source_type: "protobuf-decode".to_string(), - msg: err.to_string(), - })?; - - PENDING_ACK.save(deps.storage, (seq, channel), &pending)?; - - // cleanup the REPLIES state item - REPLIES.remove(deps.storage, msg.id); - - Ok(Response::default() - .add_attribute("pending-msg", seq.to_string()) - .add_attribute("step", format!("{pending:?}"))) -} - -pub fn handle_ack_reply( - deps: DepsMut, - msg: Reply, - seq: u64, - channel: String, -) -> Result { - let mut resp = Response::new(); - - // if we have an error in our Ack execution, the submsg saves the error in TRAPS and (should) rollback - // the entire state of the ack execution, - if let Err(error) = msg.result.into_result() { - let step = PENDING_ACK.load(deps.storage, (seq, channel.clone()))?; - unlock_on_error(deps.storage, &step)?; - - // reassignment needed since add_attribute - resp = resp.add_attribute("trapped-error", error.as_str()); - - TRAPS.save( - deps.storage, - (seq, channel), - &Trap { - error, - step, - last_succesful: true, - }, - )?; - } - // if we did not error, we can safely remove the ack entry from the contract - else { - PENDING_ACK.remove(deps.storage, (seq, channel)) - } - - // // cleanup the REPLIES state item - REPLIES.remove(deps.storage, msg.id); - Ok(resp.add_attribute("register-ack-seq", seq.to_string())) -} - -pub fn handle_callback_reply( - deps: DepsMut, - msg: Reply, - callback: ContractCallback, -) -> Result { - // TODO: if error, add manual withdraws to lp-strategy - // - // create in claimable_funds map... Addr, unbond_id -> amount - // in Callback contract add callbacl(callback, amount) - let mut res = Response::new(); - - if let Err(error) = msg.result.clone().into_result() { - match callback.clone() { - // if unbond response callback message, add the amount to the claimable funds map - ContractCallback::Callback { - callback, - amount, - owner, - } => { - if let Callback::UnbondResponse(ur) = callback { - let fund_path = FundPath::Unbond { id: ur.unbond_id }; - match amount { - Some(amount) => { - let amt = amount; - CLAIMABLE_FUNDS.save(deps.storage, (owner, fund_path), &amt)?; - res = res.add_attribute("unbond-callback-error", error.as_str()); - Ok(amt) - } - // TODO: final release should not return an error but log - None => Err(ContractError::CallbackHasNoAmount {}), - }?; - } - } - // if bank callback, add the amount to the claimable funds map - ContractCallback::Bank { - bank_msg, - unbond_id, - } => { - if let BankMsg::Send { to_address, amount } = bank_msg { - CLAIMABLE_FUNDS.save( - deps.storage, - ( - Addr::unchecked(to_address), - FundPath::Unbond { id: unbond_id }, - ), - // should we make sure users don't send more than one Coin? or this can't happen ever - &amount[0].amount, - )?; - res = res.add_attribute("bank-callback-error", error.as_str()); - } - } - } - } - - // Q: should we handle the callback bank message? - - // cleanup the REPLIES state item - REPLIES.remove(deps.storage, msg.id); - Ok(res - .add_attribute("reply-msg-id", msg.id.to_string()) - .add_attribute("reply-result", format!("{:?}", msg.result)) - .add_attribute("action", "handle-callback-reply") - .add_attribute("callback-info", format!("{callback:?}"))) -} - -// test handle callback reply - -#[cfg(test)] -mod tests { - use super::*; - use cosmwasm_std::{ - testing::mock_dependencies, Addr, Attribute, Coin, Reply, SubMsgResponse, SubMsgResult, - Uint128, - }; - use quasar_types::callback::Callback; - - use crate::{helpers::ContractCallback, reply::handle_callback_reply, state::REPLIES}; - - #[test] - fn handle_ack_reply_ok_works() { - let mut deps = mock_dependencies(); - let submsg_id = 1; - let reply = Reply { - id: submsg_id, - result: SubMsgResult::Ok(SubMsgResponse { - events: vec![], - data: None, - }), - }; - - let seq = 1; - let channel = "icq-channel".to_string(); - PENDING_ACK - .save( - deps.as_mut().storage, - (seq, channel.clone()), - &IbcMsgKind::Icq, - ) - .unwrap(); - - let res = handle_ack_reply(deps.as_mut(), reply, seq, channel.clone()).unwrap(); - assert_eq!( - res.attributes, - vec![Attribute { - key: "register-ack-seq".to_string(), - value: seq.to_string() - }] - ); - assert!(!PENDING_ACK.has(deps.as_mut().storage, (seq, channel))) - } - - #[test] - fn test_handle_callback_reply_is_unbond_err() { - use cosmwasm_std::{testing::mock_dependencies, SubMsgResult, Uint128}; - use quasar_types::callback::UnbondResponse; - - use crate::{ - helpers::SubMsgKind, - state::{FundPath, CLAIMABLE_FUNDS}, - }; - - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("owner"); - - let contract_callback = ContractCallback::Callback { - callback: Callback::UnbondResponse(UnbondResponse { - unbond_id: "unbond_id".to_string(), - }), - amount: Some(Uint128::new(100)), - owner: owner.clone(), - }; - let msg = Reply { - id: 1, - result: SubMsgResult::Err("error".to_string()), - }; - - // mocking replies - REPLIES - .save( - &mut deps.storage, - msg.id, - &SubMsgKind::Callback(contract_callback.clone()), - ) - .unwrap(); - - let res = handle_callback_reply(deps.as_mut(), msg.clone(), contract_callback).unwrap(); - assert_eq!(res.attributes.len(), 5); - assert_eq!(res.attributes[0].key, "unbond-callback-error"); - assert_eq!(res.attributes[0].value, "error"); - - assert_eq!( - CLAIMABLE_FUNDS - .load( - &deps.storage, - ( - owner, - FundPath::Unbond { - id: "unbond_id".to_string(), - }, - ), - ) - .unwrap(), - Uint128::new(100) - ); - - // after cleanup it should be empty - assert!(REPLIES.load(&deps.storage, msg.id).is_err()); - } - - #[test] - fn test_handle_callback_reply_is_bank_err() { - use cosmwasm_std::{testing::mock_dependencies, SubMsgResult, Uint128}; - - use crate::{ - helpers::SubMsgKind, - state::{FundPath, CLAIMABLE_FUNDS}, - }; - - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("owner"); - - let bank_msg = BankMsg::Send { - to_address: owner.to_string(), - amount: vec![Coin { - denom: "denom".to_string(), - amount: Uint128::new(69), - }], - }; - - let contract_callback = ContractCallback::Bank { - bank_msg, - unbond_id: "unbond_id".to_string(), - }; - - let msg = Reply { - id: 1, - result: SubMsgResult::Err("error".to_string()), - }; - - // mocking replies - REPLIES - .save( - &mut deps.storage, - msg.id, - &SubMsgKind::Callback(contract_callback.clone()), - ) - .unwrap(); - - let res = handle_callback_reply(deps.as_mut(), msg.clone(), contract_callback).unwrap(); - assert_eq!(res.attributes.len(), 5); - assert_eq!(res.attributes[0].key, "bank-callback-error"); - assert_eq!(res.attributes[0].value, "error"); - - let fund_path = FundPath::Unbond { - id: "unbond_id".to_string(), - }; - - assert_eq!( - CLAIMABLE_FUNDS - .load(&deps.storage, (owner, fund_path),) - .unwrap(), - Uint128::new(69) - ); - - // after cleanup it should be empty - assert!(REPLIES.load(&deps.storage, msg.id).is_err()); - } - - #[test] - fn test_handle_callback_reply_is_err_empty_amount() { - use cosmwasm_std::{testing::mock_dependencies, SubMsgResult}; - use quasar_types::callback::UnbondResponse; - - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("owner"); - - let contract_callback = ContractCallback::Callback { - callback: Callback::UnbondResponse(UnbondResponse { - unbond_id: "unbond_id".to_string(), - }), - amount: None, - owner, - }; - let msg = Reply { - id: 1, - result: SubMsgResult::Err("error".to_string()), - }; - - let res = handle_callback_reply(deps.as_mut(), msg, contract_callback).unwrap_err(); - assert_eq!(res, ContractError::CallbackHasNoAmount {}); - } - - #[test] - fn test_handle_callback_reply_is_ok() { - use crate::helpers::SubMsgKind; - use cosmwasm_std::{testing::mock_dependencies, SubMsgResult}; - use quasar_types::callback::UnbondResponse; - - let mut deps = mock_dependencies(); - let owner = Addr::unchecked("owner"); - - let contract_callback = ContractCallback::Callback { - callback: Callback::UnbondResponse(UnbondResponse { - unbond_id: "unbond_id".to_string(), - }), - amount: Some(Uint128::new(100)), - owner, - }; - let msg = Reply { - id: 1, - result: SubMsgResult::Ok(SubMsgResponse { - data: None, - events: vec![], - }), - }; - - // mocking replies - REPLIES - .save( - &mut deps.storage, - msg.id, - &SubMsgKind::Callback(contract_callback.clone()), - ) - .unwrap(); - - let res = handle_callback_reply(deps.as_mut(), msg, contract_callback).unwrap(); - assert_eq!(res.attributes.len(), 4); - - // after cleanup it should be empty - assert!(REPLIES.is_empty(&deps.storage)); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/start_unbond.rs b/smart-contracts/contracts/lp-strategy/src/start_unbond.rs deleted file mode 100644 index 3602a59fe..000000000 --- a/smart-contracts/contracts/lp-strategy/src/start_unbond.rs +++ /dev/null @@ -1,819 +0,0 @@ -use cosmwasm_std::{ - to_json_binary, Addr, CosmosMsg, Env, IbcMsg, IbcTimeout, QuerierWrapper, Response, Storage, - SubMsg, Uint128, WasmMsg, -}; - -use osmosis_std::types::{cosmos::base::v1beta1::Coin, osmosis::lockup::MsgBeginUnlocking}; -use quasar_types::{ - callback::{Callback, StartUnbondResponse}, - ica::packet::ica_send, -}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::{ - error::ContractError, - helpers::get_total_primitive_shares, - helpers::{ - create_callback_submsg, create_ibc_ack_submsg, get_ica_address, IbcMsgKind, IcaMessages, - }, - ibc_lock::Lock, - state::{ - LpCache, PendingSingleUnbond, Unbond, CONFIG, IBC_LOCK, IBC_TIMEOUT_TIME, ICA_CHANNEL, - LP_SHARES, OSMO_LOCK, SHARES, START_UNBOND_QUEUE, UNBONDING_CLAIMS, - }, -}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct StartUnbond { - pub owner: Addr, - pub id: String, - pub primitive_shares: Uint128, -} - -/// Checks that the unbond_id is not already in the queue or in unbonding process. -/// If the user has sufficient shares to unbond, adds the StartUnbond to the queue. -pub fn do_start_unbond( - storage: &mut dyn Storage, - unbond: StartUnbond, -) -> Result<(), ContractError> { - if UNBONDING_CLAIMS.has(storage, (unbond.owner.clone(), unbond.id.clone())) { - return Err(ContractError::DuplicateKey); - } - - //verify here against the amount in the queue aswell - let queued_shares = START_UNBOND_QUEUE - .iter(storage)? - .map(|val| { - let v = val?; - if v.id == unbond.id { - Err(ContractError::DuplicateKey) - } else { - Ok(v) - } - }) - .try_fold( - Uint128::zero(), - |acc, val| -> Result { - let v = val?; - if v.owner == unbond.owner { - Ok(acc + v.primitive_shares) - } else { - Ok(Uint128::zero()) - } - }, - )?; - - if SHARES.load(storage, unbond.owner.clone())? < (unbond.primitive_shares + queued_shares) { - return Err(ContractError::InsufficientFunds); - } - - Ok(START_UNBOND_QUEUE.push_back(storage, &unbond)?) -} - -// batch unbond tries to unbond a batch of unbondings, should be called after the icq query has returned for deposits -pub fn batch_start_unbond( - storage: &mut dyn Storage, - env: &Env, -) -> Result, ContractError> { - let mut to_unbond = Uint128::zero(); - let mut unbonds: Vec = vec![]; - - if START_UNBOND_QUEUE.is_empty(storage)? { - return Ok(None); - } - - let total_lp_shares = LP_SHARES.load(storage)?; - - while !START_UNBOND_QUEUE.is_empty(storage)? { - let unbond = - START_UNBOND_QUEUE - .pop_front(storage)? - .ok_or(ContractError::QueueItemNotFound { - queue: "start_unbond".to_string(), - })?; - let lp_shares = single_unbond(storage, &unbond, total_lp_shares.locked_shares)?; - to_unbond = to_unbond.checked_add(lp_shares)?; - unbonds.push(PendingSingleUnbond { - lp_shares, - primitive_shares: unbond.primitive_shares, - owner: unbond.owner, - id: unbond.id, - }) - } - - let pkt = do_begin_unlocking(storage, env, to_unbond)?; - - let channel = ICA_CHANNEL.load(storage)?; - - Ok(Some(create_ibc_ack_submsg( - storage, - IbcMsgKind::Ica(IcaMessages::BeginUnlocking(unbonds, to_unbond)), - pkt, - channel, - )?)) -} - -pub fn do_begin_unlocking( - storage: &mut dyn Storage, - env: &Env, - to_unbond: Uint128, -) -> Result { - let config = CONFIG.load(storage)?; - let ica_address = get_ica_address(storage, ICA_CHANNEL.load(storage)?)?; - - let msg = MsgBeginUnlocking { - owner: ica_address, - id: OSMO_LOCK.load(storage)?, - coins: vec![Coin { - denom: config.pool_denom, - amount: to_unbond.to_string(), - }], - }; - - let pkt = ica_send::( - msg, - ICA_CHANNEL.load(storage)?, - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - )?; - - Ok(pkt) -} - -pub fn handle_start_unbond_ack( - storage: &mut dyn Storage, - querier: QuerierWrapper, - env: &Env, - unbonds: Vec, - total_start_unbonding: Uint128, -) -> Result { - let mut callback_submsgs: Vec = vec![]; - for unbond in unbonds { - if let Some(msg) = start_internal_unbond(storage, querier, env, unbond.clone())? { - // convert wasm_msg into cosmos_msg to be handled in create_callback_submsg - callback_submsgs.push(create_callback_submsg( - storage, - CosmosMsg::Wasm(msg), - unbond.owner, - unbond.id, - )?); - } - } - - IBC_LOCK.update(storage, |lock| -> Result { - Ok(lock.unlock_start_unbond()) - })?; - - // TODO, update the actual amount of locked lp shares in the lp cache here aswell - LP_SHARES.update(storage, |mut cache| -> Result { - cache.w_unlocked_shares = cache.w_unlocked_shares.checked_add(total_start_unbonding)?; - cache.locked_shares = cache.locked_shares.checked_sub(total_start_unbonding)?; - Ok(cache) - })?; - - Ok(Response::new() - .add_attribute("start-unbond", "succes") - .add_attribute("callback-submsgs", callback_submsgs.len().to_string()) - .add_messages(callback_submsgs.iter().map(|m| m.msg.clone()))) -} - -// in single_unbond, we change from using internal primitive to an actual amount of lp-shares that we can unbond -fn single_unbond( - storage: &mut dyn Storage, - unbond: &StartUnbond, - total_lp_shares: Uint128, -) -> Result { - let total_primitive_shares = get_total_primitive_shares(storage)?; - - Ok(unbond - .primitive_shares - .checked_multiply_ratio(total_lp_shares, total_primitive_shares)?) -} - -// unbond starts unbonding an amount of lp shares -fn start_internal_unbond( - storage: &mut dyn Storage, - querier: QuerierWrapper, - env: &Env, - unbond: PendingSingleUnbond, -) -> Result, ContractError> { - // check that we can create a new unbond - if UNBONDING_CLAIMS.has(storage, (unbond.owner.clone(), unbond.id.clone())) { - return Err(ContractError::DuplicateKey); - } - - // remove amount of shares - let left = SHARES - .load(storage, unbond.owner.clone())? - .checked_sub(unbond.primitive_shares) - .map_err(|err| { - ContractError::TracedOverflowError(err, "lower_shares_to_unbond".to_string()) - })?; - // subtracting below zero here should trigger an error in check_sub - if left.is_zero() { - SHARES.remove(storage, unbond.owner.clone()); - } else { - SHARES.save(storage, unbond.owner.clone(), &left)?; - } - - // todo verify logic of unlock times - let unlock_time = env - .block - .time - .plus_seconds(CONFIG.load(storage)?.lock_period); - - // add amount of unbonding claims - UNBONDING_CLAIMS.save( - storage, - (unbond.owner.clone(), unbond.id.clone()), - &Unbond { - lp_shares: unbond.lp_shares, - unlock_time, - attempted: false, - id: unbond.id.clone(), - owner: unbond.owner.clone(), - }, - )?; - - let msg = Callback::StartUnbondResponse(StartUnbondResponse { - unbond_id: unbond.id.clone(), - unlock_time, - }); - - if querier - .query_wasm_contract_info(unbond.owner.as_str()) - .is_ok() - { - Ok(Some(WasmMsg::Execute { - contract_addr: unbond.owner.to_string(), - msg: to_json_binary(&msg)?, - funds: vec![], - })) - } else { - Ok(None) - } -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env}, - Addr, Binary, ContractInfoResponse, ContractResult, CosmosMsg, OverflowError, - OverflowOperation, QuerierResult, StdError, Timestamp, Uint128, WasmMsg, - }; - - use crate::{ - bond::calculate_claim, - state::{LpCache, PendingSingleUnbond, SHARES}, - test_helpers::default_setup, - }; - - use super::*; - use proptest::prelude::*; - - #[test] - fn do_start_unbond_exact_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(1000)) - .unwrap(); - - let unbond = StartUnbond { - owner, - id, - primitive_shares: Uint128::new(1000), - }; - do_start_unbond(deps.as_mut().storage, unbond).unwrap() - } - - #[test] - fn do_start_unbond_multiple_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id1 = "my-id-1".to_string(); - let id2 = "my-id-2".to_string(); - let id3 = "my-id-3".to_string(); - - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(1000)) - .unwrap(); - - START_UNBOND_QUEUE - .push_back( - deps.as_mut().storage, - &StartUnbond { - owner: Addr::unchecked("alice"), - id: "2".to_string(), - primitive_shares: Uint128::new(1500), - }, - ) - .unwrap(); - - let unbond1 = StartUnbond { - owner: owner.clone(), - id: id1, - primitive_shares: Uint128::new(500), - }; - let unbond2 = StartUnbond { - owner: owner.clone(), - id: id2, - primitive_shares: Uint128::new(300), - }; - let unbond3 = StartUnbond { - owner, - id: id3, - primitive_shares: Uint128::new(200), - }; - - do_start_unbond(deps.as_mut().storage, unbond1.clone()).unwrap(); - do_start_unbond(deps.as_mut().storage, unbond2.clone()).unwrap(); - do_start_unbond(deps.as_mut().storage, unbond3.clone()).unwrap(); - assert_eq!(START_UNBOND_QUEUE.len(deps.as_ref().storage).unwrap(), 4); - // pop alice's start_unbond - START_UNBOND_QUEUE.pop_front(deps.as_mut().storage).unwrap(); - - assert_eq!( - START_UNBOND_QUEUE - .pop_front(deps.as_mut().storage) - .unwrap() - .unwrap(), - unbond1 - ); - assert_eq!( - START_UNBOND_QUEUE - .pop_front(deps.as_mut().storage) - .unwrap() - .unwrap(), - unbond2 - ); - assert_eq!( - START_UNBOND_QUEUE - .pop_front(deps.as_mut().storage) - .unwrap() - .unwrap(), - unbond3 - ) - } - - #[test] - fn do_start_unbond_not_enough_shares_fails() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(999)) - .unwrap(); - - let unbond = StartUnbond { - owner, - id, - primitive_shares: Uint128::new(1000), - }; - let err = do_start_unbond(deps.as_mut().storage, unbond).unwrap_err(); - assert_eq!(err, ContractError::InsufficientFunds) - } - - #[test] - fn do_start_unbond_duplicate_key_fails() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(999)) - .unwrap(); - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (owner.clone(), id.clone()), - &Unbond { - lp_shares: Uint128::new(420), - unlock_time: Timestamp::from_seconds(100), - attempted: false, - owner: owner.clone(), - id: id.clone(), - }, - ) - .unwrap(); - - let unbond = StartUnbond { - owner, - id, - primitive_shares: Uint128::new(1000), - }; - let err = do_start_unbond(deps.as_mut().storage, unbond).unwrap_err(); - assert_eq!(err, ContractError::DuplicateKey) - } - - #[test] - fn batch_start_unbond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let env = mock_env(); - let id = "my-id".to_string(); - //test specific setup - OSMO_LOCK.save(deps.as_mut().storage, &1).unwrap(); - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(1000)) - .unwrap(); - - LP_SHARES - .save( - deps.as_mut().storage, - &LpCache { - locked_shares: Uint128::new(1000), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - - let unbond1 = StartUnbond { - owner, - id, - primitive_shares: Uint128::new(1000), - }; - - do_start_unbond(deps.as_mut().storage, unbond1).unwrap(); - - let res = batch_start_unbond(deps.as_mut().storage, &env).unwrap(); - assert!(res.is_some()); - - // check that the packet is as we expect - let ica = get_ica_address( - deps.as_ref().storage, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - ) - .unwrap(); - let msg = MsgBeginUnlocking { - owner: ica, - id: OSMO_LOCK.load(deps.as_mut().storage).unwrap(), - coins: vec![Coin { - denom: CONFIG.load(deps.as_ref().storage).unwrap().pool_denom, - // integer truncation present here again - amount: Uint128::new(1000).to_string(), - }], - }; - - let pkt = ica_send::( - msg, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - ) - .unwrap(); - assert_eq!(res.unwrap().msg, CosmosMsg::Ibc(pkt)); - } - - #[test] - fn single_unbond_big_math() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(100)) - .unwrap(); - SHARES - .save( - deps.as_mut().storage, - Addr::unchecked("other_user"), - &Uint128::new(900), - ) - .unwrap(); - - LP_SHARES - .save( - deps.as_mut().storage, - &LpCache { - locked_shares: Uint128::new(10_000_000_000), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - - let res = single_unbond( - deps.as_mut().storage, - &StartUnbond { - owner, - id, - primitive_shares: Uint128::new(100), - }, - Uint128::new(10_000_000_000), - ) - .unwrap(); - - assert_eq!( - get_total_primitive_shares(deps.as_mut().storage).unwrap(), - Uint128::new(1000) - ); - assert_eq!(res, Uint128::new(1000000000)) - } - - // this is an excellent first test to write a proptest for - #[test] - fn single_unbond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - SHARES - .save(deps.as_mut().storage, owner.clone(), &Uint128::new(100)) - .unwrap(); - - let res = single_unbond( - deps.as_mut().storage, - &StartUnbond { - owner, - id, - primitive_shares: Uint128::new(100), - }, - Uint128::new(100), - ) - .unwrap(); - // we have a share loss here due to truncation, is this avoidable? - assert_eq!(res, Uint128::new(100)) - } - - #[test] - fn start_internal_unbond_exact_shares_works() { - // general setup - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let env = mock_env(); - - deps.querier.update_wasm(|q| match q { - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => QuerierResult::Ok( - ContractResult::Ok(to_json_binary(&ContractInfoResponse::default()).unwrap()), - ), - _ => unimplemented!(), - }); - let w = QuerierWrapper::new(&deps.querier); - - assert!(w.query_wasm_contract_info(owner.clone()).is_ok()); - - // test specific setup - SHARES - .save(&mut deps.storage, owner.clone(), &Uint128::new(100)) - .unwrap(); - let unbond = PendingSingleUnbond { - lp_shares: Uint128::new(100), - primitive_shares: Uint128::new(100), - owner: owner.clone(), - id: id.to_string(), - }; - - let res = start_internal_unbond(&mut deps.storage, w, &env, unbond).unwrap(); - assert_eq!( - res.unwrap(), - WasmMsg::Execute { - contract_addr: owner.to_string(), - msg: to_json_binary(&Callback::StartUnbondResponse(StartUnbondResponse { - unbond_id: id.to_string(), - unlock_time: env - .block - .time - .plus_seconds(CONFIG.load(deps.as_ref().storage).unwrap().lock_period) - })) - .unwrap(), - funds: vec![] - } - ) - } - - #[test] - fn start_internal_unbond_less_shares_works() { - // general setup - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let env = mock_env(); - - deps.querier.update_wasm(|q| match q { - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => QuerierResult::Ok( - ContractResult::Ok(to_json_binary(&ContractInfoResponse::default()).unwrap()), - ), - _ => unimplemented!(), - }); - let w = QuerierWrapper::new(&deps.querier); - - // test specific setup - SHARES - .save(&mut deps.storage, owner.clone(), &Uint128::new(101)) - .unwrap(); - let unbond = PendingSingleUnbond { - lp_shares: Uint128::new(100), - primitive_shares: Uint128::new(100), - owner: owner.clone(), - id: id.to_string(), - }; - - let res = start_internal_unbond(&mut deps.storage, w, &env, unbond).unwrap(); - assert_eq!( - res.unwrap(), - WasmMsg::Execute { - contract_addr: owner.to_string(), - msg: to_json_binary(&Callback::StartUnbondResponse(StartUnbondResponse { - unbond_id: id.to_string(), - unlock_time: env - .block - .time - .plus_seconds(CONFIG.load(deps.as_ref().storage).unwrap().lock_period) - })) - .unwrap(), - funds: vec![] - } - ); - assert_eq!( - SHARES.load(deps.as_ref().storage, owner).unwrap(), - Uint128::one() - ) - } - - #[test] - fn start_internal_unbond_duplicate_key_fails() { - // general setup - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let env = mock_env(); - - deps.querier.update_wasm(|q| match q { - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Ok(ContractResult::Ok(Binary::from_base64("deadbeef").unwrap())) - } - _ => unimplemented!(), - }); - let w = QuerierWrapper::new(&deps.querier); - - // test specific setup - SHARES - .save(&mut deps.storage, owner.clone(), &Uint128::new(99)) - .unwrap(); - let unbond = PendingSingleUnbond { - lp_shares: Uint128::new(100), - primitive_shares: Uint128::new(100), - owner: owner.clone(), - id: id.to_string(), - }; - let unlock_time = env - .block - .time - .plus_seconds(CONFIG.load(deps.as_ref().storage).unwrap().lock_period); - UNBONDING_CLAIMS - .save( - &mut deps.storage, - (owner.clone(), id.to_string()), - &Unbond { - lp_shares: Uint128::new(100), - unlock_time, - attempted: false, - owner, - id: id.to_string(), - }, - ) - .unwrap(); - - let res = start_internal_unbond(&mut deps.storage, w, &env, unbond).unwrap_err(); - assert_eq!(res, ContractError::DuplicateKey) - } - - #[test] - fn start_internal_unbond_not_enough_shares_fails() { - // general setup - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let env = mock_env(); - - deps.querier.update_wasm(|q| match q { - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Ok(ContractResult::Ok(Binary::from_base64("deadbeef").unwrap())) - } - _ => unimplemented!(), - }); - let w = QuerierWrapper::new(&deps.querier); - - // test specific setup - SHARES - .save(&mut deps.storage, owner.clone(), &Uint128::new(99)) - .unwrap(); - let unbond = PendingSingleUnbond { - lp_shares: Uint128::new(100), - primitive_shares: Uint128::new(100), - owner, - id: id.to_string(), - }; - - let res = start_internal_unbond(&mut deps.storage, w, &env, unbond).unwrap_err(); - assert_eq!( - res, - ContractError::TracedOverflowError( - OverflowError { - operation: OverflowOperation::Sub, - operand1: "99".to_string(), - operand2: "100".to_string() - }, - "lower_shares_to_unbond".to_string() - ) - ) - } - - #[test] - fn start_internal_unbond_no_shares_fails() { - // general setup - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let id = "my-id"; - let env = mock_env(); - - deps.querier.update_wasm(|q| match q { - cosmwasm_std::WasmQuery::ContractInfo { contract_addr: _ } => { - QuerierResult::Ok(ContractResult::Ok(Binary::from_base64("deadbeef").unwrap())) - } - _ => unimplemented!(), - }); - let w = QuerierWrapper::new(&deps.querier); - - // test specific setup - let unbond = PendingSingleUnbond { - lp_shares: Uint128::new(100), - primitive_shares: Uint128::new(100), - owner, - id: id.to_string(), - }; - - let res = start_internal_unbond(&mut deps.storage, w, &env, unbond).unwrap_err(); - assert_eq!( - res, - ContractError::Std(StdError::NotFound { - kind: "type: cosmwasm_std::math::uint128::Uint128; key: [00, 06, 73, 68, 61, 72, 65, 73, 62, 6F, 62]".to_string() - }) - ) - } - - proptest! { - #[test] - fn test_calculate_claim_and_single_unbond( - (total_balance, user_balance) in (1..4*10_u128.pow(28)).prop_flat_map(|a| (Just(a), 1..a)), - total_primitive_shares in 1u128..4*10_u128.pow(28), - lp_shares in 1u128..4*10_u128.pow(28), - ) { - - let mut deps = mock_dependencies(); - - SHARES.save(deps.as_mut().storage, Addr::unchecked("other-shares"), &Uint128::new(total_primitive_shares)).unwrap(); - - // Calculate the claim using the calculate_claim function - // here bob gets a claim to a certain amount of - let claim = calculate_claim( - Uint128::new(user_balance), - Uint128::new(total_balance), - Uint128::new(total_primitive_shares), - ) - .unwrap(); - - // Calculate the unbond amount using the single_unbond function - let unbond = single_unbond( - deps.as_mut().storage, - &StartUnbond { - primitive_shares: claim, - id: "1".to_string(), - owner: Addr::unchecked("bobberino"), - }, - lp_shares.into(), - ) - .unwrap(); - - // how do we now assert, basically we get an expected amount of returning lp shares that - // we need to simulate a liquidation for. How do we do that? - // in the test setup, we assume that depositing total_balance has let to lp_shares, - // so the price of a single lp shares is total_balance/lp_shares - let ub = Uint128::new(user_balance); - let recv_balance = unbond.multiply_ratio(total_balance, lp_shares); - // for our assertion, since we are working with interger math and 6 decimals or more on tokens - // we're ok with being either 1 off or some micro (10^-10) off - // TODO for ease of coding, we just accept this ratio - let vals = recv_balance.multiply_ratio(9999999999u128, 10000000000u128)..recv_balance.multiply_ratio(10000000001u128, 1000000000u128); - prop_assert!(vals.contains(&ub), "recv_balance: {recv_balance}, user_balance: {user_balance}"); - } - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/state.rs b/smart-contracts/contracts/lp-strategy/src/state.rs deleted file mode 100644 index 90044db77..000000000 --- a/smart-contracts/contracts/lp-strategy/src/state.rs +++ /dev/null @@ -1,330 +0,0 @@ -use quasar_types::ibc::ChannelInfo; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use std::fmt::{Debug, Display}; - -use cosmwasm_std::{Addr, Empty, IbcAcknowledgement, StdError, StdResult, Timestamp, Uint128}; -use cw_storage_plus::{Deque, Item, Key, KeyDeserialize, Map, Prefixer, PrimaryKey}; - -use crate::{ - bond::Bond, - error::{ContractError, Trap}, - helpers::{IbcMsgKind, SubMsgKind}, - ibc_lock::Lock, - start_unbond::StartUnbond, -}; - -pub const RETURN_SOURCE_PORT: &str = "transfer"; -pub const IBC_TIMEOUT_TIME: u64 = 7200; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] -#[serde(rename_all = "snake_case")] -pub struct Config { - // The lock period is the amount of time we lock tokens on Osmosis - pub lock_period: u64, - pub pool_id: u64, - // pool_denom is the denom of the gamm pool on osmosis; eg gamm/pool/1 - pub pool_denom: String, - // the base denom of the pool on osmosis - pub base_denom: String, - // the quote denom is the "other" side of the pool we deposit tokens in - pub quote_denom: String, - // the denom on the Quasar chain - pub local_denom: String, - // the transfer channel to transfer funds to Osmosis - pub transfer_channel: String, - // the channel for sending tokens back from the counterparty chain to quasar chain - pub return_source_channel: String, - // expected_connection id on which the primitive should function - pub expected_connection: String, -} - -// TODO remove the need for ADMIN - -// the ADMIN in this case is the person allowed to deposit into the contract -// this is set to the first depositor -pub(crate) const ADMIN: Item = Item::new("admin"); -pub(crate) const LOCK_ADMIN: Map<&Addr, Empty> = Map::new("lock_admin"); -pub(crate) const DEPOSITOR: Item = Item::new("depositor"); - -pub(crate) const CONFIG: Item = Item::new("config"); -// IBC related state items -pub(crate) const REPLIES: Map = Map::new("replies"); -// RECOVERY_ACK contains ibc acknowledgements, these packets might be needed for recovery from errors -pub(crate) const RECOVERY_ACK: Map<(u64, String), IbcAcknowledgement> = - Map::new("new_recovery_ack"); -pub(crate) const _OLD_RECOVERY_ACK: Map = Map::new("recovery_ack"); - -// true when a packet has timed out and the ica channel needs to be closed and a new channel needs to be opened -pub(crate) const TIMED_OUT: Item = Item::new("timed_out"); -// Currently we only support one ICA channel to a single destination -pub(crate) const ICA_CHANNEL: Item = Item::new("ica_channel"); -// We also support one ICQ channel to Osmosis at the moment -pub(crate) const ICQ_CHANNEL: Item = Item::new("icq_channel"); - -pub(crate) const CHANNELS: Map = Map::new("channels"); -pub(crate) const _OLD_PENDING_ACK: Map = Map::new("pending_acks"); -pub(crate) const PENDING_ACK: Map<(u64, String), IbcMsgKind> = Map::new("new_pending_acks"); -// The map to store trapped errors, -pub(crate) const _OLD_TRAPS: Map = Map::new("traps"); -pub(crate) const TRAPS: Map<(u64, String), Trap> = Map::new("new_traps"); - -// all vault related state items -pub(crate) const IBC_LOCK: Item = Item::new("lock"); -pub(crate) const PENDING_BOND_QUEUE: Deque = Deque::new("pending_bond_queue"); -pub(crate) const BOND_QUEUE: Deque = Deque::new("bond_queue"); -pub(crate) const FAILED_JOIN_QUEUE: Deque = Deque::new("failed_join_queue"); -pub(crate) const REJOIN_QUEUE: Deque = Deque::new("rejoin_queue"); -pub(crate) const START_UNBOND_QUEUE: Deque = Deque::new("start_unbond_queue"); -pub(crate) const PENDING_UNBOND_QUEUE: Deque = Deque::new("pending_unbond_queue"); -pub(crate) const UNBOND_QUEUE: Deque = Deque::new("unbond_queue"); -// the amount of LP shares that the contract has entered into the pool -pub(crate) const LP_SHARES: Item = Item::new("lp_shares"); - -// the latest known ica balance -pub(crate) const TOTAL_VAULT_BALANCE: Item = Item::new("total_vault_balance"); -/// the "free balance" on osmo side, this is the amount of tokens that we can compound into the pool -/// actually, we also subtract out any failed bond attempts & any failed unbond attempts (trapped_errors, and failed join pool) -/// failed join pool is bonded back in via a different mechanism -/// trapped errors are not bonded back in, but they are not lost either -/// the only part that isn't accounted for is the failed returnTransfer attempts, but we never run that path simultaneously due to locks to it's fine -pub(crate) const USABLE_COMPOUND_BALANCE: Item = Item::new("usable_compound_balance"); - -// TODO we probably want to change this to an OngoingDeposit -pub(crate) const BONDING_CLAIMS: Map<(&Addr, &str), Uint128> = Map::new("bonding_claims"); - -// TODO: this is not being used, remove it -pub(crate) const PENDING_UNBONDING_CLAIMS: Map<(Addr, String), Unbond> = - Map::new("pending_unbonding_claims"); -pub(crate) const UNBONDING_CLAIMS: Map<(Addr, String), Unbond> = Map::new("unbonding_claims"); -// TODO make key borrowed -pub(crate) const SHARES: Map = Map::new("shares"); -// the lock id on osmosis, for each combination of denom and lock duration, only one lock id should exist on osmosis -pub(crate) const OSMO_LOCK: Item = Item::new("osmo_lock"); -// the returning transfer we can expect and their exact amount -pub(crate) const RETURNING: Map = Map::new("returning"); -// TODO, do we remove this state item? is it needed? -// whatever the above todo item is, does not apply to the following -// we save the queried simulate join swap during ICQ so we can read it right before bond join -pub(crate) const SIMULATED_JOIN_RESULT: Item = Item::new("simulated_join_result"); -// we save the amount that went into the QueryCalcJoinPool, so we can scale up the slippage amount if more deposits come -pub(crate) const SIMULATED_JOIN_AMOUNT_IN: Item = Item::new("simulated_join_amount"); -// we also save the queried simulate exit swap during ICQ so we can read it right before unbond exit -pub(crate) const SIMULATED_EXIT_RESULT: Item = Item::new("simulated_exit_result"); -// we save the amount that went into the QueryCalcExitPoolCoinsFromSharesRequest, so we can scale up the slippage amount (if more unbonds come) -// need to check if (...) applies here -pub(crate) const SIMULATED_EXIT_SHARES_IN: Item = Item::new("simulated_exit_amount"); -// CLAIMABLE_FUNDS is the amount of funds claimable by a certain address, either -pub(crate) const CLAIMABLE_FUNDS: Map<(Addr, FundPath), Uint128> = Map::new("claimable_funds"); - -impl PrimaryKey<'_> for FundPath { - type Prefix = Addr; - - type SubPrefix = (); - - type Suffix = u8; - - type SuperSuffix = Self; - - fn key(&self) -> Vec { - // this is a bit yikes but fuck it - match self { - FundPath::Bond { id } => vec![Key::Val8([0]), Key::Ref(id.as_bytes())], - FundPath::Unbond { id } => vec![Key::Val8([1]), Key::Ref(id.as_bytes())], - } - } -} - -impl KeyDeserialize for FundPath { - type Output = FundPath; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - if value[0] == 0 { - Ok(FundPath::Bond { - id: String::from_utf8(value[1..].to_vec()).map_err(|err| { - StdError::InvalidUtf8 { - msg: err.to_string(), - } - })?, - }) - } else if value[0] == 1 { - Ok(FundPath::Unbond { - id: String::from_utf8(value[1..].to_vec()).map_err(|err| { - StdError::InvalidUtf8 { - msg: err.to_string(), - } - })?, - }) - } else { - Err(StdError::SerializeErr { - source_type: "key-de".to_string(), - msg: "enum variant not found".to_string(), - }) - } - } -} - -impl Prefixer<'_> for FundPath { - fn prefix(&self) -> Vec { - match self { - FundPath::Bond { id } => vec![Key::Ref(id.as_bytes())], - FundPath::Unbond { id } => vec![Key::Ref(id.as_bytes())], - } - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub enum FundPath { - Bond { id: String }, - Unbond { id: String }, -} - -impl Display for FundPath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{self:?}") - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct LpCache { - // the amount of locked shares we currently have - pub locked_shares: Uint128, - // the amount of unlocked share we have for withdrawing - pub w_unlocked_shares: Uint128, - // the amount unlocked shares we have for depositing - pub d_unlocked_shares: Uint128, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct Unbond { - pub lp_shares: Uint128, - pub unlock_time: Timestamp, - pub attempted: bool, - pub owner: Addr, - pub id: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub struct PendingSingleUnbond { - pub lp_shares: Uint128, - pub primitive_shares: Uint128, - pub owner: Addr, - pub id: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct PendingBond { - // the bonds of the original calls - pub bonds: Vec, -} - -impl PendingBond { - pub fn update_raw_amount_to_lp(&mut self, total_lp: Uint128) -> Result<(), ContractError> { - let mut total = Uint128::zero(); - for p in self.bonds.iter() { - match p.raw_amount { - crate::state::RawAmount::LocalDenom(val) => total = total.checked_add(val)?, - crate::state::RawAmount::LpShares(_) => unimplemented!(), - } - } - for p in self.bonds.iter_mut() { - match p.raw_amount { - // amount of lp shares = val * total_lp / total - crate::state::RawAmount::LocalDenom(val) => { - p.raw_amount = - RawAmount::LpShares(val.checked_mul(total_lp)?.checked_div(total)?) - } - crate::state::RawAmount::LpShares(_) => unimplemented!(), - } - } - Ok(()) - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub struct Claim { - amount: Uint128, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct OngoingDeposit { - pub claim_amount: Uint128, // becomes shares later - pub raw_amount: RawAmount, - pub owner: Addr, - pub bond_id: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub enum RawAmount { - LocalDenom(Uint128), - LpShares(Uint128), -} - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - fn keys_work() { - let bond = FundPath::Bond { - id: "our-id-here".to_string(), - }; - let keys: Vec = bond - .key() - .iter() - .flat_map(|k| k.as_ref().iter().copied()) - .collect(); - let value = FundPath::from_vec(keys).unwrap(); - assert_eq!(bond, value) - } - - #[test] - fn test_update_raw_amount_to_lp() { - let mut pending = PendingBond { - bonds: vec![ - OngoingDeposit { - claim_amount: Uint128::new(100), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "fake".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(99), - raw_amount: RawAmount::LocalDenom(Uint128::new(999)), - owner: Addr::unchecked("address"), - bond_id: "fake".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(101), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "fake".to_string(), - }, - ], - }; - pending.update_raw_amount_to_lp(Uint128::new(300)).unwrap(); - assert_eq!( - pending.bonds[0].raw_amount, - RawAmount::LpShares(Uint128::new(100)) - ); - assert_eq!( - pending.bonds[1].raw_amount, - RawAmount::LpShares(Uint128::new(99)) - ); - // because we use integer division and relatively low values, this case us 100 - assert_eq!( - pending.bonds[2].raw_amount, - RawAmount::LpShares(Uint128::new(100)) - ) - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/test_helpers.rs b/smart-contracts/contracts/lp-strategy/src/test_helpers.rs deleted file mode 100644 index 3414c4a8a..000000000 --- a/smart-contracts/contracts/lp-strategy/src/test_helpers.rs +++ /dev/null @@ -1,237 +0,0 @@ -use cosmos_sdk_proto::tendermint::abci::ResponseQuery; -use cosmwasm_std::{IbcEndpoint, Storage}; -use prost::bytes::Bytes; -use quasar_types::{ - ibc::{ChannelInfo, ChannelType}, - ica::handshake::IcaMetadata, -}; - -use crate::{ - bond::Bond, - state::{ - Config, PendingBond, RawAmount, CHANNELS, CONFIG, ICA_CHANNEL, ICQ_CHANNEL, LP_SHARES, - }, -}; - -pub fn default_setup(storage: &mut dyn Storage) -> Result<(), cosmwasm_std::StdError> { - setup_default_icq(storage)?; - setup_default_ica(storage)?; - setup_default_config(storage)?; - setup_default_lp_cache(storage) -} - -pub(crate) fn setup_default_icq(storage: &mut dyn Storage) -> Result<(), cosmwasm_std::StdError> { - let chan = "channel-1"; - CHANNELS.save( - storage, - chan.to_string(), - &ChannelInfo { - id: chan.to_string(), - counterparty_endpoint: IbcEndpoint { - port_id: "icqhost".to_string(), - channel_id: chan.to_string(), - }, - connection_id: "connection-0".to_string(), - channel_type: ChannelType::Icq { - channel_ty: "icq-1".to_string(), - }, - handshake_state: quasar_types::ibc::HandshakeState::Open, - }, - )?; - ICQ_CHANNEL.save(storage, &chan.to_string()) -} - -pub(crate) fn setup_default_ica(storage: &mut dyn Storage) -> Result<(), cosmwasm_std::StdError> { - let chan = "channel-2"; - CHANNELS.save( - storage, - chan.to_string(), - &ChannelInfo { - id: chan.to_string(), - counterparty_endpoint: IbcEndpoint { - port_id: "icahost".to_string(), - channel_id: chan.to_string(), - }, - connection_id: "connection-0".to_string(), - channel_type: ChannelType::Ica { - channel_ty: IcaMetadata::with_connections( - "connection-1".to_string(), - "connection-2".to_string(), - ), - counter_party_address: Some("osmo-address".to_string()), - }, - handshake_state: quasar_types::ibc::HandshakeState::Open, - }, - )?; - ICA_CHANNEL.save(storage, &chan.to_string()) -} - -pub(crate) fn setup_default_config( - storage: &mut dyn Storage, -) -> Result<(), cosmwasm_std::StdError> { - CONFIG.save( - storage, - &Config { - lock_period: 100, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - local_denom: "ibc/local_osmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - }, - ) -} - -pub(crate) fn setup_default_lp_cache( - storage: &mut dyn Storage, -) -> Result<(), cosmwasm_std::StdError> { - LP_SHARES.save( - storage, - &crate::state::LpCache { - locked_shares: 100u128.into(), - w_unlocked_shares: 100u128.into(), - d_unlocked_shares: 100u128.into(), - }, - ) -} - -pub fn pending_bond_to_bond(pending: &PendingBond) -> Vec { - pending - .bonds - .iter() - .map(|bond| Bond { - amount: match &bond.raw_amount { - RawAmount::LocalDenom(amount) => *amount, - RawAmount::LpShares(_) => panic!("unexpected lp shares"), - }, - owner: bond.owner.clone(), - bond_id: bond.bond_id.clone(), - }) - .collect() -} - -pub fn create_query_response(response: Vec) -> ResponseQuery { - ResponseQuery { - code: 1, - log: "".to_string(), - info: "".to_string(), - index: 1, - key: Bytes::from("0"), - value: response.into(), - proof_ops: None, - height: 0, - codespace: "".to_string(), - } -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{testing::mock_dependencies, Addr, Uint128}; - - use crate::state::OngoingDeposit; - - use super::*; - - #[test] - fn default_setup_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - - assert_eq!( - CONFIG.load(deps.as_ref().storage).unwrap(), - Config { - lock_period: 100, - pool_id: 1, - pool_denom: "gamm/pool/1".to_string(), - base_denom: "uosmo".to_string(), - quote_denom: "uqsr".to_string(), - local_denom: "ibc/local_osmo".to_string(), - transfer_channel: "channel-0".to_string(), - return_source_channel: "channel-0".to_string(), - expected_connection: "connection-0".to_string(), - } - ); - - let ica_chan = ICA_CHANNEL.load(deps.as_ref().storage).unwrap(); - assert_eq!( - CHANNELS - .load(deps.as_ref().storage, ica_chan.clone()) - .unwrap(), - ChannelInfo { - id: ica_chan.clone(), - counterparty_endpoint: IbcEndpoint { - port_id: "icahost".to_string(), - channel_id: ica_chan, - }, - connection_id: "connection-0".to_string(), - channel_type: ChannelType::Ica { - channel_ty: IcaMetadata::with_connections( - "connection-1".to_string(), - "connection-2".to_string() - ), - counter_party_address: Some("osmo-address".to_string()), - }, - handshake_state: quasar_types::ibc::HandshakeState::Open, - } - ); - - let icq_chan = ICQ_CHANNEL.load(deps.as_ref().storage).unwrap(); - assert_eq!( - CHANNELS - .load(deps.as_ref().storage, icq_chan.clone()) - .unwrap(), - ChannelInfo { - id: icq_chan.to_string(), - counterparty_endpoint: IbcEndpoint { - port_id: "icqhost".to_string(), - channel_id: icq_chan, - }, - connection_id: "connection-0".to_string(), - channel_type: ChannelType::Icq { - channel_ty: "icq-1".to_string(), - }, - handshake_state: quasar_types::ibc::HandshakeState::Open, - } - ) - } - - #[test] - fn test_pending_bond_to_bond_works() { - let pb = PendingBond { - bonds: vec![ - OngoingDeposit { - claim_amount: Uint128::new(100), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "1".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(99), - raw_amount: RawAmount::LocalDenom(Uint128::new(999)), - owner: Addr::unchecked("address"), - bond_id: "2".to_string(), - }, - OngoingDeposit { - claim_amount: Uint128::new(101), - raw_amount: RawAmount::LocalDenom(Uint128::new(1000)), - owner: Addr::unchecked("address"), - bond_id: "3".to_string(), - }, - ], - }; - - let bonds = pending_bond_to_bond(&pb); - assert_eq!(bonds[0].amount, Uint128::new(1000)); - assert_eq!(bonds[1].amount, Uint128::new(999)); - assert_eq!(bonds[2].amount, Uint128::new(1000)); - assert_eq!(bonds[0].owner, Addr::unchecked("address")); - assert_eq!(bonds[1].owner, Addr::unchecked("address")); - assert_eq!(bonds[2].owner, Addr::unchecked("address")); - assert_eq!(bonds[0].bond_id, "1"); - assert_eq!(bonds[1].bond_id, "2"); - assert_eq!(bonds[2].bond_id, "3"); - } -} diff --git a/smart-contracts/contracts/lp-strategy/src/unbond.rs b/smart-contracts/contracts/lp-strategy/src/unbond.rs deleted file mode 100644 index 351e92b07..000000000 --- a/smart-contracts/contracts/lp-strategy/src/unbond.rs +++ /dev/null @@ -1,659 +0,0 @@ -use cosmwasm_std::{ - to_json_binary, Addr, BankMsg, Coin, CosmosMsg, Env, IbcTimeout, Order, QuerierWrapper, - Storage, SubMsg, Timestamp, Uint128, WasmMsg, -}; -use osmosis_std::types::{ - cosmos::base::v1beta1::Coin as OsmoCoin, osmosis::gamm::v1beta1::MsgExitSwapShareAmountIn, -}; -use quasar_types::{ - callback::{Callback, UnbondResponse}, - ibc::MsgTransfer, - ica::packet::ica_send, -}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::{ - error::ContractError, - helpers::{create_ibc_ack_submsg, get_ica_address, IbcMsgKind, IcaMessages}, - ibc_util::calculate_token_out_min_amount, - msg::ExecuteMsg, - state::{ - RawAmount, CONFIG, IBC_TIMEOUT_TIME, ICA_CHANNEL, PENDING_UNBOND_QUEUE, RETURNING, - RETURN_SOURCE_PORT, UNBONDING_CLAIMS, UNBOND_QUEUE, - }, -}; - -/// do_unbond is used to check whether an unbonding claim can be processed, keeps record of unbonding attempts, -/// and manages the workflow of unbonding operations. -/// -/// It first retrieves the corresponding unbonding claim from storage and checks if the unlock time -/// of the unbonding claim has already passed by comparing it to the current block time. If the unlock time -/// has not yet passed, the function returns an error indicating that the shares are not yet available for unbonding. -/// -/// If the unlock time has already passed, the `attempted` field of the unbonding claim is set to `true`. -/// This operation marks that an unbonding attempt has been made for these shares and prevents the execution of -/// multiple unbonding attempts for the same shares. -/// -/// Finally, the unbonding claim is moved into the PENDING_UNBOND_QUEUE for later processing. -pub fn do_unbond( - storage: &mut dyn Storage, - env: &Env, - owner: Addr, - id: String, -) -> Result<(), ContractError> { - let mut unbond = UNBONDING_CLAIMS.load(storage, (owner.clone(), id.clone()))?; - - if unbond.unlock_time.nanos() > env.block.time.nanos() { - return Err(ContractError::SharesNotYetUnbonded); - } - - unbond.attempted = true; - UNBONDING_CLAIMS.save(storage, (owner, id), &unbond)?; - - Ok(PENDING_UNBOND_QUEUE.push_back(storage, &unbond)?) -} - -pub fn batch_unbond(storage: &mut dyn Storage, env: &Env) -> Result, ContractError> { - let mut total_exit = Uint128::zero(); - let mut pending: Vec = vec![]; - - if UNBOND_QUEUE.is_empty(storage)? { - return Ok(None); - } - - // aggregate the current unbond queue, all items in this queue should be able to unbond - while !UNBOND_QUEUE.is_empty(storage)? { - let unbond = UNBOND_QUEUE - .pop_front(storage)? - .ok_or(ContractError::QueueItemNotFound { - queue: "unbond".to_string(), - })?; - total_exit = total_exit - .checked_add(unbond.lp_shares) - .map_err(|err| ContractError::TracedOverflowError(err, "cal_total_exit".to_string()))?; - // add the unbond to the pending unbonds - pending.push(ReturningUnbond { - amount: RawAmount::LpShares(unbond.lp_shares), - owner: unbond.owner, - id: unbond.id, - }); - } - - // important to use lp_shares before it gets updated - let token_out_min_amount = calculate_token_out_min_amount(storage)?; - - let msg = exit_swap( - storage, - env, - total_exit, - token_out_min_amount, - PendingReturningUnbonds { unbonds: pending }, - )?; - Ok(Some(msg)) -} - -pub(crate) fn exit_swap( - storage: &mut dyn Storage, - env: &Env, - total_exit: Uint128, - token_out_min_amount: Uint128, - pending: PendingReturningUnbonds, -) -> Result { - let pkt = do_exit_swap(storage, env, token_out_min_amount, total_exit)?; - - let channel = ICA_CHANNEL.load(storage)?; - - Ok(create_ibc_ack_submsg( - storage, - IbcMsgKind::Ica(IcaMessages::ExitPool(pending)), - pkt, - channel, - )?) -} - -pub(crate) fn do_exit_swap( - storage: &mut dyn Storage, - env: &Env, - token_out_min_amount: Uint128, - total_exit: Uint128, -) -> Result { - let ica_address = get_ica_address(storage, ICA_CHANNEL.load(storage)?)?; - let config = CONFIG.load(storage)?; - - let msg = MsgExitSwapShareAmountIn { - sender: ica_address, - pool_id: config.pool_id, - token_out_denom: config.base_denom, - share_in_amount: total_exit.to_string(), - token_out_min_amount: token_out_min_amount.to_string(), - }; - - let pkt = ica_send::( - msg, - ICA_CHANNEL.load(storage)?, - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - )?; - Ok(pkt) -} - -// TODO the total tokens parameter and pending is maybe a little weird, check whether we want to fold pending to get total_tokens (with gas costs etc) -pub fn transfer_batch_unbond( - storage: &mut dyn Storage, - env: &Env, - pending: PendingReturningUnbonds, - total_tokens: Uint128, -) -> Result { - let pkt = do_transfer_batch_unbond(storage, env, total_tokens, pending.clone())?; - - // this is an ica channel in transfer batch unbond which is fine because even though - // we are doing a transfer, its a return transfer which must be triggered by an ICA - let channel = ICA_CHANNEL.load(storage)?; - - Ok(create_ibc_ack_submsg( - storage, - IbcMsgKind::Ica(IcaMessages::ReturnTransfer(pending)), - pkt, - channel, - )?) -} - -pub(crate) fn do_transfer_batch_unbond( - storage: &mut dyn Storage, - env: &Env, - total_tokens: Uint128, - pending: PendingReturningUnbonds, -) -> Result { - // TODO, assert that raw amounts equal amount - let timeout_timestamp = - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)); - let msg = return_transfer( - storage, - env, - total_tokens, - timeout_timestamp.timestamp().unwrap(), - pending, - )?; - let pkt = ica_send::( - msg, - ICA_CHANNEL.load(storage)?, - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - )?; - Ok(pkt) -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Eq)] -#[serde(rename_all = "snake_case")] -pub struct PendingReturningUnbonds { - pub unbonds: Vec, -} - -impl PendingReturningUnbonds { - /// convert a se of lp shares to a set of local tokens - pub fn lp_to_local_denom(&mut self, total_local: Uint128) -> Result { - let mut total_lp = Uint128::zero(); - for p in self.unbonds.iter() { - match p.amount { - crate::state::RawAmount::LocalDenom(_) => unimplemented!(), - crate::state::RawAmount::LpShares(val) => total_lp = total_lp.checked_add(val)?, - } - } - for p in self.unbonds.iter_mut() { - match p.amount { - // amount of tokens = lp_shares * total / total_lp - crate::state::RawAmount::LpShares(val) => { - p.amount = - RawAmount::LocalDenom(val.checked_mul(total_local)?.checked_div(total_lp)?) - } - crate::state::RawAmount::LocalDenom(_) => unimplemented!(), - } - } - Ok(total_lp) - } -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct ReturningUnbond { - pub amount: RawAmount, - pub owner: Addr, - pub id: String, -} - -// TODO this only works for the happy path in the receiver -pub fn finish_unbond( - storage: &dyn Storage, - querier: QuerierWrapper, - unbond: &ReturningUnbond, -) -> Result { - let amount = match unbond.amount { - RawAmount::LocalDenom(val) => val, - RawAmount::LpShares(_) => return Err(ContractError::IncorrectRawAmount), - }; - let msg: CosmosMsg = if querier - .query_wasm_contract_info(unbond.owner.as_str()) - .is_ok() - { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: unbond.owner.to_string(), - msg: to_json_binary(&Callback::UnbondResponse(UnbondResponse { - unbond_id: unbond.id.clone(), - }))?, - funds: vec![Coin { - denom: CONFIG.load(storage)?.local_denom, - amount, - }], - }) - } else { - CosmosMsg::Bank(BankMsg::Send { - to_address: unbond.owner.to_string(), - amount: vec![Coin { - denom: CONFIG.load(storage)?.local_denom, - amount, - }], - }) - }; - Ok(msg) -} - -fn return_transfer( - storage: &mut dyn Storage, - env: &Env, - amount: Uint128, - timeout_timestamp: Timestamp, - pending: PendingReturningUnbonds, -) -> Result { - let config = CONFIG.load(storage)?; - let ica_address = get_ica_address(storage, ICA_CHANNEL.load(storage)?)?; - let id = get_next_return_id(storage)?; - - RETURNING.save(storage, id, &amount)?; - - Ok(MsgTransfer { - // TODO do we want to keep the return port a constant? Leaning towards yes since ibc transfer app uses this the same - source_port: RETURN_SOURCE_PORT.to_string(), - source_channel: config.return_source_channel, - token: Some(OsmoCoin { - denom: config.base_denom, - amount: amount.to_string(), - }), - sender: ica_address, - receiver: env.contract.address.clone().to_string(), - // timeout_height is disabled when set to 0 - // since height is kinda difficult to use, we always want to use the timestamp - timeout_height: None, - // timeout_timestamp is disabled when set to 0 - timeout_timestamp: Some(timeout_timestamp.nanos()), - memo: serde_json_wasm::to_string(&IbcHook { - wasm: Wasm { - contract: env.contract.address.clone(), - msg: ExecuteMsg::AcceptReturningFunds { id, pending }, - }, - }) - .map_err(|_| ContractError::SerdeJsonSer)?, - }) -} - -fn get_next_return_id(storage: &dyn Storage) -> Result { - let last = RETURNING - .range(storage, None, None, Order::Descending) - .next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0; - } - Ok(id) -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -struct IbcHook { - wasm: Wasm, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -struct Wasm { - contract: Addr, - msg: ExecuteMsg, -} - -#[cfg(test)] -mod tests { - - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env}, - CosmosMsg, - }; - - use crate::{ - state::{Unbond, LP_SHARES, SIMULATED_EXIT_RESULT}, - test_helpers::default_setup, - }; - - use super::*; - - #[test] - fn do_unbond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let mut env = mock_env(); - let id = "my-id".to_string(); - - let unbond = Unbond { - lp_shares: Uint128::new(100), - unlock_time: env.block.time, - attempted: true, - owner: owner.clone(), - id: id.clone(), - }; - UNBONDING_CLAIMS - .save(deps.as_mut().storage, (owner.clone(), id.clone()), &unbond) - .unwrap(); - - let time = mock_env().block.time.plus_seconds(101); - env.block.time = time; - do_unbond(deps.as_mut().storage, &env, owner, id).unwrap(); - assert_eq!( - PENDING_UNBOND_QUEUE - .pop_front(deps.as_mut().storage) - .unwrap() - .unwrap(), - unbond - ) - } - - #[test] - fn do_unbond_early_fails() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let owner = Addr::unchecked("bob"); - let env = mock_env(); - let id = "my-id".to_string(); - - UNBONDING_CLAIMS - .save( - deps.as_mut().storage, - (owner.clone(), id.clone()), - &Unbond { - lp_shares: Uint128::new(100), - unlock_time: env.block.time.plus_nanos(1), - attempted: false, - owner: owner.clone(), - id: id.clone(), - }, - ) - .unwrap(); - - let err = do_unbond(deps.as_mut().storage, &env, owner, id).unwrap_err(); - assert_eq!(err, ContractError::SharesNotYetUnbonded) - } - - #[test] - fn batch_unbond_empty_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - - let res = batch_unbond(deps.as_mut().storage, &env).unwrap(); - assert!(res.is_none()) - } - - #[test] - fn batch_unbond_multiple_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - // test specific setup - LP_SHARES - .save( - deps.as_mut().storage, - &crate::state::LpCache { - locked_shares: Uint128::new(500), - w_unlocked_shares: Uint128::zero(), - d_unlocked_shares: Uint128::zero(), - }, - ) - .unwrap(); - - let unbonds = vec![ - Unbond { - lp_shares: Uint128::new(100), - unlock_time: env.block.time, - attempted: false, - owner: owner.clone(), - id: id.clone(), - }, - Unbond { - lp_shares: Uint128::new(101), - unlock_time: env.block.time, - attempted: false, - owner: owner.clone(), - id: id.clone(), - }, - Unbond { - lp_shares: Uint128::new(102), - unlock_time: env.block.time, - attempted: false, - owner, - id, - }, - ]; - - for unbond in unbonds.iter() { - UNBOND_QUEUE - .push_back(deps.as_mut().storage, unbond) - .unwrap(); - } - - SIMULATED_EXIT_RESULT - .save(deps.as_mut().storage, &Uint128::from(100u128)) - .unwrap(); - - let res = batch_unbond(deps.as_mut().storage, &env).unwrap(); - assert!(res.is_some()); - - // checking above we have total exit amount = 100 + 101 + 102 - // while total shares in lp cache is defined at 500, this is important for calculating token_min_out_amount - // these asserts are just a quality of life improvement since the failure in this test sucks - let expected_exit_amount = Uint128::from(100u128 + 101u128 + 102u128); - let actual_exit_amount = unbonds - .iter() - .fold(Uint128::zero(), |acc, u| acc + u.lp_shares); - assert_eq!(expected_exit_amount, actual_exit_amount); - - let token_out_min_amount = calculate_token_out_min_amount(deps.as_mut().storage).unwrap(); - - // check that the packet is as we expect - let ica_address = get_ica_address( - deps.as_ref().storage, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - ) - .unwrap(); - let config = CONFIG.load(deps.as_ref().storage).unwrap(); - let msg = MsgExitSwapShareAmountIn { - sender: ica_address, - pool_id: config.pool_id, - token_out_denom: config.base_denom, - share_in_amount: Uint128::new(303).to_string(), - token_out_min_amount: token_out_min_amount.to_string(), - }; - - let pkt = ica_send::( - msg, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - ) - .unwrap(); - - assert_eq!(res.unwrap().msg, CosmosMsg::Ibc(pkt)); - } - - #[test] - fn transfer_batch_unbond_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - let owner = Addr::unchecked("bob"); - let id = "my-id".to_string(); - - let pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(101)), - owner: owner.clone(), - id: id.clone(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(102)), - owner: owner.clone(), - id: id.clone(), - }, - ReturningUnbond { - amount: RawAmount::LocalDenom(Uint128::new(103)), - owner, - id, - }, - ], - }; - - let total_tokens = Uint128::new(306); - let timeout_timestamp = - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)); - - let res = transfer_batch_unbond(deps.as_mut().storage, &env, pending.clone(), total_tokens) - .unwrap(); - - let msg = return_transfer( - deps.as_mut().storage, - &env, - total_tokens, - timeout_timestamp.timestamp().unwrap(), - pending, - ) - .unwrap(); - - let pkt = ica_send::( - msg, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - ) - .unwrap(); - assert_eq!(res.msg, CosmosMsg::Ibc(pkt)); - } - - #[test] - fn test_lp_to_local_denom() { - let mut pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - owner: Addr::unchecked("address"), - id: "bla".to_string(), - amount: RawAmount::LpShares(Uint128::new(100)), - }, - ReturningUnbond { - owner: Addr::unchecked("address"), - id: "bla".to_string(), - amount: RawAmount::LpShares(Uint128::new(50)), - }, - ReturningUnbond { - owner: Addr::unchecked("address"), - id: "bla".to_string(), - amount: RawAmount::LpShares(Uint128::new(150)), - }, - ], - }; - pending.lp_to_local_denom(Uint128::new(3000)).unwrap(); - assert_eq!( - pending.unbonds[0].amount, - RawAmount::LocalDenom(Uint128::new(1000)) - ); - assert_eq!( - pending.unbonds[1].amount, - RawAmount::LocalDenom(Uint128::new(500)) - ); - assert_eq!( - pending.unbonds[2].amount, - RawAmount::LocalDenom(Uint128::new(1500)) - ) - } - - #[test] - fn exit_swap_works() { - let mut deps = mock_dependencies(); - default_setup(deps.as_mut().storage).unwrap(); - let env = mock_env(); - - let pending = PendingReturningUnbonds { - unbonds: vec![ - ReturningUnbond { - owner: Addr::unchecked("address"), - id: "bla".to_string(), - amount: RawAmount::LpShares(Uint128::new(100)), - }, - ReturningUnbond { - owner: Addr::unchecked("address"), - id: "bla".to_string(), - amount: RawAmount::LpShares(Uint128::new(50)), - }, - ReturningUnbond { - owner: Addr::unchecked("address"), - id: "bla".to_string(), - amount: RawAmount::LpShares(Uint128::new(150)), - }, - ], - }; - - SIMULATED_EXIT_RESULT - .save(deps.as_mut().storage, &Uint128::new(3000)) - .unwrap(); - - let total_exit = pending - .unbonds - .iter() - .fold(Uint128::zero(), |acc, u| match u.amount { - RawAmount::LocalDenom(_) => unimplemented!(), - RawAmount::LpShares(val) => acc + val, - }); - - let token_out_min_amount = calculate_token_out_min_amount(deps.as_mut().storage).unwrap(); - - let msg = exit_swap( - deps.as_mut().storage, - &env, - total_exit, - token_out_min_amount, - pending, - ) - .unwrap(); - - let ica_address = get_ica_address( - deps.as_ref().storage, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - ) - .unwrap(); - let config = CONFIG.load(deps.as_ref().storage).unwrap(); - - let expected = MsgExitSwapShareAmountIn { - sender: ica_address, - pool_id: config.pool_id, - token_out_denom: config.base_denom, - share_in_amount: total_exit.to_string(), - // TODO add a more robust estimation - token_out_min_amount: token_out_min_amount.to_string(), - }; - - let pkt = ica_send::( - expected, - ICA_CHANNEL.load(deps.as_ref().storage).unwrap(), - IbcTimeout::with_timestamp(env.block.time.plus_seconds(IBC_TIMEOUT_TIME)), - ) - .unwrap(); - - assert_eq!(msg.msg, CosmosMsg::Ibc(pkt)) - } -} diff --git a/smart-contracts/contracts/multihop-router/.editorconfig b/smart-contracts/contracts/multihop-router/.editorconfig deleted file mode 100644 index 3d36f20b1..000000000 --- a/smart-contracts/contracts/multihop-router/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true - -[*.rs] -indent_size = 4 diff --git a/smart-contracts/contracts/multihop-router/.gitignore b/smart-contracts/contracts/multihop-router/.gitignore deleted file mode 100644 index 9095deaa4..000000000 --- a/smart-contracts/contracts/multihop-router/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# Build results -/target -/schema - -# Cargo+Git helper file (https://github.com/rust-lang/cargo/blob/0.44.1/src/cargo/sources/git/utils.rs#L320-L327) -.cargo-ok - -# Text file backups -**/*.rs.bk - -# macOS -.DS_Store - -# IDEs -*.iml -.idea diff --git a/smart-contracts/contracts/multihop-router/Cargo.toml b/smart-contracts/contracts/multihop-router/Cargo.toml deleted file mode 100644 index 8cbfd0392..000000000 --- a/smart-contracts/contracts/multihop-router/Cargo.toml +++ /dev/null @@ -1,62 +0,0 @@ -[package] -name = "multihop-router" -version = "0.1.0" -authors = ["LaurensKubat <32776056+LaurensKubat@users.noreply.github.com>"] -edition = "2021" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[profile.release] -opt-level = 3 -debug = false -rpath = false -lto = true -debug-assertions = false -codegen-units = 1 -panic = 'abort' -incremental = false -overflow-checks = true - -[features] -default = ["mutable"] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] -mutable = [] - -[package.metadata.scripts] -optimize = """docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.10 -""" - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -cw2 = { workspace = true } -cosmwasm-storage = { workspace = true } - -[dev-dependencies] -cw-multi-test = { workspace = true } -serde-json-wasm = { workspace = true } - -anyhow = "1" -proptest = "1.0.0" -derivative = "2.2.0" diff --git a/smart-contracts/contracts/multihop-router/LICENSE b/smart-contracts/contracts/multihop-router/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/smart-contracts/contracts/multihop-router/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/smart-contracts/contracts/multihop-router/NOTICE b/smart-contracts/contracts/multihop-router/NOTICE deleted file mode 100644 index 1d8984f55..000000000 --- a/smart-contracts/contracts/multihop-router/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2023 LaurensKubat <32776056+LaurensKubat@users.noreply.github.com> - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/smart-contracts/contracts/multihop-router/README.md b/smart-contracts/contracts/multihop-router/README.md deleted file mode 100644 index 6e2ab8be0..000000000 --- a/smart-contracts/contracts/multihop-router/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Multihop IBC router -The multihop IBC router is a contract that can be queried by other contracts for routes to get and format memo fields for IBC transfers. -The routes within the IBC router are decided upon by the admin of the contract. Adding, updating and removing routes is done by the admin. - -Depending on the expected users of the router, the admin should probably be a multisig or a dao contract to prevent abuse in formatting the memo field hops and sending the funds to a bad receiver. -Each intermediate receiver should be an some sort of account or wallet managed by the admin. - -## Use on Osmosis -For almost all tokens on Osmosis, there is no hop between Osmosis and the host chain. The only exception as of writing this is pstake. The easiest way to start using the router is to embed it in a contract or run it as a side car, depending on whether you trust any current running routers diff --git a/smart-contracts/contracts/multihop-router/src/bin/schema.rs b/smart-contracts/contracts/multihop-router/src/bin/schema.rs deleted file mode 100644 index 2e73096ab..000000000 --- a/smart-contracts/contracts/multihop-router/src/bin/schema.rs +++ /dev/null @@ -1,11 +0,0 @@ -use cosmwasm_schema::write_api; - -use multihop_router::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; - -fn main() { - write_api! { - instantiate: InstantiateMsg, - execute: ExecuteMsg, - query: QueryMsg, - } -} diff --git a/smart-contracts/contracts/multihop-router/src/contract.rs b/smart-contracts/contracts/multihop-router/src/contract.rs deleted file mode 100644 index 51bd14f86..000000000 --- a/smart-contracts/contracts/multihop-router/src/contract.rs +++ /dev/null @@ -1,261 +0,0 @@ -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdResult, -}; -// use cw2::set_contract_version; - -use crate::error::{ContractError, ContractResult}; -use crate::helpers::is_contract_admin; -use crate::msg::{ - ExecuteMsg, GetMemoResponse, GetRouteResponse, InstantiateMsg, ListRoutesResponse, - MemoResponse, QueryMsg, -}; -use crate::route::{Route, RouteId}; -use crate::state::ROUTES; - -// version info for migration info -const CONTRACT_NAME: &str = "crates.io:multihop-router"; -const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - _deps: DepsMut, - _env: Env, - _info: MessageInfo, - _msg: InstantiateMsg, -) -> Result { - Ok(Response::new() - .add_attribute("action", "instantiate") - .add_attribute("contract", CONTRACT_NAME) - .add_attribute("version", CONTRACT_VERSION)) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::AddRoute { route_id, route } => { - execute_add_route(deps, env, info, &route_id, route) - } - #[cfg(feature = "mutable")] - ExecuteMsg::MutateRoute { - route_id, - new_route, - } => execute_mutate_route(deps, env, info, &route_id, new_route), - #[cfg(feature = "mutable")] - ExecuteMsg::RemoveRoute { route_id } => execute_remove_route(deps, env, info, &route_id), - } -} - -pub fn execute_add_route( - deps: DepsMut, - env: Env, - info: MessageInfo, - route_id: &RouteId, - route: Route, -) -> ContractResult { - is_contract_admin(&deps.querier, &env, &info.sender)?; - - if ROUTES.has(deps.storage, route_id) { - return Err(ContractError::DestinationAlreadyExists); - } - - ROUTES.save(deps.storage, route_id, &route)?; - - Ok(Response::new() - .add_attribute("action", "add_route") - .add_attribute("route_id", route_id.to_string()) - .add_attribute("route", route.to_string())) -} - -#[cfg(feature = "mutable")] -pub fn execute_mutate_route( - deps: DepsMut, - env: Env, - info: MessageInfo, - route_id: &RouteId, - route: Route, -) -> ContractResult { - is_contract_admin(&deps.querier, &env, &info.sender)?; - - if !ROUTES.has(deps.storage, route_id) { - return Err(ContractError::DestinationNotExists); - } - - ROUTES.save(deps.storage, route_id, &route)?; - - Ok(Response::new() - .add_attribute("action", "mutate_route") - .add_attribute("route_id", route_id.to_string()) - .add_attribute("route", route.to_string())) -} - -#[cfg(feature = "mutable")] -pub fn execute_remove_route( - deps: DepsMut, - env: Env, - info: MessageInfo, - route_id: &RouteId, -) -> ContractResult { - is_contract_admin(&deps.querier, &env, &info.sender)?; - - if !ROUTES.has(deps.storage, route_id) { - return Err(ContractError::DestinationNotExists); - } - - ROUTES.remove(deps.storage, route_id); - - Ok(Response::new() - .add_attribute("action", "remove_route") - .add_attribute("route_id", route_id.to_string())) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult { - match msg { - QueryMsg::GetMemo { - route_id, - timeout, - retries, - actual_memo, - } => Ok(to_json_binary(&handle_get_memo( - deps, - route_id, - timeout, - retries, - actual_memo, - )?)?), - QueryMsg::GetRoute { route_id } => Ok(to_json_binary(&handle_get_route(deps, route_id)?)?), - QueryMsg::ListRoutes {} => Ok(to_json_binary(&handle_list_routes(deps)?)?), - } -} - -fn handle_get_memo( - deps: Deps, - route_id: RouteId, - timeout: String, - retries: i64, - actual_memo: Option, -) -> ContractResult { - let route = ROUTES - .may_load(deps.storage, &route_id)? - .ok_or(ContractError::DestinationNotExists)?; - match route.hop { - Some(hop) => Ok(GetMemoResponse { - channel: route.channel, - port: route.port, - memo: MemoResponse::Forward(hop.to_memo(timeout, retries, actual_memo)), - }), - None => Ok(GetMemoResponse { - channel: route.channel, - port: route.port, - memo: MemoResponse::Actual(actual_memo), - }), - } -} - -fn handle_get_route(deps: Deps, route_id: RouteId) -> ContractResult { - let route = ROUTES - .may_load(deps.storage, &route_id)? - .ok_or(ContractError::DestinationNotExists)?; - Ok(GetRouteResponse { route }) -} - -fn handle_list_routes(deps: Deps) -> ContractResult { - let routes: StdResult> = ROUTES - .range(deps.storage, None, None, Order::Descending) - .collect(); - Ok(ListRoutesResponse { - routes: routes? - .iter() - .map(|(dst, val)| (dst.clone(), val.clone())) - .collect(), - }) -} - -#[cfg(test)] -mod tests { - use cosmwasm_std::{ - from_json, - testing::{mock_dependencies, mock_env}, - }; - - use crate::route::{Destination, Hop}; - - use super::*; - - #[test] - fn query_list_routes_works() { - let mut deps = mock_dependencies(); - let env = mock_env(); - - let hop1 = Hop::new( - "channel-1", - "transfer", - "cosmosBob", - Some(Hop::new("channel-2", "transfer", "quasarBob", None)), - ); - - let route1 = Route::new("channel-2", "transfer", Some(hop1)); - - let hop2 = Hop::new( - "channel-866", - "transfer", - "osmoBob", - Some(Hop::new("channel-644", "transfer", "quasarBob", None)), - ); - - let route2 = Route::new("channel-3", "transfer", Some(hop2)); - - ROUTES - .save( - deps.as_mut().storage, - &RouteId { - destination: Destination("osmosis".to_string()), - asset: "ibc/123".to_string(), - }, - &route1, - ) - .unwrap(); - - ROUTES - .save( - deps.as_mut().storage, - &RouteId { - destination: Destination("gaia".to_string()), - asset: "osmo".to_string(), - }, - &route2, - ) - .unwrap(); - - let result = query(deps.as_ref(), env, crate::msg::QueryMsg::ListRoutes {}).unwrap(); - let response: ListRoutesResponse = from_json(&result).unwrap(); - assert_eq!( - response, - ListRoutesResponse { - routes: vec![ - ( - RouteId { - destination: Destination("osmosis".to_string()), - asset: "ibc/123".to_string() - }, - route1 - ), - ( - RouteId { - destination: Destination("gaia".to_string()), - asset: "osmo".to_string() - }, - route2 - ) - ] - } - ) - } -} diff --git a/smart-contracts/contracts/multihop-router/src/error.rs b/smart-contracts/contracts/multihop-router/src/error.rs deleted file mode 100644 index 602238d1a..000000000 --- a/smart-contracts/contracts/multihop-router/src/error.rs +++ /dev/null @@ -1,19 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -pub type ContractResult = Result; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Destination already exists")] - DestinationAlreadyExists, - - #[error("Destination does not exist")] - DestinationNotExists, -} diff --git a/smart-contracts/contracts/multihop-router/src/helpers.rs b/smart-contracts/contracts/multihop-router/src/helpers.rs deleted file mode 100644 index 84cc5fb42..000000000 --- a/smart-contracts/contracts/multihop-router/src/helpers.rs +++ /dev/null @@ -1,45 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, Env, QuerierWrapper, StdResult, WasmMsg}; - -use crate::{msg::ExecuteMsg, ContractError}; - -/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers -/// for working with this. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct CwTemplateContract(pub Addr); - -impl CwTemplateContract { - pub fn addr(&self) -> Addr { - self.0.clone() - } - - pub fn call>(&self, msg: T) -> StdResult { - let msg = to_json_binary(&msg.into())?; - Ok(WasmMsg::Execute { - contract_addr: self.addr().into(), - msg, - funds: vec![], - } - .into()) - } -} - -pub fn is_contract_admin( - querier: &QuerierWrapper, - env: &Env, - sus_admin: &Addr, -) -> Result<(), ContractError> { - let contract_admin = querier - .query_wasm_contract_info(&env.contract.address)? - .admin; - if let Some(contract_admin) = contract_admin { - if contract_admin != *sus_admin { - return Err(ContractError::Unauthorized {}); - } - } else { - return Err(ContractError::Unauthorized {}); - } - Ok(()) -} diff --git a/smart-contracts/contracts/multihop-router/src/lib.rs b/smart-contracts/contracts/multihop-router/src/lib.rs deleted file mode 100644 index 4f62f35cb..000000000 --- a/smart-contracts/contracts/multihop-router/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -pub mod contract; -mod error; -pub mod helpers; -pub mod msg; -#[cfg(test)] -pub mod multitest; - -pub mod route; -pub mod state; - -pub use crate::error::ContractError; diff --git a/smart-contracts/contracts/multihop-router/src/msg.rs b/smart-contracts/contracts/multihop-router/src/msg.rs deleted file mode 100644 index 00e2c149d..000000000 --- a/smart-contracts/contracts/multihop-router/src/msg.rs +++ /dev/null @@ -1,65 +0,0 @@ -use cosmwasm_schema::{cw_serde, QueryResponses}; - -use crate::route::{Memo, Route, RouteId}; - -#[cw_serde] -pub struct InstantiateMsg {} - -#[cw_serde] -#[non_exhaustive] -pub enum ExecuteMsg { - AddRoute { - route_id: RouteId, - route: Route, - }, - #[cfg(feature = "mutable")] - MutateRoute { - route_id: RouteId, - new_route: Route, - }, - #[cfg(feature = "mutable")] - RemoveRoute { - route_id: RouteId, - }, -} - -#[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - // TODO change timeout to either a Timestamp or a Duration, also find a datastructure that is always a json - #[returns(GetMemoResponse)] - GetMemo { - route_id: RouteId, - timeout: String, - retries: i64, - actual_memo: Option, - }, - #[returns(GetRouteResponse)] - GetRoute { route_id: RouteId }, - #[returns(ListRoutesResponse)] - ListRoutes {}, -} - -#[cw_serde] -pub struct GetMemoResponse { - pub channel: String, - pub port: String, - pub memo: MemoResponse, -} - -#[cw_serde] -#[serde(untagged)] -pub enum MemoResponse { - Forward(Memo), - Actual(Option), -} - -#[cw_serde] -pub struct GetRouteResponse { - pub route: Route, -} - -#[cw_serde] -pub struct ListRoutesResponse { - pub routes: Vec<(RouteId, Route)>, -} diff --git a/smart-contracts/contracts/multihop-router/src/multitest/common.rs b/smart-contracts/contracts/multihop-router/src/multitest/common.rs deleted file mode 100644 index cb5ef320b..000000000 --- a/smart-contracts/contracts/multihop-router/src/multitest/common.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub use anyhow::Result; -pub use derivative::Derivative; - -pub use crate::contract::{execute, instantiate, query}; -pub use crate::{ - error::ContractError, - msg::{ExecuteMsg, InstantiateMsg, QueryMsg}, -}; -pub use cosmwasm_std::{coin, BlockInfo, Coin, Decimal, Empty, StdResult, Uint128}; -pub use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; - -pub const USER: &str = "user"; -pub const DEPLOYER: &str = "deployer"; -pub const EXECUTOR: &str = "executor"; -pub const DENOM: &str = "uosmo"; -pub const LOCAL_DENOM: &str = "ibc/ilovemymom"; - -pub fn contract() -> Box> { - let contract = ContractWrapper::new(execute, instantiate, query); - Box::new(contract) -} diff --git a/smart-contracts/contracts/multihop-router/src/multitest/mod.rs b/smart-contracts/contracts/multihop-router/src/multitest/mod.rs deleted file mode 100644 index 0fcb84a57..000000000 --- a/smart-contracts/contracts/multihop-router/src/multitest/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod common; -pub mod suite; -pub mod test; diff --git a/smart-contracts/contracts/multihop-router/src/multitest/suite.rs b/smart-contracts/contracts/multihop-router/src/multitest/suite.rs deleted file mode 100644 index 7e52812d0..000000000 --- a/smart-contracts/contracts/multihop-router/src/multitest/suite.rs +++ /dev/null @@ -1,251 +0,0 @@ -use anyhow::{Ok, Result as AnyResult}; -use serde::de::DeserializeOwned; - -use crate::{ - msg::{GetMemoResponse, GetRouteResponse, ListRoutesResponse, MemoResponse}, - multitest::common::*, - route::{Route, RouteId}, -}; -use cosmwasm_std::{testing::MockApi, to_json_binary, Addr, CosmosMsg, MemoryStorage, WasmMsg}; -use cw_multi_test::{ - App, AppBuilder, BankKeeper, DistributionKeeper, FailingModule, StakeKeeper, WasmKeeper, -}; - -pub type QuasarMultiHopRouterApp = App< - BankKeeper, - MockApi, - MemoryStorage, - FailingModule, - WasmKeeper, - StakeKeeper, - DistributionKeeper, ->; - -type OnFailFunction = fn(&[(RouteId, Route)], &[(RouteId, Route)]) -> T; - -use crate::msg::{ExecuteMsg, InstantiateMsg}; - -#[derive(Derivative)] -#[derivative(Debug)] -pub struct QuasarVaultSuite { - #[derivative(Debug = "ignore")] - pub app: QuasarMultiHopRouterApp, - // The account that deploys everything - pub deployer: Addr, - // executor address - pub executor: Addr, - // user address - pub user: Addr, - // router address - pub router: Addr, -} - -impl QuasarVaultSuite { - pub fn init(init_msg: InstantiateMsg, funds: Vec) -> Result { - let genesis_funds = vec![coin(150000, DENOM), coin(150000, LOCAL_DENOM)]; - let deployer = Addr::unchecked(DEPLOYER); - let executor = Addr::unchecked(EXECUTOR); - let user = Addr::unchecked(USER); - let mut app = AppBuilder::new().build(|router, _, storage| { - router - .bank - .init_balance(storage, &deployer, genesis_funds) - .unwrap(); - }); - app.send_tokens( - deployer.clone(), - user.clone(), - &[coin(50000, DENOM), coin(50000, LOCAL_DENOM)], - )?; - app.send_tokens( - deployer.clone(), - executor.clone(), - &[coin(50000, DENOM), coin(50000, LOCAL_DENOM)], - )?; - - let router_id = app.store_code(contract()); - - let addr = app.instantiate_contract( - router_id, - deployer.clone(), - &init_msg, - &funds, - "router-contract", - Some(deployer.to_string()), - )?; - Ok(QuasarVaultSuite { - app, - deployer, - executor, - user, - router: addr, - }) - } - - pub fn execute( - &mut self, - sender: Addr, - msg: ExecuteMsg, - funds: Vec, - ) -> AnyResult { - self.app.execute( - sender, - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: self.router.to_string(), - msg: to_json_binary(&msg)?, - funds, - }), - ) - } - - pub fn query(&self, msg: QueryMsg) -> AnyResult - where - T: DeserializeOwned, - { - let res = self - .app - .wrap() - .query_wasm_smart::(self.router.clone(), &msg)?; - Ok(res) - } - - /// the same as check_queries but panics if any query gives a different result than expected from the expected routes - pub fn assert_queries(&self, expected: &[(RouteId, Route)]) { - self.assert_get_memo(expected); - self.assert_get_route(expected); - self.assert_list_route(expected); - } - - /// check whether all queries return values expected from the expected routes - pub fn check_queries(&self, expected: &[(RouteId, Route)]) -> AnyResult { - Ok(self.check_get_memo(expected)? - && self.check_get_route(expected)? - && self.check_list_routes(expected)?) - } - - pub fn assert_get_memo(&self, expected: &[(RouteId, Route)]) { - self.verify_get_memo( - expected, - |actual, expected| { - panic!( - "a different memo was produced than expected, memo: {:?} expected {:?}", - actual, expected - ) - }, - (), - ) - .unwrap() - } - - // do all contract queries and check that the values are the same as any of the routes in expected - pub fn check_get_memo(&self, expected: &[(RouteId, Route)]) -> AnyResult { - self.verify_get_memo(expected, |_, _: &[(RouteId, Route)]| false, true) - } - - pub fn verify_get_memo( - &self, - expected: &[(RouteId, Route)], - on_fail: fn(GetMemoResponse, &[(RouteId, Route)]) -> T, - on_succes: T, - ) -> AnyResult { - let timeout = "1000"; - let retries = 3; - let actual_memo = Some("{\"my-json\": \"myval\"}".to_string()); - for (id, route) in expected.iter() { - let res = self.query::(QueryMsg::GetMemo { - route_id: id.clone(), - timeout: timeout.to_string(), - retries, - actual_memo: actual_memo.clone(), - })?; - if res.channel != route.channel { - return Ok(on_fail(res, expected)); - } - if res.port != route.port { - return Ok(on_fail(res, expected)); - } - if let Some(hop) = route.hop.clone() { - if MemoResponse::Forward(hop.to_memo( - timeout.to_string(), - retries, - actual_memo.clone(), - )) != res.memo - { - return Ok(on_fail(res, expected)); - } - } else if MemoResponse::Actual(actual_memo.clone()) != res.memo { - return Ok(on_fail(res, expected)); - } - } - Ok(on_succes) - } - - pub fn assert_get_route(&self, expected: &[(RouteId, Route)]) { - self.verify_get_route( - expected, - |actual, expected| { - panic!( - "a different memo was produced than expected, memo: {:?} expected {:?}", - actual, expected - ) - }, - (), - ) - .unwrap() - } - - // do all contract queries and check that the values are the same as any of the routes in expected - pub fn check_get_route(&self, expected: &[(RouteId, Route)]) -> AnyResult { - self.verify_get_route(expected, |_, _| false, true) - } - - pub fn verify_get_route( - &self, - expected: &[(RouteId, Route)], - on_fail: fn((&RouteId, &Route), (&RouteId, &Route)) -> T, - on_succes: T, - ) -> AnyResult { - for (id, route) in expected.iter() { - let res = self.query::(QueryMsg::GetRoute { - route_id: id.clone(), - })?; - if &res.route != route { - return Ok(on_fail((id, &res.route), (id, route))); - } - } - Ok(on_succes) - } - - pub fn assert_list_route(&self, expected: &[(RouteId, Route)]) { - self.verify_get_memo( - expected, - |actual, expected| { - panic!( - "a different memo was produced than expected, memo: {:?} expected {:?}", - actual, expected - ) - }, - (), - ) - .unwrap() - } - - // do all contract queries and check that the values are the same as any of the routes in expected - pub fn check_list_routes(&self, expected: &[(RouteId, Route)]) -> AnyResult { - self.verify_get_memo(expected, |_, _| false, true) - } - - pub fn verify_list_routes( - &self, - expected: &[(RouteId, Route)], - on_fail: OnFailFunction, - on_succes: T, - ) -> AnyResult { - let res = self.query::(QueryMsg::ListRoutes {})?; - if res.routes.iter().all(|actual| expected.contains(actual)) { - Ok(on_succes) - } else { - Ok(on_fail(res.routes.as_ref(), expected)) - } - } -} diff --git a/smart-contracts/contracts/multihop-router/src/multitest/test.rs b/smart-contracts/contracts/multihop-router/src/multitest/test.rs deleted file mode 100644 index 5dd8ebc79..000000000 --- a/smart-contracts/contracts/multihop-router/src/multitest/test.rs +++ /dev/null @@ -1,99 +0,0 @@ -use cosmwasm_std::attr; -use cosmwasm_std::Addr; -use cosmwasm_std::Event; - -use crate::msg::InstantiateMsg; -use crate::multitest::common::*; -use crate::multitest::suite::*; -use crate::route::Destination; -use crate::route::Hop; -use crate::route::Route; -use crate::route::RouteId; - -#[test] -fn route_lifecycle_works() { - // initialize the suite - let mut suite = QuasarVaultSuite::init(InstantiateMsg {}, vec![]).unwrap(); - - // create some mock routes - let mut osmo_routes = vec![( - RouteId::new(Destination::new("osmosis"), "uosmo".to_string()), - Route::new("channel-12", "transfer", None), - )]; - - // add the routes as admin - for route in osmo_routes.iter() { - let res = suite - .execute( - Addr::unchecked(DEPLOYER), - ExecuteMsg::AddRoute { - route_id: route.0.clone(), - route: route.1.clone(), - }, - vec![], - ) - .unwrap(); - - let e = Event::new("wasm").add_attributes(vec![ - attr("action", "add_route"), - attr("route_id", "destination: osmosis, asset: uosmo"), - attr("route", "channel: channel-12, port: transfer"), - ]); - res.assert_event(&e); - } - - suite.assert_queries(&osmo_routes); - // mutate the first route in our vec - let osmo_routes: Vec<(RouteId, Route)> = osmo_routes - .iter_mut() - .map(|val| { - ( - val.0.clone(), - Route::new( - "channel-13", - "transfer", - Some(Hop::new("channel-11", "transfer", "cosmos123", None)), - ), - ) - }) - .collect(); - - // mutate the route in our contract - let res = suite - .execute( - Addr::unchecked(DEPLOYER), - ExecuteMsg::MutateRoute { - route_id: osmo_routes[0].0.clone(), - new_route: osmo_routes[0].1.clone(), - }, - vec![], - ) - .unwrap(); - - let e = Event::new("wasm").add_attributes(vec![ - attr("action", "mutate_route"), - attr("route_id", "destination: osmosis, asset: uosmo"), - attr( - "route", - "channel: channel-13, port: transfer, hop: (channel: channel-11, port: transfer, receiver: cosmos123)", - ), - ]); - res.assert_event(&e); - - suite.assert_queries(&osmo_routes); - let res = suite - .execute( - Addr::unchecked(DEPLOYER), - ExecuteMsg::RemoveRoute { - route_id: osmo_routes[0].0.clone(), - }, - vec![], - ) - .unwrap(); - let e = Event::new("wasm").add_attributes(vec![ - attr("action", "remove_route"), - attr("route_id", "destination: osmosis, asset: uosmo"), - ]); - res.assert_event(&e); - suite.assert_queries(&[]); -} diff --git a/smart-contracts/contracts/multihop-router/src/route.rs b/smart-contracts/contracts/multihop-router/src/route.rs deleted file mode 100644 index 0d463f22b..000000000 --- a/smart-contracts/contracts/multihop-router/src/route.rs +++ /dev/null @@ -1,379 +0,0 @@ -use std::fmt::Display; - -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{StdError, StdResult}; -use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -/// A Route represents the route to take to a certain chain. Each route might be unique for a certain asset. -/// A complete usable case of a route includes the asset to send to the destination, since a different asset -/// might need to take a different route -/// A complete Route is then the kv-pair of the Map Routes, namely -#[cw_serde] -pub struct Route { - // the channel to use in an ibc transfer from the current chain - pub channel: String, - // the port to use, this is most likely always "transfer" - pub port: String, - // any potential hops needed to get to the current chain. These hops are dependend on the associated assets - pub hop: Option, -} - -impl Display for Route { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self.hop.is_some() { - write!( - f, - "channel: {}, port: {}, hop: ({})", - self.channel, - self.port, - self.hop.as_ref().unwrap() - ) - } else { - write!(f, "channel: {}, port: {}", self.channel, self.port) - } - } -} - -impl Route { - pub fn new(channel: impl Into, port: impl Into, hop: Option) -> Route { - Route { - channel: channel.into(), - port: port.into(), - hop, - } - } -} - -#[cw_serde] -pub struct Hop { - // the channel to reach the first destination chain - channel: String, - // port will most likely be "transfer" - port: String, - // receiver is the receiver of the hop. If the chain has packet forward middelware properly integrated - // the receiver is never relevant. If PFM is not properly integrated, the receiver will have the funds. - // The users of the multihop router should ensure that the receiver works as intended - receiver: String, - // the next hop to take to reach the actual destination chain - next: Option>, -} - -impl Hop { - pub fn new( - channel: impl Into, - port: impl Into, - receiver: impl Into, - hop: Option, - ) -> Hop { - Hop { - channel: channel.into(), - port: port.into(), - receiver: receiver.into(), - next: hop.map(Box::new), - } - } - - /// create a packet forwarder memo field from a route of hops - /// receivers of the tokens on the intermediate chains - pub fn to_memo(&self, timeout: String, retries: i64, actual_memo: Option) -> Memo { - Memo::new(self.to_forward(timeout, retries, actual_memo)) - } - - // wtf are these clones even - fn to_forward(&self, timeout: String, retries: i64, actual_memo: Option) -> Forward { - Forward { - receiver: self.receiver.clone(), - port: self.port.clone(), - channel: self.channel.clone(), - timeout: timeout.clone(), - retries, - next: self - .clone() - .next - .map_or(Box::new(Next::Actual(actual_memo.clone())), |val| { - Box::new(Next::NextForward(val.to_forward( - timeout, - retries, - actual_memo, - ))) - }), - } - } -} - -impl Display for Hop { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self.next.is_some() { - write!( - f, - "channel: {}, port: {}, receiver: {}, next: ({})", - self.channel, - self.port, - self.receiver, - self.next.as_ref().unwrap() - ) - } else { - write!( - f, - "channel: {}, port: {}, receiver: {}", - self.channel, self.port, self.receiver - ) - } - } -} - -// in the case of our multihop router, a memo is a set forwarding steps with an actual memo field attached for the host chan -#[cw_serde] -pub struct Memo { - pub forward: Forward, -} - -impl Memo { - pub fn new(forward: Forward) -> Memo { - Memo { forward } - } -} - -#[cw_serde] -pub struct Forward { - pub receiver: String, - pub port: String, - pub channel: String, - pub timeout: String, - pub retries: i64, - pub next: Box, -} - -impl Forward { - pub fn new( - receiver: impl Into, - port: impl Into, - channel: impl Into, - timeout: impl Into, - retries: i64, - next: Box, - ) -> Forward { - Forward { - receiver: receiver.into(), - port: port.into(), - channel: channel.into(), - timeout: timeout.into(), - retries, - next, - } - } -} - -#[cw_serde] -#[serde(untagged)] -pub enum Next { - NextForward(Forward), - Actual(Option), -} - -#[cw_serde] -pub struct RouteId { - pub destination: Destination, - pub asset: String, -} - -impl RouteId { - pub fn new(destination: Destination, asset: String) -> RouteId { - RouteId { destination, asset } - } -} - -impl Display for RouteId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "destination: {}, asset: {}", - self.destination, self.asset - ) - } -} - -impl<'a> PrimaryKey<'a> for RouteId { - type Prefix = Destination; - - type SubPrefix = (); - - type Suffix = String; - - type SuperSuffix = (Destination, String); - - fn key(&self) -> Vec { - let mut keys = self.destination.key(); - keys.extend(self.asset.key()); - keys - } -} - -impl KeyDeserialize for RouteId { - type Output = RouteId; - - fn from_vec(mut value: Vec) -> StdResult { - let mut tu = value.split_off(2); - let t_len = parse_length(&value)?; - let u = tu.split_off(t_len); - - Ok(RouteId { - destination: Destination::from_vec(tu)?, - asset: String::from_vec(u)?, - }) - } -} - -impl KeyDeserialize for &RouteId { - type Output = RouteId; - - fn from_vec(mut value: Vec) -> StdResult { - let mut tu = value.split_off(2); - let t_len = parse_length(&value)?; - let u = tu.split_off(t_len); - - Ok(RouteId { - destination: Destination::from_vec(tu)?, - asset: String::from_vec(u)?, - }) - } -} - -fn parse_length(value: &[u8]) -> StdResult { - Ok(u16::from_be_bytes( - value - .try_into() - .map_err(|_| StdError::generic_err("Could not read 2 byte length"))?, - ) - .into()) -} - -// destination uses a special partialEq, so we don't derive it -#[derive(Serialize, Deserialize, Clone, Debug, JsonSchema)] -pub struct Destination(pub String); - -impl Destination { - pub fn new(destination: impl Into) -> Destination { - Destination(destination.into()) - } -} - -impl From for Destination { - fn from(value: String) -> Self { - Self(value) - } -} - -impl Display for Destination { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -impl PartialEq for Destination { - // Destinination uses a case insensitive eq - fn eq(&self, other: &Self) -> bool { - self.0.to_lowercase() == other.0.to_lowercase() - } -} - -impl<'a> Prefixer<'a> for Destination { - fn prefix(&self) -> Vec { - self.0.prefix() - } -} - -impl<'a> PrimaryKey<'a> for Destination { - type Prefix = (); - type SubPrefix = (); - type Suffix = Self; - type SuperSuffix = Self; - - fn key(&self) -> Vec { - self.0.key() - } -} - -impl KeyDeserialize for Destination { - type Output = Destination; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(Destination( - String::from_utf8(value).map_err(StdError::invalid_utf8)?, - )) - } -} - -impl KeyDeserialize for &Destination { - type Output = Destination; - - #[inline(always)] - fn from_vec(value: Vec) -> StdResult { - Ok(Destination( - String::from_utf8(value).map_err(StdError::invalid_utf8)?, - )) - } -} - -#[cfg(test)] -mod tests { - use cw_storage_plus::PrimaryKey; - use proptest::prelude::*; - - use super::*; - - #[test] - fn se_json_works() { - // example json from packet forward middleware without any formatting characters so we match for it - let json_str = r#"{"forward":{"receiver":"chain-c-bech32-address","port":"transfer","channel":"channel-123","timeout":"10m","retries":2,"next":{"receiver":"chain-d-bech32-address","port":"transfer","channel":"channel-234","timeout":"10m","retries":2,"next":"{\"my-json\":\"myval\"}"}}}"#; - - let actual: Memo = serde_json_wasm::from_str(json_str).unwrap(); - let expected = Memo::new(Forward::new( - "chain-c-bech32-address", - "transfer", - "channel-123", - "10m", - 2, - Box::new(Next::NextForward(Forward::new( - "chain-d-bech32-address", - "transfer", - "channel-234", - "10m", - 2, - Box::new(Next::Actual(Some("{\"my-json\":\"myval\"}".to_string()))), - ))), - )); - - assert_eq!(actual, expected); - assert_eq!(serde_json_wasm::to_string(&actual).unwrap(), json_str); - assert_eq!(serde_json_wasm::to_string(&expected).unwrap(), json_str) - } - - prop_compose! { - fn route_id()(dst in any::(), asset in any::()) -> RouteId { - RouteId { destination: Destination(dst), asset } - } - } - - proptest! { - #[test] - fn route_id_key_ser_de(id in route_id()) { - let keys = id.joined_key(); - let route_id = RouteId::from_vec(keys).unwrap(); - prop_assert_eq!(id, route_id) - } - } - - proptest! { - #[test] - fn route_id_borrow_key_ser_de(id in route_id()) { - let b_id = &id; - let keys = b_id.joined_key(); - let route_id = &RouteId::from_vec(keys).unwrap(); - prop_assert_eq!(b_id, route_id) - } - } -} diff --git a/smart-contracts/contracts/multihop-router/src/state.rs b/smart-contracts/contracts/multihop-router/src/state.rs deleted file mode 100644 index 7d9548e91..000000000 --- a/smart-contracts/contracts/multihop-router/src/state.rs +++ /dev/null @@ -1,7 +0,0 @@ -use cw_storage_plus::Map; - -use crate::route::{Route, RouteId}; - -/// ROUTES represents complete routes to a destination for a certain asset. -/// The value of Route represents the route to take to -pub const ROUTES: Map<&RouteId, Route> = Map::new("routes"); diff --git a/smart-contracts/contracts/range-middleware/.cargo/config b/smart-contracts/contracts/range-middleware/.cargo/config deleted file mode 100644 index af5698e58..000000000 --- a/smart-contracts/contracts/range-middleware/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --lib --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --bin schema" diff --git a/smart-contracts/contracts/token-burner/.cargo/config b/smart-contracts/contracts/token-burner/.cargo/config deleted file mode 100644 index 624255c74..000000000 --- a/smart-contracts/contracts/token-burner/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" \ No newline at end of file diff --git a/smart-contracts/contracts/vault-rewards/.cargo/config b/smart-contracts/contracts/vault-rewards/.cargo/config deleted file mode 100644 index 336b618a1..000000000 --- a/smart-contracts/contracts/vault-rewards/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -unit-test = "test --lib" -schema = "run --example schema" diff --git a/smart-contracts/contracts/vault-rewards/.gitignore b/smart-contracts/contracts/vault-rewards/.gitignore deleted file mode 100644 index e08217044..000000000 --- a/smart-contracts/contracts/vault-rewards/.gitignore +++ /dev/null @@ -1 +0,0 @@ -ts diff --git a/smart-contracts/contracts/vault-rewards/CHANGELOG.md b/smart-contracts/contracts/vault-rewards/CHANGELOG.md deleted file mode 100644 index 14674671c..000000000 --- a/smart-contracts/contracts/vault-rewards/CHANGELOG.md +++ /dev/null @@ -1,83 +0,0 @@ -# CHANGELOG - -## [0.1.1] - 2023-07-19 - -### Added -- Nothing - -### Changed -- Updated the query to fetch the claimable amount for give user address. - -Earlier it was not changing the user reward index, the push of current balance to history while querying fixed it : -```rust -pub fn query_pending_rewards( - deps: Deps, - env: Env, - user: Addr, -) -> Result { - let config = CONFIG.load(deps.storage)?; - let user_reward_index = get_user_reward_index(deps.storage, &user); - get_claim_amount(deps, &env, &config, &user_reward_index) -} -``` -Changed to : -```rust -pub fn query_pending_rewards( - deps: Deps, - env: Env, - user: Addr, - ) -> Result { - let config = CONFIG.load(deps.storage)?; - let cur_block_height = env.block.height; - let mut user_reward_index = get_user_reward_index(deps.storage, &user); - let user_vault_token_balance = - AssetInfo::cw20(config.vault_token.clone()).query_balance(&deps.querier, &user)?; - if let Some(prev_balance) = user_reward_index.balance { - user_reward_index.history.push(DistributionSchedule { - start: prev_balance.reward_index, - end: cur_block_height, - amount: prev_balance.balance, - }); - user_reward_index.balance = if !user_vault_token_balance.is_zero() { - Some(UserBalance { - reward_index: cur_block_height + 1, - balance: user_vault_token_balance, - }) - } else { - None - }; - } - get_claim_amount(deps, &env, &config, &user_reward_index) - } -``` - -### Deprecated -- Nothing - -### Removed -- Nothing - -### Fixed -- Fixed issue in fn `get_claim_amount()` where previously unwrap was happening on a nil vector. - -Old code -```rust -if reward_indexes.last().unwrap().0 != env.block.height && d.end == env.block.height { - reward_indexes.push((env.block.height, RewardIndex { vault_supply })); -} -``` -New code -```rust -if let Some(value) = reward_indexes.last() { - if value.0 != env.block.height & & d.end == env.block.height { - reward_indexes.push((env.block.height, RewardIndex { vault_supply })); - } -} -``` - -### Security -- Nothing - - - - diff --git a/smart-contracts/contracts/vault-rewards/Cargo.toml b/smart-contracts/contracts/vault-rewards/Cargo.toml deleted file mode 100644 index bb42d496e..000000000 --- a/smart-contracts/contracts/vault-rewards/Cargo.toml +++ /dev/null @@ -1,54 +0,0 @@ -[package] -name = "vault-rewards" -version = "0.1.0" -authors = ["shab "] -edition = "2021" - -exclude = [ - # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. - "contract.wasm", - "hash.txt", -] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[profile.release] -opt-level = 3 -debug = false -rpath = false -lto = true -debug-assertions = false -codegen-units = 1 -panic = 'abort' -incremental = false -overflow-checks = true - -[features] -# for more explicit tests, cargo test --features=backtraces -backtraces = ["cosmwasm-std/backtraces"] -# use library feature to disable all instantiate/execute/query exports -library = [] - -[package.metadata.scripts] -optimize = """docker run --rm -v "$(pwd)":/code \ - --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \ - --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/optimizer:0.16.0 -""" - -[dependencies] -cosmwasm-std = { workspace = true } -osmosis-std = { workspace = true } -osmosis-std-derive = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus ={ workspace = true } -schemars ={ workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } -cw2 = { workspace = true } -cw20 = { workspace = true } -cw-asset = { workspace = true } -itertools = { workspace = true } diff --git a/smart-contracts/contracts/vault-rewards/examples/schema.rs b/smart-contracts/contracts/vault-rewards/examples/schema.rs deleted file mode 100644 index 551f8dd30..000000000 --- a/smart-contracts/contracts/vault-rewards/examples/schema.rs +++ /dev/null @@ -1,17 +0,0 @@ -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; -use std::env::current_dir; -use std::fs::create_dir_all; -use vault_rewards::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use vault_rewards::state::Config; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(InstantiateMsg), &out_dir); - export_schema(&schema_for!(ExecuteMsg), &out_dir); - export_schema(&schema_for!(QueryMsg), &out_dir); - export_schema(&schema_for!(Config), &out_dir); -} diff --git a/smart-contracts/contracts/vault-rewards/schema/config.json b/smart-contracts/contracts/vault-rewards/schema/config.json deleted file mode 100644 index 22fdb530b..000000000 --- a/smart-contracts/contracts/vault-rewards/schema/config.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "distribution_schedules", - "reward_token", - "total_claimed", - "vault_token" - ], - "properties": { - "distribution_schedules": { - "type": "array", - "items": { - "$ref": "#/definitions/DistributionSchedule" - } - }, - "reward_token": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - }, - "total_claimed": { - "$ref": "#/definitions/Uint128" - }, - "vault_token": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionSchedule": { - "type": "object", - "required": [ - "amount", - "end", - "start" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "end": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/vault-rewards/schema/execute_msg.json b/smart-contracts/contracts/vault-rewards/schema/execute_msg.json deleted file mode 100644 index f17d66e75..000000000 --- a/smart-contracts/contracts/vault-rewards/schema/execute_msg.json +++ /dev/null @@ -1,250 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "admin" - ], - "properties": { - "admin": { - "$ref": "#/definitions/AdminExecuteMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vault" - ], - "properties": { - "vault": { - "$ref": "#/definitions/VaultExecuteMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AdminExecuteMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "withdraw_funds" - ], - "properties": { - "withdraw_funds": { - "$ref": "#/definitions/AssetBase_for_Addr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "add_distribution_schedule" - ], - "properties": { - "add_distribution_schedule": { - "$ref": "#/definitions/DistributionSchedule" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_distribution_schedule" - ], - "properties": { - "update_distribution_schedule": { - "type": "object", - "required": [ - "id", - "update" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "update": { - "$ref": "#/definitions/DistributionScheduleOptions" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_distribution_schedule" - ], - "properties": { - "remove_distribution_schedule": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "AssetBase_for_Addr": { - "description": "Represents a fungible asset with a known amount\n\nEach asset instance contains two values: `info`, which specifies the asset's type (CW20 or native), and its `amount`, which specifies the asset's amount.", - "type": "object", - "required": [ - "amount", - "info" - ], - "properties": { - "amount": { - "description": "Specifies the asset's amount", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "info": { - "description": "Specifies the asset's type (CW20 or native)", - "allOf": [ - { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - ] - } - }, - "additionalProperties": false - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionSchedule": { - "type": "object", - "required": [ - "amount", - "end", - "start" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "end": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "DistributionScheduleOptions": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "end": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "start": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "VaultExecuteMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "update_user_reward_index" - ], - "properties": { - "update_user_reward_index": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/smart-contracts/contracts/vault-rewards/schema/instantiate_msg.json b/smart-contracts/contracts/vault-rewards/schema/instantiate_msg.json deleted file mode 100644 index b1ae7f34f..000000000 --- a/smart-contracts/contracts/vault-rewards/schema/instantiate_msg.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "distribution_schedule", - "reward_token", - "vault_token" - ], - "properties": { - "distribution_schedule": { - "$ref": "#/definitions/DistributionSchedule" - }, - "reward_token": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - }, - "vault_token": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "DistributionSchedule": { - "type": "object", - "required": [ - "amount", - "end", - "start" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "end": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "start": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/smart-contracts/contracts/vault-rewards/schema/query_msg.json b/smart-contracts/contracts/vault-rewards/schema/query_msg.json deleted file mode 100644 index c570a2a41..000000000 --- a/smart-contracts/contracts/vault-rewards/schema/query_msg.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "pending_rewards" - ], - "properties": { - "pending_rewards": { - "type": "string" - } - }, - "additionalProperties": false - } - ] -} diff --git a/smart-contracts/contracts/vault-rewards/src/contract.rs b/smart-contracts/contracts/vault-rewards/src/contract.rs deleted file mode 100644 index 44cc78d77..000000000 --- a/smart-contracts/contracts/vault-rewards/src/contract.rs +++ /dev/null @@ -1,96 +0,0 @@ -use crate::error::VaultRewardsError; -use crate::execute::admin::{ - execute_add_distribution_schedule, execute_remove_distribution_schedule, - execute_update_distribution_schedule, execute_withdraw_funds, -}; -use crate::execute::user::execute_claim; -use crate::execute::vault::execute_update_user_reward_index; -use crate::helpers::is_contract_admin; -use crate::msg::{ - AdminExecuteMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, VaultExecuteMsg, -}; -use crate::query::{query_config, query_pending_rewards, query_user_rewards_index}; -use crate::state::{Config, CONFIG}; -#[cfg(not(feature = "library"))] -use cosmwasm_std::entry_point; -use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, Uint128}; - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn instantiate( - deps: DepsMut, - env: Env, - _info: MessageInfo, - msg: InstantiateMsg, -) -> Result { - let mut config = Config { - vault_token: deps.api.addr_validate(&msg.vault_token)?, - reward_token: msg.reward_token, - distribution_schedules: vec![], - total_claimed: Uint128::zero(), - }; - config.add_distribution_schedules(&deps.querier, &env, msg.distribution_schedules)?; - CONFIG.save(deps.storage, &config)?; - Ok(Response::default()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn execute( - deps: DepsMut, - env: Env, - info: MessageInfo, - msg: ExecuteMsg, -) -> Result { - match msg { - ExecuteMsg::Claim {} => execute_claim(deps, &env, info.sender), - ExecuteMsg::Admin(admin_msg) => { - is_contract_admin(&deps.querier, &env, &info.sender)?; - match admin_msg { - AdminExecuteMsg::WithdrawFunds(asset) => { - execute_withdraw_funds(deps, env, info.sender, asset) - } - AdminExecuteMsg::AddDistributionSchedule(schedule) => { - execute_add_distribution_schedule(deps, env, schedule) - } - AdminExecuteMsg::UpdateDistributionSchedule { id, update } => { - execute_update_distribution_schedule(deps, env, id, update) - } - AdminExecuteMsg::RemoveDistributionSchedule(id) => { - execute_remove_distribution_schedule(deps, env, id) - } - } - } - ExecuteMsg::Vault(vault_msg) => { - let vault_token = CONFIG.load(deps.storage)?.vault_token; - if info.sender != vault_token { - return Err(VaultRewardsError::Unauthorized {}); - } - match vault_msg { - VaultExecuteMsg::UpdateUserRewardIndex(user) => { - let user = deps.api.addr_validate(&user)?; - execute_update_user_reward_index(deps, env, user) - } - } - } - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { - match msg { - QueryMsg::Config {} => to_json_binary(&query_config(deps, env)?), - QueryMsg::PendingRewards(user) => { - let user = deps.api.addr_validate(&user)?; - to_json_binary(&query_pending_rewards(deps, env, user)?) - } - QueryMsg::GetUserRewardsIndex(user) => { - let user = deps.api.addr_validate(&user)?; - to_json_binary(&query_user_rewards_index(deps, user)?) - } - } - .map_err(|e| e.into()) -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - Ok(Response::new().add_attribute("success", "true")) -} diff --git a/smart-contracts/contracts/vault-rewards/src/error.rs b/smart-contracts/contracts/vault-rewards/src/error.rs deleted file mode 100644 index 6bf82452f..000000000 --- a/smart-contracts/contracts/vault-rewards/src/error.rs +++ /dev/null @@ -1,41 +0,0 @@ -use cosmwasm_std::{StdError, Uint128}; -use cw_asset::AssetError; -use thiserror::Error; - -#[derive(Error, Debug, PartialEq)] -pub enum VaultRewardsError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("{0}")] - Asset(#[from] AssetError), - - #[error("Unauthorized")] - Unauthorized {}, - - #[error("Invalid distribution schedule: {reason:?}")] - InvalidDistributionSchedule { reason: String }, - - #[error("No rewards to claim")] - NoRewardsToClaim {}, - - #[error("Insufficient funds in contract to process claim. Contract balance: {contract_balance:?}, Claim amount: {claim_amount:?}")] - InsufficientFunds { - contract_balance: Uint128, - claim_amount: Uint128, - }, - - #[error("Invalid distribution schedule id. Max ID: {max_id:?}")] - InvalidDistributionScheduleId { max_id: u64 }, - - #[error( - "Cannot edit distribution schedule in progress. ID: {id:?}, Start: {start:?}, End: {end:?}" - )] - DistributionScheduleInProgress { id: u64, start: u64, end: u64 }, - - #[error("Cannot remove distribution schedule with funds left to be claimed. ID: {id:?}")] - DistributionScheduleWithUnclaimedFunds { id: u64 }, - - #[error("Cannot edit distribution schedule that has already ended. ID: {id:?}, End: {end:?}")] - DistributionScheduleExpired { id: u64, end: u64 }, -} diff --git a/smart-contracts/contracts/vault-rewards/src/execute/admin.rs b/smart-contracts/contracts/vault-rewards/src/execute/admin.rs deleted file mode 100644 index e2431fc36..000000000 --- a/smart-contracts/contracts/vault-rewards/src/execute/admin.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::msg::DistributionScheduleOptions; -use crate::state::{DistributionSchedule, CONFIG}; -use crate::VaultRewardsError; -use cosmwasm_std::{attr, Addr, DepsMut, Env, Response, Uint128}; -use cw_asset::Asset; - -pub fn execute_withdraw_funds( - deps: DepsMut, - env: Env, - admin: Addr, - mut asset: Asset, -) -> Result { - let config = CONFIG.load(deps.storage)?; - - let reward_token = &config.reward_token; - - if &asset.info == reward_token { - // check if reward balance is sufficient after withdrawal - let contract_reward_balance = config - .reward_token - .query_balance(&deps.querier, &env.contract.address)? - .checked_sub(asset.amount) - .unwrap_or_default(); - let total_reward_needed_to_distribute = config.get_total_distribution_amount(); - if contract_reward_balance < total_reward_needed_to_distribute { - return Err(VaultRewardsError::InsufficientFunds { - contract_balance: contract_reward_balance, - claim_amount: total_reward_needed_to_distribute, - }); - } - } else { - // send to admin if balance > 0 - asset.amount = asset.amount.min( - asset - .info - .query_balance(&deps.querier, &env.contract.address)?, - ); - }; - - if asset.amount.is_zero() { - return Err(VaultRewardsError::InsufficientFunds { - contract_balance: Uint128::zero(), - claim_amount: Uint128::zero(), - }); - } - let transfer = asset.transfer_msg(&admin)?; - - Ok(Response::new().add_message(transfer).add_attributes(vec![ - ("action", "withdraw_funds"), - ("asset", &asset.to_string()), - ("admin", admin.as_ref()), - ])) -} - -pub fn execute_add_distribution_schedule( - deps: DepsMut, - env: Env, - schedule: DistributionSchedule, -) -> Result { - let mut config = CONFIG.load(deps.storage)?; - config.add_distribution_schedule(&deps.querier, &env, schedule.clone())?; - CONFIG.save(deps.storage, &config)?; - Ok(Response::default().add_attributes(vec![ - ("action", "add_distribution_schedule"), - ("schedule start", &schedule.start.to_string()), - ("schedule end", &schedule.end.to_string()), - ("schedule amount", &schedule.amount.to_string()), - ])) -} - -pub fn execute_update_distribution_schedule( - deps: DepsMut, - env: Env, - id: u64, - update: DistributionScheduleOptions, -) -> Result { - let mut config = CONFIG.load(deps.storage)?; - config.update_distribution_schedule(&deps.querier, &env, id, &update)?; - CONFIG.save(deps.storage, &config)?; - let mut attrs = vec![ - attr("action", "update_distribution_schedule"), - attr("id", id.to_string()), - ]; - if let Some(start) = &update.start { - attrs.push(attr("schedule_start_updated_to", start.to_string())); - } - if let Some(end) = &update.end { - attrs.push(attr("schedule_end_updated_to", end.to_string())); - } - if let Some(amount) = &update.amount { - attrs.push(attr("schedule_amount_updated_to", amount.to_string())); - } - Ok(Response::default().add_attributes(attrs)) -} - -pub fn execute_remove_distribution_schedule( - deps: DepsMut, - env: Env, - id: u64, -) -> Result { - let mut config = CONFIG.load(deps.storage)?; - config.remove_distribution_schedule(deps.storage, &env, id)?; - CONFIG.save(deps.storage, &config)?; - Ok(Response::default().add_attributes(vec![ - ("action", "remove_distribution_schedule"), - ("id", &id.to_string()), - ])) -} - -#[cfg(test)] -mod tests {} diff --git a/smart-contracts/contracts/vault-rewards/src/execute/mock_querier.rs b/smart-contracts/contracts/vault-rewards/src/execute/mock_querier.rs deleted file mode 100644 index bfa4d6b11..000000000 --- a/smart-contracts/contracts/vault-rewards/src/execute/mock_querier.rs +++ /dev/null @@ -1,104 +0,0 @@ -use cosmwasm_std::testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}; -use cosmwasm_std::{ - from_json, to_json_binary, Coin, ContractResult, Empty, OwnedDeps, Querier, QuerierResult, - QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, -}; -use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; -use std::collections::HashMap; - -pub fn mock_dependencies( - contract_balance: &[Coin], -) -> OwnedDeps { - let custom_querier: WasmMockQuerier = - WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); - - OwnedDeps { - storage: MockStorage::default(), - api: MockApi::default(), - querier: custom_querier, - custom_query_type: Default::default(), - } -} - -pub struct WasmMockQuerier { - base: MockQuerier, - token_querier: TokenQuerier, -} - -impl Querier for WasmMockQuerier { - fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - let request: QueryRequest = match from_json(bin_request) { - Ok(v) => v, - Err(e) => { - return SystemResult::Err(SystemError::InvalidRequest { - error: format!("Parsing query request: {e:?}"), - request: bin_request.into(), - }) - } - }; - self.handle_query(&request) - } -} - -#[derive(Clone, Default)] -pub struct TokenQuerier { - balance: HashMap, - supply: Uint128, -} - -impl WasmMockQuerier { - pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { - match &request { - QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: _, - msg, - }) => match from_json(msg).unwrap() { - Cw20QueryMsg::TokenInfo {} => QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&TokenInfoResponse { - total_supply: self.token_querier.supply, - name: "vault_token".to_string(), - symbol: "".to_string(), - decimals: 0, - }) - .unwrap(), - )), - Cw20QueryMsg::Balance { address } => QuerierResult::Ok(ContractResult::Ok( - to_json_binary(&BalanceResponse { - balance: match self.token_querier.balance.get(&address) { - Some(balance) => *balance, - None => Uint128::zero(), - }, - }) - .unwrap(), - )), - _ => SystemResult::Err(SystemError::UnsupportedRequest { - kind: "unimplemented".to_string(), - }), - }, - _ => self.base.handle_query(request), - } - } -} - -impl WasmMockQuerier { - pub fn new(base: MockQuerier) -> Self { - WasmMockQuerier { - base, - token_querier: TokenQuerier::default(), - } - } - - pub fn with_token_balance(&mut self, address: &str, balance: &Uint128) { - if let Some(prev_balance) = self.token_querier.balance.get(address) { - self.token_querier.supply -= prev_balance; - } - self.token_querier.supply += balance; - self.token_querier - .balance - .insert(address.to_string(), *balance); - } - - pub fn with_bank_balance(&mut self, address: &str, balance: Vec) { - self.base.update_balance(address, balance); - } -} diff --git a/smart-contracts/contracts/vault-rewards/src/execute/mod.rs b/smart-contracts/contracts/vault-rewards/src/execute/mod.rs deleted file mode 100644 index 9c9b05d84..000000000 --- a/smart-contracts/contracts/vault-rewards/src/execute/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod admin; -pub mod user; -pub mod vault; - -#[cfg(test)] -mod mock_querier; diff --git a/smart-contracts/contracts/vault-rewards/src/execute/user.rs b/smart-contracts/contracts/vault-rewards/src/execute/user.rs deleted file mode 100644 index 355d9ae2d..000000000 --- a/smart-contracts/contracts/vault-rewards/src/execute/user.rs +++ /dev/null @@ -1,505 +0,0 @@ -use crate::helpers::{get_user_reward_index, update_reward_index}; -use crate::state::{ - Config, DistributionSchedule, RewardIndex, UserBalance, UserRewardIndex, CONFIG, REWARD_INDEX, - USER_REWARD_INDEX, -}; -use crate::VaultRewardsError; -use cosmwasm_std::{Addr, Deps, DepsMut, Env, Order, Response, StdResult, Uint128}; -use cw20::Cw20Contract; -use cw_asset::{Asset, AssetInfo}; -use cw_storage_plus::Bound; - -pub fn execute_claim(deps: DepsMut, env: &Env, user: Addr) -> Result { - let mut config = CONFIG.load(deps.storage)?; - let cur_block_height = env.block.height; - let mut user_reward_index = get_user_reward_index(deps.storage, &user); - let user_vault_token_balance = - AssetInfo::cw20(config.vault_token.clone()).query_balance(&deps.querier, &user)?; - // if previous balance, move to history and start new balance index - if let Some(prev_balance) = user_reward_index.balance { - user_reward_index.history.push(DistributionSchedule { - start: prev_balance.reward_index, - end: cur_block_height, - amount: prev_balance.balance, - }); - user_reward_index.balance = if !user_vault_token_balance.is_zero() { - Some(UserBalance { - reward_index: cur_block_height + 1, - balance: user_vault_token_balance, - }) - } else { - None - }; - } - // update global reward index before calculating user claim amount - update_reward_index(deps.storage, &deps.querier, env)?; - let claim_amount = get_claim_amount(deps.as_ref(), env, &config, &user_reward_index)?; - - // double check we have enough balance to cover this - let contract_reward_token_balance = config - .reward_token - .query_balance(&deps.querier, &env.contract.address)?; - if contract_reward_token_balance < claim_amount { - return Err(VaultRewardsError::InsufficientFunds { - contract_balance: contract_reward_token_balance, - claim_amount, - }); - } - - let claim = Asset::new(config.reward_token.clone(), claim_amount).transfer_msg(&user)?; - user_reward_index.history = vec![]; - USER_REWARD_INDEX.save(deps.storage, user.clone(), &user_reward_index)?; - config.total_claimed += claim_amount; - CONFIG.save(deps.storage, &config)?; - Ok(Response::new().add_message(claim).add_attributes(vec![ - ("action", "claim"), - ("user", user.as_ref()), - ("amount", &claim_amount.to_string()), - ])) -} - -pub fn get_claim_amount( - deps: Deps, - env: &Env, - config: &Config, - user_reward_index: &UserRewardIndex, -) -> Result { - let mut user_reward_index_history = user_reward_index.history.clone(); - // if we don't have the index history until current block height - if (user_reward_index_history.is_empty() - || user_reward_index_history.last().unwrap().end < env.block.height) - && user_reward_index.balance.is_some() - { - user_reward_index_history.push(DistributionSchedule { - start: user_reward_index.balance.clone().unwrap().reward_index + 1, - end: env.block.height, - amount: user_reward_index.balance.clone().unwrap().balance, - }); - } - - let vault_supply = Cw20Contract(CONFIG.load(deps.storage)?.vault_token) - .meta(&deps.querier)? - .total_supply; - - let mut claim_amount = user_reward_index_history - .iter() - .map(|d| { - let mut cur_height = d.start; - let mut reward_indexes = REWARD_INDEX - .range( - deps.storage, - Some(Bound::inclusive(d.start - 1)), - Some(Bound::inclusive(d.end)), - Order::Ascending, - ) - .collect::>>() - .unwrap(); - - if let Some(value) = reward_indexes.last() { - if value.0 != env.block.height && d.end == env.block.height { - reward_indexes.push((env.block.height, RewardIndex { vault_supply })); - } - } - // iterate over reward indexes 2 at a time to calculate reward for each period - reward_indexes - .iter() - .zip(reward_indexes.iter().skip(1)) - .map(|(start, end)| { - let (_, reward_index_start) = start; - let (height_end, _) = end; - let mut period_claim_amount = Uint128::zero(); - while cur_height <= *height_end { - let block_reward = config.get_distribution_rate_at_height(cur_height); - // calculate reward for user based on their share of the vault supply - period_claim_amount += - block_reward * d.amount / reward_index_start.vault_supply; - cur_height += 1; - } - period_claim_amount - }) - .sum::() - }) - .sum::(); - // this accounts for edge case where final user withdraws their claim (ends up being ~1% less than expected due to rounding) - claim_amount = claim_amount.min(config.get_total_distribution_amount() - config.total_claimed); - if claim_amount.is_zero() { - return Err(VaultRewardsError::NoRewardsToClaim {}); - } - Ok(claim_amount) -} - -#[cfg(test)] -mod tests { - use crate::execute::mock_querier::{mock_dependencies, WasmMockQuerier}; - use crate::execute::user::{execute_claim, get_claim_amount}; - use crate::execute::vault::execute_update_user_reward_index; - use crate::helpers::get_user_reward_index; - use crate::state::{Config, DistributionSchedule, CONFIG}; - use crate::VaultRewardsError; - use cosmwasm_std::testing::{mock_env, MockApi, MockStorage, MOCK_CONTRACT_ADDR}; - use cosmwasm_std::{attr, Addr, Coin, Env, OwnedDeps, Uint128}; - use cw_asset::AssetInfo; - - #[test] - fn test_execute_claim() { - let mut deps = mock_dependencies(&[]); - let mut env = mock_env(); - let mut total_claim_amount = Uint128::zero(); - let config = Config { - vault_token: Addr::unchecked("vault_token"), - reward_token: AssetInfo::native("reward_token"), - distribution_schedules: vec![ - DistributionSchedule { - start: 100, - end: 1000, - amount: Uint128::new(900000000), - }, - DistributionSchedule { - start: 500, - end: 1500, - amount: Uint128::new(1000000000), - }, - ], - total_claimed: Uint128::zero(), - }; - env.block.height = 1; - CONFIG.save(deps.as_mut().storage, &config).unwrap(); - - let user1 = Addr::unchecked("user1"); - let user2 = Addr::unchecked("user2"); - let user3 = Addr::unchecked("user3"); - let user4 = Addr::unchecked("user4"); - let user5 = Addr::unchecked("user5"); - - deps.querier - .with_token_balance(user1.as_ref(), &Uint128::new(100)); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user1.clone()).unwrap(); - - let res = execute_claim(deps.as_mut(), &env, user1.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - - env.block.height = 100; - - // should error since no funds in contract (shouldn't happen tho since it's checked for when adding/updating distribution schedules) - let res = execute_claim(deps.as_mut(), &env, user1.clone()); - assert!(res.is_err()); - assert_eq!( - res.err().unwrap(), - VaultRewardsError::InsufficientFunds { - contract_balance: Uint128::zero(), - claim_amount: Uint128::new(1000000) - } - ); - - let mut contract_reward_balance = config - .distribution_schedules - .iter() - .fold(Uint128::zero(), |acc, s| acc + s.amount); - - deps.querier.with_bank_balance( - MOCK_CONTRACT_ADDR, - vec![Coin { - denom: "reward_token".to_string(), - amount: contract_reward_balance, - }], - ); - - execute_claim_helper( - &mut deps, - &env, - &user1, - Uint128::new(1000000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - - // claim in same block should error - let res = execute_claim(deps.as_mut(), &env, user1.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - - env.block.height = 200; - - execute_claim_helper( - &mut deps, - &env, - &user1, - Uint128::new(100000000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - - env.block.height = 251; - - deps.querier - .with_token_balance(user2.as_ref(), &Uint128::new(100)); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user2.clone()).unwrap(); - - env.block.height = 300; - - // user1 should have same rate until block 250, then shares reward with user2 - execute_claim_helper( - &mut deps, - &env, - &user1, - Uint128::new(75500000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - execute_claim_helper( - &mut deps, - &env, - &user2, - Uint128::new(25000000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - - env.block.height = 1000; - - // transfer balance from user1 to user2 - deps.querier - .with_token_balance(user1.as_ref(), &Uint128::zero()); - deps.querier - .with_token_balance(user2.as_ref(), &Uint128::new(200)); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user1.clone()).unwrap(); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user2.clone()).unwrap(); - - execute_claim_helper( - &mut deps, - &env, - &user1, - Uint128::new(600000000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - execute_claim_helper( - &mut deps, - &env, - &user2, - Uint128::new(600000000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - - env.block.height = 1250; - - deps.querier - .with_token_balance(user3.as_ref(), &Uint128::new(200)); - deps.querier - .with_token_balance(user4.as_ref(), &Uint128::new(400)); - deps.querier - .with_token_balance(user5.as_ref(), &Uint128::new(800)); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user3.clone()).unwrap(); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user4.clone()).unwrap(); - execute_update_user_reward_index(deps.as_mut(), env.clone(), user5.clone()).unwrap(); - - env.block.height = 2000; - - let res = execute_claim(deps.as_mut(), &env, user1.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - execute_claim_helper( - &mut deps, - &env, - &user2, - Uint128::new(281125000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - execute_claim_helper( - &mut deps, - &env, - &user3, - Uint128::new(31250000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - execute_claim_helper( - &mut deps, - &env, - &user4, - Uint128::new(62500000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - execute_claim_helper( - &mut deps, - &env, - &user5, - Uint128::new(123625000), - &mut total_claim_amount, - &mut contract_reward_balance, - ); - - env.block.height = 3000; - - let res = execute_claim(deps.as_mut(), &env, user1.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - let res = execute_claim(deps.as_mut(), &env, user2.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - let res = execute_claim(deps.as_mut(), &env, user3.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - let res = execute_claim(deps.as_mut(), &env, user4.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - let res = execute_claim(deps.as_mut(), &env, user5.clone()); - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - - let expected_claim_amount = config - .distribution_schedules - .iter() - .fold(Uint128::zero(), |acc, s| acc + s.amount); - assert_eq!(total_claim_amount, expected_claim_amount); - } - - fn execute_claim_helper( - deps: &mut OwnedDeps, - env: &Env, - user: &Addr, - expected_claim_amount: Uint128, - total_claim_amount: &mut Uint128, - contract_reward_balance: &mut Uint128, - ) { - let res = execute_claim(deps.as_mut(), env, user.clone()); - if res.is_err() { - println!("res: {res:?}"); - } - assert!(res.is_ok()); - let res = res.unwrap(); - let claim_amount = res - .attributes - .iter() - .find(|a| a.key == "amount") - .unwrap() - .value - .parse::() - .unwrap(); - *total_claim_amount += claim_amount; - *contract_reward_balance -= claim_amount; - deps.querier.with_bank_balance( - MOCK_CONTRACT_ADDR, - vec![Coin { - denom: "reward_token".to_string(), - amount: *contract_reward_balance, - }], - ); - assert_eq!( - res.attributes, - vec![ - attr("action", "claim"), - attr("user", user.to_string()), - attr("amount", expected_claim_amount.to_string()), - ] - ); - } - - #[test] - fn execute_get_claim_amount() { - let mut deps = mock_dependencies(&[]); - let mut env = mock_env(); - let config = Config { - vault_token: Addr::unchecked("vault_token"), - reward_token: AssetInfo::native("reward_token"), - distribution_schedules: vec![DistributionSchedule { - start: 2, - end: 14, - amount: Uint128::new(900000000), - }], - total_claimed: Uint128::zero(), - }; - env.block.height = 1; - CONFIG.save(deps.as_mut().storage, &config).unwrap(); - - let user1 = Addr::unchecked("user1"); - let user2 = Addr::unchecked("user2"); - - deps.querier - .with_token_balance(user1.as_ref(), &Uint128::new(100)); - deps.querier - .with_token_balance(user2.as_ref(), &Uint128::new(200)); - - let user_reward_index = get_user_reward_index(&deps.storage, &user1); - let res = get_claim_amount(deps.as_ref(), &env, &config, &user_reward_index); - - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - - let _res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user1.clone()); - let res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user2.clone()); - assert!(res.is_ok()); - - env.block.height += 10; - - let _res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user1.clone()); - - env.block.height += 10; - - let _res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user2.clone()); - - let user1_reward_index = get_user_reward_index(&deps.storage, &user1); - let user2_reward_index = get_user_reward_index(&deps.storage, &user2); - let res1 = get_claim_amount(deps.as_ref(), &env, &config, &user1_reward_index); - let res2 = get_claim_amount(deps.as_ref(), &env, &config, &user2_reward_index); - - assert!(res1.is_ok()); - assert!(res2.is_ok()); - assert_eq!(res1.unwrap(), Uint128::new(300000000)); // user1 holds 1/3 of the vaulth - assert_eq!(res2.unwrap(), Uint128::new(600000000)); // user2 holds 2/3 of the vaulth - } - - #[test] - fn execute_get_claim_amount_without_distribution_schedule() { - let mut deps = mock_dependencies(&[]); - let mut env = mock_env(); - let config = Config { - vault_token: Addr::unchecked("vault_token"), - reward_token: AssetInfo::native("reward_token"), - distribution_schedules: vec![], - total_claimed: Uint128::zero(), - }; - env.block.height = 1; - CONFIG.save(deps.as_mut().storage, &config).unwrap(); - - let user1 = Addr::unchecked("user1"); - let user2 = Addr::unchecked("user2"); - - deps.querier - .with_token_balance(user1.as_ref(), &Uint128::new(100)); - deps.querier - .with_token_balance(user2.as_ref(), &Uint128::new(200)); - - let user_reward_index = get_user_reward_index(&deps.storage, &user1); - let res = get_claim_amount(deps.as_ref(), &env, &config, &user_reward_index); - - assert!(res.is_err()); - assert_eq!(res.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - - let _res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user1.clone()); - let res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user2.clone()); - assert!(res.is_ok()); - - env.block.height += 10; - - let _res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user1.clone()); - - env.block.height += 10; - - let _res = execute_update_user_reward_index(deps.as_mut(), env.clone(), user2.clone()); - - let user1_reward_index = get_user_reward_index(&deps.storage, &user1); - let user2_reward_index = get_user_reward_index(&deps.storage, &user2); - let res1 = get_claim_amount(deps.as_ref(), &env, &config, &user1_reward_index); - let res2 = get_claim_amount(deps.as_ref(), &env, &config, &user2_reward_index); - - assert!(res1.is_err()); - assert_eq!(res1.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - assert!(res2.is_err()); - assert_eq!(res2.err().unwrap(), VaultRewardsError::NoRewardsToClaim {}); - } -} diff --git a/smart-contracts/contracts/vault-rewards/src/execute/vault.rs b/smart-contracts/contracts/vault-rewards/src/execute/vault.rs deleted file mode 100644 index a4f980a49..000000000 --- a/smart-contracts/contracts/vault-rewards/src/execute/vault.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::helpers::{get_user_reward_index, update_reward_index}; -use crate::state::{DistributionSchedule, UserBalance, CONFIG, USER_REWARD_INDEX}; -use crate::VaultRewardsError; -use cosmwasm_std::{Addr, DepsMut, Env, Response}; -use cw_asset::AssetInfo; - -pub fn execute_update_user_reward_index( - deps: DepsMut, - env: Env, - user: Addr, -) -> Result { - let cur_block_height = env.block.height; - let user_vault_token_balance = AssetInfo::cw20(CONFIG.load(deps.storage)?.vault_token) - .query_balance(&deps.querier, &user)?; - let mut user_reward_index = get_user_reward_index(deps.storage, &user); - // if previous balance, then move to history and record new balance - if let Some(prev_balance) = user_reward_index.balance { - user_reward_index.history.push(DistributionSchedule { - start: prev_balance.reward_index, - end: cur_block_height, - amount: prev_balance.balance, - }) - } - user_reward_index.balance = if !user_vault_token_balance.is_zero() { - Some(UserBalance { - reward_index: cur_block_height, - balance: user_vault_token_balance, - }) - } else { - None - }; - USER_REWARD_INDEX.save(deps.storage, user.clone(), &user_reward_index)?; - update_reward_index(deps.storage, &deps.querier, &env)?; - Ok(Response::default().add_attributes(vec![ - ("action", "update_user_index"), - ("user", user.as_ref()), - ("vault_token_balance", &user_vault_token_balance.to_string()), - ])) -} - -#[cfg(test)] -mod tests {} diff --git a/smart-contracts/contracts/vault-rewards/src/helpers.rs b/smart-contracts/contracts/vault-rewards/src/helpers.rs deleted file mode 100644 index 29210707d..000000000 --- a/smart-contracts/contracts/vault-rewards/src/helpers.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::state::{RewardIndex, UserRewardIndex, CONFIG, REWARD_INDEX, USER_REWARD_INDEX}; -use crate::VaultRewardsError; -use cosmwasm_std::{Addr, Env, QuerierWrapper, Storage}; -use cw20::Cw20Contract; - -pub fn update_reward_index( - storage: &mut dyn Storage, - querier: &QuerierWrapper, - env: &Env, -) -> Result { - let cur_block_height = env.block.height; - let mut reward_index = REWARD_INDEX - .load(storage, cur_block_height) - .unwrap_or_default(); - reward_index.vault_supply = Cw20Contract(CONFIG.load(storage)?.vault_token) - .meta(querier)? - .total_supply; - REWARD_INDEX.save(storage, cur_block_height, &reward_index)?; - Ok(reward_index) -} - -pub fn get_user_reward_index(storage: &dyn Storage, user: &Addr) -> UserRewardIndex { - USER_REWARD_INDEX - .load(storage, user.clone()) - .unwrap_or_else(|_| UserRewardIndex { - balance: None, - history: vec![], - }) -} - -pub fn is_contract_admin( - querier: &QuerierWrapper, - env: &Env, - sus_admin: &Addr, -) -> Result<(), VaultRewardsError> { - let contract_admin = querier - .query_wasm_contract_info(&env.contract.address)? - .admin; - if let Some(contract_admin) = contract_admin { - if contract_admin != *sus_admin { - return Err(VaultRewardsError::Unauthorized {}); - } - } else { - return Err(VaultRewardsError::Unauthorized {}); - } - Ok(()) -} diff --git a/smart-contracts/contracts/vault-rewards/src/lib.rs b/smart-contracts/contracts/vault-rewards/src/lib.rs deleted file mode 100644 index 6e19e0e6b..000000000 --- a/smart-contracts/contracts/vault-rewards/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod contract; -pub mod execute; -pub mod helpers; -pub mod msg; -pub mod query; -pub mod state; - -mod error; -pub use crate::error::VaultRewardsError; diff --git a/smart-contracts/contracts/vault-rewards/src/msg.rs b/smart-contracts/contracts/vault-rewards/src/msg.rs deleted file mode 100644 index 5b2547639..000000000 --- a/smart-contracts/contracts/vault-rewards/src/msg.rs +++ /dev/null @@ -1,70 +0,0 @@ -use crate::state::DistributionSchedule; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::Uint128; -use cw_asset::{Asset, AssetInfo}; - -#[cw_serde] -pub struct InstantiateMsg { - pub vault_token: String, - pub reward_token: AssetInfo, - pub distribution_schedules: Vec, -} - -#[cw_serde] -pub enum ExecuteMsg { - Claim {}, - - Admin(AdminExecuteMsg), - - Vault(VaultExecuteMsg), -} - -#[cw_serde] -pub enum AdminExecuteMsg { - WithdrawFunds(Asset), - AddDistributionSchedule(DistributionSchedule), - UpdateDistributionSchedule { - id: u64, - update: DistributionScheduleOptions, - }, - RemoveDistributionSchedule(u64), -} - -#[cw_serde] -pub enum VaultExecuteMsg { - UpdateUserRewardIndex(String), -} - -#[cw_serde] -pub enum QueryMsg { - Config {}, - PendingRewards(String), - GetUserRewardsIndex(String), -} - -#[cw_serde] -pub struct MigrateMsg {} - -#[cw_serde] -pub struct ConfigResponse { - pub reward_token: AssetInfo, - pub contract_balance: Uint128, - pub total_claimed: Uint128, - pub distribution_schedules: Vec, - pub current_distribution_rate_per_block: Uint128, -} - -#[cw_serde] -pub struct DistributionScheduleResponse { - pub id: u64, - pub start: u64, - pub end: u64, - pub amount: Uint128, -} - -#[cw_serde] -pub struct DistributionScheduleOptions { - pub start: Option, - pub end: Option, - pub amount: Option, -} diff --git a/smart-contracts/contracts/vault-rewards/src/query.rs b/smart-contracts/contracts/vault-rewards/src/query.rs deleted file mode 100644 index 61b57e8af..000000000 --- a/smart-contracts/contracts/vault-rewards/src/query.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::helpers::get_user_reward_index; -use crate::msg::ConfigResponse; -use crate::state::{DistributionSchedule, UserBalance, CONFIG}; -use crate::VaultRewardsError; -use crate::{execute::user::get_claim_amount, state::UserRewardIndex}; -use cosmwasm_std::{Addr, Deps, Env, Uint128}; -use cw_asset::AssetInfo; - -pub fn query_config(deps: Deps, env: Env) -> Result { - let config = CONFIG.load(deps.storage)?; - Ok(ConfigResponse { - reward_token: config.reward_token.clone(), - contract_balance: config - .reward_token - .query_balance(&deps.querier, env.contract.address)?, - total_claimed: config.total_claimed, - distribution_schedules: config - .distribution_schedules - .iter() - .enumerate() - .map(|(idx, s)| s.to_response(idx)) - .collect(), - current_distribution_rate_per_block: config - .get_distribution_rate_at_height(env.block.height), - }) -} - -pub fn query_pending_rewards( - deps: Deps, - env: Env, - user: Addr, -) -> Result { - let config = CONFIG.load(deps.storage)?; - let cur_block_height = env.block.height; - let mut user_reward_index = get_user_reward_index(deps.storage, &user); - let user_vault_token_balance = - AssetInfo::cw20(config.vault_token.clone()).query_balance(&deps.querier, &user)?; - if let Some(prev_balance) = user_reward_index.balance { - user_reward_index.history.push(DistributionSchedule { - start: prev_balance.reward_index, - end: cur_block_height, - amount: prev_balance.balance, - }); - user_reward_index.balance = if !user_vault_token_balance.is_zero() { - Some(UserBalance { - reward_index: cur_block_height + 1, - balance: user_vault_token_balance, - }) - } else { - None - }; - } - get_claim_amount(deps, &env, &config, &user_reward_index) -} - -pub fn query_user_rewards_index( - deps: Deps, - user: Addr, -) -> Result { - let user_reward_index = get_user_reward_index(deps.storage, &user); - Ok(user_reward_index) -} - -#[cfg(test)] -mod tests {} diff --git a/smart-contracts/contracts/vault-rewards/src/state.rs b/smart-contracts/contracts/vault-rewards/src/state.rs deleted file mode 100644 index 7456adab7..000000000 --- a/smart-contracts/contracts/vault-rewards/src/state.rs +++ /dev/null @@ -1,225 +0,0 @@ -use crate::msg::{DistributionScheduleOptions, DistributionScheduleResponse}; -use crate::VaultRewardsError; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Addr, Env, Order, QuerierWrapper, Storage, Uint128}; -use cw_asset::AssetInfo; -use cw_storage_plus::{Item, Map}; - -#[cw_serde] -pub struct Config { - pub vault_token: Addr, - pub reward_token: AssetInfo, - pub distribution_schedules: Vec, - pub total_claimed: Uint128, -} - -impl Config { - pub fn add_distribution_schedule( - &mut self, - querier: &QuerierWrapper, - env: &Env, - schedule: DistributionSchedule, - ) -> Result<(), VaultRewardsError> { - self.validate_distribution_schedule(querier, env, &schedule)?; - self.distribution_schedules.push(schedule); - Ok(()) - } - - pub fn add_distribution_schedules( - &mut self, - querier: &QuerierWrapper, - env: &Env, - schedules: Vec, - ) -> Result<(), VaultRewardsError> { - for schedule in schedules { - self.add_distribution_schedule(querier, env, schedule)?; - } - Ok(()) - } - - pub fn update_distribution_schedule( - &mut self, - querier: &QuerierWrapper, - env: &Env, - id: u64, - update: &DistributionScheduleOptions, - ) -> Result<(), VaultRewardsError> { - let cur_block_height = env.block.height; - let idx = id.checked_sub(1).unwrap_or_default() as usize; - let mut schedule = self - .distribution_schedules - .get(idx) - .ok_or(VaultRewardsError::InvalidDistributionScheduleId { - max_id: self.distribution_schedules.len() as u64, - })? - .clone(); - if schedule.start <= cur_block_height && cur_block_height < schedule.end { - return Err(VaultRewardsError::DistributionScheduleInProgress { - id, - start: schedule.start, - end: schedule.end, - }); - } - if cur_block_height >= schedule.end { - return Err(VaultRewardsError::DistributionScheduleExpired { - id, - end: schedule.end, - }); - } - self.distribution_schedules.remove(idx); - if let Some(start) = update.start { - schedule.start = start; - } else if let Some(end) = update.end { - if end <= cur_block_height { - return Err(VaultRewardsError::InvalidDistributionSchedule { - reason: "end must be in the future".to_string(), - }); - } - schedule.end = end; - } else if let Some(amount) = update.amount { - schedule.amount = amount; - } - self.validate_distribution_schedule(querier, env, &schedule)?; - self.distribution_schedules.insert(idx, schedule); - Ok(()) - } - - pub fn remove_distribution_schedule( - &mut self, - storage: &dyn Storage, - env: &Env, - id: u64, - ) -> Result<(), VaultRewardsError> { - let cur_block_height = env.block.height; - let idx = id.checked_sub(1).unwrap_or_default() as usize; - let schedule = self.distribution_schedules.get(idx).ok_or({ - VaultRewardsError::InvalidDistributionScheduleId { - max_id: self.distribution_schedules.len() as u64, - } - })?; - if schedule.start <= cur_block_height && cur_block_height < schedule.end { - return Err(VaultRewardsError::DistributionScheduleInProgress { - id, - start: schedule.start, - end: schedule.end, - }); - } - if cur_block_height >= schedule.end { - // check if all funds from period were claimed - USER_REWARD_INDEX - .range(storage, None, None, Order::Ascending) - .map(|item| { - let (_, reward_index) = item.unwrap(); - if reward_index - .history - .iter() - .any(|h| h.start >= schedule.start && h.end < schedule.end) - { - return Err(VaultRewardsError::DistributionScheduleWithUnclaimedFunds { - id, - }); - } - Ok(()) - }) - .collect::, _>>()?; - } - self.total_claimed -= schedule.amount; - self.distribution_schedules.remove(idx); - Ok(()) - } - - pub fn validate_distribution_schedule( - &self, - querier: &QuerierWrapper, - env: &Env, - schedule: &DistributionSchedule, - ) -> Result<(), VaultRewardsError> { - if schedule.start <= env.block.height { - return Err(VaultRewardsError::InvalidDistributionSchedule { - reason: "start must be in the future".to_string(), - }); - } - if schedule.start >= schedule.end { - return Err(VaultRewardsError::InvalidDistributionSchedule { - reason: "start must be before end".to_string(), - }); - } - if schedule.amount.is_zero() { - return Err(VaultRewardsError::InvalidDistributionSchedule { - reason: "amount must be greater than 0".to_string(), - }); - } - let reward_token_balance = self - .reward_token - .query_balance(querier, &env.contract.address)?; - let total_distribution_amount = self.get_total_distribution_amount() + schedule.amount; - if VALIDATE_FUNDS && reward_token_balance < total_distribution_amount { - return Err(VaultRewardsError::InsufficientFunds { - contract_balance: reward_token_balance, - claim_amount: total_distribution_amount, - }); - } - Ok(()) - } - - pub fn get_distribution_rate_at_height(&self, height: u64) -> Uint128 { - self.distribution_schedules - .iter() - .fold(Uint128::zero(), |acc, schedule| { - if schedule.start <= height && schedule.end > height { - acc + schedule.amount / Uint128::from(schedule.end - schedule.start) - } else { - acc - } - }) - } - - pub fn get_total_distribution_amount(&self) -> Uint128 { - self.distribution_schedules - .iter() - .fold(Uint128::zero(), |acc, schedule| acc + schedule.amount) - } -} - -#[cw_serde] -pub struct DistributionSchedule { - pub start: u64, - pub end: u64, - pub amount: Uint128, -} - -impl DistributionSchedule { - pub fn to_response(&self, idx: usize) -> DistributionScheduleResponse { - DistributionScheduleResponse { - id: (idx as u64) + 1, - start: self.start, - end: self.end, - amount: self.amount, - } - } -} - -#[cw_serde] -#[derive(Default)] -pub struct RewardIndex { - pub vault_supply: Uint128, -} - -#[cw_serde] -pub struct UserRewardIndex { - pub balance: Option, - pub history: Vec, -} - -#[cw_serde] -pub struct UserBalance { - pub reward_index: u64, - pub balance: Uint128, -} - -pub const CONFIG: Item = Item::new("config"); -pub const REWARD_INDEX: Map = Map::new("reward_index"); -pub const USER_REWARD_INDEX: Map = Map::new("user_reward_index"); - -// to be changed in a future migration -pub const VALIDATE_FUNDS: bool = false; diff --git a/smart-contracts/migrations/migration-004/cleaned_recoverable_6a2.json b/smart-contracts/migrations/migration-004/cleaned_recoverable_6a2.json deleted file mode 100644 index 376e1de04..000000000 --- a/smart-contracts/migrations/migration-004/cleaned_recoverable_6a2.json +++ /dev/null @@ -1,402 +0,0 @@ -[ - { - "bonds": [ - { - "claim_amount": "27572493", - "raw_amount": { - "local_denom": "36899908" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2266" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "30549409", - "raw_amount": { - "local_denom": "43106797" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1691" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "485317410", - "raw_amount": { - "local_denom": "653150114" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2111" - }, - { - "claim_amount": "125454550", - "raw_amount": { - "local_denom": "168839304" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2112" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2113" - }, - { - "claim_amount": "1455951", - "raw_amount": { - "local_denom": "1959450" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2115" - }, - { - "claim_amount": "120844034", - "raw_amount": { - "local_denom": "162634378" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2116" - }, - { - "claim_amount": "6114999", - "raw_amount": { - "local_denom": "8229691" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2117" - }, - { - "claim_amount": "9706348", - "raw_amount": { - "local_denom": "13063002" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2118" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2119" - }, - { - "claim_amount": "48046423", - "raw_amount": { - "local_denom": "64661861" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2120" - }, - { - "claim_amount": "5289959", - "raw_amount": { - "local_denom": "7119336" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2121" - }, - { - "claim_amount": "1892737", - "raw_amount": { - "local_denom": "2547285" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2122" - }, - { - "claim_amount": "4319324", - "raw_amount": { - "local_denom": "5813036" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2123" - }, - { - "claim_amount": "33244242", - "raw_amount": { - "local_denom": "44740782" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2124" - }, - { - "claim_amount": "4756110", - "raw_amount": { - "local_denom": "6400871" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2125" - }, - { - "claim_amount": "582380", - "raw_amount": { - "local_denom": "783780" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2126" - }, - { - "claim_amount": "8250395", - "raw_amount": { - "local_denom": "11103551" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2127" - }, - { - "claim_amount": "4804642", - "raw_amount": { - "local_denom": "6466186" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2128" - }, - { - "claim_amount": "9803411", - "raw_amount": { - "local_denom": "13193632" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2129" - }, - { - "claim_amount": "72312294", - "raw_amount": { - "local_denom": "97319367" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2130" - }, - { - "claim_amount": "61489715", - "raw_amount": { - "local_denom": "82754119" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2131" - }, - { - "claim_amount": "527540025", - "raw_amount": { - "local_denom": "709974174" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2132" - }, - { - "claim_amount": "421740829", - "raw_amount": { - "local_denom": "567587449" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2133" - }, - { - "claim_amount": "26692457", - "raw_amount": { - "local_denom": "35923256" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2134" - }, - { - "claim_amount": "3154562", - "raw_amount": { - "local_denom": "4245475" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2135" - }, - { - "claim_amount": "10191665", - "raw_amount": { - "local_denom": "13716152" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2136" - }, - { - "claim_amount": "3470019", - "raw_amount": { - "local_denom": "4670023" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2137" - }, - { - "claim_amount": "2098997802", - "raw_amount": { - "local_denom": "2824874245" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2138" - }, - { - "claim_amount": "24265870", - "raw_amount": { - "local_denom": "32657505" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2139" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2140" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2141" - }, - { - "claim_amount": "247997196", - "raw_amount": { - "local_denom": "333759708" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2142" - }, - { - "claim_amount": "2426586", - "raw_amount": { - "local_denom": "3265750" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2143" - }, - { - "claim_amount": "9706348", - "raw_amount": { - "local_denom": "13063002" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2144" - }, - { - "claim_amount": "970634", - "raw_amount": { - "local_denom": "1306300" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2145" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2146" - }, - { - "claim_amount": "2654686", - "raw_amount": { - "local_denom": "3572731" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2147" - }, - { - "claim_amount": "3397221", - "raw_amount": { - "local_denom": "4572050" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2148" - }, - { - "claim_amount": "4367856", - "raw_amount": { - "local_denom": "5878351" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2149" - }, - { - "claim_amount": "8007736", - "raw_amount": { - "local_denom": "10776976" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2150" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2151" - }, - { - "claim_amount": "2892491", - "raw_amount": { - "local_denom": "3892774" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2152" - }, - { - "claim_amount": "48483209", - "raw_amount": { - "local_denom": "65249696" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2153" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "4784858", - "raw_amount": { - "local_denom": "6521340" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2018" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "1705053", - "raw_amount": { - "local_denom": "2290386" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2194" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "11451213", - "raw_amount": { - "local_denom": "15419791" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2100" - } - ] - } -] \ No newline at end of file diff --git a/smart-contracts/migrations/migration-004/cleaned_recoverable_7fv.json b/smart-contracts/migrations/migration-004/cleaned_recoverable_7fv.json deleted file mode 100644 index 2a89c2777..000000000 --- a/smart-contracts/migrations/migration-004/cleaned_recoverable_7fv.json +++ /dev/null @@ -1,414 +0,0 @@ -[ - { - "bonds": [ - { - "claim_amount": "27574028", - "raw_amount": { - "local_denom": "17987877" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2266" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "4786143", - "raw_amount": { - "local_denom": "3247407" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2018" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "11451515", - "raw_amount": { - "local_denom": "7647023" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2100" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "454028", - "raw_amount": { - "local_denom": "326612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1596" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "454125", - "raw_amount": { - "local_denom": "326654" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1597" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "30552830", - "raw_amount": { - "local_denom": "21686062" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1691" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "485643187", - "raw_amount": { - "local_denom": "324236968" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2111" - }, - { - "claim_amount": "125538763", - "raw_amount": { - "local_denom": "83815256" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2112" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2113" - }, - { - "claim_amount": "1456928", - "raw_amount": { - "local_denom": "972710" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2115" - }, - { - "claim_amount": "120925153", - "raw_amount": { - "local_denom": "80735005" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2116" - }, - { - "claim_amount": "6119102", - "raw_amount": { - "local_denom": "4085385" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2117" - }, - { - "claim_amount": "9712863", - "raw_amount": { - "local_denom": "6484739" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2118" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2119" - }, - { - "claim_amount": "48078674", - "raw_amount": { - "local_denom": "32099459" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2120" - }, - { - "claim_amount": "5293509", - "raw_amount": { - "local_denom": "3534182" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2121" - }, - { - "claim_amount": "1894008", - "raw_amount": { - "local_denom": "1264524" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2122" - }, - { - "claim_amount": "4322224", - "raw_amount": { - "local_denom": "2885709" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2123" - }, - { - "claim_amount": "33266557", - "raw_amount": { - "local_denom": "22210232" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2124" - }, - { - "claim_amount": "4759302", - "raw_amount": { - "local_denom": "3177522" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2125" - }, - { - "claim_amount": "582771", - "raw_amount": { - "local_denom": "389084" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2126" - }, - { - "claim_amount": "8255933", - "raw_amount": { - "local_denom": "5512028" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2127" - }, - { - "claim_amount": "4807866", - "raw_amount": { - "local_denom": "3209945" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2128" - }, - { - "claim_amount": "9809991", - "raw_amount": { - "local_denom": "6549586" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2129" - }, - { - "claim_amount": "72360834", - "raw_amount": { - "local_denom": "48311308" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2130" - }, - { - "claim_amount": "61530990", - "raw_amount": { - "local_denom": "41080823" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2131" - }, - { - "claim_amount": "527894144", - "raw_amount": { - "local_denom": "352445584" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2132" - }, - { - "claim_amount": "422023929", - "raw_amount": { - "local_denom": "281761925" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2133" - }, - { - "claim_amount": "26710374", - "raw_amount": { - "local_denom": "17833033" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2134" - }, - { - "claim_amount": "3156680", - "raw_amount": { - "local_denom": "2107540" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2135" - }, - { - "claim_amount": "10198506", - "raw_amount": { - "local_denom": "6808976" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2136" - }, - { - "claim_amount": "3472348", - "raw_amount": { - "local_denom": "2318294" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2137" - }, - { - "claim_amount": "2100406787", - "raw_amount": { - "local_denom": "1402324887" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2138" - }, - { - "claim_amount": "24282158", - "raw_amount": { - "local_denom": "16211848" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2139" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2140" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2141" - }, - { - "claim_amount": "248163668", - "raw_amount": { - "local_denom": "165685090" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2142" - }, - { - "claim_amount": "2428214", - "raw_amount": { - "local_denom": "1621184" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2143" - }, - { - "claim_amount": "9712863", - "raw_amount": { - "local_denom": "6484739" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2144" - }, - { - "claim_amount": "971284", - "raw_amount": { - "local_denom": "648473" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2145" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2146" - }, - { - "claim_amount": "2656467", - "raw_amount": { - "local_denom": "1773576" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2147" - }, - { - "claim_amount": "3399501", - "raw_amount": { - "local_denom": "2269658" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2148" - }, - { - "claim_amount": "4370787", - "raw_amount": { - "local_denom": "2918132" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2149" - }, - { - "claim_amount": "8013111", - "raw_amount": { - "local_denom": "5349909" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2150" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2151" - }, - { - "claim_amount": "2894432", - "raw_amount": { - "local_denom": "1932452" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2152" - }, - { - "claim_amount": "48515754", - "raw_amount": { - "local_denom": "32391273" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2153" - } - ] - } -] \ No newline at end of file diff --git a/smart-contracts/migrations/migration-004/cleaned_recoverable_fps.json b/smart-contracts/migrations/migration-004/cleaned_recoverable_fps.json deleted file mode 100644 index acfb44b88..000000000 --- a/smart-contracts/migrations/migration-004/cleaned_recoverable_fps.json +++ /dev/null @@ -1,414 +0,0 @@ -[ - { - "bonds": [ - { - "claim_amount": "454093", - "raw_amount": { - "local_denom": "24592" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1597" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "4785365", - "raw_amount": { - "local_denom": "231252" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2018" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "11450657", - "raw_amount": { - "local_denom": "533184" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2100" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "30550338", - "raw_amount": { - "local_denom": "1607140" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1691" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "27574007", - "raw_amount": { - "local_denom": "1262214" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2266" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "454111", - "raw_amount": { - "local_denom": "24594" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "1596" - } - ] - }, - { - "bonds": [ - { - "claim_amount": "484187518", - "raw_amount": { - "local_denom": "22612917" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2111" - }, - { - "claim_amount": "125162472", - "raw_amount": { - "local_denom": "5845439" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2112" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2113" - }, - { - "claim_amount": "1452546", - "raw_amount": { - "local_denom": "67838" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2115" - }, - { - "claim_amount": "120562684", - "raw_amount": { - "local_denom": "5630616" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2116" - }, - { - "claim_amount": "6100746", - "raw_amount": { - "local_denom": "284922" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2117" - }, - { - "claim_amount": "9683743", - "raw_amount": { - "local_denom": "452258" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2118" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2119" - }, - { - "claim_amount": "47934547", - "raw_amount": { - "local_denom": "2238678" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2120" - }, - { - "claim_amount": "5277626", - "raw_amount": { - "local_denom": "246480" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2121" - }, - { - "claim_amount": "1888323", - "raw_amount": { - "local_denom": "88190" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2122" - }, - { - "claim_amount": "4309248", - "raw_amount": { - "local_denom": "201254" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2123" - }, - { - "claim_amount": "33166827", - "raw_amount": { - "local_denom": "1548984" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2124" - }, - { - "claim_amount": "4745025", - "raw_amount": { - "local_denom": "221606" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2125" - }, - { - "claim_amount": "581014", - "raw_amount": { - "local_denom": "27135" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2126" - }, - { - "claim_amount": "8231175", - "raw_amount": { - "local_denom": "384419" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2127" - }, - { - "claim_amount": "4793437", - "raw_amount": { - "local_denom": "223867" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2128" - }, - { - "claim_amount": "9780568", - "raw_amount": { - "local_denom": "456780" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2129" - }, - { - "claim_amount": "72143926", - "raw_amount": { - "local_denom": "3369324" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2130" - }, - { - "claim_amount": "61346546", - "raw_amount": { - "local_denom": "2865056" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2131" - }, - { - "claim_amount": "526311837", - "raw_amount": { - "local_denom": "24580241" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2132" - }, - { - "claim_amount": "420758956", - "raw_amount": { - "local_denom": "19650625" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2133" - }, - { - "claim_amount": "26630304", - "raw_amount": { - "local_denom": "1243710" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2134" - }, - { - "claim_amount": "3147198", - "raw_amount": { - "local_denom": "146983" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2135" - }, - { - "claim_amount": "10167932", - "raw_amount": { - "local_denom": "474871" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2136" - }, - { - "claim_amount": "3461933", - "raw_amount": { - "local_denom": "161682" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2137" - }, - { - "claim_amount": "2094111037", - "raw_amount": { - "local_denom": "97800867" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2138" - }, - { - "claim_amount": "24209357", - "raw_amount": { - "local_denom": "1130645" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2139" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2140" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2141" - }, - { - "claim_amount": "247419809", - "raw_amount": { - "local_denom": "11555200" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2142" - }, - { - "claim_amount": "2420925", - "raw_amount": { - "local_denom": "113064" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2143" - }, - { - "claim_amount": "9683743", - "raw_amount": { - "local_denom": "452258" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2144" - }, - { - "claim_amount": "968357", - "raw_amount": { - "local_denom": "45225" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2145" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2146" - }, - { - "claim_amount": "2648491", - "raw_amount": { - "local_denom": "123692" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2147" - }, - { - "claim_amount": "3389303", - "raw_amount": { - "local_denom": "158290" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2148" - }, - { - "claim_amount": "4357682", - "raw_amount": { - "local_denom": "203516" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2149" - }, - { - "claim_amount": "7989091", - "raw_amount": { - "local_denom": "373113" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2150" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2151" - }, - { - "claim_amount": "2885736", - "raw_amount": { - "local_denom": "134772" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2152" - }, - { - "claim_amount": "48370324", - "raw_amount": { - "local_denom": "2259030" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2153" - } - ] - } -] \ No newline at end of file diff --git a/smart-contracts/migrations/migration-004/just_big_one_6a2 b/smart-contracts/migrations/migration-004/just_big_one_6a2 deleted file mode 100644 index f019db4ea..000000000 --- a/smart-contracts/migrations/migration-004/just_big_one_6a2 +++ /dev/null @@ -1,340 +0,0 @@ -{ - "bonds": [ - { - "claim_amount": "485317410", - "raw_amount": { - "local_denom": "653150114" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2111" - }, - { - "claim_amount": "125454550", - "raw_amount": { - "local_denom": "168839304" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2112" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2113" - }, - { - "claim_amount": "1455951", - "raw_amount": { - "local_denom": "1959450" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2115" - }, - { - "claim_amount": "120844034", - "raw_amount": { - "local_denom": "162634378" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2116" - }, - { - "claim_amount": "6114999", - "raw_amount": { - "local_denom": "8229691" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2117" - }, - { - "claim_amount": "9706348", - "raw_amount": { - "local_denom": "13063002" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2118" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2119" - }, - { - "claim_amount": "48046423", - "raw_amount": { - "local_denom": "64661861" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2120" - }, - { - "claim_amount": "5289959", - "raw_amount": { - "local_denom": "7119336" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2121" - }, - { - "claim_amount": "1892737", - "raw_amount": { - "local_denom": "2547285" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2122" - }, - { - "claim_amount": "4319324", - "raw_amount": { - "local_denom": "5813036" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2123" - }, - { - "claim_amount": "33244242", - "raw_amount": { - "local_denom": "44740782" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2124" - }, - { - "claim_amount": "4756110", - "raw_amount": { - "local_denom": "6400871" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2125" - }, - { - "claim_amount": "582380", - "raw_amount": { - "local_denom": "783780" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2126" - }, - { - "claim_amount": "8250395", - "raw_amount": { - "local_denom": "11103551" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2127" - }, - { - "claim_amount": "4804642", - "raw_amount": { - "local_denom": "6466186" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2128" - }, - { - "claim_amount": "9803411", - "raw_amount": { - "local_denom": "13193632" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2129" - }, - { - "claim_amount": "72312294", - "raw_amount": { - "local_denom": "97319367" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2130" - }, - { - "claim_amount": "61489715", - "raw_amount": { - "local_denom": "82754119" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2131" - }, - { - "claim_amount": "527540025", - "raw_amount": { - "local_denom": "709974174" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2132" - }, - { - "claim_amount": "421740829", - "raw_amount": { - "local_denom": "567587449" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2133" - }, - { - "claim_amount": "26692457", - "raw_amount": { - "local_denom": "35923256" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2134" - }, - { - "claim_amount": "3154562", - "raw_amount": { - "local_denom": "4245475" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2135" - }, - { - "claim_amount": "10191665", - "raw_amount": { - "local_denom": "13716152" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2136" - }, - { - "claim_amount": "3470019", - "raw_amount": { - "local_denom": "4670023" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2137" - }, - { - "claim_amount": "2098997802", - "raw_amount": { - "local_denom": "2824874245" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2138" - }, - { - "claim_amount": "24265870", - "raw_amount": { - "local_denom": "32657505" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2139" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2140" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2141" - }, - { - "claim_amount": "247997196", - "raw_amount": { - "local_denom": "333759708" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2142" - }, - { - "claim_amount": "2426586", - "raw_amount": { - "local_denom": "3265750" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2143" - }, - { - "claim_amount": "9706348", - "raw_amount": { - "local_denom": "13063002" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2144" - }, - { - "claim_amount": "970634", - "raw_amount": { - "local_denom": "1306300" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2145" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2146" - }, - { - "claim_amount": "2654686", - "raw_amount": { - "local_denom": "3572731" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2147" - }, - { - "claim_amount": "3397221", - "raw_amount": { - "local_denom": "4572050" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2148" - }, - { - "claim_amount": "4367856", - "raw_amount": { - "local_denom": "5878351" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2149" - }, - { - "claim_amount": "8007736", - "raw_amount": { - "local_denom": "10776976" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2150" - }, - { - "claim_amount": "485317", - "raw_amount": { - "local_denom": "653150" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2151" - }, - { - "claim_amount": "2892491", - "raw_amount": { - "local_denom": "3892774" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2152" - }, - { - "claim_amount": "48483209", - "raw_amount": { - "local_denom": "65249696" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2153" - } - ] -} \ No newline at end of file diff --git a/smart-contracts/migrations/migration-004/just_big_one_7fv b/smart-contracts/migrations/migration-004/just_big_one_7fv deleted file mode 100644 index 04a6259ed..000000000 --- a/smart-contracts/migrations/migration-004/just_big_one_7fv +++ /dev/null @@ -1,340 +0,0 @@ -{ - "bonds": [ - { - "claim_amount": "485643187", - "raw_amount": { - "local_denom": "324236968" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2111" - }, - { - "claim_amount": "125538763", - "raw_amount": { - "local_denom": "83815256" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2112" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2113" - }, - { - "claim_amount": "1456928", - "raw_amount": { - "local_denom": "972710" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2115" - }, - { - "claim_amount": "120925153", - "raw_amount": { - "local_denom": "80735005" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2116" - }, - { - "claim_amount": "6119102", - "raw_amount": { - "local_denom": "4085385" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2117" - }, - { - "claim_amount": "9712863", - "raw_amount": { - "local_denom": "6484739" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2118" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2119" - }, - { - "claim_amount": "48078674", - "raw_amount": { - "local_denom": "32099459" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2120" - }, - { - "claim_amount": "5293509", - "raw_amount": { - "local_denom": "3534182" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2121" - }, - { - "claim_amount": "1894008", - "raw_amount": { - "local_denom": "1264524" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2122" - }, - { - "claim_amount": "4322224", - "raw_amount": { - "local_denom": "2885709" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2123" - }, - { - "claim_amount": "33266557", - "raw_amount": { - "local_denom": "22210232" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2124" - }, - { - "claim_amount": "4759302", - "raw_amount": { - "local_denom": "3177522" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2125" - }, - { - "claim_amount": "582771", - "raw_amount": { - "local_denom": "389084" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2126" - }, - { - "claim_amount": "8255933", - "raw_amount": { - "local_denom": "5512028" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2127" - }, - { - "claim_amount": "4807866", - "raw_amount": { - "local_denom": "3209945" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2128" - }, - { - "claim_amount": "9809991", - "raw_amount": { - "local_denom": "6549586" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2129" - }, - { - "claim_amount": "72360834", - "raw_amount": { - "local_denom": "48311308" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2130" - }, - { - "claim_amount": "61530990", - "raw_amount": { - "local_denom": "41080823" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2131" - }, - { - "claim_amount": "527894144", - "raw_amount": { - "local_denom": "352445584" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2132" - }, - { - "claim_amount": "422023929", - "raw_amount": { - "local_denom": "281761925" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2133" - }, - { - "claim_amount": "26710374", - "raw_amount": { - "local_denom": "17833033" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2134" - }, - { - "claim_amount": "3156680", - "raw_amount": { - "local_denom": "2107540" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2135" - }, - { - "claim_amount": "10198506", - "raw_amount": { - "local_denom": "6808976" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2136" - }, - { - "claim_amount": "3472348", - "raw_amount": { - "local_denom": "2318294" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2137" - }, - { - "claim_amount": "2100406787", - "raw_amount": { - "local_denom": "1402324887" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2138" - }, - { - "claim_amount": "24282158", - "raw_amount": { - "local_denom": "16211848" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2139" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2140" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2141" - }, - { - "claim_amount": "248163668", - "raw_amount": { - "local_denom": "165685090" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2142" - }, - { - "claim_amount": "2428214", - "raw_amount": { - "local_denom": "1621184" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2143" - }, - { - "claim_amount": "9712863", - "raw_amount": { - "local_denom": "6484739" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2144" - }, - { - "claim_amount": "971284", - "raw_amount": { - "local_denom": "648473" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2145" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2146" - }, - { - "claim_amount": "2656467", - "raw_amount": { - "local_denom": "1773576" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2147" - }, - { - "claim_amount": "3399501", - "raw_amount": { - "local_denom": "2269658" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2148" - }, - { - "claim_amount": "4370787", - "raw_amount": { - "local_denom": "2918132" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2149" - }, - { - "claim_amount": "8013111", - "raw_amount": { - "local_denom": "5349909" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2150" - }, - { - "claim_amount": "485641", - "raw_amount": { - "local_denom": "324236" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2151" - }, - { - "claim_amount": "2894432", - "raw_amount": { - "local_denom": "1932452" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2152" - }, - { - "claim_amount": "48515754", - "raw_amount": { - "local_denom": "32391273" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2153" - } - ] -} \ No newline at end of file diff --git a/smart-contracts/migrations/migration-004/just_big_one_fps b/smart-contracts/migrations/migration-004/just_big_one_fps deleted file mode 100644 index d805ec766..000000000 --- a/smart-contracts/migrations/migration-004/just_big_one_fps +++ /dev/null @@ -1,340 +0,0 @@ -{ - "bonds": [ - { - "claim_amount": "484187518", - "raw_amount": { - "local_denom": "22612917" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2111" - }, - { - "claim_amount": "125162472", - "raw_amount": { - "local_denom": "5845439" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2112" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2113" - }, - { - "claim_amount": "1452546", - "raw_amount": { - "local_denom": "67838" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2115" - }, - { - "claim_amount": "120562684", - "raw_amount": { - "local_denom": "5630616" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2116" - }, - { - "claim_amount": "6100746", - "raw_amount": { - "local_denom": "284922" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2117" - }, - { - "claim_amount": "9683743", - "raw_amount": { - "local_denom": "452258" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2118" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2119" - }, - { - "claim_amount": "47934547", - "raw_amount": { - "local_denom": "2238678" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2120" - }, - { - "claim_amount": "5277626", - "raw_amount": { - "local_denom": "246480" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2121" - }, - { - "claim_amount": "1888323", - "raw_amount": { - "local_denom": "88190" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2122" - }, - { - "claim_amount": "4309248", - "raw_amount": { - "local_denom": "201254" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2123" - }, - { - "claim_amount": "33166827", - "raw_amount": { - "local_denom": "1548984" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2124" - }, - { - "claim_amount": "4745025", - "raw_amount": { - "local_denom": "221606" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2125" - }, - { - "claim_amount": "581014", - "raw_amount": { - "local_denom": "27135" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2126" - }, - { - "claim_amount": "8231175", - "raw_amount": { - "local_denom": "384419" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2127" - }, - { - "claim_amount": "4793437", - "raw_amount": { - "local_denom": "223867" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2128" - }, - { - "claim_amount": "9780568", - "raw_amount": { - "local_denom": "456780" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2129" - }, - { - "claim_amount": "72143926", - "raw_amount": { - "local_denom": "3369324" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2130" - }, - { - "claim_amount": "61346546", - "raw_amount": { - "local_denom": "2865056" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2131" - }, - { - "claim_amount": "526311837", - "raw_amount": { - "local_denom": "24580241" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2132" - }, - { - "claim_amount": "420758956", - "raw_amount": { - "local_denom": "19650625" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2133" - }, - { - "claim_amount": "26630304", - "raw_amount": { - "local_denom": "1243710" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2134" - }, - { - "claim_amount": "3147198", - "raw_amount": { - "local_denom": "146983" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2135" - }, - { - "claim_amount": "10167932", - "raw_amount": { - "local_denom": "474871" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2136" - }, - { - "claim_amount": "3461933", - "raw_amount": { - "local_denom": "161682" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2137" - }, - { - "claim_amount": "2094111037", - "raw_amount": { - "local_denom": "97800867" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2138" - }, - { - "claim_amount": "24209357", - "raw_amount": { - "local_denom": "1130645" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2139" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2140" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2141" - }, - { - "claim_amount": "247419809", - "raw_amount": { - "local_denom": "11555200" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2142" - }, - { - "claim_amount": "2420925", - "raw_amount": { - "local_denom": "113064" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2143" - }, - { - "claim_amount": "9683743", - "raw_amount": { - "local_denom": "452258" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2144" - }, - { - "claim_amount": "968357", - "raw_amount": { - "local_denom": "45225" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2145" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2146" - }, - { - "claim_amount": "2648491", - "raw_amount": { - "local_denom": "123692" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2147" - }, - { - "claim_amount": "3389303", - "raw_amount": { - "local_denom": "158290" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2148" - }, - { - "claim_amount": "4357682", - "raw_amount": { - "local_denom": "203516" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2149" - }, - { - "claim_amount": "7989091", - "raw_amount": { - "local_denom": "373113" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2150" - }, - { - "claim_amount": "484167", - "raw_amount": { - "local_denom": "22612" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2151" - }, - { - "claim_amount": "2885736", - "raw_amount": { - "local_denom": "134772" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2152" - }, - { - "claim_amount": "48370324", - "raw_amount": { - "local_denom": "2259030" - }, - "owner": "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu", - "bond_id": "2153" - } - ] -} \ No newline at end of file diff --git a/smart-contracts/migrations/migration-004/trapped_errors_6a2.json b/smart-contracts/migrations/migration-004/trapped_errors_6a2.json deleted file mode 100644 index 74b2adff7..000000000 --- a/smart-contracts/migrations/migration-004/trapped_errors_6a2.json +++ /dev/null @@ -1 +0,0 @@ -{"data":{"errors":{"280-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1312-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2644-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2766-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"825-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"721-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"195-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2258-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1696-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2142-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2056-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1238-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2167-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2672-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2910-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1227-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2174-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1260-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3087-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1823-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"941-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1936-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2951-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"875-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2393-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"783-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"296-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"964-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1974-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"855-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1341-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2043-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"960-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2546-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2332-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2280-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1727-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2741-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3064-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1709-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1240-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1918-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1983-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2250-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1346-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"967-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2597-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1369-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1909-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1873-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1990-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2449-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1778-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1417-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2577-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1732-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"882-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1653-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2693-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"703-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1603-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2074-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1926-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1577-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1813-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2972-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1790-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2695-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"836-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1693-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"939-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1877-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"821-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2416-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3053-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1534-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1024-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1336-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2763-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1787-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1245-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"983-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2184-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2372-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1133-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1123-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1501-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"176-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1033-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1205-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1966-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2697-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1079-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2847-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1373-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1719-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1293-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"962-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"822-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3009-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3072-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1250-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2395-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1180-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"961-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1562-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1887-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2398-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1919-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"916-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"771-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2113-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1621-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"649-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1111-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2470-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"811-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"970-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2736-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1041-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1334-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2297-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2070-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2799-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2080-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2815-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1175-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2668-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3031-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1657-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2634-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1739-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"996-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1319-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2114-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2496-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1900-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1022-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2460-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3042-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1720-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"719-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"907-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"752-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"933-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1332-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2879-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2445-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1225-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2081-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1854-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2789-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"921-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1587-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2288-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2881-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"891-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1774-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2117-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2435-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1962-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2123-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2055-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2162-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1497-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1257-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1897-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2999-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1616-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1442-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1608-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2245-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"808-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"844-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2542-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1704-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1091-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1107-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2615-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"620-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"818-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2177-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1352-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1090-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1170-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2156-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2442-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2589-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1714-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2308-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2186-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2343-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1989-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1688-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2324-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2950-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"955-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1140-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2624-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"968-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2538-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1927-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1405-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1441-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1494-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1326-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1343-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2214-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2011-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3128-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1879-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1512-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1470-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1301-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1680-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1105-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"861-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1304-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1921-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1069-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2037-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"731-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1376-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1217-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2807-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3007-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"827-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3015-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3091-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1083-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1050-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2391-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2016-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2071-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"924-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1705053","raw_amount":{"local_denom":"2290386"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2194"}]}}},"last_succesful":false},"1426-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1208-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"266-channel-26":{"error":"packet failure: timeout","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"638820","raw_amount":{"lp_shares":"309267865341460"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"490"}]},"309267865341460"]}},"last_succesful":false},"1339-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1681-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1923-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1952-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2396-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3036-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2705-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"650-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2781-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2319-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1077-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2660-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1809-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2072-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2082-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1135-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"780-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2232-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1509-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2436-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3131-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2135-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2858-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1267-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"720-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1683-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2978-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1867-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3100-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1302-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1255-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1190-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2266-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1375-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"944-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2912-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"997-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1832-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2048-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1400-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1895-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"950-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1459-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2427-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1009-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1099-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1374-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2742-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1280-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2642-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1866-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1345-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1943-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2347-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1286-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1656-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2310-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1404-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2842-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2970-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"215-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1605-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1648-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1661-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2486-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2147-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2564-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2939-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1695-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1087-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1411-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2829-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2276-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1642-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3104-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2681-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2750-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2897-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"702-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"985-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"873-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1730-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1979-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1837-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2022-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1443-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1585-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2363-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2020-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1074-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2942-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"749-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"992-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"588-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"925-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1147-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3034-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1371-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2108-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3054-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3000-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1652-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1586-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"667-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1100-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1422-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2346-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3073-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"786-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2718-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"772-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"913-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2666-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1212-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1843-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1872-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2039-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2328-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2746-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1112-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2392-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2876-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1570-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1043-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1452-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"906-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1295-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1199-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1659-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1235-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1351-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2664-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2849-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1530-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2323-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"837-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1390-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2558-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"936-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2136-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2204-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2471-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2594-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2555-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2000-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2645-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"902-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2698-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1315-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1011-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1395-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2406-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2570-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2667-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"958-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2124-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1028-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1698-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2066-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1000-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1906-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1971-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1828-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1599-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1012-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1425-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1915-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1846-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2278-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2408-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"974-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2105-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1311-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"713-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1086-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"290-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"663-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"785-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1946-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2360-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1432-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2479-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2508-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1282-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"885-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2443-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"249-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2307-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2516-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1171-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1996-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2818-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1056-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2008-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2931-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2256-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1193-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1029-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"11-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"6"},{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"7"},{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"8"},{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"9"},{"claim_amount":"510732","raw_amount":{"lp_shares":"359199211716017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"10"}]},"3232795779359726"]}},"last_succesful":true},"864-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1030-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2367-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"805-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2963-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2411-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1462-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2537-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2735-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1640-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2235-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2917-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1483-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3075-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"776-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2127-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1360-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1210-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1757-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"684-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1106-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2224-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"773-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"815-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2315-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2151-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3035-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1154-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2002-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2038-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"867-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"676-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2566-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1412-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2547-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1564-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"847-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1654-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1591-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2785-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2797-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"971-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1492-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3142-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1472-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2889-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2457-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1403-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1178-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1951-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1136-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"843-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1734-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2877-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2261-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2572-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1461-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2826-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1256-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2857-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"258-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"871-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"735-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2934-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1758-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2338-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"975-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2621-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2707-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"898-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2223-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"766-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1424-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2052-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"877-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1165-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2227-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1829-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2069-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2784-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3039-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2606-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2894-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2861-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1435-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1045-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2673-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2441-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2063-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1597-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1737-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2940-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1273-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1636-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1830-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"896-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1882-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"161-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2014-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2646-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2927-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1804-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"838-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2010-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3030-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2218-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"801-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1521-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1543-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2091-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1868-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2157-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2206-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"602-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1324-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1298-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2079-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2497-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"817-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"795-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2786-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2952-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3051-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"724-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3125-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3141-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"227-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"953-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"582-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1691-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2138-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2155-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2201-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"793-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2489-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1474-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3097-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1703-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1669-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2254-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1932-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1566-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1555-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1707-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2437-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1786-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"868-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2600-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2592-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1795-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2813-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2700-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1187-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1195-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1520-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2729-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2215-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1802-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2133-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"141-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"245-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"814-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"856-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1731-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1948-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2379-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2180-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2979-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3068-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2058-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1300-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1456-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1590-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2023-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2650-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1131-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2981-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"777-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1511-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2304-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"876-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2468-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1015-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1842-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2279-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2488-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1748-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2466-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2553-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2706-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2754-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1485-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2548-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2856-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1156-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1864-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"900-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1285-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1428-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1436-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1686-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1440-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1115-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1014-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2610-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1419-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"946-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1093-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"727-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1620-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2375-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2499-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3095-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1629-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"615-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"865-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2051-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2502-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2414-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1781-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1567-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1181-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2251-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2628-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2980-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2945-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1290-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1550-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2985-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2262-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"144-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1874-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2030-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2330-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2560-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2104-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2013-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3102-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3138-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1833-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1413-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1013-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1393-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1047-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2397-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"869-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1192-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1561-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1216-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2240-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2756-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2599-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1984-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2840-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2362-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"611-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"965-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2946-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2989-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2252-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1503-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2313-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2475-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1551-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"669-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1638-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2306-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2287-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2825-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2886-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1142-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3120-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1772-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1807-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1347-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2916-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2336-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"738-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1141-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1619-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1930-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3096-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1506-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3092-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3101-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"736-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1957-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"549-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"755-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1835-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2439-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2725-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1398-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"632-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1515-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1794-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"235-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1924-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1649-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1956-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2607-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"146-undefined":{"error":"packet failure: timeout","step":"icq","last_succesful":false},"1104-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"857-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1150-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1988-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"928-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2274-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1317-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"903-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"726-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1498-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2702-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"725-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1637-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2571-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1502-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2094-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2602-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2685-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"833-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1330-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1660-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1959-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1869-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1182-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1784-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2273-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2652-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1078-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3041-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3044-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2773-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2120-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1851-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2523-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"894-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2683-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2937-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2973-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3059-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1153-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1525-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1753-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2767-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2780-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2888-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2484-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"779-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2647-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2473-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2456-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3003-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2463-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1233-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2089-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1858-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2904-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2949-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2550-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1490-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1261-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1883-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"691-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1527-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2198-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"622-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1938-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2716-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1203-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2228-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1331-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1861-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"291-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2309-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1818-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2286-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2009-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2843-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2529-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1816-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2977-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2835-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1471-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2485-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"800-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"994-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1031-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"757-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1258-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1729-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2521-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1478-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3017-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2106-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3027-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1632-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3133-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1645-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1037-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1359-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2674-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2833-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2567-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1134-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2493-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1058-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1321-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1444-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1595-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1489-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1552-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2562-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3085-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"834-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"787-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3048-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2563-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2425-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2631-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2805-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2824-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1237-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2387-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1825-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1071-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2377-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2868-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1365-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2185-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1596-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2413-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2838-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2623-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2744-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"984-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"874-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1270-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"804-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2003-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2639-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2907-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3045-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3056-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2793-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2480-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1183-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1253-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"839-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1007-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1430-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2771-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2007-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2374-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"831-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1634-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2096-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2500-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1793-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1810-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2249-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1505-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1741-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2513-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2551-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"789-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1941-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2922-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1447-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1589-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3040-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1863-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1523-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1275-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1678-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"579-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2350-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3067-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1408-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1841-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"662-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2478-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2699-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1898-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1911-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2169-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2491-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3089-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1152-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1348-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"999-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"767-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2640-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1423-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2559-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1725-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2295-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2068-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2522-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2593-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1122-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1350-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2165-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1394-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1283-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1889-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2687-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2691-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1960-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1964-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1023-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2748-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1118-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2509-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1970-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2753-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2804-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2110-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1569-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1770-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1241-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1518-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2031-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2171-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2339-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2386-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2511-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2618-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2111-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2682-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2738-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2292-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2936-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"924-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"284-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1997-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2112-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"973-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"884-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2438-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2498-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2745-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2622-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1039-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1486-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1614-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"320-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1557-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1759-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2045-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1665-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2905-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1617-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"963-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1386-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2991-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2345-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1313-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1388-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1338-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1097-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1504-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1857-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1130-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1125-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1514-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2808-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1296-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2519-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"977-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1716-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1848-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1059-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2723-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1048-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2995-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3098-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2883-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1219-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"920-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2103-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2118-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2757-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2440-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2331-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1697-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2655-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1453-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2709-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2272-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2810-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1101-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1243-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1228-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2202-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1449-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"694-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"792-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1366-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"842-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2482-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2720-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"567-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"638-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1516-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"645-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1785-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3079-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2402-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1328-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2532-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2633-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1701-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1754-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2853-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1176-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"851-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1820-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1902-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1824-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"679-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2506-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1246-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2164-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"706-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2533-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"905-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"966-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2730-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3119-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2380-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2275-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2401-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1940-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1114-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2282-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2620-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2540-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"904-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1279-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2320-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2349-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1002-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1046-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2100-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2172-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2595-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2896-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1201-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"612-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1576-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2694-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"770-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2574-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2739-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1008-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1928-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1583-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2641-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2061-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"218-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"140-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1563-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2337-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2827-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"705-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2512-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1476-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"299-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2364-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1477-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"12-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"6"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"7"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"8"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"9"},{"claim_amount":"510732","raw_amount":{"local_denom":"499944"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"10"}]}}},"last_succesful":true},"2216-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2234-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2768-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2487-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1821-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1875-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1677-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2654-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2770-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2878-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3058-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2109-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"993-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1247-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2714-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2462-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2911-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"729-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"890-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1890-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2938-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1085-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1862-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1340-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1364-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1415-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2611-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2382-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1468-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1396-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1532-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"853-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"11451213","raw_amount":{"local_denom":"15419791"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2100"}]}}},"last_succesful":false},"2612-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1980-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"255-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"758-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1604-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"943-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"716-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3107-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"887-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1361-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1544-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1706-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"845-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"942-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1457-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1429-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1664-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2263-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1089-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1306-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2019-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1584-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1040-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2327-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2679-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2507-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1420-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1439-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1852-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1840-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2137-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1631-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1454-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2613-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3093-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1323-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"717-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"852-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1032-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2609-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1025-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1815-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3074-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1542-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2476-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3005-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2132-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2168-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3114-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2140-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"188-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1745-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3065-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"253-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1463-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2053-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"243-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1082-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1593-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1870-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1145-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1878-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2385-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2802-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2300-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"940-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2774-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2302-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"848-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1475-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"969-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2591-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2997-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3094-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2743-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"989-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1401-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2028-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2358-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2190-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2737-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2676-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1894-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3023-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2059-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2077-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2933-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1675-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2975-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1342-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2115-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2187-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2388-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2984-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1410-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1799-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"824-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2267-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"938-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2289-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2373-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1685-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2614-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2791-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2154-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"764-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1209-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2134-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2283-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"863-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1743-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2065-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"143-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2444-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2875-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"796-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"671-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"742-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1431-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1782-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1991-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2390-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3043-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2351-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1742-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2067-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2447-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2884-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3122-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"677-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2270-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1231-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1838-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3001-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1578-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2125-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1624-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2811-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2732-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1092-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2175-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2837-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2420-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1281-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1717-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1495-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2459-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2913-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3080-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2882-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1272-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1722-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1450-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3130-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1482-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2924-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1508-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1710-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1913-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3124-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3127-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2078-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"626-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2428-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2906-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2246-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2958-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3071-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2040-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"286-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"888-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2057-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3049-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1780-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3083-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1327-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1464-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"850-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1309-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"760-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1910-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1387-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1144-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1934-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2098-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2740-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2073-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1571-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2481-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3016-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2424-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2557-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2365-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3076-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2238-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2492-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2119-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"830-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"701-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1384-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1248-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2233-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2581-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3110-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"203-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"730-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1370-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1407-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1891-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2525-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3060-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1510-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2129-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3050-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1469-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2357-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2696-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1252-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3115-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3134-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3066-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1385-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2208-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1402-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2514-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"919-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"987-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1068-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2536-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"657-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2299-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1699-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"889-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2311-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2969-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"791-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"810-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1391-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1223-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3139-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"707-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1792-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2552-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1855-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"858-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"809-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"922-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1646-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2033-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2659-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2671-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1249-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2587-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2050-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2561-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2128-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"665-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1354-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2747-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2465-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2334-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2265-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1057-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2778-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2526-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"816-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"870-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1733-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1067-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"174-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"712-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1103-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1633-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2675-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1451-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2335-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2361-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"145-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1310-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1808-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2415-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2812-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"739-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1325-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1844-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2680-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1119-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"600-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1197-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1881-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2221-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2046-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2855-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2998-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"294-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3010-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1606-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1389-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1215-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2359-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2648-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3024-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2796-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1526-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1095-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2242-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2598-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2862-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2900-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1184-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"979-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"806-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1537-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2312-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1953-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3137-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"618-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"585-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1380-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1736-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2087-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"769-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2822-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2961-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1053-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1993-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1635-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2483-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1916-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2909-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2092-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3018-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1191-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"853-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2243-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2604-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2806-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1708-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2901-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2075-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1265-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2728-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"630-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1018-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1975-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1977-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3022-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"7-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5467943","raw_amount":{"local_denom":"4774382"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4"}]}}},"last_succesful":true},"2024-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3117-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1158-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1905-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2657-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"915-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"931-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1528-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"257-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2012-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1682-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2213-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2578-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2932-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3002-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1735-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1379-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1055-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1687-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1715-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1038-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1337-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"823-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"930-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1575-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2163-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2510-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1291-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2832-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2005-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2285-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1072-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2464-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2920-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2986-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"5-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1121876","raw_amount":{"local_denom":"981549"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3"}]}}},"last_succesful":true},"2409-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1668-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2107-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2316-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2452-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"648-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1084-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2083-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1967-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1143-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2356-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3013-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"790-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1406-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1188-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1559-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2769-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1274-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2775-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"886-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1213-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1775-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2576-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"840-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"957-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2534-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2960-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2579-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1416-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2926-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"187-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1896-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2965-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2026-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1496-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2400-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2658-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"734-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1164-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3123-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"753-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1588-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1893-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2734-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"935-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"768-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"959-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2887-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"230-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"802-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1239-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1767-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1196-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1020-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1987-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1076-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1899-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2983-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"926-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1167-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1207-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2575-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1060-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2490-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"893-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2790-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1568-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2839-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1574-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2212-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"878-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2467-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"832-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2863-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1399-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3008-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1004-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2122-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2412-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"668-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2866-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2788-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1051-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1493-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1108-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2637-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2864-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"911-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1826-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2871-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3012-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"972-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1268-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2520-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"917-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1070-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1517-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1847-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1643-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2333-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2102-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2501-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"765-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1019-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1251-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2219-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"6-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"1121876","raw_amount":{"lp_shares":"705229307494444"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3"}]},"705229307494444"]}},"last_succesful":true},"1885-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1161-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2772-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2836-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2860-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"820-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2867-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2823-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2890-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3135-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1978-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"947-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2461-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1819-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1871-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2368-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2176-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1760-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1850-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3057-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1005-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1116-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2844-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1318-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3061-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"807-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"879-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1981-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2582-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2891-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2974-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1003-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1098-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2819-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"759-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2448-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2948-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2430-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"142-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1580-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"854-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1969-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"693-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"750-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"895-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2528-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1307-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2025-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1194-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2426-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"594-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1049-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2423-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1297-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1647-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1292-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2590-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1278-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2712-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2798-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1579-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2344-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1592-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1202-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"206-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1466-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1692-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2199-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2505-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"655-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2731-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2982-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2711-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2515-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3006-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"197-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2431-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3105-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1751-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1933-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2629-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2841-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1771-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2964-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1113-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2872-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1538-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2290-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2764-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2761-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1641-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3038-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3019-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2689-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2954-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3109-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2161-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2677-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1705-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1798-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1163-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2779-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1244-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1434-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1094-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2583-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1884-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2899-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1160-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"846-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1169-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2455-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1021-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2410-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2418-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1129-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2004-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2527-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2801-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1763-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2153-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1204-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1206-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1479-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1536-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1601-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1042-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1353-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2758-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1064-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"951-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1382-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"901-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2996-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2042-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2191-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2903-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2417-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1806-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2454-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"927-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"221-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"741-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2383-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1679-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2244-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3126-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"674-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2305-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2759-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1903-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3088-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2880-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"634-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2968-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3111-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1289-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1658-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1773-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2722-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2993-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1817-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2241-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2690-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"929-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1075-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1853-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2130-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"194-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"704-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1565-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1922-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1762-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2314-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2956-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"982-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1303-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"737-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"709-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1445-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3011-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2688-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2101-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1234-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"778-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2656-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1357-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3144-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"761-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2935-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2062-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1484-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2923-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"747-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1126-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1284-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1582-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1609-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1613-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1242-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1689-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2944-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3108-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1159-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"859-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1068-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27572493","raw_amount":{"local_denom":"36899908"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2266"}]}}},"last_succesful":false},"1541-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1920-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2378-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2585-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1218-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3106-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"897-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3020-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2145-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1127-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1173-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1976-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1073-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1427-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2131-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2419-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2869-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"945-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1305-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1662-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2001-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2207-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2503-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2990-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1367-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"872-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1644-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1264-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1935-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1230-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1121-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1618-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1994-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2032-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2090-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3129-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2376-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2994-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1062-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"829-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1355-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1017-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"912-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1860-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1912-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1954-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2222-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2531-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1666-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1765-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1937-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2596-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2814-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1630-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3037-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3081-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1271-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"732-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1467-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2726-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1791-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"860-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1721-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1316-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2322-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1972-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"923-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2902-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1711-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2085-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2929-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2987-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1673-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1397-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2239-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1446-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2715-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2721-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1102-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"733-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1378-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2084-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1214-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2341-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2381-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2955-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2044-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2178-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"881-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1777-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2211-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1081-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2354-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2992-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1277-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3136-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1377-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2930-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"718-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1744-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2366-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2941-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3055-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"812-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"976-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2170-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1519-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2588-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2450-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1269-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1876-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1308-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2255-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2296-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1418-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2830-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"952-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3090-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2149-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1546-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"899-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1276-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2518-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2636-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1381-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2545-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1942-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2029-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2569-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"13-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"begin_unlocking":[[{"lp_shares":"567995093018743","primitive_shares":"1075915","owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","id":"5"},{"lp_shares":"267990275290950","primitive_shares":"507636","owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","id":"11"}],"835985368309693"]}},"last_succesful":true},"2783-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"344-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"30549409","raw_amount":{"local_denom":"43106797"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1691"}]}}},"last_succesful":false},"2601-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"980-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2041-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1110-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1929-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1676-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"988-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2192-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1776-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2257-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2429-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2220-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"565-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3121-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1448-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1728-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"981-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1322-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1137-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1949-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1572-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2800-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2892-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"862-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1117-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1200-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1573-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1288-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1796-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2554-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2608-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3140-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2035-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2549-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1061-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2708-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2188-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1088-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2277-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2669-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"708-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1266-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2317-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1694-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"990-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1845-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1947-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3099-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1548-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2584-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2340-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3084-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1460-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2586-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1222-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2268-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"775-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1096-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2472-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2404-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2947-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2692-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3145-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1294-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1539-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1856-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1944-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2166-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1522-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2230-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"797-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1985-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"692-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1594-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1886-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1554-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1671-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"746-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1690-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1473-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1174-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2146-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2181-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1700-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2196-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2504-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2670-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2795-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2603-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2076-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3070-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2541-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"948-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2850-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2943-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3078-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3116-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1779-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2893-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2873-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1151-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2792-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2885-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1963-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1908-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"756-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2248-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2684-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"740-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1950-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1598-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1627-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2451-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"270-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2264-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2434-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1888-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2651-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1287-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3025-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"714-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2635-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1553-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2209-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1623-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1581-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2021-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2143-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2047-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3112-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2173-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2150-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2649-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2665-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1667-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2859-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"229-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1914-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2988-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1392-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3069-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"892-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1650-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2403-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1766-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1836-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2097-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2353-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1329-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2925-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1718-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3033-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"876-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"485317410","raw_amount":{"local_denom":"653150114"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2111"},{"claim_amount":"125454550","raw_amount":{"local_denom":"168839304"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2112"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2113"},{"claim_amount":"1455951","raw_amount":{"local_denom":"1959450"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2115"},{"claim_amount":"120844034","raw_amount":{"local_denom":"162634378"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2116"},{"claim_amount":"6114999","raw_amount":{"local_denom":"8229691"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2117"},{"claim_amount":"9706348","raw_amount":{"local_denom":"13063002"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2118"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2119"},{"claim_amount":"48046423","raw_amount":{"local_denom":"64661861"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2120"},{"claim_amount":"5289959","raw_amount":{"local_denom":"7119336"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2121"},{"claim_amount":"1892737","raw_amount":{"local_denom":"2547285"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2122"},{"claim_amount":"4319324","raw_amount":{"local_denom":"5813036"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2123"},{"claim_amount":"33244242","raw_amount":{"local_denom":"44740782"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2124"},{"claim_amount":"4756110","raw_amount":{"local_denom":"6400871"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2125"},{"claim_amount":"582380","raw_amount":{"local_denom":"783780"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2126"},{"claim_amount":"8250395","raw_amount":{"local_denom":"11103551"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2127"},{"claim_amount":"4804642","raw_amount":{"local_denom":"6466186"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2128"},{"claim_amount":"9803411","raw_amount":{"local_denom":"13193632"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2129"},{"claim_amount":"72312294","raw_amount":{"local_denom":"97319367"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2130"},{"claim_amount":"61489715","raw_amount":{"local_denom":"82754119"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2131"},{"claim_amount":"527540025","raw_amount":{"local_denom":"709974174"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2132"},{"claim_amount":"421740829","raw_amount":{"local_denom":"567587449"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2133"},{"claim_amount":"26692457","raw_amount":{"local_denom":"35923256"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2134"},{"claim_amount":"3154562","raw_amount":{"local_denom":"4245475"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2135"},{"claim_amount":"10191665","raw_amount":{"local_denom":"13716152"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2136"},{"claim_amount":"3470019","raw_amount":{"local_denom":"4670023"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2137"},{"claim_amount":"2098997802","raw_amount":{"local_denom":"2824874245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2138"},{"claim_amount":"24265870","raw_amount":{"local_denom":"32657505"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2139"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2140"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2141"},{"claim_amount":"247997196","raw_amount":{"local_denom":"333759708"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2142"},{"claim_amount":"2426586","raw_amount":{"local_denom":"3265750"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2143"},{"claim_amount":"9706348","raw_amount":{"local_denom":"13063002"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2144"},{"claim_amount":"970634","raw_amount":{"local_denom":"1306300"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2145"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2146"},{"claim_amount":"2654686","raw_amount":{"local_denom":"3572731"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2147"},{"claim_amount":"3397221","raw_amount":{"local_denom":"4572050"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2148"},{"claim_amount":"4367856","raw_amount":{"local_denom":"5878351"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2149"},{"claim_amount":"8007736","raw_amount":{"local_denom":"10776976"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2150"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2151"},{"claim_amount":"2892491","raw_amount":{"local_denom":"3892774"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2152"},{"claim_amount":"48483209","raw_amount":{"local_denom":"65249696"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2153"}]}}},"last_succesful":false},"2225-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2293-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1254-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2605-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1221-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1655-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2247-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1931-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1465-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"978-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1035-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1433-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1713-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1756-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1166-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1540-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2205-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1010-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1168-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2661-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2259-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"722-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1560-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2422-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1670-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2957-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"642-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2727-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"659-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1611-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1120-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1907-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1138-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2678-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1507-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2898-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2782-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1800-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2018-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2556-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1480-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2701-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2352-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2458-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2530-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1750-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1065-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2318-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2303-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1066-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2710-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2148-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"910-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2619-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1363-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2203-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"918-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1925-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"695-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4784858","raw_amount":{"local_denom":"6521340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2018"}]}}},"last_succesful":false},"1945-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2632-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1155-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1831-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"301-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1314-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2616-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1455-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1481-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1834-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2160-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2034-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1001-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"803-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1612-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1797-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1148-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"788-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1535-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1372-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2182-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2116-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2686-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1986-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1663-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1822-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1740-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2733-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"688-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"813-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"751-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2474-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"745-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1827-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1458-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2284-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2704-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"781-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1198-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1788-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1226-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1128-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1602-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2015-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2158-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1968-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2329-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2627-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2787-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1124-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1684-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1549-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2469-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2348-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2389-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1224-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"9-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5467943","raw_amount":{"local_denom":"4774382"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4"}]}}},"last_succesful":true},"2049-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2099-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"986-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2919-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1139-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1992-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1723-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3004-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2828-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3143-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"754-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2831-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2851-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"956-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"954-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1063-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"624-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1383-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1488-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1556-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1738-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2027-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2054-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1185-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2394-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2953-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2966-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3028-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3047-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"774-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"782-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"743-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1236-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2189-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2126-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2580-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1746-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"629-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"256-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2253-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2846-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1529-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1500-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"711-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1880-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2195-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2544-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"995-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2281-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2342-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2301-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2321-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1805-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2821-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"841-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2626-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1052-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2036-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1789-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2432-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2794-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3062-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2870-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1531-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2803-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1747-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1513-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2210-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1220-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2717-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"794-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2817-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3021-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1487-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1712-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2399-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2229-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1344-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"949-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1811-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2407-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2477-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1803-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2703-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2852-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2384-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2874-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3029-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3046-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2495-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2152-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"728-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"225-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1186-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3103-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"555-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"700-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"762-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1438-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1545-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2752-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2433-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2865-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2139-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2141-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"557-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1149-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2565-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3086-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2197-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1892-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2914-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2630-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"932-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"710-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1132-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1626-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1958-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2121-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2724-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1622-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2193-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1263-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2231-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2653-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1157-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2617-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3032-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1172-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2194-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"849-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1558-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1859-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2064-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1034-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2236-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2895-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2260-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2976-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1027-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1533-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"297-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1080-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2095-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3063-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1814-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3113-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3052-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"784-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1768-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2535-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2539-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1615-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2962-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1812-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2298-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2088-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2217-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2638-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2144-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1610-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2777-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"10-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"6"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"7"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"8"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"9"},{"claim_amount":"510732","raw_amount":{"local_denom":"499944"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"10"}]}}},"last_succesful":true},"2749-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2200-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1006-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2093-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1955-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2355-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1179-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"748-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1054-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"908-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"826-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2915-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"914-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1335-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2809-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"744-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2326-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1801-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"835-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2086-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1995-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1607-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2179-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"883-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2573-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2908-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1865-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2159-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"828-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1764-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2854-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"608-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1232-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1917-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2369-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2918-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2226-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1999-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"819-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2405-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1409-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1299-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2663-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2291-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2971-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1421-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1973-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"798-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2820-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2017-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2237-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1026-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1628-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1939-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2294-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2524-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2834-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1016-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2269-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2271-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1229-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3118-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"909-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1333-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1672-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2816-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1262-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1320-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"164-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"991-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1211-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1724-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3132-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2776-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1839-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"159-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1982-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2921-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1036-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1177-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1491-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1639-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2006-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2060-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"287-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"763-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"880-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3082-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"260-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1702-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1783-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1109-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1349-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1761-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2967-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2662-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2517-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2959-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2719-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"723-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1259-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1726-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1965-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2928-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1362-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3026-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2421-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"605-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"937-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1189-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2494-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2625-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2643-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2453-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1901-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1755-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1769-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1499-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1368-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1749-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1524-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2845-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"660-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"799-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1904-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2183-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"998-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1437-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1547-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2370-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2371-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1358-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2848-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"934-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1414-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2713-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"715-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2760-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"201-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1356-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1674-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1998-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2765-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2446-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1146-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3077-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"866-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2325-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1651-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2762-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3014-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1625-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1849-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2751-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2755-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1600-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1961-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"680-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1162-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1752-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"685-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2543-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1044-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2568-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true}}}} diff --git a/smart-contracts/migrations/migration-004/trapped_errors_7fv.json b/smart-contracts/migrations/migration-004/trapped_errors_7fv.json deleted file mode 100644 index ee3896075..000000000 --- a/smart-contracts/migrations/migration-004/trapped_errors_7fv.json +++ /dev/null @@ -1 +0,0 @@ -{"data":{"errors":{"1042-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27574028","raw_amount":{"local_denom":"17987877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2266"}]}}},"last_succesful":false},"187-undefined":{"error":"packet failure: timeout","step":"icq","last_succesful":false},"668-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4786143","raw_amount":{"local_denom":"3247407"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2018"}]}}},"last_succesful":false},"826-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"11451515","raw_amount":{"local_denom":"7647023"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2100"}]}}},"last_succesful":false},"8-undefined":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5458134","raw_amount":{"local_denom":"3794876"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4"}]}}},"last_succesful":false},"94-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1503699649","raw_amount":{"local_denom":"1041062698"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1468"}]}}},"last_succesful":false},"264-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454028","raw_amount":{"local_denom":"326612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1596"}]}}},"last_succesful":false},"265-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454125","raw_amount":{"local_denom":"326654"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1597"}]}}},"last_succesful":false},"274-channel-25":{"error":"packet failure: timeout","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"638834","raw_amount":{"lp_shares":"47745019338281363"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"490"}]},"47745019338281363"]}},"last_succesful":false},"14-undefined":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"28970931","raw_amount":{"local_denom":"22477403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"13"}]}}},"last_succesful":false},"317-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"30552830","raw_amount":{"local_denom":"21686062"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1691"}]}}},"last_succesful":false},"849-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"485643187","raw_amount":{"local_denom":"324236968"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2111"},{"claim_amount":"125538763","raw_amount":{"local_denom":"83815256"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2112"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2113"},{"claim_amount":"1456928","raw_amount":{"local_denom":"972710"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2115"},{"claim_amount":"120925153","raw_amount":{"local_denom":"80735005"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2116"},{"claim_amount":"6119102","raw_amount":{"local_denom":"4085385"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2117"},{"claim_amount":"9712863","raw_amount":{"local_denom":"6484739"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2118"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2119"},{"claim_amount":"48078674","raw_amount":{"local_denom":"32099459"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2120"},{"claim_amount":"5293509","raw_amount":{"local_denom":"3534182"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2121"},{"claim_amount":"1894008","raw_amount":{"local_denom":"1264524"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2122"},{"claim_amount":"4322224","raw_amount":{"local_denom":"2885709"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2123"},{"claim_amount":"33266557","raw_amount":{"local_denom":"22210232"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2124"},{"claim_amount":"4759302","raw_amount":{"local_denom":"3177522"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2125"},{"claim_amount":"582771","raw_amount":{"local_denom":"389084"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2126"},{"claim_amount":"8255933","raw_amount":{"local_denom":"5512028"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2127"},{"claim_amount":"4807866","raw_amount":{"local_denom":"3209945"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2128"},{"claim_amount":"9809991","raw_amount":{"local_denom":"6549586"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2129"},{"claim_amount":"72360834","raw_amount":{"local_denom":"48311308"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2130"},{"claim_amount":"61530990","raw_amount":{"local_denom":"41080823"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2131"},{"claim_amount":"527894144","raw_amount":{"local_denom":"352445584"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2132"},{"claim_amount":"422023929","raw_amount":{"local_denom":"281761925"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2133"},{"claim_amount":"26710374","raw_amount":{"local_denom":"17833033"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2134"},{"claim_amount":"3156680","raw_amount":{"local_denom":"2107540"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2135"},{"claim_amount":"10198506","raw_amount":{"local_denom":"6808976"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2136"},{"claim_amount":"3472348","raw_amount":{"local_denom":"2318294"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2137"},{"claim_amount":"2100406787","raw_amount":{"local_denom":"1402324887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2138"},{"claim_amount":"24282158","raw_amount":{"local_denom":"16211848"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2139"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2140"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2141"},{"claim_amount":"248163668","raw_amount":{"local_denom":"165685090"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2142"},{"claim_amount":"2428214","raw_amount":{"local_denom":"1621184"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2143"},{"claim_amount":"9712863","raw_amount":{"local_denom":"6484739"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2144"},{"claim_amount":"971284","raw_amount":{"local_denom":"648473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2145"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2146"},{"claim_amount":"2656467","raw_amount":{"local_denom":"1773576"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2147"},{"claim_amount":"3399501","raw_amount":{"local_denom":"2269658"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2148"},{"claim_amount":"4370787","raw_amount":{"local_denom":"2918132"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2149"},{"claim_amount":"8013111","raw_amount":{"local_denom":"5349909"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2150"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2151"},{"claim_amount":"2894432","raw_amount":{"local_denom":"1932452"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2152"},{"claim_amount":"48515754","raw_amount":{"local_denom":"32391273"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2153"}]}}},"last_succesful":false}}}} diff --git a/smart-contracts/migrations/migration-004/trapped_errors_fps.json b/smart-contracts/migrations/migration-004/trapped_errors_fps.json deleted file mode 100644 index 3aa1d5638..000000000 --- a/smart-contracts/migrations/migration-004/trapped_errors_fps.json +++ /dev/null @@ -1 +0,0 @@ -{"data":{"errors":{"98-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1503723755","raw_amount":{"local_denom":"79003403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1468"}]}}},"last_succesful":false},"188-undefined":{"error":"packet failure: timeout","step":"icq","last_succesful":false},"269-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454093","raw_amount":{"local_denom":"24592"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1597"}]}}},"last_succesful":false},"672-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4785365","raw_amount":{"local_denom":"231252"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2018"}]}}},"last_succesful":false},"830-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"11450657","raw_amount":{"local_denom":"533184"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2100"}]}}},"last_succesful":false},"15-undefined":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"28971416","raw_amount":{"local_denom":"6982413"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"13"}]}}},"last_succesful":false},"274-channel-23":{"error":"packet failure: timeout","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"638939","raw_amount":{"lp_shares":"178691736047696401"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"490"}]},"178691736047696401"]}},"last_succesful":false},"321-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"30550338","raw_amount":{"local_denom":"1607140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1691"}]}}},"last_succesful":false},"1046-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27574007","raw_amount":{"local_denom":"1262214"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2266"}]}}},"last_succesful":false},"268-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454111","raw_amount":{"local_denom":"24594"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1596"}]}}},"last_succesful":false},"853-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"484187518","raw_amount":{"local_denom":"22612917"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2111"},{"claim_amount":"125162472","raw_amount":{"local_denom":"5845439"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2112"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2113"},{"claim_amount":"1452546","raw_amount":{"local_denom":"67838"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2115"},{"claim_amount":"120562684","raw_amount":{"local_denom":"5630616"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2116"},{"claim_amount":"6100746","raw_amount":{"local_denom":"284922"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2117"},{"claim_amount":"9683743","raw_amount":{"local_denom":"452258"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2118"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2119"},{"claim_amount":"47934547","raw_amount":{"local_denom":"2238678"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2120"},{"claim_amount":"5277626","raw_amount":{"local_denom":"246480"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2121"},{"claim_amount":"1888323","raw_amount":{"local_denom":"88190"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2122"},{"claim_amount":"4309248","raw_amount":{"local_denom":"201254"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2123"},{"claim_amount":"33166827","raw_amount":{"local_denom":"1548984"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2124"},{"claim_amount":"4745025","raw_amount":{"local_denom":"221606"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2125"},{"claim_amount":"581014","raw_amount":{"local_denom":"27135"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2126"},{"claim_amount":"8231175","raw_amount":{"local_denom":"384419"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2127"},{"claim_amount":"4793437","raw_amount":{"local_denom":"223867"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2128"},{"claim_amount":"9780568","raw_amount":{"local_denom":"456780"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2129"},{"claim_amount":"72143926","raw_amount":{"local_denom":"3369324"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2130"},{"claim_amount":"61346546","raw_amount":{"local_denom":"2865056"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2131"},{"claim_amount":"526311837","raw_amount":{"local_denom":"24580241"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2132"},{"claim_amount":"420758956","raw_amount":{"local_denom":"19650625"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2133"},{"claim_amount":"26630304","raw_amount":{"local_denom":"1243710"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2134"},{"claim_amount":"3147198","raw_amount":{"local_denom":"146983"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2135"},{"claim_amount":"10167932","raw_amount":{"local_denom":"474871"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2136"},{"claim_amount":"3461933","raw_amount":{"local_denom":"161682"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2137"},{"claim_amount":"2094111037","raw_amount":{"local_denom":"97800867"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2138"},{"claim_amount":"24209357","raw_amount":{"local_denom":"1130645"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2139"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2140"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2141"},{"claim_amount":"247419809","raw_amount":{"local_denom":"11555200"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2142"},{"claim_amount":"2420925","raw_amount":{"local_denom":"113064"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2143"},{"claim_amount":"9683743","raw_amount":{"local_denom":"452258"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2144"},{"claim_amount":"968357","raw_amount":{"local_denom":"45225"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2145"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2146"},{"claim_amount":"2648491","raw_amount":{"local_denom":"123692"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2147"},{"claim_amount":"3389303","raw_amount":{"local_denom":"158290"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2148"},{"claim_amount":"4357682","raw_amount":{"local_denom":"203516"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2149"},{"claim_amount":"7989091","raw_amount":{"local_denom":"373113"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2150"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2151"},{"claim_amount":"2885736","raw_amount":{"local_denom":"134772"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2152"},{"claim_amount":"48370324","raw_amount":{"local_denom":"2259030"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2153"}]}}},"last_succesful":false}}}} diff --git a/smart-contracts/migrations/migration-005/6a2_trapped_errors.json b/smart-contracts/migrations/migration-005/6a2_trapped_errors.json deleted file mode 100644 index 42b63bd79..000000000 --- a/smart-contracts/migrations/migration-005/6a2_trapped_errors.json +++ /dev/null @@ -1 +0,0 @@ -{"data":{"errors":{"280-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1312-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2644-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2766-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"825-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"721-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"195-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2258-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1696-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2142-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2056-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1238-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2167-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2672-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2910-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1227-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2174-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1260-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3087-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1823-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"941-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1936-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2951-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"875-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2393-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"783-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"296-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"964-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1974-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"855-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1341-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2043-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"960-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2546-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2332-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2280-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1727-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2741-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3064-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1709-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1240-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1918-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1983-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2250-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1346-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"967-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2597-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1369-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1909-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1873-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1990-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2449-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1778-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1417-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2577-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1732-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"882-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1653-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2059-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"60652258","raw_amount":{"local_denom":"79450207"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2888"}]}}},"last_succesful":false},"2693-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"703-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1603-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2074-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1926-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1577-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1813-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2972-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1790-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2695-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"836-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1693-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"939-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1877-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"821-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2416-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3053-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1534-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1024-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1336-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2763-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1787-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1245-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"983-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2184-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2372-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1133-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1123-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1501-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"176-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1033-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1205-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1966-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2697-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1079-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2847-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1373-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1719-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1293-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"962-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"822-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3009-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3072-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1250-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2395-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1180-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"961-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1562-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1887-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2398-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1919-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"916-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"771-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2113-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1621-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"649-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1111-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2470-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"811-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"970-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2068-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27355861","raw_amount":{"local_denom":"35768889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2893"}]}}},"last_succesful":false},"1041-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1334-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2297-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2070-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2736-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2080-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2799-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2815-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"4344-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"390407162","raw_amount":{"local_denom":"497474122"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4006"}]}}},"last_succesful":false},"1175-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2668-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3031-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1657-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2634-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1739-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"996-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1319-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2114-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2496-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1900-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1022-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2460-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3042-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1720-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"719-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"907-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"752-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"933-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1332-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2879-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2445-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1225-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2081-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1854-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2789-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"921-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1587-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2288-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2881-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"891-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1774-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2117-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2435-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1962-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2123-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2055-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2162-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1497-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1257-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1897-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2999-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1616-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1442-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1608-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2245-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"808-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"844-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2542-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1704-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1091-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1107-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2615-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"620-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"818-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2177-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1352-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1090-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1170-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2156-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2442-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2589-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1714-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2308-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2186-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2343-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1989-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1688-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2324-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2950-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"955-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1140-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2624-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"968-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2538-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1927-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1405-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1441-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1494-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1326-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1343-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2214-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2011-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3128-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1879-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1512-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1470-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1301-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1680-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1105-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"861-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1304-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1921-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1069-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2037-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"731-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1376-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1217-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2807-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3007-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"827-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3015-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3091-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1083-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1050-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2391-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2016-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2071-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"924-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1705053","raw_amount":{"local_denom":"2290386"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2194"}]}}},"last_succesful":false},"1426-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1208-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"266-channel-26":{"error":"packet failure: timeout","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"638820","raw_amount":{"lp_shares":"309267865341460"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"490"}]},"309267865341460"]}},"last_succesful":false},"1339-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1681-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1923-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1952-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2396-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3036-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2705-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"650-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2781-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2319-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1077-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2660-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1809-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2072-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2082-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1135-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"780-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2232-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1509-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2436-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3131-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2135-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2858-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1267-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"720-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1683-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2978-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1867-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3100-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1302-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1255-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1190-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2266-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1375-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"944-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2912-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"997-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1832-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2048-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1400-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1895-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"950-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1459-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2427-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1009-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1099-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1374-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2742-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1280-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2642-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1866-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1345-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1943-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2347-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1286-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1656-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2310-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1404-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2842-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2970-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"215-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1605-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1648-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1661-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2486-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2147-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2564-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2939-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1695-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1087-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1411-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2829-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2276-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1642-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3104-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2681-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2750-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2897-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"702-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"985-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"873-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1730-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1979-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1837-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2022-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1443-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1585-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2363-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2020-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1074-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2942-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"749-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"992-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"588-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"925-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1147-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3034-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1371-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2108-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3054-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3000-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1652-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1586-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"667-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1100-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1422-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2346-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3073-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"786-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2718-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"772-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"913-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2666-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1212-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1843-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1872-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2039-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2328-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2746-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1112-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2392-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2876-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1570-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1043-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1452-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"906-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1295-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1199-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1659-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1235-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1351-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2664-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2849-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1530-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2323-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"837-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1390-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2558-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"936-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2136-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2204-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2471-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2594-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2555-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2000-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2645-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"902-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2698-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1315-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1011-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1395-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2406-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2570-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2667-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"958-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2124-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1028-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1698-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2066-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1000-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1906-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1971-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1828-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1599-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1012-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1425-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1915-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1846-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2278-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2408-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1150-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"983684","raw_amount":{"local_denom":"1313976"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2308"}]}}},"last_succesful":false},"974-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2105-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1311-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"713-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1086-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"290-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"663-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"785-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1946-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2360-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1432-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2479-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2508-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1282-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"885-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2443-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"249-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2307-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2516-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1171-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1996-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2818-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1056-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2008-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2931-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2256-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1193-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1029-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"11-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"6"},{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"7"},{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"8"},{"claim_amount":"1021466","raw_amount":{"lp_shares":"718399141910927"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"9"},{"claim_amount":"510732","raw_amount":{"lp_shares":"359199211716017"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"10"}]},"3232795779359726"]}},"last_succesful":true},"864-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1030-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2367-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"805-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2963-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2411-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1462-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2537-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2735-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1640-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2235-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2917-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1483-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3075-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"776-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2127-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1360-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1210-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1757-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"684-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1106-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2224-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"773-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"815-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2315-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2151-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3035-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1154-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2002-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2038-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"867-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"676-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2566-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1412-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2547-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1564-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"847-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1654-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1591-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2785-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2797-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"971-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1492-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3142-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1472-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2889-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2457-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1403-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1178-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1951-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1136-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"843-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1734-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2877-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2261-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2572-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1461-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2826-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1256-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2857-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"258-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"871-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"735-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2934-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1758-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2338-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"975-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2621-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2707-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"898-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2223-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"766-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1424-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2052-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"877-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1165-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2227-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1829-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2069-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2784-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3039-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2606-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2894-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2861-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1435-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1045-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2673-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2441-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2063-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1597-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1737-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2940-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1273-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1636-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1830-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"896-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1882-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"161-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2014-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2646-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2927-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1804-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"838-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2010-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3030-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2218-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"801-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1521-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1543-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2091-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1868-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2157-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2206-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"602-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1324-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1298-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2079-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2497-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"817-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"795-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2786-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2952-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3051-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"724-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3125-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3141-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"227-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"953-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"582-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1691-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2138-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2155-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2201-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"793-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2489-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1474-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3097-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1703-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1669-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2254-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1932-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1566-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1555-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1707-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2437-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1786-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"868-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2600-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2592-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1795-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2813-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2700-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1187-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1195-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1520-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2729-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2215-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1802-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2133-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"141-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"245-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"814-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"856-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1731-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1948-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2379-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2180-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2979-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3068-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2058-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1300-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1456-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1590-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2023-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2650-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1131-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2981-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"777-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1511-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2304-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"876-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2468-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1015-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1842-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1908-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"9054958","raw_amount":{"local_denom":"11888368"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2787"}]}}},"last_succesful":false},"2279-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1748-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2466-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2488-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2553-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2706-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1485-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2548-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2754-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1156-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1864-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2856-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"900-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1285-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1428-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1436-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1686-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1440-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1115-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1014-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2610-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1419-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"946-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1093-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"727-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1620-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2375-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2499-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3095-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1629-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"615-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"865-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2051-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2502-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2414-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1781-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1567-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1181-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2251-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2628-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2980-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2945-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1290-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1550-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2985-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2262-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"144-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1874-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2030-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2330-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2560-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2104-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2013-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3102-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3138-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1833-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1413-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1013-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1393-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1047-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2397-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"869-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1192-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1561-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1216-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2240-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2756-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2599-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1984-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2840-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2362-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"611-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"965-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2946-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2989-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2252-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1503-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2313-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2475-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1551-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"669-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1638-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2306-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2287-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2825-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2886-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1142-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3120-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1772-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1807-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1347-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2916-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2336-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"738-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1141-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1619-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1930-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3096-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1506-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3092-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3101-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"736-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1957-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"549-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"755-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1835-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2439-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2725-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1398-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"632-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1515-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1794-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"235-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1924-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1649-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1956-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2607-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"146-undefined":{"error":"packet failure: timeout","step":"icq","last_succesful":false},"1104-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"857-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1150-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1988-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"928-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2274-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1317-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"903-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"726-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1498-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2702-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"725-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1637-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2571-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1502-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2094-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2602-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2685-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"833-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1330-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1660-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1959-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1869-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1182-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1784-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2273-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2652-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1078-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3041-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3044-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2773-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2120-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1851-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2523-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"894-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2683-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2937-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2973-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3059-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1153-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1525-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1753-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2767-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2780-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2888-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2484-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"779-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2647-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2473-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2456-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3003-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2463-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1233-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2089-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1858-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2904-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2949-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2550-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1490-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1261-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1883-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"691-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1527-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2198-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"622-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1938-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2716-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1203-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2228-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1331-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1861-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"291-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2309-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1818-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2286-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2009-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2843-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2529-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1816-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2977-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2835-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1471-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2485-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"800-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"994-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1031-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"757-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1258-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1729-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2521-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1478-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3017-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2106-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3027-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1632-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3133-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1645-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1037-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1359-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2674-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2833-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2567-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1134-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2493-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1058-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1321-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1444-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1595-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1489-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1552-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2562-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3085-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"834-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"787-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3048-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2563-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2425-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2631-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2805-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2824-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1237-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2387-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1825-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1071-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2377-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2868-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1365-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2185-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1596-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2413-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2838-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2623-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2744-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"984-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"874-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1270-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"804-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2003-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2639-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2907-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3045-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3056-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2793-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2480-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1183-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1253-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"839-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1007-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1430-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2771-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2007-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2374-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"831-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1634-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2096-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2500-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1793-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1810-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2249-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1505-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1741-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2513-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2551-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"789-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1941-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2922-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1447-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1589-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3040-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1863-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1523-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1275-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1678-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"579-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2350-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3067-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1408-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1841-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"662-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2478-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2699-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1898-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1911-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2169-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2491-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3089-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1152-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1348-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"999-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"767-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2640-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1423-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2559-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1725-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2295-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2068-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2522-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2593-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1122-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1350-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2165-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1394-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1283-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1889-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2687-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2691-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1960-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1964-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1023-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2748-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1118-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2509-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1970-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2753-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2804-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2110-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1569-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1770-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1241-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1518-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2031-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2171-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2339-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2386-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2511-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2618-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2111-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2682-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2309-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4056316","raw_amount":{"local_denom":"5296584"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3017"}]}}},"last_succesful":false},"2292-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2738-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"924-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"284-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2936-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1997-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2112-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"973-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"884-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2438-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2498-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2745-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2622-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1039-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1486-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1614-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"320-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1557-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1759-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2045-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1665-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2905-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1617-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"963-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1386-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2991-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2345-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1313-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1388-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1338-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1097-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1504-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1857-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1130-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1125-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1514-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2808-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1296-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2519-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"977-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1716-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1848-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1059-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2723-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1048-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2995-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3098-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2883-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1219-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"920-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2103-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2118-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2757-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2440-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2331-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1697-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2655-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1453-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2709-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2272-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2810-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1101-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1243-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1228-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2202-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1449-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"694-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"792-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1366-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"842-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2482-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2720-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"567-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"638-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1516-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"645-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1785-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3079-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2402-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1328-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2532-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2633-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1701-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1754-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2853-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1176-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"851-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1820-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1902-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1824-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"679-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2506-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1246-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2164-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"706-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2533-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"905-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"966-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2730-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3119-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2380-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2275-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2401-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1940-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1114-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2282-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2620-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2540-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"904-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1279-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2320-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2349-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1002-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1046-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2100-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2172-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2595-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2896-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1201-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"612-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1576-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2694-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"770-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2574-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2739-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1008-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1928-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1583-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2641-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2061-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"218-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"140-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1563-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2337-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2827-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"705-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2512-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1476-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"299-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2364-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1477-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"12-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"6"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"7"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"8"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"9"},{"claim_amount":"510732","raw_amount":{"local_denom":"499944"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"10"}]}}},"last_succesful":true},"2216-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2234-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2768-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2487-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1821-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1875-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1677-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2654-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2770-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2878-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3058-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2109-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"993-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1247-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2714-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2462-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2911-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"729-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"890-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1890-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2938-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1085-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1862-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1340-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1364-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1415-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2611-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2382-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1468-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1396-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1532-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"853-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"11451213","raw_amount":{"local_denom":"15419791"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2100"}]}}},"last_succesful":false},"2612-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1980-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"255-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"758-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1604-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"943-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"716-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3107-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"887-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1361-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1544-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1706-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"845-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"942-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1457-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1429-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1664-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2263-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1089-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1306-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2019-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1584-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1040-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2327-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2679-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2507-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1420-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1439-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1852-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1840-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2137-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1631-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1454-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2613-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3093-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1323-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"717-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"852-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1032-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2609-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1025-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1815-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3074-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1542-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2476-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3005-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2045-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"3992775","raw_amount":{"local_denom":"5230240"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2879"}]}}},"last_succesful":false},"2132-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2168-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3114-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2140-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"188-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1745-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3065-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"253-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1463-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2053-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"243-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1082-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1593-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1870-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1145-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1878-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2385-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2802-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2300-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"940-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2774-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2302-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"848-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1475-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"969-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2591-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2997-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3094-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2743-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"989-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1401-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2028-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2358-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2190-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2737-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2676-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1894-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3023-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2059-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2077-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2933-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1675-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2975-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1342-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2115-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2187-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2388-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2984-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1410-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1799-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"824-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2267-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"938-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2289-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2373-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1685-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2614-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2791-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2154-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"764-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1209-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2134-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2283-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"863-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1743-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2065-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"143-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2444-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2875-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"796-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"671-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"742-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1431-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1782-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1991-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2390-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3043-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2351-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1742-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2067-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2447-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2884-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3122-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"677-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2270-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1231-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1838-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3001-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1578-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2125-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1624-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2811-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2732-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1092-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2175-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2837-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2420-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1281-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1717-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1495-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2459-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2913-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3080-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2882-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1272-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1722-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1450-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3130-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1482-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2924-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1508-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1710-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1913-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3124-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3127-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2078-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"626-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2428-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2906-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2246-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2958-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3071-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2040-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"286-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"888-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2057-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3049-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1780-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3083-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1327-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1464-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"850-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1309-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"760-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1910-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1387-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1144-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1934-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2098-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2740-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2073-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1571-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2481-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3016-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2424-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2557-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2365-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3076-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2238-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2492-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2119-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"830-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"701-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1384-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1248-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2233-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2581-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3110-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"203-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"730-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1370-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1407-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1891-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2525-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3060-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1510-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2129-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3050-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1469-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2357-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2696-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1252-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3115-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3134-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3066-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1385-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2208-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1402-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2514-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"919-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"987-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1068-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2536-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"657-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2299-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1699-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"889-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2311-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2969-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"791-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"810-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1391-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1223-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3139-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"707-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1792-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2552-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1855-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"858-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"809-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"922-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1646-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2033-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2659-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2671-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1249-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2587-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2050-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2561-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2128-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"665-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1354-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2747-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2465-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2334-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2265-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1057-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2778-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2526-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"816-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"870-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1733-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1067-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"174-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"712-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1103-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1633-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2675-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1451-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2335-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2361-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"145-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1310-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1808-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2415-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2812-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"739-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1325-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1844-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2680-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1119-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"600-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1197-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1881-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2221-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2046-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2855-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2998-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"294-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3010-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1606-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1389-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1215-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2359-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2648-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3935-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1671260","raw_amount":{"local_denom":"2132891"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3800"}]}}},"last_succesful":false},"3024-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2796-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1526-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1095-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2242-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2598-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2862-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2900-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1184-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"979-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"806-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1537-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2312-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1953-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3137-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"618-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"585-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1380-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1736-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2087-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"769-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2822-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2961-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1053-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1993-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1635-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2483-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1916-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2909-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2092-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3018-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1191-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"853-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2243-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2604-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2806-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1708-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2901-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2075-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1265-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2728-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"630-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1018-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1975-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1977-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3022-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"7-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5467943","raw_amount":{"local_denom":"4774382"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4"}]}}},"last_succesful":true},"2024-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3117-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1158-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1905-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2657-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"915-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"931-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1528-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"257-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2012-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1682-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2213-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2578-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2932-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3002-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1735-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1379-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1055-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1687-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1715-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1038-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1337-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"823-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"930-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1575-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2163-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2510-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1291-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2832-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2005-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2285-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1072-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2464-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2920-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2986-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"5-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1121876","raw_amount":{"local_denom":"981549"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3"}]}}},"last_succesful":true},"2409-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1668-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2107-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2316-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2452-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"648-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1084-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2083-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1967-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1143-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2356-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3013-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"790-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1406-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1188-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1559-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2769-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1274-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2775-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"886-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1213-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1775-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2576-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"840-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"957-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2534-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2960-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2579-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1416-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2926-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"187-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1896-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2965-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2026-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1496-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2400-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2658-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"734-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1164-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3123-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"753-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1588-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1893-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2734-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"935-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"768-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"959-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2887-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"230-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3958-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5222972","raw_amount":{"local_denom":"6665476"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3811"}]}}},"last_succesful":false},"802-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1239-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1767-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1196-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1020-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1987-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1076-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1899-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2983-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"926-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1167-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1207-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2575-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1060-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2490-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"893-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2790-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1568-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2839-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1574-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2212-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"878-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2467-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"832-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2863-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1399-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3008-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1004-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2122-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2412-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"668-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2866-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2788-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1051-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1493-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1108-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2637-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2864-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"911-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1826-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2871-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3012-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"972-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1268-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2520-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"917-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1070-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1517-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1847-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1643-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2333-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2102-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2501-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"765-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1019-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1251-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2219-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"6-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"1121876","raw_amount":{"lp_shares":"705229307494444"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3"}]},"705229307494444"]}},"last_succesful":true},"1885-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1161-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2772-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2836-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2860-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"820-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2867-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2823-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2890-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3135-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1978-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"947-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2461-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1819-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1871-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2368-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2176-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1760-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1850-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3057-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1005-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1116-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2844-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1318-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3061-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"807-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"879-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1981-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2582-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2891-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2974-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1003-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1098-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2819-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"759-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2448-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2948-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2430-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"142-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1580-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"854-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1969-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"693-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"750-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"895-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2528-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1307-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2025-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1194-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2426-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"594-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1049-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2423-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1297-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1647-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1292-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2590-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1278-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2417-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"9643809","raw_amount":{"local_denom":"12582024"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3071"}]}}},"last_succesful":false},"2712-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1579-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2344-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1592-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1202-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"206-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1466-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1692-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2199-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2505-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"655-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2731-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2982-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2711-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2515-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3006-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"197-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2431-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2798-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1751-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1933-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2629-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2841-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1771-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2964-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1113-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3105-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2872-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1538-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2290-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2764-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2761-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1641-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3038-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3019-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2689-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2954-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3109-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2161-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2677-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1705-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1798-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1163-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2779-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1244-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1434-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1094-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2583-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1884-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2899-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1160-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"846-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1169-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2455-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1021-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2410-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2418-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1129-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2004-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2527-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2801-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1763-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2153-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1204-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1206-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1479-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1536-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1601-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1042-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1353-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2758-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1064-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"951-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1382-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"901-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2996-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2042-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2191-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2903-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2417-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1806-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2454-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"927-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"221-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"741-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2383-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1679-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2244-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3126-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"674-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2305-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2759-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1903-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3088-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2880-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"634-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2968-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3111-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1289-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1658-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1773-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2722-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2993-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1817-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2241-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2690-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"929-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1075-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1853-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2130-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"194-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"704-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1565-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1922-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1762-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2314-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2956-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"982-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1303-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"737-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"709-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1445-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3011-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2688-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2101-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1234-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"778-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2656-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1357-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3144-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"761-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2935-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2062-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1484-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2923-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"747-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1126-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1284-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1582-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1609-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1613-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1242-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1689-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2944-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3108-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1159-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"859-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1068-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27572493","raw_amount":{"local_denom":"36899908"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2266"}]}}},"last_succesful":false},"1541-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1920-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2378-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2585-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1218-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3106-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"897-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3020-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2145-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1127-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1173-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1976-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1073-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1427-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2131-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2419-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2869-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"945-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1305-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1662-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2001-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2207-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2503-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2990-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1367-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"872-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1644-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1264-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1935-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1230-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1121-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1618-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1994-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2032-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2090-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3129-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2376-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2994-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1062-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"829-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1355-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1017-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"912-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1860-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1912-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1954-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2222-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2531-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1666-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1765-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1937-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2596-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2814-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1630-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3037-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3081-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1271-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"732-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1467-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2726-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1791-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"860-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1721-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1316-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2322-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1972-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"923-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2902-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1711-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2085-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2929-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2987-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1673-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1397-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2239-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1446-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2715-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2721-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1102-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"733-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1378-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2084-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1214-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2341-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2381-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2955-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2044-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2178-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"881-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1777-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2211-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1081-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2354-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2992-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1277-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3136-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1377-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2930-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"718-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1744-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2366-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2941-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3055-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"812-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"976-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2170-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1519-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2588-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2450-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1269-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1876-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1308-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2255-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2296-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1418-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2830-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"952-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3090-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2149-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1546-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"899-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1276-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2518-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2636-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1381-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2545-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1942-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2029-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2569-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"13-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"begin_unlocking":[[{"lp_shares":"567995093018743","primitive_shares":"1075915","owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","id":"5"},{"lp_shares":"267990275290950","primitive_shares":"507636","owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","id":"11"}],"835985368309693"]}},"last_succesful":true},"2783-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"344-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"30549409","raw_amount":{"local_denom":"43106797"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1691"}]}}},"last_succesful":false},"2601-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"980-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2041-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1110-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1929-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1676-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"988-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2192-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1776-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2257-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2429-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2220-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"565-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2056-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5913840","raw_amount":{"local_denom":"7746697"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2886"}]}}},"last_succesful":false},"1448-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1728-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"981-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3121-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1322-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1137-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1949-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1572-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2800-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2892-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"862-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1117-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1200-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1573-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1288-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1796-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2554-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2608-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3140-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2035-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2549-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1061-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2708-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2188-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1088-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2277-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2669-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"708-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1266-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2317-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1694-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"990-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1845-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1947-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3099-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1548-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2584-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2340-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3084-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1460-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2586-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1222-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2268-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"775-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1096-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2472-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2404-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2947-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2692-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3145-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1294-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1539-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1856-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1944-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2166-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1522-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2230-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"797-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1985-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"692-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1594-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1886-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1554-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1671-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"746-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1690-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1473-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1174-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2005-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"560376597","raw_amount":{"local_denom":"734446767"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2860"}]}}},"last_succesful":false},"2146-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1700-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2181-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2196-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2504-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2670-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2603-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2076-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2795-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2541-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"948-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2850-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2943-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3078-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3116-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1779-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2893-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2873-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3070-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1151-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2792-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2885-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1963-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1908-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"756-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2248-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2684-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"740-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1950-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1598-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1627-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2451-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"270-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2264-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2434-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1888-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2651-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1287-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3025-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"714-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2635-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1553-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2209-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1623-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1581-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2021-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2143-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2047-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3112-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2173-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2150-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2649-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2665-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1667-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2859-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"229-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1914-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2988-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1392-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3069-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"892-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1650-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2403-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1766-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1836-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2097-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2353-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1329-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2925-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1718-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3033-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"876-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"485317410","raw_amount":{"local_denom":"653150114"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2111"},{"claim_amount":"125454550","raw_amount":{"local_denom":"168839304"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2112"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2113"},{"claim_amount":"1455951","raw_amount":{"local_denom":"1959450"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2115"},{"claim_amount":"120844034","raw_amount":{"local_denom":"162634378"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2116"},{"claim_amount":"6114999","raw_amount":{"local_denom":"8229691"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2117"},{"claim_amount":"9706348","raw_amount":{"local_denom":"13063002"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2118"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2119"},{"claim_amount":"48046423","raw_amount":{"local_denom":"64661861"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2120"},{"claim_amount":"5289959","raw_amount":{"local_denom":"7119336"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2121"},{"claim_amount":"1892737","raw_amount":{"local_denom":"2547285"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2122"},{"claim_amount":"4319324","raw_amount":{"local_denom":"5813036"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2123"},{"claim_amount":"33244242","raw_amount":{"local_denom":"44740782"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2124"},{"claim_amount":"4756110","raw_amount":{"local_denom":"6400871"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2125"},{"claim_amount":"582380","raw_amount":{"local_denom":"783780"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2126"},{"claim_amount":"8250395","raw_amount":{"local_denom":"11103551"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2127"},{"claim_amount":"4804642","raw_amount":{"local_denom":"6466186"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2128"},{"claim_amount":"9803411","raw_amount":{"local_denom":"13193632"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2129"},{"claim_amount":"72312294","raw_amount":{"local_denom":"97319367"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2130"},{"claim_amount":"61489715","raw_amount":{"local_denom":"82754119"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2131"},{"claim_amount":"527540025","raw_amount":{"local_denom":"709974174"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2132"},{"claim_amount":"421740829","raw_amount":{"local_denom":"567587449"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2133"},{"claim_amount":"26692457","raw_amount":{"local_denom":"35923256"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2134"},{"claim_amount":"3154562","raw_amount":{"local_denom":"4245475"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2135"},{"claim_amount":"10191665","raw_amount":{"local_denom":"13716152"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2136"},{"claim_amount":"3470019","raw_amount":{"local_denom":"4670023"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2137"},{"claim_amount":"2098997802","raw_amount":{"local_denom":"2824874245"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2138"},{"claim_amount":"24265870","raw_amount":{"local_denom":"32657505"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2139"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2140"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2141"},{"claim_amount":"247997196","raw_amount":{"local_denom":"333759708"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2142"},{"claim_amount":"2426586","raw_amount":{"local_denom":"3265750"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2143"},{"claim_amount":"9706348","raw_amount":{"local_denom":"13063002"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2144"},{"claim_amount":"970634","raw_amount":{"local_denom":"1306300"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2145"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2146"},{"claim_amount":"2654686","raw_amount":{"local_denom":"3572731"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2147"},{"claim_amount":"3397221","raw_amount":{"local_denom":"4572050"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2148"},{"claim_amount":"4367856","raw_amount":{"local_denom":"5878351"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2149"},{"claim_amount":"8007736","raw_amount":{"local_denom":"10776976"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2150"},{"claim_amount":"485317","raw_amount":{"local_denom":"653150"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2151"},{"claim_amount":"2892491","raw_amount":{"local_denom":"3892774"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2152"},{"claim_amount":"48483209","raw_amount":{"local_denom":"65249696"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2153"}]}}},"last_succesful":false},"2225-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2293-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1254-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2605-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1221-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1655-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2247-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1931-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1465-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"978-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1035-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1433-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1713-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1756-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1166-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1540-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2205-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1010-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1168-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2661-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2259-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"722-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1560-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2422-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1670-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2957-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"642-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2727-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"659-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1611-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1120-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1907-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1138-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2678-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1507-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2898-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2782-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1800-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2018-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2556-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1480-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2701-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2352-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2458-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2530-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1750-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1065-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2318-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2303-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1066-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2710-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2148-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"910-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2619-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1363-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2203-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"918-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1925-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"695-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4784858","raw_amount":{"local_denom":"6521340"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2018"}]}}},"last_succesful":false},"1945-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2632-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1155-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1831-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"301-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1314-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2616-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1455-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1481-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1834-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2160-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2034-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1001-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"803-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1612-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1797-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1148-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"788-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1535-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1372-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2182-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2116-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2686-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1986-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1663-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1822-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1740-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2733-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"688-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"813-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"751-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2474-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"745-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1827-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1458-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2284-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2704-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"781-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1198-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1788-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1226-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1128-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1602-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2015-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2158-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1968-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2329-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2627-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2787-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1124-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1684-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1549-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2469-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2348-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2389-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1224-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"9-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5467943","raw_amount":{"local_denom":"4774382"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4"}]}}},"last_succesful":true},"2049-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2099-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"986-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2919-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1139-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1992-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1723-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3004-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2828-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3143-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"754-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2831-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2851-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"956-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"954-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1063-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"624-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1383-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1488-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1556-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1738-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2027-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2054-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1185-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2394-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2953-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2966-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3028-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3047-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"774-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"782-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"743-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1236-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2189-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2126-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2580-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1746-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"629-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"256-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2253-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2846-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1529-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1500-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"711-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1880-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2195-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2544-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"995-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2281-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2342-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2301-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2321-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1805-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2821-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"841-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2626-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1052-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2036-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1789-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2432-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2794-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3062-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2870-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1531-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2803-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1747-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1513-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2210-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1220-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2717-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"794-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2817-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3021-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1487-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1712-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2399-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2229-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1344-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"949-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1811-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2407-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2477-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1803-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2703-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2852-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2384-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2874-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3029-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3046-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2495-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2152-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"728-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"225-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1186-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3103-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"555-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"700-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"762-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1438-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1545-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2752-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2433-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1849-channel-35":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"3499077","raw_amount":{"local_denom":"4617248"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2667"}]}}},"last_succesful":false},"2865-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2139-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2141-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"557-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1149-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2565-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3086-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2197-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1892-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2914-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2630-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"932-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"710-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1132-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1626-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1958-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2121-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2724-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1622-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2193-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1263-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2231-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2653-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1157-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2617-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3032-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1172-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2194-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"849-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1558-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1859-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2064-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1034-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2236-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2895-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2260-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2976-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1027-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1533-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"297-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1080-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2095-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3063-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1814-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3113-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3052-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"784-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1768-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2535-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2539-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1615-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2962-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1812-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2298-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2088-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2217-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2638-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2144-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1610-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2777-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"10-undefined":{"error":"codespace: wasm, code: 5","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"6"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"7"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"8"},{"claim_amount":"1021466","raw_amount":{"local_denom":"999889"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"9"},{"claim_amount":"510732","raw_amount":{"local_denom":"499944"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"10"}]}}},"last_succesful":true},"2749-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2200-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1006-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2093-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1955-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2355-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1179-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"748-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1054-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"908-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"826-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2915-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"914-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1335-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2809-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"744-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2326-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1801-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"835-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2086-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1995-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1607-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2179-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"883-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2573-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2908-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1865-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2159-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"828-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1764-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2854-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"608-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1232-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1917-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2369-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2918-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2226-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1999-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"819-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2405-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1409-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1299-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2663-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2291-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2971-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1421-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1973-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"798-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2820-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2017-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2237-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1026-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1628-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1939-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2294-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2524-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2834-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1016-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2269-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2271-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1229-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3118-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"909-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1333-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1672-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2816-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1262-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1320-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"164-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"991-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1211-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1724-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3132-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2776-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1839-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"159-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1982-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2921-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1036-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1177-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1491-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1639-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2006-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2060-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"287-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"763-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"880-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3082-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"260-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1702-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1783-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1109-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1349-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1761-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2967-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2662-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2517-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2959-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2719-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"723-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1259-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1726-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1965-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2928-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1362-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3026-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2421-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"605-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"937-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1189-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2494-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2625-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2643-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2453-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1901-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1755-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1769-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1499-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1368-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1749-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1524-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2845-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"660-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"799-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1904-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2183-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"998-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1437-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1547-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2370-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2371-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1358-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2848-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"934-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1414-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2713-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"715-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2760-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"201-undefined":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1356-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1674-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1998-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2765-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2446-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1146-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3077-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"866-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2325-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1651-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2762-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"3014-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1625-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1849-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2751-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2755-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1600-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1961-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"680-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1162-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1752-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"685-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2543-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"1044-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true},"2568-channel-15":{"error":"codespace: wasm, code: 5","step":"icq","last_succesful":true}}}} diff --git a/smart-contracts/migrations/migration-005/7fv_trapped_errors.json b/smart-contracts/migrations/migration-005/7fv_trapped_errors.json deleted file mode 100644 index 2cfe64b00..000000000 --- a/smart-contracts/migrations/migration-005/7fv_trapped_errors.json +++ /dev/null @@ -1 +0,0 @@ -{"data":{"errors":{"3425-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1706356","raw_amount":{"local_denom":"1022534"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3569"}]}}},"last_succesful":false},"187-undefined":{"error":"packet failure: timeout","step":"icq","last_succesful":false},"8-undefined":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5458134","raw_amount":{"local_denom":"3794876"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4"}]}}},"last_succesful":false},"264-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454028","raw_amount":{"local_denom":"326612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1596"}]}}},"last_succesful":false},"265-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454125","raw_amount":{"local_denom":"326654"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1597"}]}}},"last_succesful":false},"1821-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"3498440","raw_amount":{"local_denom":"2227939"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2667"}]}}},"last_succesful":false},"1702-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"67387761","raw_amount":{"local_denom":"43186885"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2608"}]}}},"last_succesful":false},"274-channel-25":{"error":"packet failure: timeout","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"638834","raw_amount":{"lp_shares":"47745019338281363"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"490"}]},"47745019338281363"]}},"last_succesful":false},"1042-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27574028","raw_amount":{"local_denom":"17987877"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2266"}]}}},"last_succesful":false},"14-undefined":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"28970931","raw_amount":{"local_denom":"22477403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"13"}]}}},"last_succesful":false},"849-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"485643187","raw_amount":{"local_denom":"324236968"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2111"},{"claim_amount":"125538763","raw_amount":{"local_denom":"83815256"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2112"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2113"},{"claim_amount":"1456928","raw_amount":{"local_denom":"972710"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2115"},{"claim_amount":"120925153","raw_amount":{"local_denom":"80735005"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2116"},{"claim_amount":"6119102","raw_amount":{"local_denom":"4085385"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2117"},{"claim_amount":"9712863","raw_amount":{"local_denom":"6484739"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2118"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2119"},{"claim_amount":"48078674","raw_amount":{"local_denom":"32099459"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2120"},{"claim_amount":"5293509","raw_amount":{"local_denom":"3534182"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2121"},{"claim_amount":"1894008","raw_amount":{"local_denom":"1264524"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2122"},{"claim_amount":"4322224","raw_amount":{"local_denom":"2885709"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2123"},{"claim_amount":"33266557","raw_amount":{"local_denom":"22210232"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2124"},{"claim_amount":"4759302","raw_amount":{"local_denom":"3177522"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2125"},{"claim_amount":"582771","raw_amount":{"local_denom":"389084"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2126"},{"claim_amount":"8255933","raw_amount":{"local_denom":"5512028"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2127"},{"claim_amount":"4807866","raw_amount":{"local_denom":"3209945"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2128"},{"claim_amount":"9809991","raw_amount":{"local_denom":"6549586"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2129"},{"claim_amount":"72360834","raw_amount":{"local_denom":"48311308"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2130"},{"claim_amount":"61530990","raw_amount":{"local_denom":"41080823"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2131"},{"claim_amount":"527894144","raw_amount":{"local_denom":"352445584"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2132"},{"claim_amount":"422023929","raw_amount":{"local_denom":"281761925"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2133"},{"claim_amount":"26710374","raw_amount":{"local_denom":"17833033"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2134"},{"claim_amount":"3156680","raw_amount":{"local_denom":"2107540"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2135"},{"claim_amount":"10198506","raw_amount":{"local_denom":"6808976"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2136"},{"claim_amount":"3472348","raw_amount":{"local_denom":"2318294"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2137"},{"claim_amount":"2100406787","raw_amount":{"local_denom":"1402324887"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2138"},{"claim_amount":"24282158","raw_amount":{"local_denom":"16211848"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2139"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2140"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2141"},{"claim_amount":"248163668","raw_amount":{"local_denom":"165685090"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2142"},{"claim_amount":"2428214","raw_amount":{"local_denom":"1621184"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2143"},{"claim_amount":"9712863","raw_amount":{"local_denom":"6484739"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2144"},{"claim_amount":"971284","raw_amount":{"local_denom":"648473"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2145"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2146"},{"claim_amount":"2656467","raw_amount":{"local_denom":"1773576"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2147"},{"claim_amount":"3399501","raw_amount":{"local_denom":"2269658"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2148"},{"claim_amount":"4370787","raw_amount":{"local_denom":"2918132"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2149"},{"claim_amount":"8013111","raw_amount":{"local_denom":"5349909"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2150"},{"claim_amount":"485641","raw_amount":{"local_denom":"324236"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2151"},{"claim_amount":"2894432","raw_amount":{"local_denom":"1932452"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2152"},{"claim_amount":"48515754","raw_amount":{"local_denom":"32391273"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2153"}]}}},"last_succesful":false},"2032-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"60644255","raw_amount":{"local_denom":"37846350"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2888"}]}}},"last_succesful":false},"1124-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"983685","raw_amount":{"local_denom":"640989"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2308"}]}}},"last_succesful":false},"2282-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4056026","raw_amount":{"local_denom":"2517509"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3017"}]}}},"last_succesful":false},"3908-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1671264","raw_amount":{"local_denom":"993814"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3800"}]}}},"last_succesful":false},"668-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4786143","raw_amount":{"local_denom":"3247407"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2018"}]}}},"last_succesful":false},"826-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"11451515","raw_amount":{"local_denom":"7647023"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2100"}]}}},"last_succesful":false},"3931-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"5222809","raw_amount":{"local_denom":"3105693"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3811"}]}}},"last_succesful":false},"4315-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"390405500","raw_amount":{"local_denom":"235513087"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4006"}]}}},"last_succesful":false},"94-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1503699649","raw_amount":{"local_denom":"1041062698"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1468"}]}}},"last_succesful":false},"1511-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"36600805","raw_amount":{"local_denom":"23489120"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2514"}]}}},"last_succesful":false},"1878-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"9052782","raw_amount":{"local_denom":"5703801"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2787"}]}}},"last_succesful":false},"2390-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"9644400","raw_amount":{"local_denom":"5978998"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3071"}]}}},"last_succesful":false},"317-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"30552830","raw_amount":{"local_denom":"21686062"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1691"}]}}},"last_succesful":false},"2041-channel-33":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27369824","raw_amount":{"local_denom":"17017111"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2893"}]}}},"last_succesful":false}}}} diff --git a/smart-contracts/migrations/migration-005/bond_ids.json b/smart-contracts/migrations/migration-005/bond_ids.json deleted file mode 100644 index ddffc8625..000000000 --- a/smart-contracts/migrations/migration-005/bond_ids.json +++ /dev/null @@ -1 +0,0 @@ -{"prim1": [["2991-channel-32", "3375"], ["1046-channel-32", "2266"], ["1128-channel-32", "2308"], ["1827-channel-32", "2667"], ["321-channel-32", "1691"], ["2036-channel-32", "2888"], ["2045-channel-32", "2893"], ["268-channel-32", "1596"], ["98-channel-32", "1468"], ["269-channel-32", "1597"], ["672-channel-32", "2018"], ["830-channel-32", "2100"], ["1884-channel-32", "2787"], ["1981-channel-32", "2860"], ["2021-channel-32", "2879"], ["4322-channel-32", "4006"], ["2286-channel-32", "3017"], ["853-channel-32", "2111"], ["853-channel-32", "2112"], ["853-channel-32", "2113"], ["853-channel-32", "2115"], ["853-channel-32", "2116"], ["853-channel-32", "2117"], ["853-channel-32", "2118"], ["853-channel-32", "2119"], ["853-channel-32", "2120"], ["853-channel-32", "2121"], ["853-channel-32", "2122"], ["853-channel-32", "2123"], ["853-channel-32", "2124"], ["853-channel-32", "2125"], ["853-channel-32", "2126"], ["853-channel-32", "2127"], ["853-channel-32", "2128"], ["853-channel-32", "2129"], ["853-channel-32", "2130"], ["853-channel-32", "2131"], ["853-channel-32", "2132"], ["853-channel-32", "2133"], ["853-channel-32", "2134"], ["853-channel-32", "2135"], ["853-channel-32", "2136"], ["853-channel-32", "2137"], ["853-channel-32", "2138"], ["853-channel-32", "2139"], ["853-channel-32", "2140"], ["853-channel-32", "2141"], ["853-channel-32", "2142"], ["853-channel-32", "2143"], ["853-channel-32", "2144"], ["853-channel-32", "2145"], ["853-channel-32", "2146"], ["853-channel-32", "2147"], ["853-channel-32", "2148"], ["853-channel-32", "2149"], ["853-channel-32", "2150"], ["853-channel-32", "2151"], ["853-channel-32", "2152"], ["853-channel-32", "2153"]], "prim2": [["3425-channel-33", "3569"], ["264-channel-33", "1596"], ["265-channel-33", "1597"], ["1821-channel-33", "2667"], ["1702-channel-33", "2608"], ["1042-channel-33", "2266"], ["849-channel-33", "2111"], ["849-channel-33", "2112"], ["849-channel-33", "2113"], ["849-channel-33", "2115"], ["849-channel-33", "2116"], ["849-channel-33", "2117"], ["849-channel-33", "2118"], ["849-channel-33", "2119"], ["849-channel-33", "2120"], ["849-channel-33", "2121"], ["849-channel-33", "2122"], ["849-channel-33", "2123"], ["849-channel-33", "2124"], ["849-channel-33", "2125"], ["849-channel-33", "2126"], ["849-channel-33", "2127"], ["849-channel-33", "2128"], ["849-channel-33", "2129"], ["849-channel-33", "2130"], ["849-channel-33", "2131"], ["849-channel-33", "2132"], ["849-channel-33", "2133"], ["849-channel-33", "2134"], ["849-channel-33", "2135"], ["849-channel-33", "2136"], ["849-channel-33", "2137"], ["849-channel-33", "2138"], ["849-channel-33", "2139"], ["849-channel-33", "2140"], ["849-channel-33", "2141"], ["849-channel-33", "2142"], ["849-channel-33", "2143"], ["849-channel-33", "2144"], ["849-channel-33", "2145"], ["849-channel-33", "2146"], ["849-channel-33", "2147"], ["849-channel-33", "2148"], ["849-channel-33", "2149"], ["849-channel-33", "2150"], ["849-channel-33", "2151"], ["849-channel-33", "2152"], ["849-channel-33", "2153"], ["2032-channel-33", "2888"], ["1124-channel-33", "2308"], ["2282-channel-33", "3017"], ["3908-channel-33", "3800"], ["668-channel-33", "2018"], ["826-channel-33", "2100"], ["3931-channel-33", "3811"], ["4315-channel-33", "4006"], ["94-channel-33", "1468"], ["1511-channel-33", "2514"], ["1878-channel-33", "2787"], ["2390-channel-33", "3071"], ["317-channel-33", "1691"], ["2041-channel-33", "2893"]], "prim3": [["2059-channel-35", "2888"], ["2068-channel-35", "2893"], ["4344-channel-35", "4006"], ["924-channel-35", "2194"], ["1150-channel-35", "2308"], ["1908-channel-35", "2787"], ["2309-channel-35", "3017"], ["853-channel-35", "2100"], ["2045-channel-35", "2879"], ["3935-channel-35", "3800"], ["3958-channel-35", "3811"], ["2417-channel-35", "3071"], ["1068-channel-35", "2266"], ["344-channel-35", "1691"], ["2056-channel-35", "2886"], ["2005-channel-35", "2860"], ["876-channel-35", "2111"], ["876-channel-35", "2112"], ["876-channel-35", "2113"], ["876-channel-35", "2115"], ["876-channel-35", "2116"], ["876-channel-35", "2117"], ["876-channel-35", "2118"], ["876-channel-35", "2119"], ["876-channel-35", "2120"], ["876-channel-35", "2121"], ["876-channel-35", "2122"], ["876-channel-35", "2123"], ["876-channel-35", "2124"], ["876-channel-35", "2125"], ["876-channel-35", "2126"], ["876-channel-35", "2127"], ["876-channel-35", "2128"], ["876-channel-35", "2129"], ["876-channel-35", "2130"], ["876-channel-35", "2131"], ["876-channel-35", "2132"], ["876-channel-35", "2133"], ["876-channel-35", "2134"], ["876-channel-35", "2135"], ["876-channel-35", "2136"], ["876-channel-35", "2137"], ["876-channel-35", "2138"], ["876-channel-35", "2139"], ["876-channel-35", "2140"], ["876-channel-35", "2141"], ["876-channel-35", "2142"], ["876-channel-35", "2143"], ["876-channel-35", "2144"], ["876-channel-35", "2145"], ["876-channel-35", "2146"], ["876-channel-35", "2147"], ["876-channel-35", "2148"], ["876-channel-35", "2149"], ["876-channel-35", "2150"], ["876-channel-35", "2151"], ["876-channel-35", "2152"], ["876-channel-35", "2153"], ["695-channel-35", "2018"], ["1849-channel-35", "2667"]]} \ No newline at end of file diff --git a/smart-contracts/migrations/migration-005/fps_trapped_errors.json b/smart-contracts/migrations/migration-005/fps_trapped_errors.json deleted file mode 100644 index 19ca18e59..000000000 --- a/smart-contracts/migrations/migration-005/fps_trapped_errors.json +++ /dev/null @@ -1 +0,0 @@ -{"data":{"errors":{"2991-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"2564060","raw_amount":{"local_denom":"114861"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3375"}]}}},"last_succesful":false},"1046-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27574007","raw_amount":{"local_denom":"1262214"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2266"}]}}},"last_succesful":false},"1128-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"983678","raw_amount":{"local_denom":"45033"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2308"}]}}},"last_succesful":false},"1827-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"3499006","raw_amount":{"local_denom":"154811"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2667"}]}}},"last_succesful":false},"15-undefined":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"28971416","raw_amount":{"local_denom":"6982413"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"13"}]}}},"last_succesful":false},"321-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"30550338","raw_amount":{"local_denom":"1607140"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1691"}]}}},"last_succesful":false},"2036-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"60636582","raw_amount":{"local_denom":"2703441"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2888"}]}}},"last_succesful":false},"2045-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"27380214","raw_amount":{"local_denom":"1213999"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2893"}]}}},"last_succesful":false},"268-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454111","raw_amount":{"local_denom":"24594"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1596"}]}}},"last_succesful":false},"98-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"1503723755","raw_amount":{"local_denom":"79003403"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1468"}]}}},"last_succesful":false},"188-undefined":{"error":"packet failure: timeout","step":"icq","last_succesful":false},"269-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"454093","raw_amount":{"local_denom":"24592"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"1597"}]}}},"last_succesful":false},"672-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4785365","raw_amount":{"local_denom":"231252"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2018"}]}}},"last_succesful":false},"830-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"11450657","raw_amount":{"local_denom":"533184"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2100"}]}}},"last_succesful":false},"1884-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"9054065","raw_amount":{"local_denom":"407829"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2787"}]}}},"last_succesful":false},"274-channel-23":{"error":"packet failure: timeout","step":{"ica":{"lock_tokens":[{"bonds":[{"claim_amount":"638939","raw_amount":{"lp_shares":"178691736047696401"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"490"}]},"178691736047696401"]}},"last_succesful":false},"1981-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"560372297","raw_amount":{"local_denom":"24878611"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2860"}]}}},"last_succesful":false},"2021-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"3992882","raw_amount":{"local_denom":"177898"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2879"}]}}},"last_succesful":false},"4322-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"390380141","raw_amount":{"local_denom":"17012790"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"4006"}]}}},"last_succesful":false},"2286-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"4056380","raw_amount":{"local_denom":"185905"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"3017"}]}}},"last_succesful":false},"853-channel-32":{"error":"packet failure: ABCI code: 29: error handling packet: see events for details","step":{"ica":{"join_swap_extern_amount_in":{"bonds":[{"claim_amount":"484187518","raw_amount":{"local_denom":"22612917"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2111"},{"claim_amount":"125162472","raw_amount":{"local_denom":"5845439"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2112"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2113"},{"claim_amount":"1452546","raw_amount":{"local_denom":"67838"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2115"},{"claim_amount":"120562684","raw_amount":{"local_denom":"5630616"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2116"},{"claim_amount":"6100746","raw_amount":{"local_denom":"284922"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2117"},{"claim_amount":"9683743","raw_amount":{"local_denom":"452258"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2118"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2119"},{"claim_amount":"47934547","raw_amount":{"local_denom":"2238678"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2120"},{"claim_amount":"5277626","raw_amount":{"local_denom":"246480"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2121"},{"claim_amount":"1888323","raw_amount":{"local_denom":"88190"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2122"},{"claim_amount":"4309248","raw_amount":{"local_denom":"201254"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2123"},{"claim_amount":"33166827","raw_amount":{"local_denom":"1548984"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2124"},{"claim_amount":"4745025","raw_amount":{"local_denom":"221606"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2125"},{"claim_amount":"581014","raw_amount":{"local_denom":"27135"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2126"},{"claim_amount":"8231175","raw_amount":{"local_denom":"384419"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2127"},{"claim_amount":"4793437","raw_amount":{"local_denom":"223867"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2128"},{"claim_amount":"9780568","raw_amount":{"local_denom":"456780"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2129"},{"claim_amount":"72143926","raw_amount":{"local_denom":"3369324"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2130"},{"claim_amount":"61346546","raw_amount":{"local_denom":"2865056"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2131"},{"claim_amount":"526311837","raw_amount":{"local_denom":"24580241"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2132"},{"claim_amount":"420758956","raw_amount":{"local_denom":"19650625"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2133"},{"claim_amount":"26630304","raw_amount":{"local_denom":"1243710"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2134"},{"claim_amount":"3147198","raw_amount":{"local_denom":"146983"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2135"},{"claim_amount":"10167932","raw_amount":{"local_denom":"474871"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2136"},{"claim_amount":"3461933","raw_amount":{"local_denom":"161682"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2137"},{"claim_amount":"2094111037","raw_amount":{"local_denom":"97800867"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2138"},{"claim_amount":"24209357","raw_amount":{"local_denom":"1130645"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2139"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2140"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2141"},{"claim_amount":"247419809","raw_amount":{"local_denom":"11555200"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2142"},{"claim_amount":"2420925","raw_amount":{"local_denom":"113064"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2143"},{"claim_amount":"9683743","raw_amount":{"local_denom":"452258"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2144"},{"claim_amount":"968357","raw_amount":{"local_denom":"45225"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2145"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2146"},{"claim_amount":"2648491","raw_amount":{"local_denom":"123692"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2147"},{"claim_amount":"3389303","raw_amount":{"local_denom":"158290"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2148"},{"claim_amount":"4357682","raw_amount":{"local_denom":"203516"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2149"},{"claim_amount":"7989091","raw_amount":{"local_denom":"373113"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2150"},{"claim_amount":"484167","raw_amount":{"local_denom":"22612"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2151"},{"claim_amount":"2885736","raw_amount":{"local_denom":"134772"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2152"},{"claim_amount":"48370324","raw_amount":{"local_denom":"2259030"},"owner":"quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu","bond_id":"2153"}]}}},"last_succesful":false}}}} diff --git a/smart-contracts/migrations/migration-005/traps_to_delete.py b/smart-contracts/migrations/migration-005/traps_to_delete.py deleted file mode 100644 index d1e1228a4..000000000 --- a/smart-contracts/migrations/migration-005/traps_to_delete.py +++ /dev/null @@ -1,115 +0,0 @@ -import json -import subprocess -import re - - -def run_command(command): - process = subprocess.Popen( - command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - output, error = process.communicate() - return output.decode('utf-8'), error.decode('utf-8') - - -prim1 = "quasar1kj8q8g2pmhnagmfepp9jh9g2mda7gzd0m5zdq0s08ulvac8ck4dq9ykfps" -prim2 = "quasar1ma0g752dl0yujasnfs9yrk6uew7d0a2zrgvg62cfnlfftu2y0egqx8e7fv" -prim3 = "quasar1ery8l6jquynn9a4cz2pff6khg8c68f7urt33l5n9dng2cwzz4c4qxhm6a2" -node = "--node https://quasar-rpc.polkachu.com:443 --chain-id quasar-1 -o json" -query = '\'{\"trapped_errors\": {}}\'' - -# Create a dictionary to store bond_id lists -bond_ids = {"prim1": [], "prim2": [], "prim3": []} - -for i, prim in enumerate([prim1, prim2, prim3]): - output, error = run_command( - f'quasard q wasm contract-state smart {prim} {query} {node} | tee {prim[-3:]}_trapped_errors.json') - - data = json.loads(output) if not error else print( - 'Error executing command 1:', error) - - # Get the errors from the data - errors = data["data"]["errors"] - - # Iterate over the errors - for key, value in errors.items(): - # Check if key matches the desired format - if re.match(r'\d+-channel-\d+', key): - # If the error includes 'step' data - if 'step' in value and isinstance(value['step'], dict): - steps = value['step'] - - # Check if steps includes 'ica' data - if 'ica' in steps: - ica = steps['ica'] - - # Check if ica includes 'join_swap_extern_amount_in' data - if 'join_swap_extern_amount_in' in ica: - join_swap = ica['join_swap_extern_amount_in'] - - # Check if join_swap includes 'bonds' data - if 'bonds' in join_swap: - bonds = join_swap['bonds'] - - # Iterate over the bonds - for bond in bonds: - # If bond includes 'bond_id' - if 'bond_id' in bond: - bond_id = bond['bond_id'] - - # Add the tuple (key, bond_id) to the appropriate list - bond_ids[f"prim{i+1}"].append( - (key, bond_id)) - -# save all bond_ids, per primitive, to a json file -with open('bond_ids.json', 'w') as f: - json.dump(bond_ids, f) - -vault = "quasar18a2u6az6dzw528rptepfg6n49ak6hdzkf8ewf0n5r0nwju7gtdgqamr7qu" - -# get bond_ids that are null for prim1 -null_ids_prim1 = [] -for id in bond_ids['prim1']: - output, error = run_command( - f'quasard q wasm contract-state smart {vault} \'{{"pending_bonds_by_id": {{"bond_id": "{id[1]}"}}}}\' {node}') - if ':null' in output: - null_ids_prim1.append(id) - -# get bond_ids that are null for prim2 -null_ids_prim2 = [] -for id in bond_ids['prim2']: - output, error = run_command( - f'quasard q wasm contract-state smart {vault} \'{{"pending_bonds_by_id": {{"bond_id": "{id[1]}"}}}}\' {node}') - if ':null' in output: - null_ids_prim2.append(id) - -# get bond_ids that are null for prim3 -null_ids_prim3 = [] -for id in bond_ids['prim3']: - output, error = run_command( - f'quasard q wasm contract-state smart {vault} \'{{"pending_bonds_by_id": {{"bond_id": "{id[1]}"}}}}\' {node}') - if ':null' in output: - null_ids_prim3.append(id) - -print(f'PRIM1: {null_ids_prim1}') -print(f'PRIM2: {null_ids_prim2}') -print(f'PRIM3: {null_ids_prim3}') - -# Filter bond_ids for each primitive by checking if each tuple is not in the corresponding null_ids list - -filtered_bond_ids_prim1 = [ - id for id in bond_ids['prim1'] if id not in null_ids_prim1] -filtered_bond_ids_prim2 = [ - id for id in bond_ids['prim2'] if id not in null_ids_prim2] -filtered_bond_ids_prim3 = [ - id for id in bond_ids['prim3'] if id not in null_ids_prim3] - -# Print filtered bond_ids -print("Filtered bond_ids for prim1:", filtered_bond_ids_prim1) -print("Filtered bond_ids for prim2:", filtered_bond_ids_prim2) -print("Filtered bond_ids for prim3:", filtered_bond_ids_prim3) - -print("Number of filtered bond_ids for prim1:", len(filtered_bond_ids_prim1)) -print("Number of unfiltered bond_ids for prim1:", len(bond_ids['prim1'])) -print("Number of filtered bond_ids for prim2:", len(filtered_bond_ids_prim2)) -print("Number of unfiltered bond_ids for prim2:", len(bond_ids['prim2'])) -print("Number of filtered bond_ids for prim3:", len(filtered_bond_ids_prim3)) -print("Number of unfiltered bond_ids for prim3:", len(bond_ids['prim3'])) diff --git a/smart-contracts/osmosis/.cargo/config.toml b/smart-contracts/osmosis/.cargo/config.toml new file mode 100644 index 000000000..7ad1f6f91 --- /dev/null +++ b/smart-contracts/osmosis/.cargo/config.toml @@ -0,0 +1,6 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +schema = "run --example schema" +lint = "clippy --all-targets -- -D warnings" +lint-fix = "clippy --all-targets --fix -- -D warnings" +unit-test = "test --lib" \ No newline at end of file diff --git a/smart-contracts/Cargo.toml b/smart-contracts/osmosis/Cargo.toml similarity index 80% rename from smart-contracts/Cargo.toml rename to smart-contracts/osmosis/Cargo.toml index 270f37c13..f50ea5c37 100644 --- a/smart-contracts/Cargo.toml +++ b/smart-contracts/osmosis/Cargo.toml @@ -1,23 +1,7 @@ [workspace] resolver = "2" -members = [ - # "contracts/icq", - # "contracts/ibc-transfer", - # "contracts/intergamm-bindings-test", - # "contracts/airdrop", - # "contracts/lp-strategy", - # "contracts/basic-vault", - # "contracts/vault-rewards", - # "contracts/multihop-router", - "contracts/token-burner", - "contracts/cl-vault", - "contracts/merkle-incentives", - "contracts/range-middleware", - "contracts/dex-router-osmosis", - "contracts/lst-dex-adapter-osmosis", - "contracts/lst-adapter-osmosis", -] +members = ["contracts/*", "packages/*"] [workspace.dependencies] # CosmWasm @@ -34,6 +18,7 @@ cw20-base = {version = "1.1.2", features = ["library"]} cw20-staking = "0.11.1" apollo-cw-asset = "0.1.2" mars-owner = "2.0.0" +quasar-std = { path = "../quasar/packages/quasar-std" } quasar-types = { path = "packages/quasar-types" } dex-router-osmosis = { path = "contracts/dex-router-osmosis", features = ["library"] } lst-dex-adapter-osmosis = { path = "contracts/lst-dex-adapter-osmosis", features = ["library"] } diff --git a/smart-contracts/README.md b/smart-contracts/osmosis/README.md similarity index 100% rename from smart-contracts/README.md rename to smart-contracts/osmosis/README.md diff --git a/smart-contracts/contracts/README.md b/smart-contracts/osmosis/contracts/README.md similarity index 100% rename from smart-contracts/contracts/README.md rename to smart-contracts/osmosis/contracts/README.md diff --git a/smart-contracts/osmosis/contracts/cl-vault/.cargo/config.toml b/smart-contracts/osmosis/contracts/cl-vault/.cargo/config.toml new file mode 100644 index 000000000..aea3032f8 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/.cargo/config.toml @@ -0,0 +1,8 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema" +# test-tube = "test --test * --features test-tube -- --test-threads=1" +test-tube = "test --test test-tube --features test-tube -- --test-threads=1" +prop-test = "test --test prop-test --features test-tube -- --test-threads=1 --nocapture" +test-tube-build = "build --release --lib --target wasm32-unknown-unknown --target-dir ./test-tube-build" diff --git a/smart-contracts/contracts/cl-vault/.github/workflows/Basic.yml b/smart-contracts/osmosis/contracts/cl-vault/.github/workflows/Basic.yml similarity index 100% rename from smart-contracts/contracts/cl-vault/.github/workflows/Basic.yml rename to smart-contracts/osmosis/contracts/cl-vault/.github/workflows/Basic.yml diff --git a/smart-contracts/contracts/cl-vault/.github/workflows/Release.yml b/smart-contracts/osmosis/contracts/cl-vault/.github/workflows/Release.yml similarity index 100% rename from smart-contracts/contracts/cl-vault/.github/workflows/Release.yml rename to smart-contracts/osmosis/contracts/cl-vault/.github/workflows/Release.yml diff --git a/smart-contracts/contracts/cl-vault/Cargo.toml b/smart-contracts/osmosis/contracts/cl-vault/Cargo.toml similarity index 82% rename from smart-contracts/contracts/cl-vault/Cargo.toml rename to smart-contracts/osmosis/contracts/cl-vault/Cargo.toml index d4844bee2..01f3569f2 100644 --- a/smart-contracts/contracts/cl-vault/Cargo.toml +++ b/smart-contracts/osmosis/contracts/cl-vault/Cargo.toml @@ -15,6 +15,16 @@ crate-type = ["cdylib", "rlib"] [[bin]] name = "schema" +[[test]] +name = "test-tube" +path = "tests/test-tube/integration.rs" +required-features = ["test-tube"] + +[[test]] +name = "prop-test" +path = "tests/test-tube/fuzzer.rs" +required-features = ["test-tube"] + [features] backtraces = ["cosmwasm-std/backtraces"] library = [] @@ -37,6 +47,7 @@ apollo-cw-asset = { workspace = true } dex-router-osmosis = {workspace = true} cw-vault-multi-standard = {git = "https://github.com/quasar-finance/cw-vault-standard", branch ="master", features = ["lockup", "force-unlock"]} osmosis-test-tube = { workspace = true, optional = true } +quasar-types = { workspace = true } [dev-dependencies] proptest = { workspace = true } diff --git a/smart-contracts/contracts/cl-vault/README.md b/smart-contracts/osmosis/contracts/cl-vault/README.md similarity index 100% rename from smart-contracts/contracts/cl-vault/README.md rename to smart-contracts/osmosis/contracts/cl-vault/README.md diff --git a/smart-contracts/contracts/cl-vault/proptest-regressions/test_tube/proptest.txt b/smart-contracts/osmosis/contracts/cl-vault/proptest-regressions/test_tube/proptest.txt similarity index 100% rename from smart-contracts/contracts/cl-vault/proptest-regressions/test_tube/proptest.txt rename to smart-contracts/osmosis/contracts/cl-vault/proptest-regressions/test_tube/proptest.txt diff --git a/smart-contracts/contracts/cl-vault/schema/cl-vault.json b/smart-contracts/osmosis/contracts/cl-vault/schema/cl-vault.json similarity index 90% rename from smart-contracts/contracts/cl-vault/schema/cl-vault.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/cl-vault.json index a58f08468..31409d9dd 100644 --- a/smart-contracts/contracts/cl-vault/schema/cl-vault.json +++ b/smart-contracts/osmosis/contracts/cl-vault/schema/cl-vault.json @@ -72,46 +72,35 @@ "type": "string" }, "VaultConfig": { - "description": "VAULT_CONFIG: Base config struct for the contract.", "type": "object", "required": [ "dex_router", "performance_fee", + "swap_admin", "swap_max_slippage", - "treasury" + "treasury", + "twap_window_seconds" ], "properties": { "dex_router": { - "description": "Dex router address", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" }, "performance_fee": { - "description": "Percentage of profit to be charged as performance fee", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" + }, + "swap_admin": { + "$ref": "#/definitions/Addr" }, "swap_max_slippage": { - "description": "swap max slippage", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" }, "treasury": { - "description": "Account to receive fee payments", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" + }, + "twap_window_seconds": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false @@ -388,66 +377,6 @@ } ] }, - "AuthzExtension": { - "description": "Extension messages for Authz. This interface basically reexports certain vault functionality but sets recipient forcibly to None", - "oneOf": [ - { - "type": "object", - "required": [ - "exact_deposit" - ], - "properties": { - "exact_deposit": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "any_deposit" - ], - "properties": { - "any_deposit": { - "type": "object", - "required": [ - "max_slippage" - ], - "properties": { - "max_slippage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "redeem" - ], - "properties": { - "redeem": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, "Decimal": { "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", "type": "string" @@ -468,19 +397,6 @@ }, "additionalProperties": false }, - { - "description": "An interface of certain vault interaction with forced values for authz", - "type": "object", - "required": [ - "authz" - ], - "properties": { - "authz": { - "$ref": "#/definitions/AuthzExtension" - } - }, - "additionalProperties": false - }, { "description": "Rebalance our liquidity range based on an off-chain message given to us by RANGE_ADMIN", "type": "object", @@ -535,28 +451,6 @@ }, "additionalProperties": false }, - { - "description": "MigrationStep", - "type": "object", - "required": [ - "migration_step" - ], - "properties": { - "migration_step": { - "type": "object", - "required": [ - "amount_of_users" - ], - "properties": { - "amount_of_users": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "description": "SwapNonVaultFunds", "type": "object", @@ -575,6 +469,14 @@ "items": { "$ref": "#/definitions/SwapOperation" } + }, + "twap_window_seconds": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false @@ -602,7 +504,6 @@ "additionalProperties": false }, "Metadata": { - "description": "metadata useful for display purposes", "type": "object", "required": [ "name", @@ -610,7 +511,6 @@ ], "properties": { "name": { - "description": "the name of the vault", "type": "string" }, "thesis": { @@ -710,12 +610,12 @@ "SwapOperation": { "type": "object", "required": [ - "pool_id_0", - "pool_id_1", + "pool_id_base", + "pool_id_quote", "token_in_denom" ], "properties": { - "forced_swap_route_token_0": { + "forced_swap_route_base": { "type": [ "array", "null" @@ -724,7 +624,7 @@ "$ref": "#/definitions/SwapAmountInRoute" } }, - "forced_swap_route_token_1": { + "forced_swap_route_quote": { "type": [ "array", "null" @@ -733,12 +633,12 @@ "$ref": "#/definitions/SwapAmountInRoute" } }, - "pool_id_0": { + "pool_id_base": { "type": "integer", "format": "uint64", "minimum": 0.0 }, - "pool_id_1": { + "pool_id_quote": { "type": "integer", "format": "uint64", "minimum": 0.0 @@ -754,46 +654,35 @@ "type": "string" }, "VaultConfig": { - "description": "VAULT_CONFIG: Base config struct for the contract.", "type": "object", "required": [ "dex_router", "performance_fee", + "swap_admin", "swap_max_slippage", - "treasury" + "treasury", + "twap_window_seconds" ], "properties": { "dex_router": { - "description": "Dex router address", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" }, "performance_fee": { - "description": "Percentage of profit to be charged as performance fee", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" + }, + "swap_admin": { + "$ref": "#/definitions/Addr" }, "swap_max_slippage": { - "description": "swap max slippage", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" }, "treasury": { - "description": "Account to receive fee payments", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" + }, + "twap_window_seconds": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false @@ -1172,11 +1061,17 @@ "title": "MigrateMsg", "type": "object", "required": [ - "dex_router" + "swap_admin", + "twap_window_seconds" ], "properties": { - "dex_router": { + "swap_admin": { "$ref": "#/definitions/Addr" + }, + "twap_window_seconds": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, diff --git a/smart-contracts/contracts/cl-vault/schema/raw/execute.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/execute.json similarity index 83% rename from smart-contracts/contracts/cl-vault/schema/raw/execute.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/execute.json index 6825e09a0..cc4f7079e 100644 --- a/smart-contracts/contracts/cl-vault/schema/raw/execute.json +++ b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/execute.json @@ -268,66 +268,6 @@ } ] }, - "AuthzExtension": { - "description": "Extension messages for Authz. This interface basically reexports certain vault functionality but sets recipient forcibly to None", - "oneOf": [ - { - "type": "object", - "required": [ - "exact_deposit" - ], - "properties": { - "exact_deposit": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "any_deposit" - ], - "properties": { - "any_deposit": { - "type": "object", - "required": [ - "max_slippage" - ], - "properties": { - "max_slippage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "redeem" - ], - "properties": { - "redeem": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, "Decimal": { "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", "type": "string" @@ -348,19 +288,6 @@ }, "additionalProperties": false }, - { - "description": "An interface of certain vault interaction with forced values for authz", - "type": "object", - "required": [ - "authz" - ], - "properties": { - "authz": { - "$ref": "#/definitions/AuthzExtension" - } - }, - "additionalProperties": false - }, { "description": "Rebalance our liquidity range based on an off-chain message given to us by RANGE_ADMIN", "type": "object", @@ -415,28 +342,6 @@ }, "additionalProperties": false }, - { - "description": "MigrationStep", - "type": "object", - "required": [ - "migration_step" - ], - "properties": { - "migration_step": { - "type": "object", - "required": [ - "amount_of_users" - ], - "properties": { - "amount_of_users": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "description": "SwapNonVaultFunds", "type": "object", @@ -455,6 +360,14 @@ "items": { "$ref": "#/definitions/SwapOperation" } + }, + "twap_window_seconds": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false @@ -482,7 +395,6 @@ "additionalProperties": false }, "Metadata": { - "description": "metadata useful for display purposes", "type": "object", "required": [ "name", @@ -490,7 +402,6 @@ ], "properties": { "name": { - "description": "the name of the vault", "type": "string" }, "thesis": { @@ -590,12 +501,12 @@ "SwapOperation": { "type": "object", "required": [ - "pool_id_0", - "pool_id_1", + "pool_id_base", + "pool_id_quote", "token_in_denom" ], "properties": { - "forced_swap_route_token_0": { + "forced_swap_route_base": { "type": [ "array", "null" @@ -604,7 +515,7 @@ "$ref": "#/definitions/SwapAmountInRoute" } }, - "forced_swap_route_token_1": { + "forced_swap_route_quote": { "type": [ "array", "null" @@ -613,12 +524,12 @@ "$ref": "#/definitions/SwapAmountInRoute" } }, - "pool_id_0": { + "pool_id_base": { "type": "integer", "format": "uint64", "minimum": 0.0 }, - "pool_id_1": { + "pool_id_quote": { "type": "integer", "format": "uint64", "minimum": 0.0 @@ -634,46 +545,35 @@ "type": "string" }, "VaultConfig": { - "description": "VAULT_CONFIG: Base config struct for the contract.", "type": "object", "required": [ "dex_router", "performance_fee", + "swap_admin", "swap_max_slippage", - "treasury" + "treasury", + "twap_window_seconds" ], "properties": { "dex_router": { - "description": "Dex router address", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" }, "performance_fee": { - "description": "Percentage of profit to be charged as performance fee", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" + }, + "swap_admin": { + "$ref": "#/definitions/Addr" }, "swap_max_slippage": { - "description": "swap max slippage", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" }, "treasury": { - "description": "Account to receive fee payments", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" + }, + "twap_window_seconds": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false diff --git a/smart-contracts/contracts/cl-vault/schema/raw/instantiate.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/instantiate.json similarity index 80% rename from smart-contracts/contracts/cl-vault/schema/raw/instantiate.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/instantiate.json index 7d7ae5b4d..36c9ca99d 100644 --- a/smart-contracts/contracts/cl-vault/schema/raw/instantiate.json +++ b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/instantiate.json @@ -68,46 +68,35 @@ "type": "string" }, "VaultConfig": { - "description": "VAULT_CONFIG: Base config struct for the contract.", "type": "object", "required": [ "dex_router", "performance_fee", + "swap_admin", "swap_max_slippage", - "treasury" + "treasury", + "twap_window_seconds" ], "properties": { "dex_router": { - "description": "Dex router address", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" }, "performance_fee": { - "description": "Percentage of profit to be charged as performance fee", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" + }, + "swap_admin": { + "$ref": "#/definitions/Addr" }, "swap_max_slippage": { - "description": "swap max slippage", - "allOf": [ - { - "$ref": "#/definitions/Decimal" - } - ] + "$ref": "#/definitions/Decimal" }, "treasury": { - "description": "Account to receive fee payments", - "allOf": [ - { - "$ref": "#/definitions/Addr" - } - ] + "$ref": "#/definitions/Addr" + }, + "twap_window_seconds": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false diff --git a/smart-contracts/contracts/cl-vault/schema/raw/migrate.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/migrate.json similarity index 87% rename from smart-contracts/contracts/cl-vault/schema/raw/migrate.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/migrate.json index a95026e2d..b5ea62fd9 100644 --- a/smart-contracts/contracts/cl-vault/schema/raw/migrate.json +++ b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/migrate.json @@ -3,11 +3,17 @@ "title": "MigrateMsg", "type": "object", "required": [ - "dex_router" + "swap_admin", + "twap_window_seconds" ], "properties": { - "dex_router": { + "swap_admin": { "$ref": "#/definitions/Addr" + }, + "twap_window_seconds": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } }, "additionalProperties": false, diff --git a/smart-contracts/contracts/cl-vault/schema/raw/query.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/query.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/query.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/query.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_convert_to_assets.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_convert_to_assets.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_convert_to_assets.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_convert_to_assets.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_convert_to_shares.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_convert_to_shares.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_convert_to_shares.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_convert_to_shares.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_deposit_ratio.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_deposit_ratio.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_deposit_ratio.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_deposit_ratio.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_info.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_info.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_info.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_info.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_preview_deposit.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_preview_deposit.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_preview_deposit.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_preview_deposit.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_preview_redeem.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_preview_redeem.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_preview_redeem.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_preview_redeem.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_total_assets.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_total_assets.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_total_assets.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_total_assets.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_total_vault_token_supply.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_total_vault_token_supply.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_total_vault_token_supply.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_total_vault_token_supply.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_vault_extension.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_vault_extension.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_vault_extension.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_vault_extension.json diff --git a/smart-contracts/contracts/cl-vault/schema/raw/response_to_vault_standard_info.json b/smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_vault_standard_info.json similarity index 100% rename from smart-contracts/contracts/cl-vault/schema/raw/response_to_vault_standard_info.json rename to smart-contracts/osmosis/contracts/cl-vault/schema/raw/response_to_vault_standard_info.json diff --git a/smart-contracts/contracts/cl-vault/src/bin/schema.rs b/smart-contracts/osmosis/contracts/cl-vault/src/bin/schema.rs similarity index 100% rename from smart-contracts/contracts/cl-vault/src/bin/schema.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/bin/schema.rs diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/contract.rs b/smart-contracts/osmosis/contracts/cl-vault/src/contract.rs new file mode 100644 index 000000000..67b8d339a --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/contract.rs @@ -0,0 +1,326 @@ +use crate::error::ContractError; +use crate::helpers::coinlist::CoinList; +use crate::helpers::getters::get_range_admin; +use crate::helpers::prepend::prepend_claim_msg; +use crate::instantiate::{ + handle_create_denom_reply, handle_instantiate, handle_instantiate_create_position_reply, +}; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, ModifyRangeMsg, QueryMsg}; +use crate::query::{ + query_assets_from_shares, query_dex_router, query_info, query_metadata, query_pool, + query_position, query_total_assets, query_total_vault_token_supply, query_user_assets, + query_user_balance, query_verify_tick_cache, RangeAdminResponse, +}; +use crate::reply::Replies; +use crate::state::{VaultConfig, VAULT_CONFIG}; +use crate::vault::{ + admin::execute_admin, + autocompound::{execute_autocompound, handle_autocompound_reply, handle_merge_reply}, + deposit::{execute_any_deposit, execute_exact_deposit, handle_any_deposit_swap_reply}, + distribution::{ + execute_collect_rewards, handle_collect_incentives_reply, + handle_collect_spread_rewards_reply, + }, + merge::{ + execute_merge_position, handle_merge_create_position_reply, + handle_merge_withdraw_position_reply, + }, + range::{ + execute_update_range, handle_create_position, handle_swap_reply, + handle_withdraw_position_reply, + }, + swap::execute_swap_non_vault_funds, + withdraw::{execute_withdraw, handle_withdraw_user_reply}, +}; +use cosmwasm_schema::cw_serde; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + to_json_binary, Addr, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, +}; +use cw2::set_contract_version; +use cw_storage_plus::{Item, Map}; +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:cl-vault"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + handle_instantiate(deps, env, info, msg) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + cw_vault_multi_standard::VaultStandardExecuteMsg::AnyDeposit { + recipient, + max_slippage, + .. // asset and amount fields are not used in this implementation, they are for CW20 tokens + } => execute_any_deposit(deps, env, info, recipient, max_slippage), + cw_vault_multi_standard::VaultStandardExecuteMsg::ExactDeposit { recipient } => { + execute_exact_deposit(deps, env, info, recipient) + } + cw_vault_multi_standard::VaultStandardExecuteMsg::Redeem { recipient, amount } => { + prepend_claim_msg( + &env, + execute_withdraw(deps, &env, info, recipient, amount.into())?, + ) + } + cw_vault_multi_standard::VaultStandardExecuteMsg::VaultExtension(vault_msg) => { + match vault_msg { + crate::msg::ExtensionExecuteMsg::Admin(admin_msg) => { + execute_admin(deps, info, admin_msg) + } + crate::msg::ExtensionExecuteMsg::Merge(msg) => { + execute_merge_position(deps, env, info, msg) + } + crate::msg::ExtensionExecuteMsg::Autocompound {} => { + prepend_claim_msg(&env, execute_autocompound(deps, &env, info)?) + } + crate::msg::ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { + lower_price, + upper_price, + max_slippage, + ratio_of_swappable_funds_to_use, + twap_window_seconds, + forced_swap_route, + claim_after, + }) => prepend_claim_msg( + &env, + execute_update_range( + deps, + &env, + info, + lower_price, + upper_price, + max_slippage, + ratio_of_swappable_funds_to_use, + twap_window_seconds, + forced_swap_route, + claim_after, + )?, + ), + crate::msg::ExtensionExecuteMsg::SwapNonVaultFunds { + swap_operations, + twap_window_seconds, + } => execute_swap_non_vault_funds(deps, env, info, swap_operations, twap_window_seconds), + crate::msg::ExtensionExecuteMsg::CollectRewards {} => { + execute_collect_rewards(deps, env) + } + } + } + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + cw_vault_multi_standard::VaultStandardQueryMsg::VaultStandardInfo {} => todo!(), + cw_vault_multi_standard::VaultStandardQueryMsg::Info {} => { + Ok(to_json_binary(&query_info(deps)?)?) + } + cw_vault_multi_standard::VaultStandardQueryMsg::PreviewDeposit { assets: _ } => todo!(), + cw_vault_multi_standard::VaultStandardQueryMsg::DepositRatio => todo!(), + cw_vault_multi_standard::VaultStandardQueryMsg::PreviewRedeem { amount: shares } => Ok( + to_json_binary(&query_assets_from_shares(deps, env, shares)?)?, + ), + cw_vault_multi_standard::VaultStandardQueryMsg::TotalAssets {} => { + Ok(to_json_binary(&query_total_assets(deps, env)?)?) + } + cw_vault_multi_standard::VaultStandardQueryMsg::TotalVaultTokenSupply {} => { + Ok(to_json_binary(&query_total_vault_token_supply(deps)?)?) + } + cw_vault_multi_standard::VaultStandardQueryMsg::ConvertToShares { amount: _ } => todo!(), + cw_vault_multi_standard::VaultStandardQueryMsg::ConvertToAssets { amount: shares } => Ok( + to_json_binary(&query_assets_from_shares(deps, env, shares)?)?, + ), + cw_vault_multi_standard::VaultStandardQueryMsg::VaultExtension(msg) => match msg { + crate::msg::ExtensionQueryMsg::Metadata {} => { + Ok(to_json_binary(&query_metadata(deps)?)?) + } + crate::msg::ExtensionQueryMsg::DexRouter {} => { + Ok(to_json_binary(&query_dex_router(deps)?)?) + } + crate::msg::ExtensionQueryMsg::Balances(msg) => match msg { + crate::msg::UserBalanceQueryMsg::UserSharesBalance { user } => { + Ok(to_json_binary(&query_user_balance(deps, user)?)?) + } + crate::msg::UserBalanceQueryMsg::UserAssetsBalance { user } => { + Ok(to_json_binary(&query_user_assets(deps, env, user)?)?) + } + }, + crate::msg::ExtensionQueryMsg::ConcentratedLiquidity(msg) => match msg { + crate::msg::ClQueryMsg::Pool {} => Ok(to_json_binary(&query_pool(deps)?)?), + crate::msg::ClQueryMsg::Position {} => Ok(to_json_binary(&query_position(deps)?)?), + crate::msg::ClQueryMsg::RangeAdmin {} => { + let range_admin = get_range_admin(deps)?; + Ok(to_json_binary(&RangeAdminResponse { + address: range_admin.to_string(), + })?) + } + crate::msg::ClQueryMsg::VerifyTickCache => { + Ok(to_json_binary(&query_verify_tick_cache(deps)?)?) + } + }, + }, + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result { + match msg.id.into() { + Replies::InstantiateCreatePosition => { + handle_instantiate_create_position_reply(deps, env, msg.result) + } + Replies::CollectIncentives => handle_collect_incentives_reply(deps, env, msg.result), + Replies::CollectSpreadRewards => handle_collect_spread_rewards_reply(deps, env, msg.result), + Replies::WithdrawPosition => handle_withdraw_position_reply(deps, env), + Replies::CreatePosition => handle_create_position(deps, env, msg.result), + Replies::Swap => handle_swap_reply(deps, env), + Replies::Merge => handle_merge_reply(deps, env, msg.result), + Replies::CreateDenom => handle_create_denom_reply(deps, msg.result), + Replies::WithdrawUser => handle_withdraw_user_reply(deps, msg.result), + Replies::WithdrawMerge => handle_merge_withdraw_position_reply(deps, env, msg.result), + Replies::CreatePositionMerge => handle_merge_create_position_reply(deps, env, msg.result), + Replies::Autocompound => handle_autocompound_reply(deps, env, msg.result), + Replies::AnyDepositSwap => handle_any_deposit_swap_reply(deps, env, msg.result), + Replies::Unknown => unimplemented!(), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> Result { + // VaultConfig + #[cw_serde] + struct OldVaultConfig { + pub performance_fee: Decimal, + pub treasury: Addr, + pub swap_max_slippage: Decimal, + pub dex_router: Addr, + } + const OLD_VAULT_CONFIG: Item = Item::new("vault_config_v2"); + let old_vault_config: OldVaultConfig = OLD_VAULT_CONFIG.load(deps.storage)?; + OLD_VAULT_CONFIG.remove(deps.storage); + VAULT_CONFIG.save( + deps.storage, + &VaultConfig { + performance_fee: old_vault_config.performance_fee, + treasury: old_vault_config.treasury, + swap_max_slippage: old_vault_config.swap_max_slippage, + dex_router: old_vault_config.dex_router, + swap_admin: msg.swap_admin, + twap_window_seconds: msg.twap_window_seconds, + }, + )?; + + // MigrationStatus + #[cw_serde] + pub enum MigrationStatus { + Open, + Closed, + } + pub const MIGRATION_STATUS: Item = Item::new("migration_status"); + let migration_status = MIGRATION_STATUS.load(deps.storage)?; + // we want the v1.0.8-skn migration_step to be occurred completely here. + if migration_status == MigrationStatus::Open { + return Err(ContractError::ParseError { + msg: "Migration status should be closed.".to_string(), + }); + } + MIGRATION_STATUS.remove(deps.storage); + + // UserRewards + pub const USER_REWARDS: Map = Map::new("user_rewards"); + USER_REWARDS.clear(deps.storage); + + let response = Response::new().add_attribute("migrate", "successful"); + Ok(response) +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + + use super::*; + + #[test] + fn test_migrate() { + let env = mock_env(); + let mut deps = mock_dependencies(); + + // VaultConfig mocking + #[cw_serde] + struct OldVaultConfig { + pub performance_fee: Decimal, + pub treasury: Addr, + pub swap_max_slippage: Decimal, + pub dex_router: Addr, + } + const OLD_VAULT_CONFIG: Item = Item::new("vault_config_v2"); + OLD_VAULT_CONFIG + .save( + &mut deps.storage, + &OldVaultConfig { + performance_fee: Decimal::percent(1), + treasury: Addr::unchecked("treasury"), + swap_max_slippage: Decimal::percent(1), + dex_router: Addr::unchecked("dex_router"), + }, + ) + .unwrap(); + + // MigrationStatus mocking + #[cw_serde] + pub enum MigrationStatus { + Open, + Closed, + } + pub const MIGRATION_STATUS: Item = Item::new("migration_status"); + MIGRATION_STATUS + .save(&mut deps.storage, &MigrationStatus::Closed) + .unwrap(); + + // UserRewards mocking + pub const USER_REWARDS: Map = Map::new("user_rewards"); + USER_REWARDS + .save(&mut deps.storage, Addr::unchecked("user"), &CoinList::new()) + .unwrap(); + + // Migrate and assert new states + migrate( + deps.as_mut(), + env, + MigrateMsg { + swap_admin: Addr::unchecked("swap_admin"), + twap_window_seconds: 24u64, + }, + ) + .unwrap(); + + let vault_config: VaultConfig = VAULT_CONFIG.load(&deps.storage).unwrap(); + assert_eq!(vault_config.performance_fee, Decimal::percent(1)); + assert_eq!(vault_config.treasury, Addr::unchecked("treasury")); + assert_eq!(vault_config.swap_max_slippage, Decimal::percent(1)); + assert_eq!(vault_config.dex_router, Addr::unchecked("dex_router")); + assert_eq!(vault_config.swap_admin, Addr::unchecked("swap_admin")); + assert!(matches!(OLD_VAULT_CONFIG.may_load(&deps.storage), Ok(None))); + + assert!(matches!(MIGRATION_STATUS.may_load(&deps.storage), Ok(None))); + + assert!(matches!( + USER_REWARDS.may_load(&deps.storage, Addr::unchecked("user")), + Ok(None) + )); + } +} diff --git a/smart-contracts/contracts/cl-vault/src/error.rs b/smart-contracts/osmosis/contracts/cl-vault/src/error.rs similarity index 64% rename from smart-contracts/contracts/cl-vault/src/error.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/error.rs index 3257949af..281a6efea 100644 --- a/smart-contracts/contracts/cl-vault/src/error.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/error.rs @@ -1,14 +1,14 @@ +use crate::state::{PoolConfig, ADMIN_ADDRESS, RANGE_ADMIN, VAULT_CONFIG}; use cosmwasm_std::{ - CheckedFromRatioError, CheckedMultiplyRatioError, Coin, CoinFromStrError, - ConversionOverflowError, Decimal256, Decimal256RangeExceeded, DivideByZeroError, OverflowError, - StdError, Uint128, + Addr, CheckedFromRatioError, CheckedMultiplyFractionError, CheckedMultiplyRatioError, Coin, + CoinFromStrError, ConversionOverflowError, Decimal, Decimal256, Decimal256RangeExceeded, + DecimalRangeExceeded, DivideByZeroError, OverflowError, StdError, Storage, Uint128, }; use cw_utils::PaymentError; use prost::DecodeError; use std::num::{ParseIntError, TryFromIntError}; use thiserror::Error; -/// AutocompoundingVault errors #[allow(missing_docs)] #[derive(Error, Debug, PartialEq)] pub enum ContractError { @@ -21,14 +21,11 @@ pub enum ContractError { #[error("Pool-id {pool_id} not found")] PoolNotFound { pool_id: u64 }, - #[error("Position Not Found")] + #[error("Position not found")] PositionNotFound, - #[error("Sent the wrong amount of denoms")] - IncorrectAmountFunds, - - #[error("Modify range state item not found")] - ModifyRangeStateNotFound, + #[error("Incorrect deposit funds")] + IncorrectDepositFunds, #[error("ratio_of_swappable_funds_to_use should be >0 and <=1")] InvalidRatioOfSwappableFundsToUse, @@ -39,9 +36,6 @@ pub enum ContractError { #[error("Swap deposit merge state item not found")] SwapDepositMergeStateNotFound, - #[error("Swap failed: {message}")] - SwapFailed { message: String }, - #[error("Vault shares sent in does not equal amount requested")] IncorrectShares, @@ -59,12 +53,6 @@ pub enum ContractError { actual: Vec, }, - #[error("Bad token out requested for swap, must be one of: {base_token:?}, {quote_token:?}")] - BadTokenForSwap { - base_token: String, - quote_token: String, - }, - #[error("Insufficient funds for swap. Have: {balance}, Need: {needed}")] InsufficientFundsForSwap { balance: Uint128, needed: Uint128 }, @@ -95,18 +83,15 @@ pub enum ContractError { #[error("Mismatch in old and new pool tokens")] PoolTokenMismatch {}, + /// This function compares the address of the message sender (caller) with the current admin + /// address stored in the state. This provides a convenient way to verify if the caller + /// is the admin in a single line. #[error("Cannot force a recommended route if recommended route is passed in as None")] TryForceRouteWithoutRecommendedSwapRoute {}, #[error("Swap operations for non vault funds swap cannot be empty")] EmptySwapOperations {}, - #[error("Migration status is closed")] - MigrationStatusClosed {}, - - #[error("Migration status is open")] - MigrationStatusOpen {}, - #[error("Vault is not distributing rewards, claiming is needed first")] IsNotDistributing {}, @@ -125,9 +110,6 @@ pub enum ContractError { #[error("Missing recommended swap route.")] MissingRecommendedSwapRoute {}, - #[error("Missing best path for swap.")] - MissingBestPath {}, - #[error("Missing information for {asset}")] MissingAssetInfo { asset: String }, @@ -150,6 +132,15 @@ pub enum ContractError { #[error("{0}")] ConversionOverflowError(#[from] ConversionOverflowError), + #[error("{0}")] + CheckedMultiplyRatio(#[from] CheckedMultiplyRatioError), + + #[error("{0}")] + CheckedMultiplyFraction(#[from] CheckedMultiplyFractionError), + + #[error("{0}")] + DecimalRange(#[from] DecimalRangeExceeded), + #[error("{0}")] DecodeError(#[from] DecodeError), @@ -157,17 +148,55 @@ pub enum ContractError { CoinFromStrError(#[from] CoinFromStrError), #[error("{0}")] - MultiplyRatioError(#[from] CheckedFromRatioError), + CheckedFromRatio(#[from] CheckedFromRatioError), #[error("{0}")] DivideByZeroError(#[from] DivideByZeroError), - #[error("{0}")] - CheckedMultiplyRatioError(#[from] CheckedMultiplyRatioError), - #[error("{0}")] Decimal256RangeExceededError(#[from] Decimal256RangeExceeded), #[error("{0}")] TryFromIntError(#[from] TryFromIntError), } + +pub fn assert_deposits(funds: &[Coin], config: &PoolConfig) -> Result<(), ContractError> { + if (funds.len() != 2 && funds.len() != 1) + || funds + .iter() + .any(|deposit| !config.pool_contains_token(&deposit.denom)) + { + return Err(ContractError::IncorrectDepositFunds); + } + Ok(()) +} + +pub fn assert_admin(storage: &dyn Storage, caller: &Addr) -> Result<(), ContractError> { + if ADMIN_ADDRESS.load(storage)? != caller { + return Err(ContractError::Unauthorized {}); + } + Ok(()) +} + +pub fn assert_range_admin(storage: &dyn Storage, sender: &Addr) -> Result<(), ContractError> { + let admin = RANGE_ADMIN.load(storage)?; + if admin != sender { + return Err(ContractError::Unauthorized {}); + } + Ok(()) +} + +pub fn assert_swap_admin(storage: &dyn Storage, sender: &Addr) -> Result<(), ContractError> { + let vault_config = VAULT_CONFIG.load(storage)?; + if vault_config.swap_admin != sender { + return Err(ContractError::Unauthorized {}); + } + Ok(()) +} + +pub fn assert_ratio(ratio: Decimal) -> Result<(), ContractError> { + if ratio > Decimal::one() || ratio <= Decimal::zero() { + return Err(ContractError::InvalidRatioOfSwappableFundsToUse {}); + } + Ok(()) +} diff --git a/smart-contracts/contracts/cl-vault/src/helpers/coinlist.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/coinlist.rs similarity index 66% rename from smart-contracts/contracts/cl-vault/src/helpers/coinlist.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/helpers/coinlist.rs index 164a486dd..e7ba57450 100644 --- a/smart-contracts/contracts/cl-vault/src/helpers/coinlist.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/coinlist.rs @@ -1,13 +1,13 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{coin, Attribute, BankMsg, Coin, CosmosMsg, Decimal, Fraction, Uint128}; +use cosmwasm_std::{ + coin, Attribute, BankMsg, CheckedMultiplyFractionError, Coin, CosmosMsg, Decimal, Uint128, +}; use osmosis_std::types::cosmos::base::v1beta1::Coin as OsmoCoin; use crate::ContractError; use super::generic::sort_tokens; -/// COIN LIST - #[cw_serde] #[derive(Default)] pub struct CoinList(Vec); @@ -18,25 +18,23 @@ impl CoinList { } /// calculates the ratio of the current rewards - pub fn mul_ratio(&self, ratio: Decimal) -> CoinList { + pub fn mul_ratio(&self, ratio: Decimal) -> Result { if ratio == Decimal::zero() { // Return an empty list if the ratio is zero. - return CoinList::new(); + return Ok(CoinList::new()); } - CoinList( - self.0 - .iter() - .map(|c| { - coin( - c.amount - .multiply_ratio(ratio.numerator(), ratio.denominator()) - .u128(), - c.denom.clone(), - ) - }) - .collect(), - ) + let coins: Result, _> = self + .0 + .iter() + .map(|c| -> Result { + Ok(coin( + c.amount.checked_mul_floor(ratio)?.u128(), + c.denom.clone(), + )) + }) + .collect(); + Ok(CoinList(coins?)) } pub fn is_empty(&self) -> bool { @@ -50,24 +48,10 @@ impl CoinList { .map(|c| Ok(coin(c.amount.parse()?, c.denom.clone()))) .collect(); - // Append and merge to - self.merge(parsed_rewards?)?; - Ok(()) - } - - pub fn update_rewards_coin_list(&mut self, rewards: CoinList) -> Result<(), ContractError> { - let parsed_rewards: Result, ContractError> = rewards - .coins() - .into_iter() - .map(|c| Ok(coin(c.amount.u128(), c.denom))) - .collect(); - - // Append and merge to self.merge(parsed_rewards?)?; Ok(()) } - /// add rewards to self and mutate self pub fn add(&mut self, rewards: CoinList) -> Result<(), ContractError> { self.merge(rewards.coins())?; Ok(()) @@ -85,20 +69,17 @@ impl CoinList { Ok(()) } - /// Subtracts a percentage from self, mutate self and return the subtracted rewards, - /// excluding any coins with zero amounts. + /// Subtracts a percentage from self and return the subtracted rewards, pub fn sub_ratio(&mut self, ratio: Decimal) -> Result { - let to_sub = self.mul_ratio(ratio); - - // Actually subtract the funds + let to_sub = self.mul_ratio(ratio)?; self.sub(&to_sub)?; - // Return only coins with non-zero amounts, filtering out any zeros that might result from the subtraction. Ok(CoinList( to_sub .0 - .into_iter() + .iter() .filter(|c| c.amount != Uint128::zero()) + .cloned() .collect(), )) } @@ -141,23 +122,26 @@ impl CoinList { } pub fn coins(&self) -> Vec { - sort_tokens(self.0.clone()) - .into_iter() - .filter(|c| c.amount > Uint128::zero()) - .collect() + sort_tokens( + self.0 + .iter() + .filter(|c| c.amount > Uint128::zero()) + .cloned() + .collect(), + ) } pub fn from_coins(coins: Vec) -> Self { CoinList(coins) } - pub fn find_coin(&self, denom: String) -> Coin { + pub fn find(&self, denom: &str) -> Coin { self.0 - .clone() - .into_iter() + .iter() .find(|c| c.denom == denom) + .cloned() .unwrap_or(Coin { - denom, + denom: denom.to_string(), amount: 0u128.into(), }) } @@ -173,7 +157,7 @@ mod tests { fn coins_works() { let mut rewards = CoinList::new(); rewards - .update_rewards(&vec![ + .update_rewards(&[ OsmoCoin { denom: "uosmo".into(), amount: "1000".into(), @@ -200,7 +184,7 @@ mod tests { fn coins_only_positive_works() { let mut rewards = CoinList::new(); rewards - .update_rewards(&vec![ + .update_rewards(&[ OsmoCoin { denom: "uosmo".into(), amount: "1000".into(), @@ -227,7 +211,7 @@ mod tests { fn sub_works() { let mut rewards = CoinList::new(); rewards - .update_rewards(&vec![ + .update_rewards(&[ OsmoCoin { denom: "uosmo".into(), amount: "1000".into(), @@ -290,7 +274,7 @@ mod tests { fn percentage_works() { let mut rewards = CoinList::new(); rewards - .update_rewards(&vec![ + .update_rewards(&[ OsmoCoin { denom: "uosmo".into(), amount: "1000".into(), @@ -306,7 +290,9 @@ mod tests { ]) .unwrap(); - let ratio = rewards.mul_ratio(Decimal::from_ratio(Uint128::new(10), Uint128::new(100))); + let ratio = rewards + .mul_ratio(Decimal::from_ratio(Uint128::new(10), Uint128::new(100))) + .unwrap(); assert_eq!( ratio, CoinList(vec![ @@ -319,23 +305,11 @@ mod tests { #[test] fn sub_percentage_works() { - let mut rewards = CoinList::new(); - rewards - .update_rewards(&vec![ - OsmoCoin { - denom: "uosmo".into(), - amount: "1000".into(), - }, - OsmoCoin { - denom: "uatom".into(), - amount: "2000".into(), - }, - OsmoCoin { - denom: "uqsr".into(), - amount: "3000".into(), - }, - ]) - .unwrap(); + let mut rewards = CoinList::from_coins(vec![ + coin(1000, "uosmo"), + coin(2000, "uatom"), + coin(3000, "uqsr"), + ]); let ratio = rewards .sub_ratio(Decimal::from_ratio(Uint128::new(10), Uint128::new(100))) @@ -363,23 +337,12 @@ mod tests { #[test] fn add_works() { - let mut rewards = CoinList::new(); - rewards - .update_rewards(&vec![ - OsmoCoin { - denom: "uosmo".into(), - amount: "1000".into(), - }, - OsmoCoin { - denom: "uatom".into(), - amount: "2000".into(), - }, - OsmoCoin { - denom: "uqsr".into(), - amount: "3000".into(), - }, - ]) - .unwrap(); + let mut rewards = CoinList::from_coins(vec![ + coin(1000, "uosmo"), + coin(2000, "uatom"), + coin(3000, "uqsr"), + ]); + rewards .add(CoinList::from_coins(vec![ coin(2000, "uosmo"), @@ -398,52 +361,4 @@ mod tests { ]) ) } - - #[test] - fn update_rewards_works() { - let mut rewards = CoinList::new(); - rewards - .update_rewards(&vec![ - OsmoCoin { - denom: "uosmo".into(), - amount: "1000".into(), - }, - OsmoCoin { - denom: "uatom".into(), - amount: "2000".into(), - }, - OsmoCoin { - denom: "uqsr".into(), - amount: "3000".into(), - }, - ]) - .unwrap(); - - rewards - .update_rewards(&vec![ - OsmoCoin { - denom: "uosmo".into(), - amount: "1000".into(), - }, - OsmoCoin { - denom: "umars".into(), - amount: "1234".into(), - }, - OsmoCoin { - denom: "uqsr".into(), - amount: "3000".into(), - }, - ]) - .unwrap(); - - assert_eq!( - rewards, - CoinList::from_coins(vec![ - coin(2000, "uosmo"), - coin(2000, "uatom"), - coin(6000, "uqsr"), - coin(1234, "umars") - ]) - ); - } } diff --git a/smart-contracts/contracts/cl-vault/src/helpers/generic.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/generic.rs similarity index 100% rename from smart-contracts/contracts/cl-vault/src/helpers/generic.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/helpers/generic.rs diff --git a/smart-contracts/contracts/cl-vault/src/helpers/getters.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs similarity index 53% rename from smart-contracts/contracts/cl-vault/src/helpers/getters.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs index e6ba63f4a..df0af8e9e 100644 --- a/smart-contracts/contracts/cl-vault/src/helpers/getters.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/getters.rs @@ -1,18 +1,21 @@ -use crate::math::tick::tick_to_price; -use crate::state::{PoolConfig, RANGE_ADMIN}; +use std::cmp::min; use std::str::FromStr; use osmosis_std::shim::Timestamp as OsmoTimestamp; use osmosis_std::types::osmosis::poolmanager::v1beta1::PoolmanagerQuerier; use osmosis_std::types::osmosis::twap::v1beta1::TwapQuerier; +use quasar_types::pool_pair::PoolPair; use crate::vault::concentrated_liquidity::get_position; -use crate::{state::POOL_CONFIG, ContractError}; +use crate::{ + math::tick::tick_to_price, + state::{PoolConfig, POOL_CONFIG, RANGE_ADMIN}, + ContractError, +}; use cosmwasm_std::{ - Addr, Coin, Decimal, Decimal256, Deps, DepsMut, Env, Fraction, QuerierWrapper, Storage, - Uint128, Uint256, + coin, Addr, Coin, Decimal, Decimal256, Deps, Env, QuerierWrapper, Storage, Timestamp, Uint128, + Uint256, }; -use osmosis_std::try_proto_to_cosmwasm_coins; use super::coinlist::CoinList; @@ -21,7 +24,7 @@ pub fn get_range_admin(deps: Deps) -> Result { } /// Calculate the total value of two assets in asset0. -pub fn get_asset0_value( +pub fn get_value_wrt_asset0( storage: &dyn Storage, querier: &QuerierWrapper, token0: Uint128, @@ -35,26 +38,25 @@ pub fn get_asset0_value( .spot_price .parse()?; - let total = token0 - .checked_add(token1.multiply_ratio(spot_price.denominator(), spot_price.numerator()))?; + let total = token0.checked_add(token1.checked_div_floor(spot_price)?)?; Ok(total) } pub fn get_twap_price( - storage: &dyn Storage, querier: &QuerierWrapper, - env: &Env, + block_time: Timestamp, twap_window_seconds: u64, + pool_id: u64, + token0_denom: String, + token1_denom: String, ) -> Result { - let pool_config = POOL_CONFIG.load(storage)?; - let twap_querier = TwapQuerier::new(querier); - let start_of_window = env.block.time.minus_seconds(twap_window_seconds); + let start_of_window = block_time.minus_seconds(twap_window_seconds); let twap_price = twap_querier.arithmetic_twap_to_now( - pool_config.pool_id, - pool_config.token0, - pool_config.token1, + pool_id, + token0_denom, + token1_denom, Some(OsmoTimestamp { seconds: start_of_window.seconds().try_into()?, nanos: 0, @@ -64,77 +66,77 @@ pub fn get_twap_price( Ok(Decimal::from_str(&twap_price.arithmetic_twap)?) } -/// Calculate the amount of tokens that can be deposited while maintaining the current position ratio in the vault. -#[allow(clippy::type_complexity)] +#[derive(Debug, PartialEq)] +pub struct DepositInfo { + pub base_deposit: Uint128, + pub quote_deposit: Uint128, + pub base_refund: Coin, + pub quote_refund: Coin, +} + pub fn get_depositable_tokens( - deps: DepsMut, - token0: Coin, - token1: Coin, -) -> Result<((Uint128, Uint128), (Uint128, Uint128)), ContractError> { + deps: &Deps, + funds: Vec, + pool_config: &PoolConfig, +) -> Result { + let funds_in_pool = get_vault_funds_or_zero(&CoinList::from_coins(funds), pool_config); + let position = get_position(deps.storage, &deps.querier)?; - let asset0_amount = Uint128::from_str(&position.clone().asset0.unwrap_or_default().amount)?; - let asset1_amount = Uint128::from_str(&position.clone().asset1.unwrap_or_default().amount)?; - - match (asset0_amount.is_zero(), asset1_amount.is_zero()) { - (true, false) => Ok(( - (Uint128::zero(), token1.amount), - (token0.amount, Uint128::zero()), - )), - (false, true) => Ok(( - (token0.amount, Uint128::zero()), - (Uint128::zero(), token1.amount), - )), - /* - Figure out how many of the tokens we can use for a double sided position. - First we find whether token0 or token0 is the limiting factor for the token by - dividing token0 by the current amount of token0 in the position and do the same for token1 - for calculating further amounts we start from: - token0 / token1 = ratio0 / ratio1, where ratio0 / ratio1 are the ratios from the position - - if token0 is limiting, we calculate the token1 amount by - token1 = token0*ratio1/ratio0 - - if token1 is limiting, we calculate the token0 amount by - token0 = token1 * ratio0 / ratio1 - */ - (false, false) => { - let token0 = token0.amount; - let token1 = token1.amount; - let assets = try_proto_to_cosmwasm_coins(vec![ - position.asset0.unwrap(), - position.asset1.unwrap(), - ])?; - let ratio = Decimal::from_ratio(assets[0].amount, assets[1].amount); - - // Refund token0 if ratio.numerator is zero - if ratio.numerator().is_zero() { - return Ok(((Uint128::zero(), token1), (token0, Uint128::zero()))); - } + let assets = PoolPair::new( + position.asset0.unwrap_or_default().try_into()?, + position.asset1.unwrap_or_default().try_into()?, + ); + get_deposit_info(&assets, &funds_in_pool) +} - let zero_usage: Uint128 = ((Uint256::from(token0) - * Uint256::from_u128(1_000_000_000_000_000_000u128)) - / Uint256::from(ratio.numerator())) - .try_into()?; - let one_usage: Uint128 = ((Uint256::from(token1) - * Uint256::from_u128(1_000_000_000_000_000_000u128)) - / Uint256::from(ratio.denominator())) - .try_into()?; - - if zero_usage < one_usage { - let t1: Uint128 = (Uint256::from(token0) * (Uint256::from(ratio.denominator())) - / Uint256::from(ratio.numerator())) - .try_into()?; - Ok(((token0, t1), (Uint128::zero(), token1.checked_sub(t1)?))) - } else { - let t0: Uint128 = ((Uint256::from(token1) * Uint256::from(ratio.numerator())) - / Uint256::from(ratio.denominator())) - .try_into()?; - Ok(((t0, token1), (token0.checked_sub(t0)?, Uint128::zero()))) - } - } - // (true, true) => { - _ => Err(ContractError::InvalidRatioOfSwappableFundsToUse {}), - } +fn get_vault_funds_or_zero(funds: &CoinList, config: &PoolConfig) -> PoolPair { + let base = funds.find(&config.token0); + let quote = funds.find(&config.token1); + PoolPair::new(base, quote) +} + +fn get_deposit_info( + assets: &PoolPair, + provided: &PoolPair, +) -> Result { + let provided_base_amount: Uint256 = provided.base.amount.into(); + let provided_quote_amount: Uint256 = provided.quote.amount.into(); + + let base_deposit = if assets.quote.amount.is_zero() { + provided_base_amount + } else { + min( + provided_base_amount, + provided_quote_amount.checked_mul_floor(Decimal256::from_ratio( + assets.base.amount, + assets.quote.amount, + ))?, + ) + }; + let quote_deposit = if assets.base.amount.is_zero() { + provided_quote_amount + } else { + min( + provided_quote_amount, + provided_base_amount.checked_mul_floor(Decimal256::from_ratio( + assets.quote.amount, + assets.base.amount, + ))?, + ) + }; + + Ok(DepositInfo { + base_deposit: base_deposit.try_into()?, + quote_deposit: quote_deposit.try_into()?, + base_refund: coin( + TryInto::::try_into(provided_base_amount.checked_sub(base_deposit)?)?.into(), + assets.base.denom.clone(), + ), + quote_refund: coin( + TryInto::::try_into(provided_quote_amount.checked_sub(quote_deposit)?)?.into(), + assets.quote.denom.clone(), + ), + }) } // this math is straight from the readme @@ -163,7 +165,7 @@ pub fn get_single_sided_deposit_0_to_1_swap_amount( let denominator = Decimal256::one().checked_add(spot_price_over_pool_metadata_constant)?; let swap_amount: Uint128 = Uint256::from(token0_balance) - .multiply_ratio(denominator.denominator(), denominator.numerator()) + .checked_div_floor(denominator)? .try_into()?; Ok(swap_amount) @@ -194,66 +196,50 @@ pub fn get_single_sided_deposit_1_to_0_swap_amount( let denominator = Decimal256::one().checked_add(pool_metadata_constant_over_spot_price)?; let swap_amount: Uint128 = Uint256::from(token1_balance) - .multiply_ratio(denominator.denominator(), denominator.numerator()) + .checked_div_floor(denominator)? .try_into()?; Ok(swap_amount) } -/// this function subtracts out anything from the raw contract balance that isn't dedicated towards user or strategist rewards. -pub fn get_unused_balances(querier: &QuerierWrapper, env: &Env) -> Result { +pub fn get_unused_balances( + querier: &QuerierWrapper, + addr: &Addr, +) -> Result { Ok(CoinList::from_coins( - querier.query_all_balances(env.contract.address.to_string())?, + querier.query_all_balances(addr.to_string())?, )) } -pub fn get_unused_pair_balances( - deps: &DepsMut, - env: &Env, +pub fn get_unused_pair( + deps: &Deps, + addr: &Addr, pool_config: &PoolConfig, -) -> Result<(Uint128, Uint128), ContractError> { - // Get unused balances from the contract. This is the amount of tokens that are not currently in a position. - // This amount already includes the withdrawn amounts from previous steps as in this reply those funds already compose the contract balance. - let unused_balances = get_unused_balances(&deps.querier, env)?; - - // Use the unused balances to get the token0 and token1 amounts that we can use to create a new position - let amount0 = unused_balances.find_coin(pool_config.token0.clone()).amount; - let amount1 = unused_balances.find_coin(pool_config.token1.clone()).amount; - - Ok((amount0, amount1)) +) -> Result, ContractError> { + let unused_balances = get_unused_balances(&deps.querier, addr)?; + Ok(get_vault_funds_or_zero(&unused_balances, pool_config)) } -pub fn get_tokens_provided( - amount0: Uint128, - amount1: Uint128, +pub fn get_unused_pair_balances( + deps: &Deps, + env: &Env, pool_config: &PoolConfig, ) -> Result, ContractError> { - let mut tokens_provided = vec![]; - if !amount0.is_zero() { - tokens_provided.push(Coin { - denom: pool_config.token0.clone(), - amount: amount0, - }) - } - if !amount1.is_zero() { - tokens_provided.push(Coin { - denom: pool_config.token1.clone(), - amount: amount1, - }) - } - - Ok(tokens_provided) + let vault_funds = get_unused_pair(deps, &env.contract.address, pool_config)?; + Ok(vec![vault_funds.base, vault_funds.quote]) } #[cfg(test)] mod tests { - use std::collections::HashMap; - - use cosmwasm_std::testing::mock_dependencies; - + use super::*; use crate::math::tick::{build_tick_exp_cache, price_to_tick}; + use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{coin, Decimal256}; + use std::collections::HashMap; + use std::str::FromStr; - use super::*; + const TOKEN0: &str = "token0"; + const TOKEN1: &str = "token1"; #[test] fn test_0_to_1_swap() { @@ -371,4 +357,101 @@ mod tests { assert_eq!(swap_amount, result); } } + + #[test] + fn test_position_in_both_asset() { + let token0 = coin(1_000_000_000, TOKEN0); + let token1 = coin(100_000_000_000_000_000_000_000_000_000, TOKEN1); + + let assets = PoolPair::new(token0.clone(), token1.clone()); + let provided = PoolPair::new(token0.clone(), token1.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); + assert_eq!( + result, + DepositInfo { + base_deposit: Uint128::zero(), + quote_deposit: token1.amount, + base_refund: token0, + quote_refund: coin(0, token1.denom), + } + ); + } + + #[test] + fn test_position_in_asset1_only() { + let token0 = coin(50, TOKEN0); + let token1 = coin(100, TOKEN1); + + let assets = PoolPair::new(coin(0, TOKEN0), token1.clone()); + let provided = PoolPair::new(token0.clone(), token1.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); + assert_eq!( + result, + DepositInfo { + base_deposit: Uint128::zero(), + quote_deposit: token1.amount, + base_refund: token0, + quote_refund: coin(0, token1.denom), + } + ); + } + + #[test] + fn test_position_in_asset0_only() { + let token0 = coin(50, TOKEN0); + let token1 = coin(100, TOKEN1); + + let assets = PoolPair::new(token0.clone(), coin(0, TOKEN1)); + let provided = PoolPair::new(token0.clone(), token1.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); + assert_eq!( + result, + DepositInfo { + base_deposit: token0.amount, + quote_deposit: Uint128::zero(), + base_refund: coin(0, token0.denom), + quote_refund: token1, + } + ); + } + + #[test] + fn test_both_assets_present_token0_limiting() { + let token0 = coin(50, TOKEN0); + let token1 = coin(100, TOKEN1); + + let assets = PoolPair::new(token0.clone(), token1.clone()); + let base_deposit = coin(2000, TOKEN0); + let provided = PoolPair::new(base_deposit.clone(), coin(5000, TOKEN1)); + let result = get_deposit_info(&assets, &provided).unwrap(); + assert_eq!( + result, + DepositInfo { + base_deposit: base_deposit.amount, + quote_deposit: Uint128::new(4000), + base_refund: coin(0, token0.denom), + quote_refund: coin(1000, token1.denom), + } + ); + } + + #[test] + fn test_both_assets_present_token1_limiting() { + let token0 = coin(50, TOKEN0); + let token1 = coin(100, TOKEN1); + + let assets = PoolPair::new(token0.clone(), token1.clone()); + let quote_deposit = coin(3000, TOKEN1); + let provided = PoolPair::new(coin(2000, TOKEN0), quote_deposit.clone()); + let result = get_deposit_info(&assets, &provided).unwrap(); + assert_eq!( + result, + DepositInfo { + base_deposit: Uint128::new(1500), + quote_deposit: quote_deposit.amount, + base_refund: coin(500, token0.denom), + quote_refund: coin(0, token1.denom), + } + ); + } } diff --git a/smart-contracts/contracts/cl-vault/src/helpers/mod.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs similarity index 83% rename from smart-contracts/contracts/cl-vault/src/helpers/mod.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs index c517f5cf2..0cefdac7b 100644 --- a/smart-contracts/contracts/cl-vault/src/helpers/mod.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/mod.rs @@ -1,4 +1,3 @@ -pub mod assert; pub mod coinlist; pub mod generic; pub mod getters; diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/helpers/msgs.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/msgs.rs new file mode 100644 index 000000000..315b48863 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/msgs.rs @@ -0,0 +1,58 @@ +use crate::{state::POSITION, ContractError}; +use cosmwasm_std::{attr, Addr, Attribute, BankMsg, Coin, Deps, Env, Uint128}; +use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::{ + MsgCollectIncentives, MsgCollectSpreadRewards, +}; + +pub fn refund_bank_msg( + receiver: Addr, + refund0: Option, + refund1: Option, +) -> Result)>, ContractError> { + let mut attributes: Vec = vec![]; + let mut coins: Vec = vec![]; + + if let Some(refund0) = refund0 { + if refund0.amount > Uint128::zero() { + attributes.push(attr("refund0", refund0.amount)); + coins.push(refund0) + } + } + if let Some(refund1) = refund1 { + if refund1.amount > Uint128::zero() { + attributes.push(attr("refund1", refund1.amount)); + coins.push(refund1) + } + } + let result: Option<(BankMsg, Vec)> = if !coins.is_empty() { + Some(( + BankMsg::Send { + to_address: receiver.to_string(), + amount: coins, + }, + attributes, + )) + } else { + None + }; + Ok(result) +} + +pub fn collect_incentives_msg(deps: Deps, env: Env) -> Result { + let position = POSITION.load(deps.storage)?; + Ok(MsgCollectIncentives { + position_ids: vec![position.position_id], + sender: env.contract.address.into(), + }) +} + +pub fn collect_spread_rewards_msg( + deps: Deps, + env: Env, +) -> Result { + let position = POSITION.load(deps.storage)?; + Ok(MsgCollectSpreadRewards { + position_ids: vec![position.position_id], + sender: env.contract.address.into(), + }) +} diff --git a/smart-contracts/contracts/cl-vault/src/helpers/prepend.rs b/smart-contracts/osmosis/contracts/cl-vault/src/helpers/prepend.rs similarity index 100% rename from smart-contracts/contracts/cl-vault/src/helpers/prepend.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/helpers/prepend.rs diff --git a/smart-contracts/contracts/cl-vault/src/instantiate.rs b/smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs similarity index 85% rename from smart-contracts/contracts/cl-vault/src/instantiate.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs index 32d5e5b86..023ebe70f 100644 --- a/smart-contracts/contracts/cl-vault/src/instantiate.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/instantiate.rs @@ -11,14 +11,14 @@ use osmosis_std::types::osmosis::tokenfactory::v1beta1::{ MsgCreateDenom, MsgCreateDenomResponse, MsgMint, }; -use crate::helpers::assert::must_pay_one_or_two; -use crate::helpers::getters::get_asset0_value; +use crate::error::assert_deposits; +use crate::helpers::getters::{get_unused_pair_balances, get_value_wrt_asset0}; use crate::math::tick::{build_tick_exp_cache, verify_tick_exp_cache}; use crate::msg::InstantiateMsg; use crate::reply::Replies; use crate::state::{ - Metadata, MigrationStatus, PoolConfig, Position, ADMIN_ADDRESS, METADATA, MIGRATION_STATUS, - POOL_CONFIG, POSITION, RANGE_ADMIN, VAULT_CONFIG, VAULT_DENOM, + Metadata, PoolConfig, Position, ADMIN_ADDRESS, METADATA, POOL_CONFIG, POSITION, RANGE_ADMIN, + VAULT_CONFIG, VAULT_DENOM, }; use crate::vault::concentrated_liquidity::{create_position, get_position}; use crate::ContractError; @@ -50,15 +50,13 @@ pub fn handle_instantiate( pool_id: msg.pool_id, })? .try_into()?; - - POOL_CONFIG.save( - deps.storage, - &PoolConfig { - pool_id: pool.id, - token0: pool.token0.clone(), - token1: pool.token1.clone(), - }, - )?; + let pool_config = PoolConfig { + pool_id: pool.id, + token0: pool.token0.clone(), + token1: pool.token1.clone(), + }; + assert_deposits(&info.funds, &pool_config)?; + POOL_CONFIG.save(deps.storage, &pool_config)?; METADATA.save( deps.storage, @@ -72,7 +70,6 @@ pub fn handle_instantiate( ADMIN_ADDRESS.save(deps.storage, &admin)?; RANGE_ADMIN.save(deps.storage, &deps.api.addr_validate(&msg.range_admin)?)?; - MIGRATION_STATUS.save(deps.storage, &MigrationStatus::Closed)?; let create_denom_msg: CosmosMsg = MsgCreateDenom { sender: env.contract.address.to_string(), @@ -80,15 +77,14 @@ pub fn handle_instantiate( } .into(); - // in order to create the initial position, we need some funds to throw in there, these funds should be seen as burned - let (initial0, initial1) = must_pay_one_or_two(&info, (pool.token0, pool.token1))?; + let vault_funds = get_unused_pair_balances(&deps.as_ref(), &env, &pool_config)?; let create_position_msg = create_position( deps, &env, msg.initial_lower_tick, msg.initial_upper_tick, - vec![initial0, initial1], + vault_funds, Uint128::zero(), Uint128::zero(), )?; @@ -150,7 +146,7 @@ pub fn handle_instantiate_create_position_reply( .querier .query_balance(&env.contract.address, assets[1].denom.clone())?; - let asset_value = get_asset0_value( + let asset_value = get_value_wrt_asset0( deps.storage, &deps.querier, assets[0].amount + free_asset0.amount, diff --git a/smart-contracts/contracts/cl-vault/src/lib.rs b/smart-contracts/osmosis/contracts/cl-vault/src/lib.rs similarity index 100% rename from smart-contracts/contracts/cl-vault/src/lib.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/lib.rs diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/math/mod.rs b/smart-contracts/osmosis/contracts/cl-vault/src/math/mod.rs new file mode 100644 index 000000000..e127cb341 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/math/mod.rs @@ -0,0 +1 @@ +pub mod tick; diff --git a/smart-contracts/contracts/cl-vault/src/math/tick.rs b/smart-contracts/osmosis/contracts/cl-vault/src/math/tick.rs similarity index 91% rename from smart-contracts/contracts/cl-vault/src/math/tick.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/math/tick.rs index 13eb50254..bf2d28f85 100644 --- a/smart-contracts/contracts/cl-vault/src/math/tick.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/math/tick.rs @@ -1,5 +1,3 @@ -use std::str::FromStr; - use cosmwasm_std::{Decimal, Decimal256, OverflowError, Storage, Uint128}; use crate::{ @@ -7,8 +5,8 @@ use crate::{ ContractError, }; -const MAX_SPOT_PRICE: &str = "100000000000000000000000000000000000000"; // 10^35 -const MIN_SPOT_PRICE: &str = "0.000000000001"; // 10^-12 +const MAX_SPOT_PRICE: u128 = 100_000_000_000_000_000_000_000_000_000_000_000_000u128; // 10^35 +const MIN_SPOT_PRICE_DENOMINATOR: u128 = 1_000_000_000_000u128; const EXPONENT_AT_PRICE_ONE: i64 = -6; const MIN_INITIALIZED_TICK: i64 = -108000000; const MAX_TICK: i128 = 342000000; @@ -19,10 +17,11 @@ pub fn tick_to_price(tick_index: i64) -> Result { return Ok(Decimal256::one()); } - let geometric_exponent_increment_distance_in_ticks = Decimal::from_str("9")? + let geometric_exponent_increment_distance_in_ticks: i64 = Decimal::from_ratio(9u128, 1u128) .checked_mul(_pow_ten_internal_dec(-EXPONENT_AT_PRICE_ONE)?)? - .to_string() - .parse::()?; + .to_uint_floor() + .u128() + .try_into()?; // Check that the tick index is between min and max value if tick_index < MIN_INITIALIZED_TICK { @@ -56,24 +55,23 @@ pub fn tick_to_price(tick_index: i64) -> Result { // Finally, we can calculate the price let price: Decimal256 = if num_additive_ticks < 0 { - _pow_ten_internal_dec(geometric_exponent_delta)? - .checked_sub( - Decimal::from_str(&num_additive_ticks.abs().to_string())?.checked_mul( - Decimal::from_str(¤t_additive_increment_in_ticks.to_string())?, - )?, - )? - .into() + let num_additive_ticks: u128 = num_additive_ticks.abs().try_into()?; + pow_ten_internal_dec_256(geometric_exponent_delta)?.checked_sub( + Decimal256::checked_from_ratio(num_additive_ticks, 1u128)? + .checked_mul(current_additive_increment_in_ticks)?, + )? } else { + let num_additive_ticks: u128 = num_additive_ticks.try_into()?; pow_ten_internal_dec_256(geometric_exponent_delta)?.checked_add( - Decimal256::from_str(&num_additive_ticks.to_string())? + Decimal256::checked_from_ratio(num_additive_ticks, 1u128)? .checked_mul(current_additive_increment_in_ticks)?, )? }; // defense in depth, this logic would not be reached due to use having checked if given tick is in between // min tick and max tick. - if price > Decimal256::from_str(MAX_SPOT_PRICE)? - || price < Decimal256::from_str(MIN_SPOT_PRICE)? + if price > Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128)? + || price < Decimal256::checked_from_ratio(1u128, MIN_SPOT_PRICE_DENOMINATOR)? { return Err(ContractError::PriceBoundError { price }); } @@ -81,8 +79,8 @@ pub fn tick_to_price(tick_index: i64) -> Result { } pub fn price_to_tick(storage: &mut dyn Storage, price: Decimal256) -> Result { - if price > Decimal256::from_str(MAX_SPOT_PRICE)? - || price < Decimal256::from_str(MIN_SPOT_PRICE)? + if price > Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128)? + || price < Decimal256::checked_from_ratio(1u128, MIN_SPOT_PRICE_DENOMINATOR)? { return Err(ContractError::PriceBoundError { price }); } @@ -159,8 +157,8 @@ fn _pow_ten_internal_dec(exponent: i64) -> Result { // same as pow_ten_internal but returns a Decimal to work with negative exponents fn pow_ten_internal_dec_256(exponent: i64) -> Result { - let p = Decimal256::from_str("10")?.checked_pow(exponent.unsigned_abs() as u32)?; - // let p = 10_u128.pow(exponent as u32); + let p = Decimal256::checked_from_ratio(10u128, 1u128)? + .checked_pow(exponent.unsigned_abs() as u32)?; if exponent >= 0 { Ok(p) } else { @@ -173,7 +171,7 @@ pub fn build_tick_exp_cache(storage: &mut dyn Storage) -> Result<(), ContractErr let mut max_price = Decimal256::one(); let mut cur_exp_index = 0i64; - while max_price < Decimal256::from_str(MAX_SPOT_PRICE)? { + while max_price < Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128)? { let initial_price = pow_ten_internal_dec_256(cur_exp_index)?; let max_price_temp = pow_ten_internal_dec_256(cur_exp_index + 1)?; let additive_increment_per_tick = @@ -213,7 +211,7 @@ pub fn build_tick_exp_cache(storage: &mut dyn Storage) -> Result<(), ContractErr let mut min_price = Decimal256::one(); cur_exp_index = -1; - while min_price > Decimal256::from_str(MIN_SPOT_PRICE)? { + while min_price > Decimal256::checked_from_ratio(1u128, MIN_SPOT_PRICE_DENOMINATOR)? { let initial_price = pow_ten_internal_dec_256(cur_exp_index)?; let max_price_temp = pow_ten_internal_dec_256(cur_exp_index + 1)?; let additive_increment_per_tick = @@ -259,7 +257,7 @@ pub fn verify_tick_exp_cache(storage: &dyn Storage) -> Result<(), ContractError> // until we reach MAX or MIN price, we should have a cache hit at each increasing or decreasing index let mut max_price = Decimal256::one(); let mut positive_index = 0i64; - let max_spot_price = Decimal256::from_str(MAX_SPOT_PRICE)?; + let max_spot_price = Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128)?; // Verify positive indices while max_price < max_spot_price { @@ -276,7 +274,7 @@ pub fn verify_tick_exp_cache(storage: &dyn Storage) -> Result<(), ContractError> // Verify negative indices let mut min_price = Decimal256::one(); let mut negative_index = 0; - let min_spot_price = Decimal256::from_str(MIN_SPOT_PRICE)?; + let min_spot_price = Decimal256::checked_from_ratio(1u128, MIN_SPOT_PRICE_DENOMINATOR)?; while min_price > min_spot_price { let tick_exp_index_data = TICK_EXP_CACHE.load(storage, negative_index).map_err(|_| { @@ -295,6 +293,7 @@ pub fn verify_tick_exp_cache(storage: &dyn Storage) -> Result<(), ContractError> mod tests { use super::*; use cosmwasm_std::{testing::mock_dependencies, Order}; + use std::str::FromStr; #[test] fn test_verify_tick_cache() { @@ -419,7 +418,7 @@ mod tests { // example8 let tick_index = MAX_TICK as i64; - let expected_price = Decimal256::from_str(MAX_SPOT_PRICE).unwrap(); + let expected_price = Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128).unwrap(); let price = tick_to_price(tick_index).unwrap(); assert_eq!(price, expected_price); @@ -532,7 +531,7 @@ mod tests { assert_eq!(tick_index, expected_tick_index); // example8 - price = Decimal256::from_str(MAX_SPOT_PRICE).unwrap(); + price = Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128).unwrap(); expected_tick_index = MAX_TICK; tick_index = price_to_tick(deps.as_mut().storage, price).unwrap(); assert_eq!(tick_index, expected_tick_index); @@ -610,11 +609,12 @@ mod tests { assert_eq!(tick_index, expected_tick_index); // example19 - price = Decimal256::from_str(MAX_SPOT_PRICE).unwrap() + Decimal256::one(); + price = Decimal256::checked_from_ratio(MAX_SPOT_PRICE, 1u128).unwrap() + Decimal256::one(); assert!(price_to_tick(deps.as_mut().storage, price).is_err()); // example20 - price = Decimal256::from_str(MIN_SPOT_PRICE).unwrap() / Decimal256::from_str("10").unwrap(); + price = Decimal256::checked_from_ratio(1u128, MIN_SPOT_PRICE_DENOMINATOR).unwrap() + / Decimal256::from_str("10").unwrap(); assert!(price_to_tick(deps.as_mut().storage, price).is_err()); } } diff --git a/smart-contracts/contracts/cl-vault/src/msg.rs b/smart-contracts/osmosis/contracts/cl-vault/src/msg.rs similarity index 84% rename from smart-contracts/contracts/cl-vault/src/msg.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/msg.rs index be196a7db..ce323ccc2 100644 --- a/smart-contracts/contracts/cl-vault/src/msg.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/msg.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Decimal, Uint128}; +use cosmwasm_std::{Addr, Decimal}; use cw_vault_multi_standard::{VaultStandardExecuteMsg, VaultStandardQueryMsg}; use osmosis_std::types::osmosis::poolmanager::v1beta1::SwapAmountInRoute; @@ -15,8 +15,6 @@ use crate::state::{Metadata, VaultConfig}; pub enum ExtensionExecuteMsg { /// Execute Admin operations. Admin(AdminExtensionExecuteMsg), - /// An interface of certain vault interaction with forced values for authz - Authz(AuthzExtension), /// Rebalance our liquidity range based on an off-chain message /// given to us by RANGE_ADMIN ModifyRange(ModifyRangeMsg), @@ -26,19 +24,11 @@ pub enum ExtensionExecuteMsg { Autocompound {}, /// Distribute any rewards over all users CollectRewards {}, - /// MigrationStep - MigrationStep { amount_of_users: Uint128 }, /// SwapNonVaultFunds - SwapNonVaultFunds { swap_operations: Vec }, -} - -/// Extension messages for Authz. This interface basically reexports certain vault functionality -/// but sets recipient forcibly to None -#[cw_serde] -pub enum AuthzExtension { - ExactDeposit {}, - AnyDeposit { max_slippage: Decimal }, - Redeem { amount: Uint128 }, + SwapNonVaultFunds { + swap_operations: Vec, + twap_window_seconds: Option, + }, } /// Apollo extension messages define functionality that is part of all apollo @@ -100,10 +90,10 @@ pub struct MergePositionMsg { #[cw_serde] pub struct SwapOperation { pub token_in_denom: String, - pub pool_id_0: u64, // the osmosis pool_id as mandatory to have at least the chance to swap on CL pools - pub pool_id_1: u64, // the osmosis pool_id as mandatory to have at least the chance to swap on CL pools - pub forced_swap_route_token_0: Option>, - pub forced_swap_route_token_1: Option>, + pub pool_id_base: u64, // the osmosis pool_id as mandatory to have at least the chance to swap on CL pools + pub pool_id_quote: u64, // the osmosis pool_id as mandatory to have at least the chance to swap on CL pools + pub forced_swap_route_base: Option>, + pub forced_swap_route_quote: Option>, } /// Extension query messages for an apollo autocompounding vault @@ -175,5 +165,6 @@ pub struct InstantiateMsg { #[cw_serde] pub struct MigrateMsg { - pub dex_router: Addr, + pub swap_admin: Addr, + pub twap_window_seconds: u64, } diff --git a/smart-contracts/contracts/cl-vault/src/query.rs b/smart-contracts/osmosis/contracts/cl-vault/src/query.rs similarity index 96% rename from smart-contracts/contracts/cl-vault/src/query.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/query.rs index f85eaf672..c0f17a5b3 100644 --- a/smart-contracts/contracts/cl-vault/src/query.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/query.rs @@ -144,7 +144,7 @@ pub fn query_assets_from_shares( let vault_balance = CoinList::from_coins(vec![vault_assets.token0, vault_assets.token1]); - let assets_from_shares = vault_balance.mul_ratio(Decimal::from_ratio(shares, vault_supply)); + let assets_from_shares = vault_balance.mul_ratio(Decimal::from_ratio(shares, vault_supply))?; Ok(AssetsBalanceResponse { balances: assets_from_shares.coins(), @@ -177,7 +177,7 @@ pub fn query_user_balance( pub fn query_total_assets(deps: Deps, env: Env) -> Result { let position = get_position(deps.storage, &deps.querier)?; let pool = POOL_CONFIG.load(deps.storage)?; - let unused_balance = get_unused_balances(&deps.querier, &env)?; + let unused_balance = get_unused_balances(&deps.querier, &env.contract.address)?; // add token0 unused balance to what's in the position let mut token0 = position @@ -190,7 +190,7 @@ pub fn query_total_assets(deps: Deps, env: Env) -> Result Result = Item::new("vault_config"); - -#[deprecated] -pub const OLD_POSITION: Item = Item::new("position"); - -/// REWARDS: Current rewards are the rewards being gathered, these can be both spread rewards as well as incentives -#[deprecated] -pub const STRATEGIST_REWARDS: Item = Item::new("strategist_rewards"); - -/// Shared collection+distribution states -#[deprecated] -pub const USER_REWARDS: Map = Map::new("user_rewards"); - -#[deprecated] -pub const CURRENT_BALANCE: Item<(Uint128, Uint128)> = Item::new("current_balance"); // CURRENT_BALANCE is intended as CURRENT_SWAP_BALANCE - -#[deprecated] -pub const CURRENT_SWAP: Item<(SwapDirection, Uint128)> = Item::new("current_swap"); - -/// metadata useful for display purposes #[cw_serde] pub struct Metadata { /// the underlying thesis of the vault's positions, eg aggresive pub thesis: String, - /// the name of the vault pub name: String, } @@ -41,42 +16,19 @@ pub const METADATA: Item = Item::new("metadata"); pub const ADMIN_ADDRESS: Item = Item::new("admin_address"); pub const RANGE_ADMIN: Item = Item::new("range_admin"); -/// VAULT_CONFIG: Base config struct for the contract. #[cw_serde] pub struct VaultConfig { - /// Percentage of profit to be charged as performance fee pub performance_fee: Decimal, - /// Account to receive fee payments pub treasury: Addr, - /// swap max slippage pub swap_max_slippage: Decimal, - /// Dex router address pub dex_router: Addr, + pub swap_admin: Addr, + pub twap_window_seconds: u64, } -/// OLD_VAULT_CONFIG: Base config struct for the contract (pre-autocompound implementation). -#[cw_serde] -pub struct OldVaultConfig { - /// Percentage of profit to be charged as performance fee - pub performance_fee: Decimal, - /// Account to receive fee payments - pub treasury: Addr, - /// swap max slippage - pub swap_max_slippage: Decimal, -} - -pub const VAULT_CONFIG: Item = Item::new("vault_config_v2"); +pub const VAULT_CONFIG: Item = Item::new("vault_config"); pub const VAULT_DENOM: Item = Item::new("vault_denom"); -/// MIGRATION_STATUS: Is a temporary state we need to paginate the migration process for the auto-compounding upgrade // TODO: Deprecate! -#[cw_serde] -pub enum MigrationStatus { - Open, - Closed, -} -pub const MIGRATION_STATUS: Item = Item::new("migration_status"); - -/// POOL_CONFIG #[cw_serde] pub struct PoolConfig { pub pool_id: u64, @@ -85,19 +37,13 @@ pub struct PoolConfig { } impl PoolConfig { - pub fn pool_contains_token(&self, token: impl Into) -> bool { - [&self.token0, &self.token1].contains(&&token.into()) + pub fn pool_contains_token(&self, token: &str) -> bool { + self.token0 == token || self.token1 == token } } pub const POOL_CONFIG: Item = Item::new("pool_config"); -/// POSITION -#[cw_serde] -pub struct OldPosition { - pub position_id: u64, -} - #[cw_serde] pub struct Position { pub position_id: u64, @@ -109,7 +55,6 @@ pub const POSITION: Item = Item::new("position_v2"); pub const SHARES: Map = Map::new("shares"); -/// The merge of positions currently being executed pub const CURRENT_MERGE: Deque = Deque::new("current_merge"); #[cw_serde] @@ -127,36 +72,19 @@ pub struct CurrentDeposit { pub sender: Addr, } -pub const CURRENT_DEPOSIT: Item = Item::new("current_deposit"); - -#[cw_serde] -pub enum RewardsStatus { - Ready, - Collecting, - Distributing, -} - -/// Swap helper states -pub const CURRENT_SWAP_ANY_DEPOSIT: Item<(SwapDirection, Uint128, Addr, (Uint128, Uint128))> = +pub const CURRENT_SWAP_ANY_DEPOSIT: Item<(Coin, Addr, (Uint128, Uint128))> = Item::new("current_swap_any_deposit"); -/// DEX_ROUTER: The address of the dex router contract pub const DEX_ROUTER: Item = Item::new("dex_router"); #[cw_serde] pub struct ModifyRangeState { - // pre-withdraw state items pub lower_tick: i64, pub upper_tick: i64, - // the max slippage for modifying the range pub max_slippage: Decimal, - // pre-deposit state items pub new_range_position_ids: Vec, - // the percent of funds to try for the next swap pub ratio_of_swappable_funds_to_use: Decimal, - // the twap window to use for the swap in seconds pub twap_window_seconds: u64, - // the recommended path to take for the swap pub forced_swap_route: Option>, } diff --git a/smart-contracts/contracts/cl-vault/src/test_helpers.rs b/smart-contracts/osmosis/contracts/cl-vault/src/test_helpers.rs similarity index 75% rename from smart-contracts/contracts/cl-vault/src/test_helpers.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/test_helpers.rs index 9402048c6..e92175556 100644 --- a/smart-contracts/contracts/cl-vault/src/test_helpers.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/test_helpers.rs @@ -1,9 +1,10 @@ use std::marker::PhantomData; -use cosmwasm_std::testing::{BankQuerier, MockApi, MockStorage, MOCK_CONTRACT_ADDR}; +use cosmwasm_std::testing::{mock_info, BankQuerier, MockApi, MockStorage, MOCK_CONTRACT_ADDR}; use cosmwasm_std::{ - from_json, to_json_binary, Addr, BankQuery, Binary, Coin, ContractResult as CwContractResult, - Decimal, Empty, MessageInfo, OwnedDeps, Querier, QuerierResult, QueryRequest, + coin, from_json, to_json_binary, Addr, BankQuery, Binary, Coin, + ContractResult as CwContractResult, Decimal, DepsMut, Empty, Env, MessageInfo, OwnedDeps, + Querier, QuerierResult, QueryRequest, }; use osmosis_std::types::cosmos::bank::v1beta1::{QuerySupplyOfRequest, QuerySupplyOfResponse}; use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::Pool; @@ -19,11 +20,20 @@ use osmosis_std::types::{ }, }; +use crate::contract::instantiate; use crate::math::tick::tick_to_price; +use crate::msg::InstantiateMsg; use crate::state::{ PoolConfig, Position, VaultConfig, POOL_CONFIG, POSITION, RANGE_ADMIN, VAULT_CONFIG, + VAULT_DENOM, }; +pub const POOL_ID: u64 = 1; +pub const POSITION_ID: u64 = 101; +pub const BASE_DENOM: &str = "base"; +pub const QUOTE_DENOM: &str = "quote"; +pub const TEST_VAULT_DENOM: &str = "uqsr"; + pub struct QuasarQuerier { position: FullPositionBreakdown, current_tick: i64, @@ -54,7 +64,7 @@ impl QuasarQuerier { impl Querier for QuasarQuerier { fn raw_query(&self, bin_request: &[u8]) -> cosmwasm_std::QuerierResult { - let request: QueryRequest = from_json(&Binary::from(bin_request)).unwrap(); + let request: QueryRequest = from_json(Binary::from(bin_request)).unwrap(); match request { QueryRequest::Stargate { path, data } => match path.as_str() { "/osmosis.concentratedliquidity.v1beta1.Query/PositionById" => { @@ -89,11 +99,11 @@ impl Querier for QuasarQuerier { )) } "/cosmos.bank.v1beta.Query/Balance" => { - let query: BankQuery = from_json(&Binary::from(bin_request)).unwrap(); + let query: BankQuery = from_json(Binary::from(bin_request)).unwrap(); self.bank.query(&query) } "/cosmos.bank.v1beta.Query/AllBalances" => { - let query: BankQuery = from_json(&Binary::from(bin_request)).unwrap(); + let query: BankQuery = from_json(Binary::from(bin_request)).unwrap(); self.bank.query(&query) } "/osmosis.poolmanager.v1beta1.Query/Pool" => { @@ -104,10 +114,10 @@ impl Querier for QuasarQuerier { address: "idc".to_string(), incentives_address: "not being used".to_string(), spread_rewards_address: "not being used".to_string(), - id: 1, + id: POOL_ID, current_tick_liquidity: "100".to_string(), - token0: "uosmo".to_string(), - token1: "uion".to_string(), + token0: BASE_DENOM.to_string(), + token1: QUOTE_DENOM.to_string(), current_sqrt_price: "not used".to_string(), current_tick: self.current_tick, tick_spacing: 100, @@ -154,7 +164,6 @@ impl Querier for QuasarQuerier { kind: format!("Unmocked query type: {request:?}"), }), } - // QuerierResult::Ok(ContractResult::Ok(to_json_binary(&"hello").unwrap())) } } @@ -168,36 +177,36 @@ pub fn mock_deps_with_querier_with_balance( querier: QuasarQuerier::new_with_balances( FullPositionBreakdown { position: Some(OsmoPosition { - position_id: 1, + position_id: POSITION_ID, address: MOCK_CONTRACT_ADDR.to_string(), - pool_id: 1, + pool_id: POOL_ID, lower_tick: 100, upper_tick: 1000, join_time: None, liquidity: "1000000.1".to_string(), }), asset0: Some(OsmoCoin { - denom: "token0".to_string(), + denom: BASE_DENOM.to_string(), amount: "1000000".to_string(), }), asset1: Some(OsmoCoin { - denom: "token1".to_string(), + denom: QUOTE_DENOM.to_string(), amount: "1000000".to_string(), }), claimable_spread_rewards: vec![ OsmoCoin { - denom: "token0".to_string(), + denom: BASE_DENOM.to_string(), amount: "100".to_string(), }, OsmoCoin { - denom: "token1".to_string(), + denom: QUOTE_DENOM.to_string(), amount: "100".to_string(), }, ], claimable_incentives: vec![], forfeited_incentives: vec![], }, - 500, + 0, balances, ), custom_query_type: PhantomData, @@ -210,9 +219,9 @@ pub fn mock_deps_with_querier_with_balance( .save( storage, &PoolConfig { - pool_id: 1, - token0: "token0".to_string(), - token1: "token1".to_string(), + pool_id: POOL_ID, + token0: BASE_DENOM.to_string(), + token1: QUOTE_DENOM.to_string(), }, ) .unwrap(); @@ -224,6 +233,8 @@ pub fn mock_deps_with_querier_with_balance( treasury: Addr::unchecked("treasure"), swap_max_slippage: Decimal::from_ratio(1u128, 20u128), dex_router: Addr::unchecked("dex_router"), + swap_admin: Addr::unchecked("swap_admin"), + twap_window_seconds: 24u64, }, ) .unwrap(); @@ -231,7 +242,7 @@ pub fn mock_deps_with_querier_with_balance( .save( storage, &crate::state::Position { - position_id: 1, + position_id: POSITION_ID, join_time: 0, claim_after: None, }, @@ -241,40 +252,36 @@ pub fn mock_deps_with_querier_with_balance( deps } -pub fn mock_deps_with_querier( - info: &MessageInfo, -) -> OwnedDeps { - let position_id = 1; - - let mut deps = OwnedDeps { +pub fn mock_deps_with_querier() -> OwnedDeps { + OwnedDeps { storage: MockStorage::default(), api: MockApi::default(), querier: QuasarQuerier::new( FullPositionBreakdown { position: Some(OsmoPosition { - position_id, + position_id: POSITION_ID, address: MOCK_CONTRACT_ADDR.to_string(), - pool_id: 1, + pool_id: POOL_ID, lower_tick: 100, upper_tick: 1000, join_time: None, liquidity: "1000000.1".to_string(), }), asset0: Some(OsmoCoin { - denom: "token0".to_string(), + denom: BASE_DENOM.to_string(), amount: "1000000".to_string(), }), asset1: Some(OsmoCoin { - denom: "token1".to_string(), + denom: QUOTE_DENOM.to_string(), amount: "1000000".to_string(), }), claimable_spread_rewards: vec![ OsmoCoin { - denom: "token0".to_string(), + denom: BASE_DENOM.to_string(), amount: "100".to_string(), }, OsmoCoin { - denom: "token1".to_string(), + denom: QUOTE_DENOM.to_string(), amount: "100".to_string(), }, ], @@ -284,53 +291,45 @@ pub fn mock_deps_with_querier( 500, ), custom_query_type: PhantomData, - }; + } +} - let storage = &mut deps.storage; +pub fn get_init_msg(admin: &str) -> InstantiateMsg { + InstantiateMsg { + admin: admin.to_string(), + pool_id: POOL_ID, + config: VaultConfig { + performance_fee: Decimal::percent(10), + treasury: Addr::unchecked(admin), + swap_max_slippage: Decimal::percent(95), + dex_router: Addr::unchecked(admin), + swap_admin: Addr::unchecked(admin), + twap_window_seconds: 24u64, + }, + vault_token_subdenom: "utestvault".to_string(), + range_admin: admin.to_string(), + initial_lower_tick: 1, + initial_upper_tick: 100, + thesis: "Test thesis".to_string(), + name: "Contract".to_string(), + } +} - POSITION - .save( - storage, - &Position { - position_id, - join_time: 0, - claim_after: None, - }, - ) - .unwrap(); - - RANGE_ADMIN.save(storage, &info.sender).unwrap(); - POOL_CONFIG - .save( - storage, - &PoolConfig { - pool_id: 1, - token0: "token0".to_string(), - token1: "token1".to_string(), - }, - ) - .unwrap(); - VAULT_CONFIG - .save( - storage, - &VaultConfig { - performance_fee: Decimal::zero(), - treasury: Addr::unchecked("treasure"), - swap_max_slippage: Decimal::from_ratio(1u128, 20u128), - dex_router: Addr::unchecked("dex_router"), - }, - ) +pub fn instantiate_contract(mut deps: DepsMut, env: Env, admin: &str) { + let msg = get_init_msg(admin); + let info = mock_info(admin, &[coin(100, BASE_DENOM), coin(100, QUOTE_DENOM)]); + assert!(instantiate(deps.branch(), env, info, msg).is_ok()); + VAULT_DENOM + .save(deps.storage, &TEST_VAULT_DENOM.to_string()) .unwrap(); POSITION .save( - storage, - &crate::state::Position { - position_id: 1, + deps.storage, + &Position { + position_id: POSITION_ID, join_time: 0, claim_after: None, }, ) .unwrap(); - - deps } diff --git a/smart-contracts/contracts/cl-vault/src/vault/admin.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/admin.rs similarity index 93% rename from smart-contracts/contracts/cl-vault/src/vault/admin.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/vault/admin.rs index 61e239095..6f176075d 100644 --- a/smart-contracts/contracts/cl-vault/src/vault/admin.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/admin.rs @@ -1,4 +1,4 @@ -use crate::helpers::assert::assert_admin; +use crate::error::assert_admin; use crate::math::tick::build_tick_exp_cache; use crate::state::{ Metadata, VaultConfig, ADMIN_ADDRESS, DEX_ROUTER, METADATA, RANGE_ADMIN, VAULT_CONFIG, @@ -43,8 +43,9 @@ pub fn execute_update_admin( address: String, ) -> Result { nonpayable(&info).map_err(|_| ContractError::NonPayable {})?; + assert_admin(deps.storage, &info.sender)?; - let previous_admin = assert_admin(deps.as_ref(), &info.sender)?; + let previous_admin = ADMIN_ADDRESS.load(deps.storage)?; let new_admin = deps.api.addr_validate(&address)?; ADMIN_ADDRESS.save(deps.storage, &new_admin)?; @@ -66,7 +67,7 @@ pub fn execute_update_range_admin( address: String, ) -> Result { nonpayable(&info).map_err(|_| ContractError::NonPayable {})?; - assert_admin(deps.as_ref(), &info.sender)?; + assert_admin(deps.storage, &info.sender)?; let previous_admin = RANGE_ADMIN.load(deps.storage)?; let new_admin = deps.api.addr_validate(&address)?; @@ -86,7 +87,7 @@ pub fn execute_update_dex_router( address: Option, ) -> Result { nonpayable(&info).map_err(|_| ContractError::NonPayable {})?; - assert_admin(deps.as_ref(), &info.sender)?; + assert_admin(deps.storage, &info.sender)?; match address.clone() { Some(address) => { @@ -115,7 +116,7 @@ pub fn execute_update_config( updates: VaultConfig, ) -> Result { nonpayable(&info).map_err(|_| ContractError::NonPayable {})?; - assert_admin(deps.as_ref(), &info.sender)?; + assert_admin(deps.storage, &info.sender)?; deps.api.addr_validate(updates.dex_router.as_str())?; deps.api.addr_validate(updates.treasury.as_str())?; @@ -140,7 +141,7 @@ pub fn execute_update_metadata( updates: Metadata, ) -> Result { nonpayable(&info).map_err(|_| ContractError::NonPayable {})?; - assert_admin(deps.as_ref(), &info.sender)?; + assert_admin(deps.storage, &info.sender)?; METADATA.save(deps.storage, &updates)?; @@ -156,7 +157,7 @@ pub fn execute_build_tick_exp_cache( info: MessageInfo, ) -> Result { nonpayable(&info).map_err(|_| ContractError::NonPayable {})?; - assert_admin(deps.as_ref(), &info.sender)?; + assert_admin(deps.storage, &info.sender)?; build_tick_exp_cache(deps.storage)?; @@ -181,8 +182,7 @@ mod tests { let mut deps = mock_dependencies(); build_tick_exp_cache(&mut deps.storage).unwrap(); - let verify_resp = verify_tick_exp_cache(&mut deps.storage).unwrap(); - assert_eq!((), verify_resp); + assert!(verify_tick_exp_cache(&deps.storage).is_ok()); } #[test] @@ -332,6 +332,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(100u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("old_dex_router"), + swap_admin: Addr::unchecked("old_swap_admin"), + twap_window_seconds: 0u64, }; let mut deps = mock_dependencies(); ADMIN_ADDRESS.save(deps.as_mut().storage, &admin).unwrap(); @@ -344,6 +346,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(200u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("new_dex_router"), + swap_admin: Addr::unchecked("new_swap_admin"), + twap_window_seconds: 24u64, }; let info_admin: MessageInfo = mock_info("admin", &[]); @@ -362,6 +366,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(100u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("old_dex_router"), + swap_admin: Addr::unchecked("old_swap_admin"), + twap_window_seconds: 0u64, }; let mut deps = mock_dependencies(); ADMIN_ADDRESS.save(deps.as_mut().storage, &admin).unwrap(); @@ -374,6 +380,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(200u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("new_dex_router"), + swap_admin: Addr::unchecked("new_swap_admin"), + twap_window_seconds: 24u64, }; let info_not_admin = mock_info("not_admin", &[]); @@ -392,6 +400,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(100u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("old_dex_router"), + swap_admin: Addr::unchecked("old_swap_admin"), + twap_window_seconds: 0u64, }; let mut deps = mock_dependencies(); ADMIN_ADDRESS.save(deps.as_mut().storage, &admin).unwrap(); @@ -404,6 +414,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(200u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("new_dex_router"), + swap_admin: Addr::unchecked("new_swap_admin"), + twap_window_seconds: 24u64, }; let info_admin_with_funds = mock_info("admin", &[coin(1, "token")]); @@ -420,6 +432,8 @@ mod tests { performance_fee: Decimal::new(Uint128::from(100u128)), swap_max_slippage: Decimal::from_ratio(1u128, 100u128), dex_router: Addr::unchecked("old_dex_router"), + swap_admin: Addr::unchecked("old_swap_admin"), + twap_window_seconds: 24u64, }; let mut deps = mock_dependencies(); ADMIN_ADDRESS.save(deps.as_mut().storage, &admin).unwrap(); @@ -526,7 +540,7 @@ mod tests { let not_admin = Addr::unchecked("not_admin"); ADMIN_ADDRESS.save(deps.as_mut().storage, &admin).unwrap(); - assert!(assert_admin(deps.as_ref(), &admin).is_ok()); - assert!(assert_admin(deps.as_ref(), ¬_admin).is_err()); + assert!(assert_admin(deps.as_ref().storage, &admin).is_ok()); + assert!(assert_admin(deps.as_ref().storage, ¬_admin).is_err()); } } diff --git a/smart-contracts/contracts/cl-vault/src/vault/autocompound.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/autocompound.rs similarity index 50% rename from smart-contracts/contracts/cl-vault/src/vault/autocompound.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/vault/autocompound.rs index 96310bbb9..d587fb6ea 100644 --- a/smart-contracts/contracts/cl-vault/src/vault/autocompound.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/autocompound.rs @@ -1,21 +1,14 @@ -use cosmwasm_std::Order; use cosmwasm_std::{ to_json_binary, DepsMut, Env, MessageInfo, Response, SubMsg, SubMsgResult, Uint128, }; -use osmosis_std::cosmwasm_to_proto_coins; -use osmosis_std::types::cosmos::bank::v1beta1::{Input, MsgMultiSend, Output}; use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::ConcentratedliquidityQuerier; use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::MsgCreatePositionResponse; -use crate::helpers::assert::must_pay_one_or_two_from_balance; -use crate::helpers::coinlist::CoinList; -use crate::helpers::getters::get_unused_balances; +use crate::helpers::getters::get_unused_pair_balances; use crate::msg::{ExecuteMsg, MergePositionMsg}; use crate::reply::Replies; -#[allow(deprecated)] -use crate::state::USER_REWARDS; -use crate::state::{MigrationStatus, MIGRATION_STATUS, POOL_CONFIG, POSITION}; -use crate::vault::concentrated_liquidity::create_position; +use crate::state::{Position, POOL_CONFIG, POSITION}; +use crate::vault::{concentrated_liquidity::create_position, merge::MergeResponse}; use crate::ContractError; pub fn execute_autocompound( @@ -39,11 +32,11 @@ pub fn execute_autocompound( .position .ok_or(ContractError::PositionNotFound)?; - let balance = get_unused_balances(&deps.querier, env)?; let pool = POOL_CONFIG.load(deps.storage)?; + let balance = get_unused_pair_balances(&deps.as_ref(), env, &pool)?; - let (token0, token1) = - must_pay_one_or_two_from_balance(balance.coins(), (pool.token0, pool.token1))?; + let token0 = balance[0].clone(); + let token1 = balance[1].clone(); // Create coins_to_send with no zero amounts let mut coins_to_send = vec![]; @@ -109,76 +102,26 @@ pub fn handle_autocompound_reply( )) } -// Migration is a to-depreacate entrypoint useful to migrate from Distribute to Accumulate after Autocompound implementation -pub fn execute_migration_step( +pub fn handle_merge_reply( deps: DepsMut, env: Env, - amount_of_users: Uint128, + data: SubMsgResult, ) -> Result { - let mut migration_status = MIGRATION_STATUS.load(deps.storage)?; - - if matches!(migration_status, MigrationStatus::Closed) { - return Err(ContractError::MigrationStatusClosed {}); - } - - let mut outputs = Vec::new(); - let mut addresses = Vec::new(); - let mut total_amount = CoinList::new(); - - // Iterate user rewards in a paginated fashion - #[allow(deprecated)] - for item in USER_REWARDS - .range(deps.storage, None, None, Order::Ascending) - .take(amount_of_users.u128() as usize) - { - let (address, rewards) = item?; - - // We always push the address in order to remove it later - addresses.push(address.clone()); - // If there are no rewards, we skip the address or we will get invalid_coins error - // This is because USER_REWARDS is holding 0 amount coins. rewards.coins() only returns a list of coins with non-zero amounts, which it could be empty - if rewards.coins().is_empty() { - continue; - } - outputs.push(Output { - address: address.to_string(), - coins: cosmwasm_to_proto_coins(rewards.coins().iter().cloned()), - }); - total_amount.add(rewards)?; - } - - // Remove processed rewards in a separate iteration. - #[allow(deprecated)] - for addr in addresses { - USER_REWARDS.remove(deps.storage, addr); - } - - // Check if this is the last execution. - #[allow(deprecated)] - let is_last_execution = USER_REWARDS - .range(deps.storage, None, None, Order::Ascending) - .next() - .is_none(); - if is_last_execution { - migration_status = MigrationStatus::Closed; - MIGRATION_STATUS.save(deps.storage, &migration_status)?; - } - - let mut response = Response::new(); - // Only if there are rewards append the send_message - if !total_amount.is_empty() { - let send_message = MsgMultiSend { - inputs: vec![Input { - address: env.contract.address.to_string(), - coins: cosmwasm_to_proto_coins(total_amount.coins().iter().cloned()), - }], - outputs, - }; - response = response.add_message(send_message); - } - response = response - .add_attribute("migration_status", format!("{:?}", migration_status)) - .add_attribute("is_last_execution", is_last_execution.to_string()); + let merge_response: MergeResponse = data.try_into()?; + + let position = POSITION.load(deps.storage)?; + POSITION.save( + deps.storage, + &Position { + position_id: merge_response.new_position_id, + join_time: env.block.time.seconds(), + claim_after: position.claim_after, + }, + )?; - Ok(response) + Ok(Response::new() + .add_attribute("method", "reply") + .add_attribute("action", "handle_merge_reply") + .add_attribute("swap_deposit_merge_status", "success") + .add_attribute("status", "success")) } diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/vault/concentrated_liquidity.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/concentrated_liquidity.rs new file mode 100644 index 000000000..abfee5a3b --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/concentrated_liquidity.rs @@ -0,0 +1,449 @@ +use cosmwasm_std::{Coin, Decimal256, DepsMut, Env, QuerierWrapper, Storage, Uint128, Uint256}; +use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::{ + ConcentratedliquidityQuerier, FullPositionBreakdown, MsgCreatePosition, MsgWithdrawPosition, + Pool, +}; +use osmosis_std::types::osmosis::poolmanager::v1beta1::PoolmanagerQuerier; +use prost::Message; + +use crate::helpers::generic::{round_up_to_nearest_multiple, sort_tokens}; +use crate::{ + state::{POOL_CONFIG, POSITION}, + ContractError, +}; + +pub fn create_position( + deps: DepsMut, + env: &Env, + lower_tick: i64, + upper_tick: i64, + tokens_provided: Vec, + token_min_amount0: Uint128, + token_min_amount1: Uint128, +) -> Result { + let pool_config = POOL_CONFIG.load(deps.storage)?; + let sender = env.contract.address.to_string(); + + let sorted_tokens = sort_tokens(tokens_provided); + + let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; + let tick_spacing = pool_details + .tick_spacing + .try_into() + .expect("tick spacing is too big to fit into i64"); + + let create_position = MsgCreatePosition { + pool_id: pool_config.pool_id, + sender, + lower_tick: round_up_to_nearest_multiple(lower_tick, tick_spacing), + upper_tick: round_up_to_nearest_multiple(upper_tick, tick_spacing), + tokens_provided: sorted_tokens + .into_iter() + .filter(|c| !c.amount.is_zero()) + .map(|c| c.into()) + .collect(), + // An sdk.Int in the Go code + token_min_amount0: token_min_amount0.to_string(), + // An sdk.Int in the Go code + token_min_amount1: token_min_amount1.to_string(), + }; + Ok(create_position) +} + +// TODO verify that liquidity amount should be Decimal256 +pub fn withdraw_from_position( + storage: &dyn Storage, + env: &Env, + liquidity_amount: Decimal256, +) -> Result { + let sender = env.contract.address.to_string(); + let position = POSITION.load(storage)?; + + let withdraw_position = MsgWithdrawPosition { + position_id: position.position_id, + sender, + liquidity_amount: liquidity_amount.atomics().to_string(), + }; + Ok(withdraw_position) +} + +pub fn get_position( + storage: &dyn Storage, + querier: &QuerierWrapper, +) -> Result { + let position = POSITION.load(storage)?; + + let cl_querier = ConcentratedliquidityQuerier::new(querier); + let position = cl_querier.position_by_id(position.position_id)?; + position.position.ok_or(ContractError::PositionNotFound) +} + +pub fn get_cl_pool_info(querier: &QuerierWrapper, pool_id: u64) -> Result { + let pm_querier = PoolmanagerQuerier::new(querier); + let pool = pm_querier.pool(pool_id)?; + + match pool.pool { + Some(pool) => { + let decoded_pool = Message::decode(pool.value.as_ref())?; + Ok(decoded_pool) + } + None => Err(ContractError::PoolNotFound { pool_id }), + } +} + +pub fn _may_get_position( + storage: &dyn Storage, + querier: &QuerierWrapper, + _env: &Env, +) -> Result, ContractError> { + let position = POSITION.may_load(storage)?; + if let Some(position) = position { + let cl_querier = ConcentratedliquidityQuerier::new(querier); + let position = cl_querier.position_by_id(position.position_id)?; + Ok(Some( + position.position.ok_or(ContractError::PositionNotFound)?, + )) + } else { + Ok(None) + } +} + +// see https://uniswap.org/whitepaper-v3.pdf for below formulas (eq 6.29 & 6.30) +pub fn get_liquidity_for_base_token( + amount: Uint256, + sqrt_p: Decimal256, + sqrt_pl: Decimal256, + sqrt_pu: Decimal256, +) -> Result { + if sqrt_p >= sqrt_pu { + return Ok(Uint256::MAX); + } + let sqrt_p = std::cmp::max(sqrt_p, sqrt_pl); + let delta_p = sqrt_pu - sqrt_p; + Ok(amount.checked_mul_floor(sqrt_pu.checked_mul(sqrt_p)?.checked_div(delta_p)?)?) +} + +pub fn get_liquidity_for_quote_token( + amount: Uint256, + sqrt_p: Decimal256, + sqrt_pl: Decimal256, + sqrt_pu: Decimal256, +) -> Result { + if sqrt_p <= sqrt_pl { + return Ok(Uint256::MAX); + } + let sqrt_p = std::cmp::min(sqrt_p, sqrt_pu); + let delta_p = sqrt_p - sqrt_pl; + Ok(amount.checked_div_floor(delta_p)?) +} + +pub fn get_amount_from_liquidity_for_base_token( + liq: Uint256, + sqrt_p: Decimal256, + sqrt_pl: Decimal256, + sqrt_pu: Decimal256, +) -> Result { + let sqrt_p = std::cmp::max(sqrt_p, sqrt_pl); + let delta_p = sqrt_pu.checked_sub(sqrt_p).unwrap_or_default(); + Ok(liq.checked_mul_floor(delta_p.checked_div(sqrt_pu.checked_mul(sqrt_p)?)?)?) +} + +pub fn get_amount_from_liquidity_for_quote_token( + liq: Uint256, + sqrt_p: Decimal256, + sqrt_pl: Decimal256, + sqrt_pu: Decimal256, +) -> Result { + let sqrt_p = std::cmp::min(sqrt_p, sqrt_pu); + let delta_p = sqrt_p.checked_sub(sqrt_pl).unwrap_or_default(); + Ok(liq.checked_mul_floor(delta_p)?) +} + +#[cfg(test)] +mod tests { + use crate::{ + state::{PoolConfig, Position}, + test_helpers::QuasarQuerier, + }; + use cosmwasm_std::{ + assert_approx_eq, coin, + testing::{mock_dependencies, mock_env}, + Coin, Uint128, + }; + + use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::Position as OsmoPosition; + + use super::*; + + #[test] + fn test_create_position() { + let mut deps = mock_dependencies(); + let pool_id = 1; + POOL_CONFIG + .save( + deps.as_mut().storage, + &PoolConfig { + pool_id, + token0: "uosmo".to_string(), + token1: "uatom".to_string(), + }, + ) + .unwrap(); + let qq = QuasarQuerier::new( + FullPositionBreakdown { + position: Some(OsmoPosition { + position_id: 1, + address: "bob".to_string(), + pool_id: 1, + lower_tick: 1, + upper_tick: 100, + join_time: None, + liquidity: "123.214".to_string(), + }), + asset0: Some(coin(1000, "uosmo").into()), + asset1: Some(coin(1000, "uatom").into()), + claimable_spread_rewards: vec![coin(1000, "uosmo").into()], + claimable_incentives: vec![coin(123, "uatom").into()], + forfeited_incentives: vec![], + }, + 100, + ); + + let mut deps_mut = deps.as_mut(); + deps_mut.querier = QuerierWrapper::new(&qq); + + let env = mock_env(); + let lower_tick = 100; + let upper_tick = 200; + let tokens_provided = vec![Coin::new(100, "uosmo"), Coin::new(200, "uatom")]; + let token_min_amount0 = Uint128::new(1000); + let token_min_amount1 = Uint128::new(2000); + + let result = create_position( + deps_mut, + &env, + lower_tick, + upper_tick, + tokens_provided.clone(), + token_min_amount0, + token_min_amount1, + ) + .unwrap(); + + assert_eq!( + result, + MsgCreatePosition { + pool_id, + sender: env.contract.address.into(), + lower_tick, + upper_tick, + tokens_provided: sort_tokens(tokens_provided) + .into_iter() + .map(|c| c.into()) + .collect(), + token_min_amount0: token_min_amount0.to_string(), + token_min_amount1: token_min_amount1.to_string() + } + ); + } + + #[test] + fn test_withdraw_from_position() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let liquidity_amount = Decimal256::from_ratio(100_u128, 1_u128); + + let position_id = 1; + POSITION + .save( + deps.as_mut().storage, + &Position { + position_id, + join_time: 0, + claim_after: None, + }, + ) + .unwrap(); + + let result = withdraw_from_position(&deps.storage, &env, liquidity_amount).unwrap(); + + assert_eq!( + result, + MsgWithdrawPosition { + position_id, + sender: env.contract.address.into(), + liquidity_amount: liquidity_amount.atomics().to_string() + } + ); + } + + #[test] + fn test_get_amount_from_liquidity_for_base_token_if_price_above_range() { + let liq = Uint256::from(50u64); + let sqrt_pl = Decimal256::percent(50); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(200); + let amount = + get_amount_from_liquidity_for_base_token(liq, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_amount = Uint256::zero(); + assert_eq!(amount, expected_amount); + } + + #[test] + fn test_get_amount_from_liquidity_for_base_token_if_price_in_range() { + let liq = Uint256::from(50u64); + let sqrt_pl = Decimal256::percent(25); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(50); + let amount = + get_amount_from_liquidity_for_base_token(liq, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_amount = liq; + assert_eq!(amount, expected_amount); + } + + #[test] + fn test_get_amount_from_liquidity_for_base_token_if_price_below_range() { + let liq = Uint256::from(50u64); + let sqrt_pl = Decimal256::percent(50); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(25); + let amount = + get_amount_from_liquidity_for_base_token(liq, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_amount = liq; + assert_eq!(amount, expected_amount); + } + + #[test] + fn test_get_amount_from_liquidity_for_quote_token_if_price_below_range() { + let liq = Uint256::from(50u64); + let sqrt_pl = Decimal256::percent(50); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(25); + let amount = + get_amount_from_liquidity_for_quote_token(liq, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_amount = Uint256::zero(); + assert_eq!(amount, expected_amount); + } + + #[test] + fn test_get_amount_from_liquidity_for_quote_token_if_price_in_range() { + let liq = Uint256::from(50u64); + let sqrt_pl = Decimal256::percent(25); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(75); + let amount = + get_amount_from_liquidity_for_quote_token(liq, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_amount = Uint256::from(25u64); + assert_eq!(amount, expected_amount); + } + + #[test] + fn test_get_amount_from_liquidity_for_quote_token_if_price_above_range() { + let liq = Uint256::from(50u64); + let sqrt_pl = Decimal256::percent(50); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(200); + let amount = + get_amount_from_liquidity_for_quote_token(liq, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_amount = Uint256::from(25u64); + assert_eq!(amount, expected_amount); + } + + #[test] + fn test_get_liquidity_from_amount_for_base_token_if_price_in_range() { + let amount = Uint256::from(150u64); + let sqrt_pl = Decimal256::percent(10); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(25); + let liq = get_liquidity_for_base_token(amount, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_liq = Uint256::from(49u64); + assert_eq!(liq, expected_liq); + } + + #[test] + fn test_get_liquidity_from_amount_for_base_token_if_price_below_range() { + let amount = Uint256::from(150u64); + let sqrt_pl = Decimal256::percent(25); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(10); + let liq = get_liquidity_for_base_token(amount, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_liq = Uint256::from(49u64); + assert_eq!(liq, expected_liq); + } + + #[test] + fn test_get_liquidity_from_amount_for_quote_token_if_price_in_range() { + let amount = Uint256::from(150u64); + let sqrt_pl = Decimal256::percent(10); + let sqrt_pu = Decimal256::percent(100); + let sqrt_p = Decimal256::percent(60); + let liq = get_liquidity_for_quote_token(amount, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_liq = Uint256::from(300u64); + assert_eq!(liq, expected_liq); + } + + #[test] + fn test_get_liquidity_from_amount_for_quote_token_if_price_above_range() { + let amount = Uint256::from(150u64); + let sqrt_pl = Decimal256::percent(10); + let sqrt_pu = Decimal256::percent(60); + let sqrt_p = Decimal256::percent(100); + let liq = get_liquidity_for_quote_token(amount, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_liq = Uint256::from(300u64); + assert_eq!(liq, expected_liq); + } + + // tests + + #[test] + fn test_get_liquidity_for_base() { + let amount = Uint256::from(1_000_000u64); + let sqrt_pl = Decimal256::percent(65); + let sqrt_pu = Decimal256::percent(130); + let sqrt_p = Decimal256::one(); + let liq = get_liquidity_for_base_token(amount, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_liq = Uint256::from(4_333_333u64); + assert_eq!(liq, expected_liq); + + let final_amount: Uint128 = + get_amount_from_liquidity_for_base_token(liq, sqrt_p, sqrt_pl, sqrt_pu) + .unwrap() + .try_into() + .unwrap(); + assert_approx_eq!(final_amount, amount.try_into().unwrap(), "0.000001"); + + let used_liquidity = Uint256::from(2_857_142u64); + let residual_liquidity = Uint256::from(4_333_333u64) - used_liquidity; + let residual_amount: Uint128 = + get_amount_from_liquidity_for_base_token(residual_liquidity, sqrt_p, sqrt_pl, sqrt_pu) + .unwrap() + .try_into() + .unwrap(); + let expected_residual_amount = Uint128::from(340659u64); + assert_eq!(residual_amount, expected_residual_amount); + + let used_amount = + get_amount_from_liquidity_for_base_token(used_liquidity, sqrt_p, sqrt_pl, sqrt_pu) + .unwrap(); + let residual_amount: Uint128 = (amount - used_amount).try_into().unwrap(); + let expected_residual_amount = Uint128::from(340660u64); + assert_eq!(residual_amount, expected_residual_amount); + } + #[test] + fn test_get_liquidity_for_quote() { + let amount = Uint256::from(1_000_000u64); + let sqrt_pl = Decimal256::percent(65); + let sqrt_pu = Decimal256::percent(130); + let sqrt_p = Decimal256::one(); + let liq = get_liquidity_for_quote_token(amount, sqrt_p, sqrt_pl, sqrt_pu).unwrap(); + let expected_liq = Uint256::from(2_857_142u64); + assert_eq!(liq, expected_liq); + + let final_amount: Uint128 = + get_amount_from_liquidity_for_quote_token(liq, sqrt_p, sqrt_pl, sqrt_pu) + .unwrap() + .try_into() + .unwrap(); + assert_approx_eq!(final_amount, amount.try_into().unwrap(), "0.000001"); + } +} diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs new file mode 100644 index 000000000..ed32f19b0 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/deposit.rs @@ -0,0 +1,406 @@ +use crate::{ + error::assert_deposits, + helpers::{ + getters::{ + get_depositable_tokens, get_single_sided_deposit_0_to_1_swap_amount, + get_single_sided_deposit_1_to_0_swap_amount, get_twap_price, get_value_wrt_asset0, + DepositInfo, + }, + msgs::refund_bank_msg, + }, + query::{query_total_assets, query_total_vault_token_supply}, + reply::Replies, + state::{CURRENT_SWAP_ANY_DEPOSIT, DEX_ROUTER, POOL_CONFIG, SHARES, VAULT_CONFIG, VAULT_DENOM}, + vault::{ + concentrated_liquidity::{get_cl_pool_info, get_position}, + swap::{estimate_swap_min_out_amount, swap_msg}, + }, + ContractError, +}; +use cosmwasm_std::{ + attr, coin, Addr, Coin, Decimal, DepsMut, Env, Fraction, MessageInfo, Response, SubMsg, + SubMsgResult, Uint128, Uint256, +}; +use osmosis_std::types::osmosis::{ + poolmanager::v1beta1::MsgSwapExactAmountInResponse, tokenfactory::v1beta1::MsgMint, +}; + +pub(crate) fn execute_exact_deposit( + mut deps: DepsMut, + env: Env, + info: MessageInfo, + recipient: Option, +) -> Result { + let pool_config = POOL_CONFIG.load(deps.storage)?; + assert_deposits(&info.funds, &pool_config)?; + let recipient = recipient.map_or(Ok(info.sender.clone()), |x| deps.api.addr_validate(&x))?; + let deposit_info = get_depositable_tokens(&deps.as_ref(), info.funds, &pool_config)?; + + execute_deposit(&mut deps, env, recipient, deposit_info) +} + +pub(crate) fn execute_any_deposit( + mut deps: DepsMut, + env: Env, + info: MessageInfo, + recipient: Option, + max_slippage: Decimal, +) -> Result { + let pool_config = POOL_CONFIG.load(deps.storage)?; + assert_deposits(&info.funds, &pool_config)?; + let recipient = recipient.map_or(Ok(info.sender.clone()), |x| deps.api.addr_validate(&x))?; + + let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; + let position = get_position(deps.storage, &deps.querier)? + .position + .ok_or(ContractError::MissingPosition {})?; + + let deposit_info = get_depositable_tokens(&deps.as_ref(), info.funds, &pool_config)?; + if deposit_info.base_refund.amount.is_zero() && deposit_info.quote_refund.amount.is_zero() { + return execute_deposit(&mut deps, env, recipient, deposit_info); + } + + let vault_config = VAULT_CONFIG.load(deps.storage)?; + let twap_price = get_twap_price( + &deps.querier, + env.block.time, + vault_config.twap_window_seconds, + pool_config.pool_id, + pool_config.clone().token0, + pool_config.clone().token1, + )?; + let (token_in, out_denom, remainder, price) = if !deposit_info.base_refund.amount.is_zero() { + let token_in_amount = if pool_details.current_tick > position.upper_tick { + deposit_info.base_refund.amount + } else { + get_single_sided_deposit_0_to_1_swap_amount( + deposit_info.base_refund.amount, + position.lower_tick, + pool_details.current_tick, + position.upper_tick, + )? + }; + let token_in = coin(token_in_amount.into(), pool_config.token0.clone()); + let remainder = coin( + deposit_info + .base_refund + .amount + .checked_sub(token_in.amount)? + .into(), + pool_config.token0.clone(), + ); + (token_in, pool_config.token1.clone(), remainder, twap_price) + } else { + let token_in_amount = if pool_details.current_tick < position.lower_tick { + deposit_info.quote_refund.amount + } else { + get_single_sided_deposit_1_to_0_swap_amount( + deposit_info.quote_refund.amount, + position.lower_tick, + pool_details.current_tick, + position.upper_tick, + )? + }; + let token_in = coin(token_in_amount.into(), pool_config.token1.clone()); + let remainder = coin( + deposit_info + .quote_refund + .amount + .checked_sub(token_in.amount)? + .into(), + pool_config.token1.clone(), + ); + ( + token_in, + pool_config.token0.clone(), + remainder, + twap_price.inv().expect("Invalid price"), + ) + }; + CURRENT_SWAP_ANY_DEPOSIT.save( + deps.storage, + &( + remainder, + recipient.clone(), + (deposit_info.base_deposit, deposit_info.quote_deposit), + ), + )?; + + let token_out_min_amount = estimate_swap_min_out_amount(token_in.amount, price, max_slippage)?; + + let dex_router = DEX_ROUTER.may_load(deps.storage)?; + let swap_msg = swap_msg( + env.contract.address, + pool_config.pool_id, + token_in.clone(), + coin(token_out_min_amount.into(), out_denom.clone()), + None, // TODO: check this None + dex_router, + )?; + + Ok(Response::new() + .add_submessage(SubMsg::reply_on_success( + swap_msg, + Replies::AnyDepositSwap.into(), + )) + .add_attributes(vec![ + attr("method", "execute"), + attr("action", "any_deposit"), + attr("token_in", format!("{}", token_in)), + attr("token_out_min_amount", format!("{}", token_out_min_amount)), + ])) +} + +pub fn handle_any_deposit_swap_reply( + mut deps: DepsMut, + env: Env, + data: SubMsgResult, +) -> Result { + // Attempt to directly parse the data to MsgSwapExactAmountInResponse outside of the match + let resp: MsgSwapExactAmountInResponse = data.try_into()?; + + let (remainder, recipient, deposit_amount_in_ratio) = + CURRENT_SWAP_ANY_DEPOSIT.load(deps.storage)?; + CURRENT_SWAP_ANY_DEPOSIT.remove(deps.storage); + + let pool_config = POOL_CONFIG.load(deps.storage)?; + let (balance0, balance1): (Uint128, Uint128) = if remainder.denom == pool_config.token0 { + ( + remainder.amount, + Uint128::new(resp.token_out_amount.parse()?), + ) + } else { + ( + Uint128::new(resp.token_out_amount.parse()?), + remainder.amount, + ) + }; + + let coins_to_mint_for = ( + Coin { + denom: pool_config.token0.clone(), + amount: balance0 + deposit_amount_in_ratio.0, + }, + Coin { + denom: pool_config.token1.clone(), + amount: balance1 + deposit_amount_in_ratio.1, + }, + ); + + execute_deposit( + &mut deps, + env, + recipient, + DepositInfo { + base_deposit: coins_to_mint_for.0.amount, + quote_deposit: coins_to_mint_for.1.amount, + base_refund: coin(0u128, pool_config.token0), + quote_refund: coin(0u128, pool_config.token1), + }, + ) +} + +/// Try to deposit as much user funds as we can in the current ratio of the vault and +/// refund the rest to the caller. +fn execute_deposit( + deps: &mut DepsMut, + env: Env, + recipient: Addr, + deposit_info: DepositInfo, +) -> Result { + let vault_denom = VAULT_DENOM.load(deps.storage)?; + let total_vault_shares: Uint256 = query_total_vault_token_supply(deps.as_ref())?.total.into(); + + let user_value = get_value_wrt_asset0( + deps.storage, + &deps.querier, + deposit_info.base_deposit, + deposit_info.quote_deposit, + )?; + let refund_value = get_value_wrt_asset0( + deps.storage, + &deps.querier, + deposit_info.base_refund.amount, + deposit_info.quote_refund.amount, + )?; + + // calculate the amount of shares we can mint for this + let total_assets = query_total_assets(deps.as_ref(), env.clone())?; + let total_assets_value = get_value_wrt_asset0( + deps.storage, + &deps.querier, + total_assets.token0.amount, + total_assets.token1.amount, + )?; + + // total_vault_shares.is_zero() should never be zero. This should ideally always enter the else and we are just sanity checking. + let user_shares: Uint128 = if total_vault_shares.is_zero() { + user_value + } else { + total_vault_shares + .checked_mul(user_value.into())? + .checked_div( + total_assets_value + .checked_sub(user_value)? + .checked_sub(refund_value)? + .into(), + )? + .try_into()? + }; + + // save the shares in the user map + SHARES.update( + deps.storage, + recipient.clone(), + |old| -> Result { + if let Some(existing_user_shares) = old { + Ok(user_shares + existing_user_shares) + } else { + Ok(user_shares) + } + }, + )?; + + // TODO the locking of minted shares is a band-aid for giving out rewards to users, + // once tokenfactory has send hooks, we can remove the lockup and have the users + // own the shares in their balance + // we mint shares to the contract address here, so we can lock those shares for the user later in the same call + // this is blocked by Osmosis v17 update + let mint_msg = MsgMint { + sender: env.clone().contract.address.to_string(), + amount: Some(coin(user_shares.into(), vault_denom).into()), + mint_to_address: env.clone().contract.address.to_string(), + }; + + let mut resp = Response::new() + .add_attribute("method", "execute") + .add_attribute("action", "deposit") + .add_attribute("amount0", deposit_info.base_deposit) + .add_attribute("amount1", deposit_info.quote_deposit) + .add_message(mint_msg) + .add_attribute("mint_shares_amount", user_shares) + .add_attribute("receiver", recipient.as_str()); + + if let Some((bank_msg, bank_attr)) = refund_bank_msg( + recipient, + Some(deposit_info.base_refund), + Some(deposit_info.quote_refund), + )? { + resp = resp.add_message(bank_msg).add_attributes(bank_attr); + } + + Ok(resp) +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use cosmwasm_std::{ + testing::{mock_env, mock_info}, + Addr, BankMsg, Decimal256, Fraction, Uint256, + }; + + use crate::{ + helpers::msgs::refund_bank_msg, + test_helpers::{instantiate_contract, mock_deps_with_querier, BASE_DENOM, QUOTE_DENOM}, + }; + + use super::*; + + #[test] + fn execute_exact_deposit_works() { + let mut deps = mock_deps_with_querier(); + let env = mock_env(); + let sender = "alice"; + + instantiate_contract(deps.as_mut(), env.clone(), sender); + + let info = mock_info(sender, &[coin(100, BASE_DENOM), coin(100, QUOTE_DENOM)]); + execute_exact_deposit(deps.as_mut(), env, info, None).unwrap(); + + // we currently have 100_000 total_vault_shares outstanding and the equivalent of 1999500token0, the user deposits the equivalent of 199token0, thus shares are + // 199 * 100000 / 1999500 = 9.95, which we round down. Thus we expect 9 shares in this example + assert_eq!( + SHARES + .load(deps.as_ref().storage, Addr::unchecked(sender)) + .unwrap(), + Uint128::new(9) + ); + } + + #[test] + fn test_shares() { + let total_shares = Uint256::from(1000000000_u128); + let total_liquidity = Decimal256::from_str("1000000000").unwrap(); + let liquidity = Decimal256::from_str("5000000").unwrap(); + + let _user_shares: Uint128 = if total_shares.is_zero() && total_liquidity.is_zero() { + liquidity.to_uint_floor().try_into().unwrap() + } else { + let _ratio = liquidity.checked_div(total_liquidity).unwrap(); + total_shares + .multiply_ratio(liquidity.numerator(), liquidity.denominator()) + .multiply_ratio(total_liquidity.denominator(), total_liquidity.numerator()) + .try_into() + .unwrap() + }; + } + + #[test] + fn refund_bank_msg_2_coins() { + let _env = mock_env(); + let user = Addr::unchecked("alice"); + + let refund0 = coin(150, "uosmo"); + let refund1 = coin(250, "uatom"); + + let response = refund_bank_msg(user.clone(), Some(refund0), Some(refund1)).unwrap(); + assert!(response.is_some()); + assert_eq!( + response.unwrap().0, + BankMsg::Send { + to_address: user.to_string(), + amount: vec![coin(150, "uosmo"), coin(250, "uatom")], + } + ) + } + + #[test] + fn refund_bank_msg_token0() { + let _env = mock_env(); + let user = Addr::unchecked("alice"); + + let refund0 = coin(150, "uosmo"); + let refund1 = coin(0, "uatom"); + + let response = refund_bank_msg(user.clone(), Some(refund0), Some(refund1)).unwrap(); + assert!(response.is_some()); + assert_eq!( + response.unwrap().0, + BankMsg::Send { + to_address: user.to_string(), + amount: vec![coin(150, "uosmo")], + } + ) + } + + #[test] + fn refund_bank_msg_token1() { + let _env = mock_env(); + let user = Addr::unchecked("alice"); + + let refund0 = coin(0, "uosmo"); + let refund1 = coin(250, "uatom"); + + let response = refund_bank_msg(user.clone(), Some(refund0), Some(refund1)).unwrap(); + assert!(response.is_some()); + assert_eq!( + response.unwrap().0, + BankMsg::Send { + to_address: user.to_string(), + amount: vec![coin(250, "uatom")], + } + ) + } +} diff --git a/smart-contracts/contracts/cl-vault/src/vault/distribution.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/distribution.rs similarity index 95% rename from smart-contracts/contracts/cl-vault/src/vault/distribution.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/vault/distribution.rs index 9d484b832..ba70b9393 100644 --- a/smart-contracts/contracts/cl-vault/src/vault/distribution.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/distribution.rs @@ -7,16 +7,11 @@ use osmosis_std::types::osmosis::concentratedliquidity::v1beta1::{ use crate::helpers::coinlist::CoinList; use crate::helpers::generic::sort_tokens; use crate::helpers::msgs::{collect_incentives_msg, collect_spread_rewards_msg}; -use crate::state::{MigrationStatus, MIGRATION_STATUS, POSITION}; +use crate::state::POSITION; use crate::{reply::Replies, state::VAULT_CONFIG, ContractError}; /// claim_rewards claims rewards from Osmosis and update the rewards map to reflect each users rewards pub fn execute_collect_rewards(deps: DepsMut, env: Env) -> Result { - let migration_status = MIGRATION_STATUS.load(deps.storage)?; - - if matches!(migration_status, MigrationStatus::Open) { - return Err(ContractError::MigrationStatusOpen {}); - } let msg = collect_spread_rewards_msg(deps.as_ref(), env)?; Ok(Response::new() diff --git a/smart-contracts/contracts/cl-vault/src/vault/merge.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/merge.rs similarity index 100% rename from smart-contracts/contracts/cl-vault/src/vault/merge.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/vault/merge.rs diff --git a/smart-contracts/contracts/cl-vault/src/vault/mod.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/mod.rs similarity index 77% rename from smart-contracts/contracts/cl-vault/src/vault/mod.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/vault/mod.rs index b4aa809cb..1b628ec8d 100644 --- a/smart-contracts/contracts/cl-vault/src/vault/mod.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/mod.rs @@ -1,9 +1,8 @@ pub mod admin; -pub mod any_deposit; pub mod autocompound; pub mod concentrated_liquidity; +pub mod deposit; pub mod distribution; -pub mod exact_deposit; pub mod merge; pub mod range; pub mod swap; diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/vault/range.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/range.rs new file mode 100644 index 000000000..0d4fb7aa6 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/range.rs @@ -0,0 +1,541 @@ +use crate::{ + error::{assert_range_admin, assert_ratio}, + helpers::getters::{ + get_single_sided_deposit_0_to_1_swap_amount, get_single_sided_deposit_1_to_0_swap_amount, + get_twap_price, get_unused_pair_balances, + }, + math::tick::{price_to_tick, tick_to_price}, + reply::Replies, + state::{ + ModifyRangeState, Position, SwapDepositMergeState, DEX_ROUTER, MODIFY_RANGE_STATE, + POOL_CONFIG, POSITION, SWAP_DEPOSIT_MERGE_STATE, + }, + vault::{ + concentrated_liquidity::{ + create_position, get_amount_from_liquidity_for_base_token, + get_amount_from_liquidity_for_quote_token, get_cl_pool_info, + get_liquidity_for_base_token, get_liquidity_for_quote_token, get_position, + }, + swap::{estimate_swap_min_out_amount, swap_msg}, + }, + ContractError, +}; +use cosmwasm_std::{ + coin, Decimal, Decimal256, DepsMut, Env, Fraction, MessageInfo, Response, StdResult, SubMsg, + SubMsgResult, Uint128, Uint256, +}; +use osmosis_std::types::osmosis::{ + concentratedliquidity::v1beta1::{MsgCreatePositionResponse, MsgWithdrawPosition}, + poolmanager::v1beta1::SwapAmountInRoute, +}; +use std::str::FromStr; + +#[allow(clippy::too_many_arguments)] +pub fn execute_update_range( + deps: DepsMut, + env: &Env, + info: MessageInfo, + lower_price: Decimal, + upper_price: Decimal, + max_slippage: Decimal, + ratio_of_swappable_funds_to_use: Decimal, + twap_window_seconds: u64, + forced_swap_route: Option>, + claim_after: Option, +) -> Result { + assert_range_admin(deps.storage, &info.sender)?; + assert_ratio(ratio_of_swappable_funds_to_use)?; + + let lower_tick: i64 = price_to_tick(deps.storage, lower_price.into())?.try_into()?; + let upper_tick: i64 = price_to_tick(deps.storage, upper_price.into())?.try_into()?; + + let position_breakdown = get_position(deps.storage, &deps.querier)?; + let position = position_breakdown + .position + .ok_or(ContractError::MissingPosition {})?; + + let withdraw_msg = MsgWithdrawPosition { + position_id: position.position_id, + sender: env.contract.address.to_string(), + liquidity_amount: Decimal256::from_str(position.liquidity.as_str())? + .atomics() + .to_string(), + }; + + MODIFY_RANGE_STATE.save( + deps.storage, + &Some(ModifyRangeState { + lower_tick, + upper_tick, + max_slippage, + new_range_position_ids: vec![], + ratio_of_swappable_funds_to_use, + twap_window_seconds, + forced_swap_route, + }), + )?; + + POSITION.update(deps.storage, |position| -> StdResult { + let mut position = position; + position.join_time = env.block.time.seconds(); + position.claim_after = claim_after; + Ok(position) + })?; + + Ok(Response::default() + .add_submessage(SubMsg::reply_on_success( + withdraw_msg, + Replies::WithdrawPosition.into(), + )) + .add_attribute("method", "execute") + .add_attribute("action", "update_range_ticks") + .add_attribute("position_id", position.position_id.to_string()) + .add_attribute("liquidity_amount", position.liquidity)) +} + +fn requires_swap( + sqrt_p: Decimal256, + sqrt_pl: Decimal256, + sqrt_pu: Decimal256, + base_amount: Uint128, + quote_amount: Uint128, + base_liquidity: Uint256, + quote_liquidity: Uint256, +) -> bool { + if sqrt_p >= sqrt_pu { + return !base_amount.is_zero(); + } + if sqrt_p <= sqrt_pl { + return !quote_amount.is_zero(); + } + base_liquidity != quote_liquidity +} + +pub fn handle_withdraw_position_reply(deps: DepsMut, env: Env) -> Result { + let modify_range_state = MODIFY_RANGE_STATE.load(deps.storage)?.unwrap(); + let pool_config = POOL_CONFIG.load(deps.storage)?; + let pool_details = get_cl_pool_info(&deps.querier, pool_config.pool_id)?; + + let unused_pair_balances = get_unused_pair_balances(&deps.as_ref(), &env, &pool_config)?; + + let sqrt_pu = tick_to_price(modify_range_state.upper_tick)?.sqrt(); + let sqrt_pl = tick_to_price(modify_range_state.lower_tick)?.sqrt(); + let sqrt_p = tick_to_price(pool_details.current_tick)?.sqrt(); + let base_coin = unused_pair_balances[0].clone(); + let quote_coin = unused_pair_balances[1].clone(); + let base_liquidity = + get_liquidity_for_base_token(base_coin.amount.into(), sqrt_p, sqrt_pl, sqrt_pu)?; + let quote_liquidity = + get_liquidity_for_quote_token(quote_coin.amount.into(), sqrt_p, sqrt_pl, sqrt_pu)?; + + let response = Response::new() + .add_attribute("method", "reply") + .add_attribute("action", "handle_withdraw_position") + .add_attribute("lower_tick", modify_range_state.lower_tick.to_string()) + .add_attribute("upper_tick", modify_range_state.upper_tick.to_string()) + .add_attribute("token0", format!("{}", base_coin)) + .add_attribute("token1", format!("{}", quote_coin)); + + if requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_coin.amount, + quote_coin.amount, + base_liquidity, + quote_liquidity, + ) { + let twap_price = get_twap_price( + &deps.querier, + env.block.time, + modify_range_state.twap_window_seconds, + pool_config.pool_id, + pool_config.token0, + pool_config.token1, + )?; + let (token_in, out_denom, price) = if sqrt_p <= sqrt_pl { + ( + quote_coin, + base_coin.denom, + twap_price.inv().expect("Invalid price"), + ) + } else if sqrt_p >= sqrt_pu { + (base_coin, quote_coin.denom, twap_price) + } else if base_liquidity > quote_liquidity { + let used_base_amount: Uint128 = get_amount_from_liquidity_for_base_token( + quote_liquidity, + sqrt_p, + sqrt_pl, + sqrt_pu, + )? + .try_into()?; + let residual_amount = base_coin.amount.checked_sub(used_base_amount)?; + let swap_amount = get_single_sided_deposit_0_to_1_swap_amount( + residual_amount, + modify_range_state.lower_tick, + pool_details.current_tick, + modify_range_state.upper_tick, + )?; + ( + coin(swap_amount.into(), base_coin.denom), + quote_coin.denom, + twap_price, + ) + } else { + let used_quote_amount = get_amount_from_liquidity_for_quote_token( + base_liquidity, + sqrt_p, + sqrt_pl, + sqrt_pu, + )? + .try_into()?; + let residual_amount = quote_coin.amount.checked_sub(used_quote_amount)?; + let swap_amount = get_single_sided_deposit_1_to_0_swap_amount( + residual_amount, + modify_range_state.lower_tick, + pool_details.current_tick, + modify_range_state.upper_tick, + )?; + ( + coin(swap_amount.into(), quote_coin.denom), + base_coin.denom, + twap_price.inv().expect("Invalid price"), + ) + }; + + SWAP_DEPOSIT_MERGE_STATE.save( + deps.storage, + &SwapDepositMergeState { + target_lower_tick: modify_range_state.lower_tick, + target_upper_tick: modify_range_state.upper_tick, + target_range_position_ids: vec![], + }, + )?; + + let token_out_min_amount = + estimate_swap_min_out_amount(token_in.amount, price, modify_range_state.max_slippage)?; + + let dex_router = DEX_ROUTER.may_load(deps.storage)?; + let swap_msg = swap_msg( + env.contract.address, + pool_config.pool_id, + token_in.clone(), + coin(token_out_min_amount.into(), out_denom.clone()), + None, // TODO: check this None + dex_router, + )?; + Ok(response + .add_submessage(SubMsg::reply_on_success(swap_msg, Replies::Swap.into())) + .add_attribute("action", "do_swap_deposit_merge") + .add_attribute("token_in", format!("{}", token_in)) + .add_attribute("token_out_min", token_out_min_amount.to_string())) + } else { + let create_position_msg = create_position( + deps, + &env, + modify_range_state.lower_tick, + modify_range_state.upper_tick, + unused_pair_balances.clone(), + Uint128::zero(), + Uint128::zero(), + )?; + + Ok(response.add_submessage(SubMsg::reply_on_success( + create_position_msg, + Replies::CreatePosition.into(), + ))) + } +} + +pub fn handle_swap_reply(deps: DepsMut, env: Env) -> Result { + let swap_deposit_merge_state = SWAP_DEPOSIT_MERGE_STATE.load(deps.storage)?; + SWAP_DEPOSIT_MERGE_STATE.remove(deps.storage); + let pool_config = POOL_CONFIG.load(deps.storage)?; + let unused_pair_balances = get_unused_pair_balances(&deps.as_ref(), &env, &pool_config)?; + + let create_position_msg = create_position( + deps, + &env, + swap_deposit_merge_state.target_lower_tick, + swap_deposit_merge_state.target_upper_tick, + unused_pair_balances.clone(), + Uint128::zero(), + Uint128::zero(), + )?; + + Ok(Response::new() + .add_submessage(SubMsg::reply_on_success( + create_position_msg, + Replies::CreatePosition.into(), + )) + .add_attribute("method", "reply") + .add_attribute("action", "handle_swap_success") + .add_attribute( + "lower_tick", + swap_deposit_merge_state.target_lower_tick.to_string(), + ) + .add_attribute( + "upper_tick", + swap_deposit_merge_state.target_upper_tick.to_string(), + ) + .add_attribute("token0", format!("{}", unused_pair_balances[0])) + .add_attribute("token1", format!("{}", unused_pair_balances[1]))) +} + +pub fn handle_create_position( + deps: DepsMut, + env: Env, + data: SubMsgResult, +) -> Result { + let create_position_message: MsgCreatePositionResponse = data.try_into()?; + + POSITION.update(deps.storage, |position| -> StdResult { + let mut position = position; + position.position_id = create_position_message.position_id; + position.join_time = env.block.time.seconds(); + Ok(position) + })?; + + Ok(Response::default()) +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use cosmwasm_std::{ + coin, + testing::{mock_dependencies, mock_env, mock_info, MOCK_CONTRACT_ADDR}, + Addr, Decimal, Decimal256, Uint128, Uint256, + }; + + use crate::{ + helpers::getters::get_range_admin, + math::tick::build_tick_exp_cache, + state::{MODIFY_RANGE_STATE, RANGE_ADMIN}, + test_helpers::{ + instantiate_contract, mock_deps_with_querier, mock_deps_with_querier_with_balance, + BASE_DENOM, POSITION_ID, QUOTE_DENOM, + }, + vault::range::requires_swap, + }; + + #[test] + fn test_get_range_admin() { + let mut deps = mock_dependencies(); + let info = mock_info("addr0000", &[]); + + RANGE_ADMIN.save(&mut deps.storage, &info.sender).unwrap(); + + assert_eq!(get_range_admin(deps.as_ref()).unwrap(), info.sender); + } + + #[test] + fn test_execute_update_range() { + let range_admin = "range_admin".to_string(); + let mut deps = mock_deps_with_querier(); + let env = mock_env(); + build_tick_exp_cache(deps.as_mut().storage).unwrap(); + instantiate_contract(deps.as_mut(), env.clone(), &range_admin); + RANGE_ADMIN + .save(deps.as_mut().storage, &Addr::unchecked(range_admin.clone())) + .unwrap(); + + let lower_price = Decimal::from_str("100").unwrap(); + let upper_price = Decimal::from_str("100.20").unwrap(); + let max_slippage = Decimal::from_str("0.5").unwrap(); + + let info = mock_info(&range_admin, &[]); + let res = super::execute_update_range( + deps.as_mut(), + &env, + info, + lower_price, + upper_price, + max_slippage, + Decimal::one(), + 45, + None, + None, + ) + .unwrap(); + + assert_eq!(res.messages.len(), 1); + assert_eq!(res.attributes[0].value, "execute"); + assert_eq!(res.attributes[1].value, "update_range_ticks"); + assert_eq!(res.attributes[2].value, POSITION_ID.to_string()); + assert_eq!(res.attributes[3].value, "1000000.1"); + } + + #[test] + fn test_handle_withdraw_position_reply_selects_correct_next_step_for_new_range() { + let info = mock_info("addr0000", &[]); + let env = mock_env(); + + let mut deps = mock_deps_with_querier_with_balance( + &info, + &[( + MOCK_CONTRACT_ADDR, + &[coin(11000, BASE_DENOM), coin(11234, QUOTE_DENOM)], + )], + ); + + MODIFY_RANGE_STATE + .save( + deps.as_mut().storage, + &Some(crate::state::ModifyRangeState { + lower_tick: 100, + upper_tick: 1000, // since both times we are moving into range and in the quasarquerier we configured the current_tick as 500, this would mean we are trying to move into range + new_range_position_ids: vec![], + max_slippage: Decimal::zero(), + ratio_of_swappable_funds_to_use: Decimal::one(), + twap_window_seconds: 45, + forced_swap_route: None, + }), + ) + .unwrap(); + + let res = super::handle_withdraw_position_reply(deps.as_mut(), env).unwrap(); + + // verify that we did create_position first + assert_eq!(res.messages.len(), 1); + assert_eq!(res.attributes[0].value, "reply"); + assert_eq!(res.attributes[1].value, "handle_withdraw_position"); + assert_eq!( + res.attributes + .iter() + .find(|a| { a.key == "token1" }) + .unwrap() + .value, + format!("11234{}", QUOTE_DENOM) + ); // 10000 withdrawn + 1234 local balance + } + + #[test] + fn test_when_price_is_below_range_and_quote_amount_is_zero_then_no_swap_is_required() { + let sqrt_p = Decimal256::one(); + let sqrt_pl = Decimal256::from_str("2.0").unwrap(); + let sqrt_pu = Decimal256::from_str("3.0").unwrap(); + let base_amount = Uint128::one(); + let quote_amount = Uint128::zero(); + let base_liquidity = Uint256::one(); + let quote_liquidity = Uint256::one(); + + assert!(!requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_amount, + quote_amount, + base_liquidity, + quote_liquidity + )); + } + + #[test] + fn test_when_price_is_below_range_and_quote_amount_is_not_zero_then_swap_is_required() { + let sqrt_p = Decimal256::one(); + let sqrt_pl = Decimal256::from_str("2.0").unwrap(); + let sqrt_pu = Decimal256::from_str("3.0").unwrap(); + let base_amount = Uint128::one(); + let quote_amount = Uint128::one(); + let base_liquidity = Uint256::one(); + let quote_liquidity = Uint256::one(); + + assert!(requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_amount, + quote_amount, + base_liquidity, + quote_liquidity + )); + } + + #[test] + fn test_when_price_is_above_range_and_base_amount_is_zero_then_no_swap_is_required() { + let sqrt_p = Decimal256::from_str("4.0").unwrap(); + let sqrt_pl = Decimal256::from_str("2.0").unwrap(); + let sqrt_pu = Decimal256::from_str("3.0").unwrap(); + let base_amount = Uint128::zero(); + let quote_amount = Uint128::one(); + let base_liquidity = Uint256::one(); + let quote_liquidity = Uint256::one(); + + assert!(!requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_amount, + quote_amount, + base_liquidity, + quote_liquidity + )); + } + + #[test] + fn test_when_price_is_above_range_and_base_amount_is_not_zero_then_swap_is_required() { + let sqrt_p = Decimal256::from_str("4.0").unwrap(); + let sqrt_pl = Decimal256::from_str("2.0").unwrap(); + let sqrt_pu = Decimal256::from_str("3.0").unwrap(); + let base_amount = Uint128::one(); + let quote_amount = Uint128::one(); + let base_liquidity = Uint256::one(); + let quote_liquidity = Uint256::one(); + + assert!(requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_amount, + quote_amount, + base_liquidity, + quote_liquidity + )); + } + + #[test] + fn test_when_price_is_in_range_and_base_liquidity_differs_from_quote_liquidity_then_swap_is_required( + ) { + let sqrt_p = Decimal256::from_str("2.5").unwrap(); + let sqrt_pl = Decimal256::from_str("2.0").unwrap(); + let sqrt_pu = Decimal256::from_str("3.0").unwrap(); + let base_amount = Uint128::one(); + let quote_amount = Uint128::one(); + let base_liquidity = Uint256::one(); + let quote_liquidity = Uint256::from(2u32); + + assert!(requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_amount, + quote_amount, + base_liquidity, + quote_liquidity + )); + } + + #[test] + fn test_when_price_is_in_range_and_base_liquidity_equals_quote_liquidity_then_no_swap_is_required( + ) { + let sqrt_p = Decimal256::from_str("2.5").unwrap(); + let sqrt_pl = Decimal256::from_str("2.0").unwrap(); + let sqrt_pu = Decimal256::from_str("3.0").unwrap(); + let base_amount = Uint128::one(); + let quote_amount = Uint128::one(); + let base_liquidity = Uint256::one(); + let quote_liquidity = Uint256::one(); + + assert!(!requires_swap( + sqrt_p, + sqrt_pl, + sqrt_pu, + base_amount, + quote_amount, + base_liquidity, + quote_liquidity + )); + } +} diff --git a/smart-contracts/osmosis/contracts/cl-vault/src/vault/swap.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/swap.rs new file mode 100644 index 000000000..cf2492fdd --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/swap.rs @@ -0,0 +1,199 @@ +use cosmwasm_std::{ + coin, to_json_binary, Addr, CheckedMultiplyFractionError, Coin, CosmosMsg, Decimal, DepsMut, + Env, MessageInfo, Response, Uint128, WasmMsg, +}; +use dex_router_osmosis::msg::ExecuteMsg as DexRouterExecuteMsg; +use osmosis_std::types::osmosis::poolmanager::v1beta1::SwapAmountInRoute; + +use crate::{ + error::assert_swap_admin, + helpers::getters::get_twap_price, + msg::SwapOperation, + state::{DEX_ROUTER, POOL_CONFIG, VAULT_CONFIG}, + ContractError, +}; + +pub fn execute_swap_non_vault_funds( + deps: DepsMut, + env: Env, + info: MessageInfo, + swap_operations: Vec, + twap_window_seconds: Option, +) -> Result { + assert_swap_admin(deps.storage, &info.sender)?; + + let pool_config = POOL_CONFIG.load(deps.storage)?; + + if swap_operations.is_empty() { + return Err(ContractError::EmptySwapOperations {}); + } + + let mut swap_msgs: Vec = vec![]; + + for swap_operation in swap_operations { + let token_in_denom = &swap_operation.token_in_denom; + + if token_in_denom == &pool_config.token0 || token_in_denom == &pool_config.token1 { + return Err(ContractError::InvalidSwapAssets {}); + } + + let token_in_balance = deps + .querier + .query_balance(env.clone().contract.address, token_in_denom.clone())? + .amount; + if token_in_balance.is_zero() { + return Err(ContractError::InsufficientFundsForSwap { + balance: token_in_balance, + needed: Uint128::new(2), // we need at least 2 udenom to be able swap into 2 denoms + }); + } + + let token_in_amount = token_in_balance.checked_div(Uint128::new(2))?; + + swap_msgs.push(prepare_swap_msg( + &deps, + &env, + coin(token_in_amount.into(), token_in_denom.clone()), + pool_config.clone().token0, + swap_operation.pool_id_base, + swap_operation.forced_swap_route_base, + twap_window_seconds, + )?); + + swap_msgs.push(prepare_swap_msg( + &deps, + &env, + coin(token_in_amount.into(), token_in_denom.clone()), + pool_config.clone().token1, + swap_operation.pool_id_quote, + swap_operation.forced_swap_route_quote, + twap_window_seconds, + )?); + } + + Ok(Response::new() + .add_messages(swap_msgs) + .add_attribute("method", "execute") + .add_attribute("action", "swap_non_vault_funds")) +} + +fn prepare_swap_msg( + deps: &DepsMut, + env: &Env, + token_in: Coin, + token_out_denom: String, + pool_id: u64, + forced_swap_route: Option>, + twap_window_seconds: Option, +) -> Result { + let vault_config = VAULT_CONFIG.load(deps.storage)?; + let dex_router = DEX_ROUTER.may_load(deps.storage)?; + + let twap_price = get_twap_price( + &deps.querier, + env.block.time, + twap_window_seconds.unwrap_or(vault_config.twap_window_seconds), + pool_id, + token_in.denom.to_string(), + token_out_denom.to_string(), + )?; + + let token_out_min_amount = + estimate_swap_min_out_amount(token_in.amount, twap_price, vault_config.swap_max_slippage)?; + + let swap_msg = swap_msg( + env.clone().contract.address, + pool_id, + token_in, + coin(token_out_min_amount.into(), token_out_denom), + forced_swap_route, + dex_router, + )?; + + Ok(swap_msg) +} + +pub fn estimate_swap_min_out_amount( + in_amount: Uint128, + price: Decimal, + slippage_factor: Decimal, +) -> Result { + in_amount + .checked_mul_floor(price)? + .checked_mul_floor(slippage_factor) +} + +pub fn swap_msg( + sender: Addr, + pool_id: u64, + token_in: Coin, + min_receive: Coin, + forced_swap_route: Option>, + dex_router: Option, +) -> Result { + if let Some(dex_router) = dex_router { + cw_dex_execute_swap_operations_msg(dex_router, forced_swap_route, token_in, min_receive) + } else { + let pool_route = SwapAmountInRoute { + pool_id, + token_out_denom: min_receive.denom, + }; + Ok(osmosis_swap_exact_amount_in_msg( + sender, + pool_route, + token_in, + min_receive.amount, + )) + } +} + +fn osmosis_swap_exact_amount_in_msg( + sender: Addr, + pool_route: SwapAmountInRoute, + token_in: Coin, + token_out_min_amount: Uint128, +) -> CosmosMsg { + osmosis_std::types::osmosis::poolmanager::v1beta1::MsgSwapExactAmountIn { + sender: sender.to_string(), + routes: vec![pool_route], + token_in: Some(token_in.into()), + token_out_min_amount: token_out_min_amount.to_string(), + } + .into() +} + +fn cw_dex_execute_swap_operations_msg( + dex_router_address: Addr, + path: Option>, + token_in: Coin, + min_receive: Coin, +) -> Result { + let swap_msg: CosmosMsg = WasmMsg::Execute { + contract_addr: dex_router_address.to_string(), + msg: to_json_binary(&DexRouterExecuteMsg::Swap { + path, + out_denom: min_receive.denom, + minimum_receive: Some(min_receive.amount), + })?, + funds: vec![token_in], + } + .into(); + + Ok(swap_msg) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::Uint128; + + #[test] + fn test_estimate_swap_min_out_amount() { + let in_amount = Uint128::from(50u64); + let price = Decimal::percent(300); + let max_slippage = Decimal::percent(50); + + let out_amount = estimate_swap_min_out_amount(in_amount, price, max_slippage).unwrap(); + assert_eq!(out_amount, Uint128::from(75u64)); + } +} diff --git a/smart-contracts/contracts/cl-vault/src/vault/withdraw.rs b/smart-contracts/osmosis/contracts/cl-vault/src/vault/withdraw.rs similarity index 62% rename from smart-contracts/contracts/cl-vault/src/vault/withdraw.rs rename to smart-contracts/osmosis/contracts/cl-vault/src/vault/withdraw.rs index 0d439b2a3..ada3a7762 100644 --- a/smart-contracts/contracts/cl-vault/src/vault/withdraw.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/src/vault/withdraw.rs @@ -54,12 +54,9 @@ pub fn execute_withdraw( // get the dust amounts belonging to the user let pool_config = POOL_CONFIG.load(deps.storage)?; // TODO replace dust with queries for balance - let unused_balances = get_unused_balances(&deps.querier, env)?; - let dust0: Uint256 = unused_balances - .find_coin(pool_config.token0.clone()) - .amount - .into(); - let dust1: Uint256 = unused_balances.find_coin(pool_config.token1).amount.into(); + let unused_balances = get_unused_balances(&deps.querier, &env.contract.address)?; + let dust0: Uint256 = unused_balances.find(&pool_config.token0).amount.into(); + let dust1: Uint256 = unused_balances.find(&pool_config.token1).amount.into(); let user_dust0: Uint128 = dust0 .checked_mul(shares_to_withdraw)? @@ -162,12 +159,9 @@ fn withdraw_msg( #[cfg(test)] mod tests { - use crate::helpers::coinlist::CoinList; - #[allow(deprecated)] use crate::{ - // rewards::CoinList, - state::{PoolConfig, STRATEGIST_REWARDS}, - test_helpers::mock_deps_with_querier_with_balance, + state::PoolConfig, + test_helpers::{mock_deps_with_querier_with_balance, BASE_DENOM, QUOTE_DENOM}, }; use cosmwasm_std::{ testing::{mock_dependencies, mock_env, mock_info, MOCK_CONTRACT_ADDR}, @@ -183,16 +177,11 @@ mod tests { &info, &[( MOCK_CONTRACT_ADDR, - &[coin(2000, "token0"), coin(3000, "token1")], + &[coin(2000, BASE_DENOM), coin(3000, QUOTE_DENOM)], )], ); let env = mock_env(); - // TODO_FUTURE: We should remove this in the next patch or just adjust now accordingly as we depcreate this state - #[allow(deprecated)] - STRATEGIST_REWARDS - .save(deps.as_mut().storage, &CoinList::new()) - .unwrap(); VAULT_DENOM .save(deps.as_mut().storage, &"share_token".to_string()) .unwrap(); @@ -206,119 +195,12 @@ mod tests { let _res = execute_withdraw(deps.as_mut(), &env, info, None, Uint128::new(1000).into()).unwrap(); - // our querier returns a total supply of 100_000, this user unbonds 1000, or 1%. The Dust saved should be one lower assert_eq!( CURRENT_WITHDRAWER_DUST.load(deps.as_ref().storage).unwrap(), (Uint128::new(20), Uint128::new(30)) ) } - // #[test] - // fn execute_withdraw_works_user_rewards() { - // let info = mock_info("bolice", &[]); - // let mut deps = mock_deps_with_querier_with_balance( - // &info, - // &[( - // MOCK_CONTRACT_ADDR, - // &[coin(2000, "token0"), coin(3000, "token1")], - // )], - // ); - // let env = mock_env(); - - // STRATEGIST_REWARDS - // .save(deps.as_mut().storage, &CoinList::new()) - // .unwrap(); - // VAULT_DENOM - // .save(deps.as_mut().storage, &"share_token".to_string()) - // .unwrap(); - // SHARES - // .save( - // deps.as_mut().storage, - // Addr::unchecked("bolice"), - // &Uint128::new(1000), - // ) - // .unwrap(); - - // USER_REWARDS - // .save( - // deps.as_mut().storage, - // Addr::unchecked("alice"), - // &CoinList::from_coins(vec![coin(100, "token0"), coin(175, "token1")]), - // ) - // .unwrap(); - // USER_REWARDS - // .save( - // deps.as_mut().storage, - // Addr::unchecked("bob"), - // &CoinList::from_coins(vec![coin(50, "token0"), coin(125, "token1")]), - // ) - // .unwrap(); - - // let _res = - // execute_withdraw(deps.as_mut(), env, info, None, Uint128::new(1000).into()).unwrap(); - // // our querier returns a total supply of 100_000, this user unbonds 1000, or 1%. The Dust saved should be one lower - // assert_eq!( - // CURRENT_WITHDRAWER_DUST.load(deps.as_ref().storage).unwrap(), - // (Uint128::new(18), Uint128::new(27)) - // ) - // } - - // #[test] - // fn execute_withdraw_works_user_strategist_rewards() { - // let info = mock_info("bolice", &[]); - // let mut deps = mock_deps_with_querier_with_balance( - // &info, - // &[( - // MOCK_CONTRACT_ADDR, - // &[coin(200000, "token0"), coin(300000, "token1")], - // )], - // ); - // let env = mock_env(); - - // STRATEGIST_REWARDS - // .save( - // deps.as_mut().storage, - // &CoinList::from_coins(vec![coin(50, "token0"), coin(50, "token1")]), - // ) - // .unwrap(); - // VAULT_DENOM - // .save(deps.as_mut().storage, &"share_token".to_string()) - // .unwrap(); - // SHARES - // .save( - // deps.as_mut().storage, - // Addr::unchecked("bolice"), - // &Uint128::new(1000), - // ) - // .unwrap(); - - // USER_REWARDS - // .save( - // deps.as_mut().storage, - // Addr::unchecked("alice"), - // &CoinList::from_coins(vec![coin(200, "token0"), coin(300, "token1")]), - // ) - // .unwrap(); - // USER_REWARDS - // .save( - // deps.as_mut().storage, - // Addr::unchecked("bob"), - // &CoinList::from_coins(vec![coin(400, "token0"), coin(100, "token1")]), - // ) - // .unwrap(); - - // let _res = - // execute_withdraw(deps.as_mut(), env, info, None, Uint128::new(1000).into()).unwrap(); - // // our querier returns a total supply of 100_000, this user unbonds 1000, or 1%. The Dust saved should be one lower - // // user dust should be 1% of 200000 - 650 (= 1993.5) and 1% of 300000 - 450 (= 2995.5) - // assert_eq!( - // CURRENT_WITHDRAWER_DUST.load(deps.as_ref().storage).unwrap(), - // (Uint128::new(1993), Uint128::new(2995)) - // ) - // } - - // the execute withdraw flow should be easiest to test in test-tube, since it requires quite a bit of Osmsosis specific information - // we just test the handle withdraw implementation here #[test] fn handle_withdraw_user_reply_works() { let mut deps = mock_dependencies(); @@ -348,8 +230,7 @@ mod tests { amount0: "1000".to_string(), amount1: "1000".to_string(), } - .try_into() - .unwrap(); + .into(); let response = handle_withdraw_user_reply( deps.as_mut(), diff --git a/smart-contracts/contracts/cl-vault/tests/admin.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/admin.rs similarity index 81% rename from smart-contracts/contracts/cl-vault/tests/admin.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/admin.rs index cb6882616..20e468ad3 100644 --- a/smart-contracts/contracts/cl-vault/tests/admin.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/admin.rs @@ -1,7 +1,4 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{fixture_default, PERFORMANCE_FEE_DEFAULT}; +use crate::setup::{fixture_default, PERFORMANCE_FEE_DEFAULT}; use cl_vault::{ msg::{ @@ -14,8 +11,7 @@ use osmosis_test_tube::{Module, Wasm}; #[test] fn admin_build_tick_cache_works() { - let (app, contract_address, _cl_pool_id, admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); + let (app, contract_address, _cl_pool_id, admin, _) = fixture_default(PERFORMANCE_FEE_DEFAULT); let wasm = Wasm::new(&app); let build_resp = wasm @@ -46,5 +42,5 @@ fn admin_build_tick_cache_works() { )), ) .unwrap(); - assert_eq!((), verify_resp.result.unwrap()); + assert!(verify_resp.result.is_ok()); } diff --git a/smart-contracts/contracts/cl-vault/tests/any_deposit.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/any_deposit.rs similarity index 81% rename from smart-contracts/contracts/cl-vault/tests/any_deposit.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/any_deposit.rs index 5298ff46f..d72d4f76f 100644 --- a/smart-contracts/contracts/cl-vault/tests/any_deposit.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/any_deposit.rs @@ -1,9 +1,6 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ - fixture_dex_router, ACCOUNTS_INIT_BALANCE, ACCOUNTS_NUM, DENOM_BASE, DENOM_QUOTE, - MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT, +use crate::setup::{ + fixture_default, fixture_dex_router, ACCOUNTS_INIT_BALANCE, ACCOUNTS_NUM, DENOM_BASE, + DENOM_QUOTE, MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT, }; use cl_vault::msg::ExecuteMsg; @@ -20,16 +17,16 @@ use std::str::FromStr; #[test] fn test_any_deposit() { let test_cases = vec![ - (DENOM_BASE, Uint128::new(10000), Uint128::zero()), - (DENOM_QUOTE, Uint128::new(5000), Uint128::zero()), - (DENOM_BASE, Uint128::new(2000), Uint128::zero()), - (DENOM_QUOTE, Uint128::new(1500), Uint128::zero()), - (DENOM_BASE, Uint128::new(1000), Uint128::new(500)), + (Uint128::new(10000), Uint128::zero()), + (Uint128::new(5000), Uint128::zero()), + (Uint128::new(2000), Uint128::zero()), + (Uint128::new(1500), Uint128::zero()), + (Uint128::new(1000), Uint128::new(500)), ]; - for (_asset, amount_base, amount_quote) in test_cases { - let (app, contract_address, _dex_router_addr, vault_pool_id, _pools_ids, admin, _, _) = - fixture_dex_router(PERFORMANCE_FEE_DEFAULT); + for (amount_base, amount_quote) in test_cases { + let (app, contract_address, vault_pool_id, admin, ..) = + fixture_default(PERFORMANCE_FEE_DEFAULT); do_and_verify_any_deposit( app, @@ -95,8 +92,7 @@ fn do_and_verify_any_deposit( .find(|coin| coin.denom == DENOM_QUOTE) .map(|coin| { let quote_amount = Uint128::from(coin.amount.parse::().unwrap()); - let quote_as_base = quote_amount * spot_price_quote_to_base; - quote_as_base + quote_amount * spot_price_quote_to_base }) .unwrap_or_else(Uint128::zero); @@ -115,8 +111,7 @@ fn do_and_verify_any_deposit( .find(|coin| coin.denom == DENOM_QUOTE) .map(|coin| { let quote_amount = Uint128::from(coin.amount.parse::().unwrap()); - let quote_as_base = quote_amount * spot_price_quote_to_base; - quote_as_base + quote_amount * spot_price_quote_to_base }) .unwrap_or_else(Uint128::zero); @@ -197,15 +192,15 @@ fn do_any_deposit( #[test] fn test_any_deposit_slippage_fails() { let test_cases = vec![ - (DENOM_BASE, Uint128::new(10000), Uint128::zero()), - (DENOM_QUOTE, Uint128::new(5000), Uint128::zero()), - (DENOM_BASE, Uint128::new(2000), Uint128::zero()), - (DENOM_QUOTE, Uint128::new(1500), Uint128::zero()), - (DENOM_BASE, Uint128::new(1000), Uint128::new(500)), + (Uint128::new(10000), Uint128::zero()), + (Uint128::new(5000), Uint128::zero()), + (Uint128::new(2000), Uint128::zero()), + (Uint128::new(1500), Uint128::zero()), + (Uint128::new(1000), Uint128::new(500)), ]; - for (_asset, amount_base, amount_quote) in test_cases { - let (app, contract_address, _dex_router_addr, _vault_pool_id, _pools_ids, _admin, _, _) = + for (amount_base, amount_quote) in test_cases { + let (app, contract_address, _dex_router_addr, _vault_pool_id, _pools_ids, _admin, _) = fixture_dex_router(PERFORMANCE_FEE_DEFAULT); do_any_deposit( diff --git a/smart-contracts/contracts/cl-vault/tests/autocompound.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/autocompound.rs similarity index 67% rename from smart-contracts/contracts/cl-vault/tests/autocompound.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/autocompound.rs index e20834c82..02c9a2121 100644 --- a/smart-contracts/contracts/cl-vault/tests/autocompound.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/autocompound.rs @@ -1,7 +1,4 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ +use crate::setup::{ calculate_expected_refunds, fixture_dex_router, get_balance_amount, get_event_attributes_by_ty_and_key, ACCOUNTS_INIT_BALANCE, ACCOUNTS_NUM, DENOM_BASE, DENOM_QUOTE, DENOM_REWARD, DEPOSIT_AMOUNT, INITIAL_POSITION_BURN, PERFORMANCE_FEE_DEFAULT, @@ -28,7 +25,8 @@ use osmosis_std::types::cosmos::base::v1beta1::Coin as OsmoCoin; use osmosis_std::types::osmosis::poolmanager::v1beta1::SwapAmountInRoute; use osmosis_test_tube::{Account, Bank, Module, Wasm}; -const DENOM_REWARD_AMOUNT: u128 = 100000000000; +const DENOM_REWARD_AMOUNT: u128 = 100_000_000_000; +const APPROX_EQ_FACTOR: &str = "0.00005"; #[test] fn test_autocompound_with_rewards_swap_non_vault_funds() { @@ -39,13 +37,11 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { _vault_pool_id, swap_pools_ids, admin, - deposit_ratio, - deposit_ratio_approx, + deposit_ratio_base, ) = fixture_dex_router(PERFORMANCE_FEE_DEFAULT); let bm = Bank::new(&app); let wasm = Wasm::new(&app); - // Initialize accounts as users let accounts = app .init_accounts( &[ @@ -85,21 +81,19 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { shares_underlying_assets.balances[1].amount ); - // BEFORE DEPOSITS CHECKS - - // This will be useful after all deposits to assert the contract balance - let balance_before_contract_base = - get_balance_amount(&app, contract_address.to_string(), DENOM_BASE.to_string()); + // BEFORE USERS DEPOSITS - // Keep track of the total refunded amount on token0 from user deposits let mut refund0_amount_total = Uint128::zero(); let mut refund1_amount_total = Uint128::zero(); - - // Keep track of the total minted shares from deposits let mut total_minted_shares_from_deposits = Uint128::zero(); + + let initial_base_balance = + get_balance_amount(&app, contract_address.to_string(), DENOM_BASE.to_string()); + let initial_quote_balance = + get_balance_amount(&app, contract_address.to_string(), DENOM_QUOTE.to_string()); + // Execute exact_deposit for each account using the same amount of tokens for each asset and user for account in &accounts { - // Assert user starts with 0 shares let balance_user_shares_before: UserSharesBalanceResponse = wasm .query( contract_address.as_str(), @@ -108,9 +102,9 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { })), ) .unwrap(); + // Assert user starts with 0 shares assert!(balance_user_shares_before.balance.is_zero()); - // Make the deposit asserting the correct refund based on deposit ratio let exact_deposit = wasm .execute( contract_address.as_str(), @@ -123,9 +117,8 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { ) .unwrap(); - // Expected refund amounts based on the deposit ratio let (expected_refund0, expected_refund1) = - calculate_expected_refunds(DEPOSIT_AMOUNT, DEPOSIT_AMOUNT, deposit_ratio); + calculate_expected_refunds(DEPOSIT_AMOUNT, DEPOSIT_AMOUNT, deposit_ratio_base); // Assert balance refunded is either the expected value or not empty for token0 let refund0_amount = @@ -137,9 +130,8 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { .unwrap() .u128(), expected_refund0, - &deposit_ratio_approx + APPROX_EQ_FACTOR ); - // Increment the refund0 amount total count for future math assertions refund0_amount_parsed = refund0_amount[0].value.parse::().unwrap(); refund0_amount_total = refund0_amount_total .checked_add(Uint128::new(refund0_amount_parsed)) @@ -153,14 +145,12 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { get_event_attributes_by_ty_and_key(&exact_deposit, "wasm", vec!["refund1"]); let mut refund1_amount_parsed: u128 = 0; if expected_refund1 > 0 { - assert_approx_eq!( + assert_eq!( Uint128::from_str(refund1_amount[0].value.as_str()) .unwrap() .u128(), - expected_refund1, - &deposit_ratio_approx + expected_refund1 ); - // Increment the refund1 amount total count for future math assertions refund1_amount_parsed = refund1_amount[0].value.parse::().unwrap(); refund1_amount_total = refund1_amount_total .checked_add(Uint128::new(refund1_amount_parsed)) @@ -187,8 +177,6 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { .sub(refund1_amount_parsed) ) ); - - // Increment the total minted shares counter total_minted_shares_from_deposits = total_minted_shares_from_deposits .checked_add(balance_user_shares_after.balance) .unwrap(); @@ -196,31 +184,30 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { // AFTER DEPOSITS CHECKS - // Assert total vault shares - let total_vault_token_supply_after_deposit: TotalVaultTokenSupplyResponse = wasm + let after_deposit_vault_token_supply: TotalVaultTokenSupplyResponse = wasm .query( contract_address.as_str(), &QueryMsg::TotalVaultTokenSupply {}, ) .unwrap(); + + // Assert that the current vault token supply is equal to the initial plus each supply mint obtained from each deposit assert_eq!( total_minted_shares_from_deposits .checked_add(initial_total_vault_token_supply.total) .unwrap(), - total_vault_token_supply_after_deposit.total + after_deposit_vault_token_supply.total ); - // Assert shares underlying assets - let shares_assets: AssetsBalanceResponse = wasm + let after_deposit_total_assets: AssetsBalanceResponse = wasm .query( contract_address.as_str(), &QueryMsg::ConvertToAssets { - amount: total_vault_token_supply_after_deposit.total, + amount: after_deposit_vault_token_supply.total, }, ) .unwrap(); - // declare expected contract balance after 10x user deposits let users_total_deposit_per_asset = DEPOSIT_AMOUNT.checked_mul(ACCOUNTS_NUM as u128).unwrap(); // Assert that the total vault shares are consistent with refunded amounts and initial burnt shares assets @@ -228,32 +215,37 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { users_total_deposit_per_asset .sub(refund0_amount_total.u128()) .add(INITIAL_POSITION_BURN), - shares_assets.balances[0].amount.u128() + after_deposit_total_assets.balances[0].amount.u128() ); assert_eq!( users_total_deposit_per_asset .sub(refund1_amount_total.u128()) .add(INITIAL_POSITION_BURN), - shares_assets.balances[1].amount.u128() + after_deposit_total_assets.balances[1].amount.u128() ); - // Asssert contract balances for base and quote denoms - let expected_balance_base_after_deposit = users_total_deposit_per_asset - .checked_add(balance_before_contract_base) + // Asssert that contract balances for base and quote denoms are consistent with the amount of funds deposited and refunded by users + let expected_after_deposit_base_balance = users_total_deposit_per_asset + .checked_add(initial_base_balance) .unwrap() .checked_sub(refund0_amount_total.u128()) .unwrap(); - let balances_base = + let after_deposit_base_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_BASE.to_string()); assert_eq!( - expected_balance_base_after_deposit.to_string(), - balances_base.to_string() + expected_after_deposit_base_balance.to_string(), + after_deposit_base_balance.to_string() ); - let balances_quote = + let expected_after_deposit_quote_balance = users_total_deposit_per_asset + .checked_add(initial_quote_balance) + .unwrap() + .checked_sub(refund1_amount_total.u128()) + .unwrap(); + let after_deposit_quote_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_QUOTE.to_string()); assert_eq!( - users_total_deposit_per_asset.to_string(), - balances_quote.to_string() + expected_after_deposit_quote_balance.to_string(), + after_deposit_quote_balance.to_string() ); // Airdrop some DENOM_REWARD funds to the contract that are not token0 nor token1 from vault position @@ -269,98 +261,103 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { &admin, ) .unwrap(); - - // Assert contract balance about the just airdropped non vault token funds - let balances_rewards = + let initial_rewards_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_REWARD.to_string()); assert_eq!( DENOM_REWARD_AMOUNT.to_string(), - balances_rewards.to_string(), + initial_rewards_balance.to_string(), ); // SWAP NON VAULT ASSETS BEFORE AUTOCOMPOUND ASSETS - // Swap non vault funds to vault funds - // 50000000000ustride to 49500000000uatom as spot price 1.0 less swap_fees - // 50000000000ustride to 49500000000uosmo as spot price 1.0 less swap_fees - let expected_amount_rewards = 49500000000u128; + let swap_token_in_amount = Uint128::new(DENOM_REWARD_AMOUNT) + .checked_div(Uint128::new(2)) + .unwrap(); + // Calculate the total rewards swap amount using 0.01 as swap_fee as osmosis_test_tube hardcodes it this way: https://github.com/osmosis-labs/test-tube/blob/main/packages/osmosis-test-tube/src/module/gamm.rs#L59 + const BALANCER_FEE_RATE: f64 = 0.01; + const INITIAL_AMOUNT: f64 = 1_000_000.0; + let adjusted_numerator = ((1.0 - BALANCER_FEE_RATE) * INITIAL_AMOUNT) as u128; + let denominator = 1_000_000u128; + // we work with the assumption that the spot price is always 1.0 for both assets + let swap_token_out_amount = swap_token_in_amount + .checked_multiply_ratio(adjusted_numerator, denominator) + .expect("Multiplication overflow"); + + // We want to swap DENOM_REWARDS and pass the SwapOperation information to perform the swap using the dex-router wasm.execute( contract_address.as_str(), &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::SwapNonVaultFunds { swap_operations: vec![SwapOperation { token_in_denom: DENOM_REWARD.to_string(), - pool_id_0: swap_pools_ids[2], - pool_id_1: swap_pools_ids[1], - forced_swap_route_token_0: Some(vec![ - SwapAmountInRoute { - pool_id: swap_pools_ids[1], - token_out_denom: DENOM_QUOTE.to_string(), - }, - SwapAmountInRoute { - pool_id: swap_pools_ids[2], - token_out_denom: DENOM_BASE.to_string(), - }, - ]), - forced_swap_route_token_1: Some(vec![SwapAmountInRoute { + pool_id_base: swap_pools_ids[1], + pool_id_quote: swap_pools_ids[2], + forced_swap_route_base: Some(vec![SwapAmountInRoute { pool_id: swap_pools_ids[1], + token_out_denom: DENOM_BASE.to_string(), + }]), + forced_swap_route_quote: Some(vec![SwapAmountInRoute { + pool_id: swap_pools_ids[2], token_out_denom: DENOM_QUOTE.to_string(), }]), }], + twap_window_seconds: None, }), &[], &admin, ) .unwrap(); - // Assert there is no balance for DENOM_REWARD (ustrd) and there is more DENOM_BASE - let balances_after_swap_rewards = + + let after_swap_rewards_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_REWARD.to_string()); - assert_eq!(0u128, balances_after_swap_rewards); - // Assert vault position tokens balances - let balances_after_swap_base = + assert_eq!(0u128, after_swap_rewards_balance); + + let after_swap_base_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_BASE.to_string()); + // Assert vault position tokens balances increased accordingly to the swapped funds from DENOM_REWARD to DENOM_BASE and DENOM_QUOTE assert_eq!( - expected_balance_base_after_deposit - .checked_add(expected_amount_rewards) + after_deposit_base_balance + .checked_add(swap_token_out_amount.into()) .unwrap(), - balances_after_swap_base + after_swap_base_balance ); - let balances_after_swap_quote = + let after_swap_quote_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_QUOTE.to_string()); assert_eq!( - DENOM_REWARD_AMOUNT - .div(2) - .checked_add(expected_amount_rewards) + after_deposit_quote_balance + .checked_add(swap_token_out_amount.into()) .unwrap(), - balances_after_swap_quote + after_swap_quote_balance ); - // Query contract to convert all LP token supply into assets after swapping non vault funds - let shares_assets: AssetsBalanceResponse = wasm + // Query contract to convert the same amount of LP token supply into assets after swapping non vault funds + let after_swap_total_assets: AssetsBalanceResponse = wasm .query( contract_address.as_str(), &QueryMsg::ConvertToAssets { - amount: total_vault_token_supply_after_deposit.total, + amount: after_deposit_vault_token_supply.total, }, ) .unwrap(); - // Check shares value of underlying assets after swapping non vault funds + + // Check shares value of underlying assets increased after swapping non vault funds assert_eq!( users_total_deposit_per_asset .sub(refund0_amount_total.u128()) .add(INITIAL_POSITION_BURN) - .add(expected_amount_rewards), - shares_assets.balances[0].amount.u128() + .add(swap_token_out_amount.u128()), + after_swap_total_assets.balances[0].amount.u128(), ); assert_eq!( users_total_deposit_per_asset .sub(refund1_amount_total.u128()) .add(INITIAL_POSITION_BURN) - .add(expected_amount_rewards), - shares_assets.balances[1].amount.u128() + .add(swap_token_out_amount.u128()), + after_swap_total_assets.balances[1].amount.u128(), ); - // AUTOCOMPOUND CONTRCT BALANCE ASSETS INTO POSITION + // AUTOCOMPOUND CONTRACT BALANCE ASSETS INTO POSITION + wasm.execute( contract_address.as_str(), &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::Autocompound {}), @@ -369,24 +366,18 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { ) .unwrap(); - // Assert balances after autocompound of funds - let (expected_refund_base, expected_refund_quote) = - calculate_expected_refunds(49500000000, 49500000000, deposit_ratio); - // Base about rewards swapped to token base - let balances_after_autocompound_base = + let after_autocompound_base_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_BASE.to_string()); - assert_approx_eq!( - expected_refund_base, - balances_after_autocompound_base, - &deposit_ratio_approx - ); - // Quote about rewards swapped to token quote - let balances_after_autocompound_quote = + let after_autocompound_quote_balance = get_balance_amount(&app, contract_address.to_string(), DENOM_QUOTE.to_string()); - assert_eq!(expected_refund_quote, balances_after_autocompound_quote); + assert!( + after_autocompound_base_balance == 0u128 || after_autocompound_quote_balance == 0u128, + "Either one of the balances must be 0, or both must be 0. Base balance: {}, Quote balance: {}", + after_autocompound_base_balance, + after_autocompound_quote_balance + ); - // Assert total vault shares - let total_vault_token_supply_after_autocompound: TotalVaultTokenSupplyResponse = wasm + let after_autocompound_vault_token_supply: TotalVaultTokenSupplyResponse = wasm .query( contract_address.as_str(), &QueryMsg::TotalVaultTokenSupply {}, @@ -395,8 +386,8 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { // Assert that total existing LP tokens didnt change after autocompound, // so we ensure that we just increase the vlaue of underlying assets for the same existing number of shares assert_eq!( - total_vault_token_supply_after_deposit.total, - total_vault_token_supply_after_autocompound.total + after_deposit_vault_token_supply.total, + after_autocompound_vault_token_supply.total ); // Assert again, but with previously tracked values to ensure the autocompound worked as expected // We expect this to be the exact same amount of total shares of before autocompunding. @@ -404,25 +395,23 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { total_minted_shares_from_deposits .checked_add(initial_total_vault_token_supply.total) .unwrap(), - total_vault_token_supply_after_autocompound.total + after_autocompound_vault_token_supply.total ); - // Query contract to convert all LP token supply into assets after autocompound - let shares_assets: AssetsBalanceResponse = wasm + let after_autocompound_total_assets: AssetsBalanceResponse = wasm .query( contract_address.as_str(), &QueryMsg::ConvertToAssets { - amount: total_vault_token_supply_after_autocompound.total, + amount: after_autocompound_vault_token_supply.total, }, ) .unwrap(); // Redeem all shares for each user and assert things accordingly for account in &accounts { - // Get balances before for current account - let balances_before_withdraw_base_denom = + let before_withdraw_base_balance = get_balance_amount(&app, account.address().to_string(), DENOM_BASE.to_string()); - let balances_before_withdraw_quote_denom = + let before_withdraw_quote_balance = get_balance_amount(&app, account.address().to_string(), DENOM_QUOTE.to_string()); // Get shares balance for current account @@ -435,9 +424,7 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { ) .unwrap(); - // If the current account have some share to redeem if !shares_to_redeem.balance.is_zero() { - // Redeem all shares_to_redeem.balance wasm.execute( contract_address.as_str(), &ExecuteMsg::Redeem { @@ -451,31 +438,29 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { // Assert after balances expecting the withdrawn amount // includes the compounded funds and idle funds from the vault position and balance - // Base - let balances_after_withdraw_base_denom = + let after_withdraw_base_balance = get_balance_amount(&app, account.address().to_string(), DENOM_BASE.to_string()); assert_approx_eq!( - balances_after_withdraw_base_denom - .checked_sub(balances_before_withdraw_base_denom) + after_withdraw_base_balance + .checked_sub(before_withdraw_base_balance) .unwrap(), - shares_assets.balances[0] + after_autocompound_total_assets.balances[0] .amount .u128() .div(ACCOUNTS_NUM as u128), - &deposit_ratio_approx + APPROX_EQ_FACTOR ); - // Quote - let balances_after_withdraw_quote_denom = + let after_withdraw_quote_balance = get_balance_amount(&app, account.address().to_string(), DENOM_QUOTE.to_string()); assert_approx_eq!( - balances_after_withdraw_quote_denom - .checked_sub(balances_before_withdraw_quote_denom) + after_withdraw_quote_balance + .checked_sub(before_withdraw_quote_balance) .unwrap(), - shares_assets.balances[1] + after_autocompound_total_assets.balances[1] .amount .u128() .div(ACCOUNTS_NUM as u128), - &deposit_ratio_approx + APPROX_EQ_FACTOR ); } else { panic!("User has no shares to redeem") @@ -483,7 +468,7 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { } // Assert total vault shares after autocompounding tokens. - let total_vault_token_supply_after_users_redeem: TotalVaultTokenSupplyResponse = wasm + let after_withdraw_vault_token_supply: TotalVaultTokenSupplyResponse = wasm .query( contract_address.as_str(), &QueryMsg::TotalVaultTokenSupply {}, @@ -491,6 +476,6 @@ fn test_autocompound_with_rewards_swap_non_vault_funds() { .unwrap(); assert_eq!( INITIAL_POSITION_BURN.mul(2u128), - total_vault_token_supply_after_users_redeem.total.u128() + after_withdraw_vault_token_supply.total.u128() ); } diff --git a/smart-contracts/contracts/cl-vault/tests/deposit_withdraw.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/deposit_withdraw.rs similarity index 95% rename from smart-contracts/contracts/cl-vault/tests/deposit_withdraw.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/deposit_withdraw.rs index b866c66f3..e12eeca70 100644 --- a/smart-contracts/contracts/cl-vault/tests/deposit_withdraw.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/deposit_withdraw.rs @@ -1,7 +1,4 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ +use crate::setup::{ fixture_default, get_event_attributes_by_ty_and_key, ACCOUNTS_INIT_BALANCE, DENOM_BASE, DENOM_QUOTE, PERFORMANCE_FEE_DEFAULT, }; @@ -15,8 +12,7 @@ use osmosis_test_tube::{Account, Module, Wasm}; #[test] fn single_deposit_withdraw_works() { - let (app, contract_address, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); + let (app, contract_address, _cl_pool_id, _admin, _) = fixture_default(PERFORMANCE_FEE_DEFAULT); let wasm = Wasm::new(&app); let alice = app @@ -72,20 +68,20 @@ fn single_deposit_withdraw_works() { // assert that the refund + used funds are equal to what we deposited let refund0: u128 = get_event_attributes_by_ty_and_key(&response, "wasm", vec!["refund0"]) - .get(0) + .first() .map(|attr| attr.value.parse().unwrap()) .unwrap_or(0); let refund1: u128 = get_event_attributes_by_ty_and_key(&response, "wasm", vec!["refund1"]) - .get(0) + .first() .map(|attr| attr.value.parse().unwrap()) .unwrap_or(0); let deposited0: u128 = get_event_attributes_by_ty_and_key(&response, "wasm", vec!["amount0"]) - .get(0) + .first() .map(|attr| attr.value.parse().unwrap()) .unwrap_or(0); let deposited1: u128 = get_event_attributes_by_ty_and_key(&response, "wasm", vec!["amount1"]) - .get(0) + .first() .map(|attr| attr.value.parse().unwrap()) .unwrap_or(0); @@ -198,8 +194,7 @@ fn single_deposit_withdraw_works() { #[test] fn multiple_deposit_withdraw_works() { - let (app, contract_address, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); + let (app, contract_address, _cl_pool_id, _admin, _) = fixture_default(PERFORMANCE_FEE_DEFAULT); let wasm = Wasm::new(&app); // Create Alice account @@ -327,8 +322,7 @@ fn multiple_deposit_withdraw_works() { #[test] fn multiple_deposit_withdraw_unused_funds_works() { - let (app, contract_address, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); + let (app, contract_address, _cl_pool_id, _admin, _) = fixture_default(PERFORMANCE_FEE_DEFAULT); let wasm = Wasm::new(&app); // Create 3 accounts diff --git a/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/fuzzer.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/fuzzer.rs new file mode 100644 index 000000000..941f2cd28 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/fuzzer.rs @@ -0,0 +1,3 @@ +mod setup; + +mod proptest; diff --git a/smart-contracts/contracts/cl-vault/tests/initialize.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/initialize.rs similarity index 91% rename from smart-contracts/contracts/cl-vault/tests/initialize.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/initialize.rs index 6b21624e9..b38d8c988 100644 --- a/smart-contracts/contracts/cl-vault/tests/initialize.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/initialize.rs @@ -1,7 +1,6 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{fixture_default, DENOM_BASE, DENOM_QUOTE, MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT}; +use crate::setup::{ + fixture_dex_router, DENOM_BASE, DENOM_QUOTE, MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT, +}; use cl_vault::{ msg::{ @@ -26,9 +25,9 @@ use osmosis_test_tube::{ use std::str::FromStr; #[test] -fn fixture_default_works() { - let (app, contract_address, cl_pool_id, admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); +fn fixture_dex_router_works() { + let (app, contract_address, _dex_router, cl_pool_id, _pools, admin, ..) = + fixture_dex_router(PERFORMANCE_FEE_DEFAULT); let wasm = Wasm::new(&app); let cl = ConcentratedLiquidity::new(&app); let tf = TokenFactory::new(&app); diff --git a/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/integration.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/integration.rs new file mode 100644 index 000000000..4dffde690 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/integration.rs @@ -0,0 +1,9 @@ +mod setup; + +mod admin; +mod any_deposit; +mod autocompound; +mod deposit_withdraw; +mod initialize; +mod range; +mod rewards; diff --git a/smart-contracts/contracts/cl-vault/tests/proptest.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/proptest.rs similarity index 99% rename from smart-contracts/contracts/cl-vault/tests/proptest.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/proptest.rs index dc0b2ddc7..667b283de 100644 --- a/smart-contracts/contracts/cl-vault/tests/proptest.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/proptest.rs @@ -1,7 +1,4 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ +use crate::setup::{ get_event_attributes_by_ty_and_key, init_test_contract, MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT, }; @@ -332,14 +329,13 @@ fn get_cases() -> u32 { proptest! { #![proptest_config(ProptestConfig::with_cases(get_cases()))] #[test] - #[ignore] fn test_complete_works( (initial_lower_tick, initial_upper_tick) in get_initial_range(), actions in get_strategy_list(), percentages in get_percentage_list(), account_indexes in get_account_index_list() ) { - let (app, contract_address, _cl_pool_id, admin_account, _deposit_ratio, _deposit_ratio_approx) = init_test_contract( + let (app, contract_address, _cl_pool_id, admin_account, _) = init_test_contract( "./test-tube-build/wasm32-unknown-unknown/release/cl_vault.wasm", &[ Coin::new(340282366920938463463374607431768211455, "uosmo"), diff --git a/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/range.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/range.rs new file mode 100644 index 000000000..d3b572e66 --- /dev/null +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/range.rs @@ -0,0 +1,502 @@ +use crate::setup::{ + fixture_dex_router, init_test_contract, ADMIN_BALANCE_AMOUNT, DENOM_BASE, DENOM_QUOTE, + MAX_SLIPPAGE_HIGH, PERFORMANCE_FEE_DEFAULT, +}; + +use cosmwasm_std::{coin, Coin, Decimal, Uint128}; +use osmosis_std::types::{ + cosmos::base::v1beta1, + osmosis::{ + concentratedliquidity::{ + poolmodel::concentrated::v1beta1::MsgCreateConcentratedPool, + v1beta1::{MsgCreatePosition, Pool, PoolsRequest, PositionByIdRequest}, + }, + poolmanager::v1beta1::SwapAmountInRoute, + }, +}; +use osmosis_test_tube::{Account, ConcentratedLiquidity, Module, Wasm}; +use prost::Message; +use std::str::FromStr; + +use cl_vault::{ + msg::{ + ClQueryMsg, ExecuteMsg, ExtensionExecuteMsg, ExtensionQueryMsg, ModifyRangeMsg, QueryMsg, + }, + query::PositionResponse, +}; + +const DO_SWAP_DEPOSIT_TOKEN_IN_OFFSET: usize = 1; +const DO_SWAP_DEPOSIT_MIN_OUT_OFFSET: usize = 2; +const SWAP_SUCCESS_BASE_BALANCE_OFFSET: usize = 3; +const SWAP_SUCCESS_QUOTE_BALANCE_OFFSET: usize = 4; + +#[test] +fn move_range_works() { + let (app, contract_address, _dex_router, _cl_pool_id, _pools, admin, ..) = + fixture_dex_router(PERFORMANCE_FEE_DEFAULT); + let wasm = Wasm::new(&app); + + let _before_position: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + + let response = wasm + .execute( + contract_address.as_str(), + &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { + lower_price: Decimal::from_str("0.65").unwrap(), + upper_price: Decimal::from_str("1.3").unwrap(), + max_slippage: Decimal::percent(89), + ratio_of_swappable_funds_to_use: Decimal::one(), + twap_window_seconds: 45, + forced_swap_route: None, + claim_after: None, + })), + &[], + &admin, + ) + .unwrap(); + + for event in &response.events { + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "do_swap_deposit_merge"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_TOKEN_IN_OFFSET].value, + "223645uatom" + ); + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_MIN_OUT_OFFSET].value, + "199044" + ); + } + + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "handle_swap_success"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_BASE_BALANCE_OFFSET].value, + "776354uatom" + ); + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_QUOTE_BALANCE_OFFSET].value, + "1221399ubtc" + ); + } + } + + let response: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + assert_eq!(response.position_ids.len(), 1); + let position_id = response.position_ids[0]; + assert_eq!(position_id, 3u64); + + let cl = ConcentratedLiquidity::new(&app); + let pos = cl + .query_position_by_id(&PositionByIdRequest { position_id }) + .unwrap() + .position + .unwrap(); + let pos_base: Coin = pos.asset0.unwrap().try_into().unwrap(); + let pos_quote: Coin = pos.asset1.unwrap().try_into().unwrap(); + assert_eq!(pos_base, coin(774929u128, DENOM_BASE)); + assert_eq!(pos_quote, coin(1221399u128, DENOM_QUOTE)); +} + +#[test] +fn move_range_cw_dex_works() { + let (app, contract_address, _dex_router_addr, _vault_pool_id, _swap_pools_ids, admin, ..) = + fixture_dex_router(PERFORMANCE_FEE_DEFAULT); + let wasm = Wasm::new(&app); + + let _before_position: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + + let response = wasm + .execute( + contract_address.as_str(), + &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { + lower_price: Decimal::from_str("400").unwrap(), + upper_price: Decimal::from_str("1466").unwrap(), + max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), + ratio_of_swappable_funds_to_use: Decimal::one(), + twap_window_seconds: 45, + forced_swap_route: None, + claim_after: None, + })), + &[], + &admin, + ) + .unwrap(); + for event in &response.events { + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "do_swap_deposit_merge"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_TOKEN_IN_OFFSET].value, + "999999ubtc" + ); + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_MIN_OUT_OFFSET].value, + "899999" + ); + } + + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "handle_swap_success"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_BASE_BALANCE_OFFSET].value, + "1989999uatom" + ); + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_QUOTE_BALANCE_OFFSET].value, + "0ubtc" + ); + } + } + + let response: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + assert_eq!(response.position_ids.len(), 1); + let position_id = response.position_ids[0]; + assert_eq!(position_id, 3u64); + + let cl = ConcentratedLiquidity::new(&app); + let pos = cl + .query_position_by_id(&PositionByIdRequest { position_id }) + .unwrap() + .position + .unwrap(); + let pos_base: Coin = pos.asset0.unwrap().try_into().unwrap(); + let pos_quote: Coin = pos.asset1.unwrap().try_into().unwrap(); + assert_eq!(pos_base, coin(1989999u128, DENOM_BASE)); + assert_eq!(pos_quote, coin(0u128, DENOM_QUOTE)); +} + +#[test] +fn move_range_cw_dex_works_forced_swap_route() { + let (app, contract_address, _dex_router_addr, vault_pool_id, _swap_pools_ids, admin, ..) = + fixture_dex_router(PERFORMANCE_FEE_DEFAULT); + let wasm = Wasm::new(&app); + + let _before_position: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + + // Define CW Dex Router swap route to force + // In this case we are going from in range, to out of range to the upper side, so we swap all the quote token to base token + let path1 = SwapAmountInRoute { + pool_id: vault_pool_id, + token_out_denom: DENOM_BASE.to_string(), + }; + + let response = wasm + .execute( + contract_address.as_str(), + &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { + lower_price: Decimal::from_str("400").unwrap(), + upper_price: Decimal::from_str("1466").unwrap(), + max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), + ratio_of_swappable_funds_to_use: Decimal::one(), + twap_window_seconds: 45, + forced_swap_route: Some(vec![path1]), + claim_after: None, + })), + &[], + &admin, + ) + .unwrap(); + + for event in &response.events { + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "do_swap_deposit_merge"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_TOKEN_IN_OFFSET].value, + "999999ubtc" + ); + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_MIN_OUT_OFFSET].value, + "899999" + ); + } + + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "handle_swap_success"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_BASE_BALANCE_OFFSET].value, + "1989999uatom" + ); + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_QUOTE_BALANCE_OFFSET].value, + "0ubtc" + ); + } + } + let response: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + assert_eq!(response.position_ids.len(), 1); + let position_id = response.position_ids[0]; + assert_eq!(position_id, 3u64); + + let cl = ConcentratedLiquidity::new(&app); + let pos = cl + .query_position_by_id(&PositionByIdRequest { position_id }) + .unwrap() + .position + .unwrap(); + let pos_base: Coin = pos.asset0.unwrap().try_into().unwrap(); + let pos_quote: Coin = pos.asset1.unwrap().try_into().unwrap(); + assert_eq!(pos_base, coin(1989999u128, DENOM_BASE)); + assert_eq!(pos_quote, coin(0u128, DENOM_QUOTE)); +} + +#[test] +fn move_range_single_side_works() { + let (app, contract_address, _dex_router_addr, _vault_pool_id, _swap_pools_ids, admin, ..) = + fixture_dex_router(PERFORMANCE_FEE_DEFAULT); + let wasm = Wasm::new(&app); + + let response = wasm + .execute( + contract_address.as_str(), + &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { + lower_price: Decimal::from_str("20.71").unwrap(), + upper_price: Decimal::from_str("45").unwrap(), + max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), + ratio_of_swappable_funds_to_use: Decimal::one(), + twap_window_seconds: 45, + forced_swap_route: None, + claim_after: None, + })), + &[], + &admin, + ) + .unwrap(); + + for event in &response.events { + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "do_swap_deposit_merge"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_TOKEN_IN_OFFSET].value, + "999999ubtc" + ); + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_MIN_OUT_OFFSET].value, + "899999" + ); + } + + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "handle_swap_success"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_BASE_BALANCE_OFFSET].value, + "1989999uatom" + ); + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_QUOTE_BALANCE_OFFSET].value, + "0ubtc" + ); + } + } + + let response = wasm + .execute( + contract_address.as_str(), + &ExecuteMsg::VaultExtension(ExtensionExecuteMsg::ModifyRange(ModifyRangeMsg { + lower_price: Decimal::from_str("0.1").unwrap(), + upper_price: Decimal::from_str("0.2").unwrap(), + max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), + ratio_of_swappable_funds_to_use: Decimal::one(), + twap_window_seconds: 45, + forced_swap_route: None, + claim_after: None, + })), + &[], + &admin, + ) + .unwrap(); + + for event in &response.events { + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "do_swap_deposit_merge"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_TOKEN_IN_OFFSET].value, + "1989998uatom" + ); + assert_eq!( + event.attributes[pos + DO_SWAP_DEPOSIT_MIN_OUT_OFFSET].value, + "1790998" + ); + } + + let pos = event + .attributes + .iter() + .position(|attr| attr.key == "action" && attr.value == "handle_swap_success"); + if let Some(pos) = pos { + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_BASE_BALANCE_OFFSET].value, + "0uatom" + ); + assert_eq!( + event.attributes[pos + SWAP_SUCCESS_QUOTE_BALANCE_OFFSET].value, + "1970100ubtc" + ); + } + } + + let response: PositionResponse = wasm + .query( + contract_address.as_str(), + &QueryMsg::VaultExtension(ExtensionQueryMsg::ConcentratedLiquidity( + ClQueryMsg::Position {}, + )), + ) + .unwrap(); + assert_eq!(response.position_ids.len(), 1); + let position_id = response.position_ids[0]; + assert_eq!(position_id, 4u64); + + let cl = ConcentratedLiquidity::new(&app); + let pos = cl + .query_position_by_id(&PositionByIdRequest { position_id }) + .unwrap() + .position + .unwrap(); + let pos_base: Coin = pos.asset0.unwrap().try_into().unwrap(); + let pos_quote: Coin = pos.asset1.unwrap().try_into().unwrap(); + assert_eq!(pos_base, coin(0u128, DENOM_BASE)); + assert_eq!(pos_quote, coin(1970100u128, DENOM_QUOTE)); +} + +/* +we try the following position from https://docs.google.com/spreadsheets/d/1xPsKsQkM0apTZQPBBwVlEyB5Sk31sw6eE8U0FgnTWUQ/edit?usp=sharing +lower_price: 4500 +current_price: 4692.937 +upper_price: 5500 + +the spreadsheet says we need to leave 42806.28569 in token x and swap over 157193.7143 +157193.7143 / 4692.937 = 33.49580749 +both token amounts are used in 5 decimals, since the leftover amount is in 5 decimals +so we want to deposit 4280628569 and 3349580 +*/ +#[test] +fn test_swap_math_poc() { + let (app, _contract, _cl_pool_id, _admin, _) = init_test_contract( + // TODO: Evaluate using fixture_default() + "./test-tube-build/wasm32-unknown-unknown/release/cl_vault.wasm", + &[ + Coin::new(ADMIN_BALANCE_AMOUNT, "uosmo"), + Coin::new(ADMIN_BALANCE_AMOUNT, DENOM_BASE), + Coin::new(ADMIN_BALANCE_AMOUNT, DENOM_QUOTE), + ], + MsgCreateConcentratedPool { + sender: "overwritten".to_string(), + denom0: DENOM_BASE.to_string(), //token0 is uatom + denom1: DENOM_QUOTE.to_string(), //token1 is uosmo + tick_spacing: 100, + spread_factor: Decimal::from_str("0.0001").unwrap().atomics().to_string(), + }, + 30500000, // 4500 + 31500000, // 5500 + vec![ + v1beta1::Coin { + denom: DENOM_BASE.to_string(), + amount: "1000000".to_string(), + }, + v1beta1::Coin { + denom: DENOM_QUOTE.to_string(), + amount: "1000000".to_string(), + }, + ], + Uint128::zero(), + Uint128::zero(), + PERFORMANCE_FEE_DEFAULT, + ); + let alice = app + .init_account(&[ + Coin::new(1_000_000_000_000, "uosmo"), + Coin::new(1_000_000_000_000, DENOM_BASE), + Coin::new(1_000_000_000_000, DENOM_QUOTE), + ]) + .unwrap(); + + let cl = ConcentratedLiquidity::new(&app); + + let pools = cl.query_pools(&PoolsRequest { pagination: None }).unwrap(); + let pool: Pool = Pool::decode(pools.pools[0].value.as_slice()).unwrap(); + + // from the spreadsheet + // create a basic position on the pool + let initial_position = MsgCreatePosition { + pool_id: pool.id, + sender: alice.address(), + lower_tick: 30500000, + upper_tick: 31500000, + tokens_provided: vec![ + coin(3349580, DENOM_BASE).into(), + coin(4280628569, DENOM_QUOTE).into(), + ], + token_min_amount0: "0".to_string(), + token_min_amount1: "0".to_string(), + }; + let _position = cl.create_position(initial_position, &alice).unwrap(); +} diff --git a/smart-contracts/contracts/cl-vault/tests/rewards.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/rewards.rs similarity index 95% rename from smart-contracts/contracts/cl-vault/tests/rewards.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/rewards.rs index 232436ae7..9175216c6 100644 --- a/smart-contracts/contracts/cl-vault/tests/rewards.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/rewards.rs @@ -1,7 +1,4 @@ -#![cfg(feature = "test-tube")] - -mod setup; -use setup::{ +use crate::setup::{ fixture_default, get_amount_from_denom, get_balance_amount, get_event_attributes_by_ty_and_key, ACCOUNTS_INIT_BALANCE, ACCOUNTS_NUM, DENOM_BASE, DENOM_QUOTE, DEPOSIT_AMOUNT, PERFORMANCE_FEE_DEFAULT, @@ -35,8 +32,7 @@ fn test_collect_rewards_with_rewards_full_works() { } fn collect_rewards_with_rewards(performance_fee: u64) { - let (app, contract_address, cl_pool_id, admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(performance_fee); + let (app, contract_address, cl_pool_id, admin, _) = fixture_default(performance_fee); // Initialize accounts let utility_account = app @@ -153,8 +149,7 @@ fn collect_rewards_with_rewards(performance_fee: u64) { #[test] fn test_collect_rewards_no_rewards_works() { - let (app, contract_address, _cl_pool_id, _admin, _deposit_ratio, _deposit_ratio_approx) = - fixture_default(PERFORMANCE_FEE_DEFAULT); + let (app, contract_address, _cl_pool_id, _admin, _) = fixture_default(PERFORMANCE_FEE_DEFAULT); // Initialize accounts let accounts = app diff --git a/smart-contracts/contracts/cl-vault/tests/setup/mod.rs b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/setup.rs similarity index 91% rename from smart-contracts/contracts/cl-vault/tests/setup/mod.rs rename to smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/setup.rs index 8b8df58aa..129ba21f0 100644 --- a/smart-contracts/contracts/cl-vault/tests/setup/mod.rs +++ b/smart-contracts/osmosis/contracts/cl-vault/tests/test-tube/setup.rs @@ -1,7 +1,10 @@ -#![cfg(feature = "test-tube")] #![allow(dead_code)] -use cl_vault::{helpers::generic::sort_tokens, msg::InstantiateMsg, state::VaultConfig}; +use cl_vault::{ + helpers::generic::sort_tokens, + msg::{AdminExtensionExecuteMsg, ExtensionExecuteMsg, InstantiateMsg}, + state::VaultConfig, +}; use cosmwasm_std::{coin, Addr, Attribute, Coin, Decimal, Uint128}; use dex_router_osmosis::msg::{ExecuteMsg as DexExecuteMsg, InstantiateMsg as DexInstantiate}; use osmosis_std::types::{ @@ -39,9 +42,7 @@ pub const DEPOSIT_AMOUNT: u128 = 5_000_000_000; pub const INITIAL_POSITION_BURN: u128 = 1_000_000; -pub fn fixture_default( - performance_fee: u64, -) -> (OsmosisTestApp, Addr, u64, SigningAccount, f64, String) { +pub fn fixture_default(performance_fee: u64) -> (OsmosisTestApp, Addr, u64, SigningAccount, f64) { init_test_contract( "./test-tube-build/wasm32-unknown-unknown/release/cl_vault.wasm", &[ @@ -87,7 +88,6 @@ pub fn fixture_dex_router( Vec, SigningAccount, f64, - String, ) { init_test_contract_with_dex_router_and_swap_pools( "./test-tube-build/wasm32-unknown-unknown/release/cl_vault.wasm", @@ -126,9 +126,8 @@ pub fn fixture_dex_router( ) } -// INIT PRIVATE METHODS - // TODO: This is pub because of the proptest still not having a default_init implementation +#[allow(clippy::too_many_arguments)] pub fn init_test_contract( filename: &str, admin_balance: &[Coin], @@ -139,7 +138,7 @@ pub fn init_test_contract( token_min_amount0: Uint128, token_min_amount1: Uint128, performance_fee: u64, -) -> (OsmosisTestApp, Addr, u64, SigningAccount, f64, String) { +) -> (OsmosisTestApp, Addr, u64, SigningAccount, f64) { // Create new osmosis appchain instance let app = OsmosisTestApp::new(); let pm = PoolManager::new(&app); @@ -207,7 +206,7 @@ pub fn init_test_contract( .unwrap(); assert_eq!(spot_price.spot_price, "1.000000000000000000"); - let (deposit_ratio, deposit_ratio_approx) = calculate_deposit_ratio( + let deposit_ratio_base = calculate_deposit_ratio( spot_price.spot_price, tokens_provided, create_position.data.amount0, @@ -230,7 +229,9 @@ pub fn init_test_contract( performance_fee: Decimal::percent(performance_fee), treasury: Addr::unchecked(admin.address()), swap_max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), - dex_router: Addr::unchecked(admin.address()), // Just to fulfill bech32 requirement + dex_router: Addr::unchecked(admin.address()), + swap_admin: Addr::unchecked(admin.address()), + twap_window_seconds: 24u64, }, vault_token_subdenom: "utestvault".to_string(), range_admin: admin.address(), @@ -255,11 +256,11 @@ pub fn init_test_contract( Addr::unchecked(contract.data.address), vault_pool.id, admin, - deposit_ratio, - deposit_ratio_approx, + deposit_ratio_base, ) } +#[allow(clippy::too_many_arguments)] fn init_test_contract_with_dex_router_and_swap_pools( filename_cl: &str, filename_dex: &str, @@ -279,7 +280,6 @@ fn init_test_contract_with_dex_router_and_swap_pools( Vec, SigningAccount, f64, - String, ) { // Create new osmosis appchain instance let app = OsmosisTestApp::new(); @@ -303,7 +303,7 @@ fn init_test_contract_with_dex_router_and_swap_pools( ], vec![ Coin { - denom: DENOM_QUOTE.to_string(), + denom: DENOM_BASE.to_string(), amount: Uint128::from_str(TOKENS_PROVIDED_AMOUNT_HIGH).unwrap(), }, Coin { @@ -313,7 +313,7 @@ fn init_test_contract_with_dex_router_and_swap_pools( ], vec![ Coin { - denom: DENOM_BASE.to_string(), + denom: DENOM_QUOTE.to_string(), amount: Uint128::from_str(TOKENS_PROVIDED_AMOUNT_HIGH).unwrap(), }, Coin { @@ -366,7 +366,7 @@ fn init_test_contract_with_dex_router_and_swap_pools( // TODO: We could be using a mixed set of CL and gAMM pools here let mut lp_pools = vec![]; for pool_coins in &pools_coins { - let lp_pool = gm.create_basic_pool(&pool_coins, &admin).unwrap(); + let lp_pool = gm.create_basic_pool(pool_coins, &admin).unwrap(); lp_pools.push(lp_pool.data.pool_id); } @@ -401,7 +401,7 @@ fn init_test_contract_with_dex_router_and_swap_pools( .unwrap(); assert_eq!(spot_price.spot_price, "1.000000000000000000"); - let (deposit_ratio, deposit_ratio_approx) = calculate_deposit_ratio( + let deposit_ratio_base = calculate_deposit_ratio( spot_price.spot_price, tokens_provided, create_position.data.amount0, @@ -420,7 +420,7 @@ fn init_test_contract_with_dex_router_and_swap_pools( &DexInstantiate {}, Some(admin.address().as_str()), Some("dex-router"), - sort_tokens(vec![]).as_ref(), + &[], &admin, ) .unwrap(); @@ -428,7 +428,7 @@ fn init_test_contract_with_dex_router_and_swap_pools( // Here we pass only the 3x swap LP pools, not the Vault CL pool id 1 set_dex_router_paths( &app, - contract_dex_router.data.address.to_string(), + &contract_dex_router.data.address, &lp_pools, &pools_coins, &admin, @@ -446,6 +446,8 @@ fn init_test_contract_with_dex_router_and_swap_pools( treasury: Addr::unchecked(admin.address()), swap_max_slippage: Decimal::bps(MAX_SLIPPAGE_HIGH), dex_router: Addr::unchecked(contract_dex_router.clone().data.address), + swap_admin: Addr::unchecked(admin.address()), + twap_window_seconds: 24u64, }, vault_token_subdenom: "utestvault".to_string(), range_admin: admin.address(), @@ -465,6 +467,18 @@ fn init_test_contract_with_dex_router_and_swap_pools( ) .unwrap(); + wasm.execute( + &contract_cl.data.address, + &cw_vault_multi_standard::VaultStandardExecuteMsg::VaultExtension( + ExtensionExecuteMsg::Admin(AdminExtensionExecuteMsg::UpdateDexRouter { + address: Some(contract_dex_router.data.address.clone()), + }), + ), + &[], + &admin, + ) + .unwrap(); + ( app, Addr::unchecked(contract_cl.data.address), @@ -472,16 +486,15 @@ fn init_test_contract_with_dex_router_and_swap_pools( vault_pool.id, lp_pools, admin, - deposit_ratio, - deposit_ratio_approx, + deposit_ratio_base, ) } fn set_dex_router_paths( app: &OsmosisTestApp, - dex_router: String, - pools: &Vec, - pools_coins: &Vec>, + dex_router: &str, + pools: &[u64], + pools_coins: &[Vec], admin: &SigningAccount, ) { let wasm = Wasm::new(app); @@ -490,15 +503,15 @@ fn set_dex_router_paths( // Set Dex Router contract paths for (index, pool_id) in pools.iter().enumerate() { wasm.execute( - &dex_router, + dex_router, &DexExecuteMsg::SetPath { offer_denom: pools_coins[index][0].denom.to_string(), ask_denom: pools_coins[index][1].denom.to_string(), path: vec![*pool_id], bidirectional: true, }, - vec![].as_ref(), - &admin, + &[], + admin, ) .unwrap(); } @@ -530,7 +543,7 @@ pub fn get_balance_amount(app: &OsmosisTestApp, address: String, denom: String) .unwrap() } -pub fn get_amount_from_denom(value: &String) -> u128 { +pub fn get_amount_from_denom(value: &str) -> u128 { // Find the position where the non-numeric part starts let pos = value.find(|c: char| !c.is_numeric()).unwrap_or(value.len()); // Extract the numeric part from the string @@ -546,7 +559,7 @@ pub fn calculate_deposit_ratio( amount1_deposit: String, denom_base: String, denom_quote: String, -) -> (f64, String) { +) -> f64 { // Parse the input amounts let amount0_deposit: u128 = amount0_deposit.parse().unwrap(); let amount1_deposit: u128 = amount1_deposit.parse().unwrap(); @@ -579,32 +592,27 @@ pub fn calculate_deposit_ratio( provided_amount0 as f64 + (provided_amount1 as f64 / spot_price_value); // Calculate the ratio of total refunds in terms of token0 to total attempted deposits in terms of token0 - let ratio = if total_attempted_deposit_in_token0 == 0.0 { + if total_attempted_deposit_in_token0 == 0.0 { 0.5 // Balanced deposit } else { 2.0 * total_refunds_in_token0 / total_attempted_deposit_in_token0 - }; - - // TODO: Compute this based on tokens_provided size - let ratio_approx: String = "0.00005".to_string(); - - (ratio, ratio_approx) + } } pub fn calculate_expected_refunds( initial_amount0: u128, initial_amount1: u128, - deposit_ratio: f64, + deposit_ratio_base: f64, ) -> (u128, u128) { - if deposit_ratio < 0.5 { + if deposit_ratio_base < 0.5 { // More token1 to be deposited, so token0 has a higher refund - let adjusted_amount0 = ((1.0 - deposit_ratio) * initial_amount0 as f64) as u128; + let adjusted_amount0 = ((1.0 - deposit_ratio_base) * initial_amount0 as f64) as u128; let expected_refund0 = initial_amount0 - adjusted_amount0; (expected_refund0, 0) - } else if deposit_ratio > 0.5 { + } else if deposit_ratio_base > 0.5 { // More token0 to be deposited, so token1 has a higher refund let adjusted_amount1 = - ((1.0 - (deposit_ratio - 0.5) * 2.0) * initial_amount1 as f64) as u128; + ((1.0 - (deposit_ratio_base - 0.5) * 2.0) * initial_amount1 as f64) as u128; let expected_refund1 = initial_amount1 - adjusted_amount1; (0, expected_refund1) } else { diff --git a/smart-contracts/contracts/dex-router-osmosis/.cargo/config.toml b/smart-contracts/osmosis/contracts/dex-router-osmosis/.cargo/config.toml similarity index 74% rename from smart-contracts/contracts/dex-router-osmosis/.cargo/config.toml rename to smart-contracts/osmosis/contracts/dex-router-osmosis/.cargo/config.toml index f7b529309..9b08a6ee7 100644 --- a/smart-contracts/contracts/dex-router-osmosis/.cargo/config.toml +++ b/smart-contracts/osmosis/contracts/dex-router-osmosis/.cargo/config.toml @@ -2,5 +2,5 @@ wasm = "build --release --target wasm32-unknown-unknown" unit-test = "test --lib" schema = "run --bin schema" -test-tube = "test --features test-tube -- --include-ignored --test-threads=1" +test-tube = "test --test test-tube --features test-tube -- --test-threads=1" test-tube-build = "build --release --lib --target wasm32-unknown-unknown --target-dir ./test-tube-build" diff --git a/smart-contracts/contracts/dex-router-osmosis/Cargo.toml b/smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml similarity index 90% rename from smart-contracts/contracts/dex-router-osmosis/Cargo.toml rename to smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml index 9f9d41da6..a7a7223a1 100644 --- a/smart-contracts/contracts/dex-router-osmosis/Cargo.toml +++ b/smart-contracts/osmosis/contracts/dex-router-osmosis/Cargo.toml @@ -22,6 +22,11 @@ crate-type = ["cdylib", "rlib"] [[bin]] name = "schema" +[[test]] +name = "test-tube" +path = "tests/integration.rs" +required-features = ["test-tube"] + [features] default = [] library = [] diff --git a/smart-contracts/contracts/dex-router-osmosis/README.md b/smart-contracts/osmosis/contracts/dex-router-osmosis/README.md similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/README.md rename to smart-contracts/osmosis/contracts/dex-router-osmosis/README.md diff --git a/smart-contracts/contracts/dex-router-osmosis/schema/execute_msg.json b/smart-contracts/osmosis/contracts/dex-router-osmosis/schema/execute_msg.json similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/schema/execute_msg.json rename to smart-contracts/osmosis/contracts/dex-router-osmosis/schema/execute_msg.json diff --git a/smart-contracts/contracts/dex-router-osmosis/schema/instantiate_msg.json b/smart-contracts/osmosis/contracts/dex-router-osmosis/schema/instantiate_msg.json similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/schema/instantiate_msg.json rename to smart-contracts/osmosis/contracts/dex-router-osmosis/schema/instantiate_msg.json diff --git a/smart-contracts/contracts/dex-router-osmosis/schema/query_msg.json b/smart-contracts/osmosis/contracts/dex-router-osmosis/schema/query_msg.json similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/schema/query_msg.json rename to smart-contracts/osmosis/contracts/dex-router-osmosis/schema/query_msg.json diff --git a/smart-contracts/contracts/dex-router-osmosis/src/bin/schema.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/bin/schema.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/bin/schema.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/bin/schema.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/contract.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/contract.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/contract.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/contract.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/error.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/error.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/error.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/error.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/lib.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/lib.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/lib.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/lib.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/msg.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/msg.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/msg.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/msg.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/state.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/state.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/state.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/state.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/tests/mod.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/mod.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/tests/mod.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/mod.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/tests/remove_path.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/remove_path.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/tests/remove_path.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/remove_path.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/tests/set_path.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/set_path.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/tests/set_path.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/set_path.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/src/tests/swap.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/swap.rs similarity index 100% rename from smart-contracts/contracts/dex-router-osmosis/src/tests/swap.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/src/tests/swap.rs diff --git a/smart-contracts/contracts/dex-router-osmosis/tests/initialize/mod.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/tests/initialize/mod.rs similarity index 96% rename from smart-contracts/contracts/dex-router-osmosis/tests/initialize/mod.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/tests/initialize/mod.rs index 1d827d1f3..e19f2f311 100644 --- a/smart-contracts/contracts/dex-router-osmosis/tests/initialize/mod.rs +++ b/smart-contracts/osmosis/contracts/dex-router-osmosis/tests/initialize/mod.rs @@ -55,7 +55,7 @@ pub fn single_cl_pool_fixture( let pm = PoolManager::new(app); let cl = ConcentratedLiquidity::new(app); - let gov = GovWithAppAccess::new(&app); + let gov = GovWithAppAccess::new(app); gov.propose_and_execute( CreateConcentratedLiquidityPoolsProposal::TYPE_URL.to_string(), @@ -65,12 +65,12 @@ pub fn single_cl_pool_fixture( pool_records: vec![PoolRecord { denom0: cl_pool.denom0.clone(), denom1: cl_pool.denom1.clone(), - tick_spacing: cl_pool.tick_spacing.clone(), + tick_spacing: cl_pool.tick_spacing, spread_factor: cl_pool.spread_factor.clone(), }], }, admin.address(), - &admin, + admin, ) .unwrap(); @@ -110,7 +110,7 @@ pub fn single_cl_pool_fixture( token_min_amount0: "1".to_string(), token_min_amount1: "1".to_string(), }, - &admin, + admin, ) .unwrap(); @@ -199,18 +199,18 @@ pub fn single_gamm_pool_fixture( .unwrap(), }, ], - &admin, + admin, ) .unwrap(); let ty = "pool_created"; - let keys = vec!["pool_id"]; + let key = "pool_id"; let pool_id: u64 = response .events .iter() .filter(|event| event.ty == ty) .flat_map(|event| event.attributes.clone()) - .filter(|attribute| keys.contains(&attribute.key.as_str())) + .filter(|attribute| key == attribute.key.as_str()) .collect::>() .first() .unwrap() @@ -220,7 +220,7 @@ pub fn single_gamm_pool_fixture( let _ = MsgJoinPool { sender: admin.address().to_string(), - pool_id: pool_id.clone(), + pool_id, share_out_amount: "100".to_string(), token_in_maxs: vec![ Coin { @@ -303,7 +303,7 @@ pub fn setup_paths( admin: &SigningAccount, ) { wasm.execute( - &contract_address.to_string(), + contract_address.as_ref(), &ExecuteMsg::SetPath { path, bidirectional: true, @@ -339,7 +339,7 @@ pub fn perform_swap( admin: &SigningAccount, ) -> Result, osmosis_test_tube::RunnerError> { wasm.execute( - &contract_address.to_string(), + contract_address.as_ref(), &ExecuteMsg::Swap { out_denom: ask_denom, path: Some(path.first().unwrap().clone()), diff --git a/smart-contracts/contracts/dex-router-osmosis/tests/integration.rs b/smart-contracts/osmosis/contracts/dex-router-osmosis/tests/integration.rs similarity index 99% rename from smart-contracts/contracts/dex-router-osmosis/tests/integration.rs rename to smart-contracts/osmosis/contracts/dex-router-osmosis/tests/integration.rs index 5af1f04bb..2dbff1237 100644 --- a/smart-contracts/contracts/dex-router-osmosis/tests/integration.rs +++ b/smart-contracts/osmosis/contracts/dex-router-osmosis/tests/integration.rs @@ -44,7 +44,7 @@ fn default_init_works() { let resp: BestPathForPairResponse = wasm .query( - &contract_address.to_string(), + contract_address.as_ref(), &QueryMsg::BestPathForPair { offer: Coin::new( Uint128::from(100000000u128).into(), @@ -152,7 +152,7 @@ fn test_set_and_remove_path() { ); let _ = wasm .execute( - &contract_address.to_string(), + contract_address.as_ref(), &ExecuteMsg::RemovePath { path: vec![pools.first().unwrap().pool], bidirectional: true, diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/Cargo.toml b/smart-contracts/osmosis/contracts/fake-lst-adapter/Cargo.toml new file mode 100644 index 000000000..e20adcfb1 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "fake-lst-adapter" +version = "0.1.0" +authors = ["Lars Lubkoll "] +edition = "2018" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "fake_lst_adapter.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[[bin]] +name = "gen" +required-features = ["protobuf", "protobuf-codegen"] + +[features] +default = ["export"] +export = [] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +thiserror = { workspace = true } +const_format = { workspace = true } +osmosis-std = { workspace = true } + +# Dependencies for interface +cw-orch = { workspace = true } + +# Dependencies for bins +clap = { workspace = true, optional = true, features = ["derive"] } +dotenv = { workspace = true, optional = true } +env_logger = { workspace = true, optional = true } +protobuf = { version = "3.5.0", optional = true } +protobuf-codegen = { version = "3.5.0", optional = true } \ No newline at end of file diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/protos/protos/mod.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/protos/protos/mod.rs new file mode 100644 index 000000000..f17d3bdd2 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/protos/protos/mod.rs @@ -0,0 +1,3 @@ +// @generated + +pub mod test; diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/protos/protos/test.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/protos/protos/test.rs new file mode 100644 index 000000000..1f4033e70 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/protos/protos/test.rs @@ -0,0 +1,255 @@ +// This file is generated by rust-protobuf 3.5.0. Do not edit +// .proto file is parsed by protoc 27.2 +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_results)] +#![allow(unused_mut)] + +//! Generated file from `v1beta1/test.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_3_5_0; + +// @@protoc_insertion_point(message:Fruit) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct Fruit { + // message fields + // @@protoc_insertion_point(field:Fruit.name) + pub name: ::std::option::Option<::std::string::String>, + // @@protoc_insertion_point(field:Fruit.weight) + pub weight: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:Fruit.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a Fruit { + fn default() -> &'a Fruit { + ::default_instance() + } +} + +impl Fruit { + pub fn new() -> Fruit { + ::std::default::Default::default() + } + + // optional string name = 1; + + pub fn name(&self) -> &str { + match self.name.as_ref() { + Some(v) => v, + None => "", + } + } + + pub fn clear_name(&mut self) { + self.name = ::std::option::Option::None; + } + + pub fn has_name(&self) -> bool { + self.name.is_some() + } + + // Param is passed by value, moved + pub fn set_name(&mut self, v: ::std::string::String) { + self.name = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_name(&mut self) -> &mut ::std::string::String { + if self.name.is_none() { + self.name = ::std::option::Option::Some(::std::string::String::new()); + } + self.name.as_mut().unwrap() + } + + // Take field + pub fn take_name(&mut self) -> ::std::string::String { + self.name.take().unwrap_or_else(|| ::std::string::String::new()) + } + + // optional float weight = 2; + + pub fn weight(&self) -> f32 { + self.weight.unwrap_or(0.) + } + + pub fn clear_weight(&mut self) { + self.weight = ::std::option::Option::None; + } + + pub fn has_weight(&self) -> bool { + self.weight.is_some() + } + + // Param is passed by value, moved + pub fn set_weight(&mut self, v: f32) { + self.weight = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "name", + |m: &Fruit| { &m.name }, + |m: &mut Fruit| { &mut m.name }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "weight", + |m: &Fruit| { &m.weight }, + |m: &mut Fruit| { &mut m.weight }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "Fruit", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for Fruit { + const NAME: &'static str = "Fruit"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.name = ::std::option::Option::Some(is.read_string()?); + }, + 21 => { + self.weight = ::std::option::Option::Some(is.read_float()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.name.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + if let Some(v) = self.weight { + my_size += 1 + 4; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.name.as_ref() { + os.write_string(1, v)?; + } + if let Some(v) = self.weight { + os.write_float(2, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> Fruit { + Fruit::new() + } + + fn clear(&mut self) { + self.name = ::std::option::Option::None; + self.weight = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static Fruit { + static instance: Fruit = Fruit { + name: ::std::option::Option::None, + weight: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for Fruit { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("Fruit").unwrap()).clone() + } +} + +impl ::std::fmt::Display for Fruit { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Fruit { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x12v1beta1/test.proto\"3\n\x05Fruit\x12\x12\n\x04name\x18\x01\x20\x01\ + (\tR\x04name\x12\x16\n\x06weight\x18\x02\x20\x01(\x02R\x06weight\ +"; + +/// `FileDescriptorProto` object which was a source for this generated file +fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + static file_descriptor_proto_lazy: ::protobuf::rt::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::Lazy::new(); + file_descriptor_proto_lazy.get(|| { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() + }) +} + +/// `FileDescriptor` object which allows dynamic access to files +pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { + static generated_file_descriptor_lazy: ::protobuf::rt::Lazy<::protobuf::reflect::GeneratedFileDescriptor> = ::protobuf::rt::Lazy::new(); + static file_descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::FileDescriptor> = ::protobuf::rt::Lazy::new(); + file_descriptor.get(|| { + let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { + let mut deps = ::std::vec::Vec::with_capacity(0); + let mut messages = ::std::vec::Vec::with_capacity(1); + messages.push(Fruit::generated_message_descriptor_data()); + let mut enums = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedFileDescriptor::new_generated( + file_descriptor_proto(), + deps, + messages, + enums, + ) + }); + ::protobuf::reflect::FileDescriptor::new_generated_2(generated_file_descriptor) + }) +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/bin/gen.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/bin/gen.rs new file mode 100644 index 000000000..7728664d2 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/bin/gen.rs @@ -0,0 +1,39 @@ +use protobuf::descriptor::field_descriptor_proto::Type; +use protobuf::reflect::FieldDescriptor; +use protobuf::reflect::MessageDescriptor; +use protobuf_codegen::Codegen; +use protobuf_codegen::Customize; +use protobuf_codegen::CustomizeCallback; + +fn main() { + struct GenSerde; + + impl CustomizeCallback for GenSerde { + fn message(&self, _message: &MessageDescriptor) -> Customize { + Customize::default().before("#[derive(::serde::Serialize, ::serde::Deserialize)]") + } + + fn field(&self, field: &FieldDescriptor) -> Customize { + // if field.proto().type_() == Type::TYPE_ENUM { + // // `EnumOrUnknown` is not a part of rust-protobuf, so external serializer is needed. + // Customize::default().before( + // "#[serde(serialize_with = \"crate::serialize_enum_or_unknown\", deserialize_with = \"crate::deserialize_enum_or_unknown\")]") + // } else { + Customize::default() + // } + } + + fn special_field(&self, _message: &MessageDescriptor, _field: &str) -> Customize { + Customize::default().before("#[serde(skip)]") + } + } + + Codegen::new() + .protoc() + .includes(&["tokenfactory"]) + // Inputs must reside in some of include paths. + .input("tokenfactory/v1beta1/test.proto") + // Specify output directory relative to Cargo output directory. + .cargo_out_dir("protos") + .run_from_script(); +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/contract.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/contract.rs new file mode 100644 index 000000000..2873e7352 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/contract.rs @@ -0,0 +1,59 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; +use osmosis_std::types::ibc::applications::interchain_accounts::controller::v1::MsgRegisterInterchainAccount; + +use crate::error::ContractError; +use crate::msg::{ + FakeLstExecuteMsg, FakeLstInstantiateMsg, FakeLstQueryMsg, RedemptionRateResponse, +}; +use crate::state::STATE; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: FakeLstInstantiateMsg, +) -> Result { + STATE.save(deps.storage, &msg.redemption_rate)?; + + let reg_msg = MsgRegisterInterchainAccount { + owner: env.contract.address.to_string(), + connection_id: "connection-3027".to_string(), + version: "ics27-1".to_string(), + }; + // let reg_msg = MsgRegisterInterchainAccount { + // owner: Signer::from_str(env.contract.address.as_ref()).unwrap(), + // connection_id: ConnectionId::new(3027), + // version: Version::new("0.0.1".to_string()), + // }; + Ok(Response::new().add_message(reg_msg)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + msg: FakeLstExecuteMsg, +) -> Result { + match msg { + FakeLstExecuteMsg::Update { redemption_rate } => { + STATE.update(deps.storage, |_| -> Result<_, ContractError> { + Ok(redemption_rate) + })?; + } + } + Ok(Response::new()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: FakeLstQueryMsg) -> Result { + match msg { + FakeLstQueryMsg::RedemptionRate { .. } => Ok(to_json_binary(&RedemptionRateResponse { + redemption_rate: STATE.load(deps.storage)?, + update_time: 0u64, + })?), + } +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/error.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/error.rs new file mode 100644 index 000000000..74972d6c0 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/error.rs @@ -0,0 +1,17 @@ +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + Std(#[from] StdError), + + #[error("Price is not low enough.")] + InvalidPrice {}, + + #[error("Wrong offer denom.")] + WrongDenom {}, + + #[error("Missing or too many funds.")] + InvalidFunds {}, +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/examples/schema.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/examples/schema.rs new file mode 100644 index 000000000..bda1293a4 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/examples/schema.rs @@ -0,0 +1,20 @@ +use std::env::current_dir; +use std::fs::create_dir_all; + +use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; + +use fake_lst_adapter::msg::{ + FakeLstExecuteMsg, FakeLstInstantiateMsg, FakeLstQueryMsg, RedemptionRateResponse, +}; + +fn main() { + let mut out_dir = current_dir().unwrap(); + out_dir.push("schema"); + create_dir_all(&out_dir).unwrap(); + remove_schemas(&out_dir).unwrap(); + + export_schema(&schema_for!(FakeLstInstantiateMsg), &out_dir); + export_schema(&schema_for!(FakeLstExecuteMsg), &out_dir); + export_schema(&schema_for!(FakeLstQueryMsg), &out_dir); + export_schema(&schema_for!(RedemptionRateResponse), &out_dir); +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/lib.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/lib.rs new file mode 100644 index 000000000..7664c97fb --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/lib.rs @@ -0,0 +1,12 @@ +pub mod contract; +mod error; +pub mod msg; +pub mod state; + +pub use crate::error::ContractError; + +pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub const MY_NAMESPACE: &str = "quasar"; +pub const MY_APP_NAME: &str = "fake-lst-adapter"; +pub const MY_APP_ID: &str = const_format::formatcp!("{MY_NAMESPACE}:{MY_APP_NAME}"); diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/msg.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/msg.rs new file mode 100644 index 000000000..32234cd99 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/msg.rs @@ -0,0 +1,29 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Binary, Decimal}; + +#[cw_serde] +pub struct FakeLstInstantiateMsg { + pub redemption_rate: Decimal, +} + +#[cw_serde] +pub struct FakeLstMigrateMsg {} + +#[cw_serde] +pub enum FakeLstExecuteMsg { + Update { redemption_rate: Decimal }, +} + +#[cw_serde] +pub enum FakeLstQueryMsg { + RedemptionRate { + denom: String, + params: Option, + }, +} + +#[cw_serde] +pub struct RedemptionRateResponse { + pub redemption_rate: Decimal, + pub update_time: u64, +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/src/state.rs b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/state.rs new file mode 100644 index 000000000..fc92d7c85 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/src/state.rs @@ -0,0 +1,4 @@ +use cosmwasm_std::Decimal; +use cw_storage_plus::Item; + +pub const STATE: Item = Item::new("state"); diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/authorityMetadata.proto b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/authorityMetadata.proto new file mode 100644 index 000000000..a8af6712a --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/authorityMetadata.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package quasarlabs.quasarnode.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/quasarlabs/quasarnode/x/tokenfactory/types"; + +// DenomAuthorityMetadata specifies metadata for addresses that have specific +// capabilities over a token factory denom. Right now there is only one Admin +// permission, but is planned to be extended to the future. +message DenomAuthorityMetadata { + option (gogoproto.equal) = true; + + // Can be empty for no admin, or a valid osmosis address + string admin = 1 [ (gogoproto.moretags) = "yaml:\"admin\"" ]; +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/genesis.proto b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/genesis.proto new file mode 100644 index 000000000..3e9b629cc --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/genesis.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +package quasarlabs.quasarnode.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "quasarlabs/quasarnode/tokenfactory/v1beta1/authorityMetadata.proto"; +import "quasarlabs/quasarnode/tokenfactory/v1beta1/params.proto"; + + +option go_package = "github.com/quasarlabs/quasarnode/x/tokenfactory/types"; + +// GenesisState defines the tokenfactory module's genesis state. +message GenesisState { + // params defines the paramaters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; + + repeated GenesisDenom factory_denoms = 2 [ + (gogoproto.moretags) = "yaml:\"factory_denoms\"", + (gogoproto.nullable) = false + ]; +} + +// GenesisDenom defines a tokenfactory denom that is defined within genesis +// state. The structure contains DenomAuthorityMetadata which defines the +// denom's admin. +message GenesisDenom { + option (gogoproto.equal) = true; + + string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; + DenomAuthorityMetadata authority_metadata = 2 [ + (gogoproto.moretags) = "yaml:\"authority_metadata\"", + (gogoproto.nullable) = false + ]; +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/params.proto b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/params.proto new file mode 100644 index 000000000..79899ea26 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/params.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package quasarlabs.quasarnode.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "quasarlabs/quasarnode/tokenfactory/v1beta1/authorityMetadata.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/base/v1beta1/coin.proto"; + +option go_package = "github.com/quasarlabs/quasarnode/x/tokenfactory/types"; + +// Params defines the parameters for the tokenfactory module. +message Params { + repeated cosmos.base.v1beta1.Coin denom_creation_fee = 1 [ + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.moretags) = "yaml:\"denom_creation_fee\"", + (gogoproto.nullable) = false + ]; + + // if denom_creation_fee is an empty array, then this field is used to add more gas consumption + // to the base cost. + // https://github.com/CosmWasm/token-factory/issues/11 + uint64 denom_creation_gas_consume = 2 [ + (gogoproto.moretags) = "yaml:\"denom_creation_gas_consume\"", + (gogoproto.nullable) = true + ]; +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/query.proto b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/query.proto new file mode 100644 index 000000000..6addec058 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/query.proto @@ -0,0 +1,71 @@ +syntax = "proto3"; +package quasarlabs.quasarnode.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "quasarlabs/quasarnode/tokenfactory/v1beta1/authorityMetadata.proto"; +import "quasarlabs/quasarnode/tokenfactory/v1beta1/params.proto"; + +option go_package = "github.com/quasarlabs/quasarnode/x/tokenfactory/types"; + +// Query defines the gRPC querier service. +service Query { + // Params defines a gRPC query method that returns the tokenfactory module's + // parameters. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/quasarlabs.quasarnode.tokenfactory.v1beta1/params"; + } + + // DenomAuthorityMetadata defines a gRPC query method for fetching + // DenomAuthorityMetadata for a particular denom. + rpc DenomAuthorityMetadata(QueryDenomAuthorityMetadataRequest) + returns (QueryDenomAuthorityMetadataResponse) { + option (google.api.http).get = + "/quasarlabs.quasarnode.tokenfactory.v1beta1/denoms/{denom}/authority_metadata"; + } + + // DenomsFromCreator defines a gRPC query method for fetching all + // denominations created by a specific admin/creator. + rpc DenomsFromCreator(QueryDenomsFromCreatorRequest) + returns (QueryDenomsFromCreatorResponse) { + option (google.api.http).get = + "/quasarlabs.quasarnode.tokenfactory.v1beta1/denoms_from_creator/{creator}"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1 [ (gogoproto.nullable) = false ]; +} + +// QueryDenomAuthorityMetadataRequest defines the request structure for the +// DenomAuthorityMetadata gRPC query. +message QueryDenomAuthorityMetadataRequest { + string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; +} + +// QueryDenomAuthorityMetadataResponse defines the response structure for the +// DenomAuthorityMetadata gRPC query. +message QueryDenomAuthorityMetadataResponse { + DenomAuthorityMetadata authority_metadata = 1 [ + (gogoproto.moretags) = "yaml:\"authority_metadata\"", + (gogoproto.nullable) = false + ]; +} + +// QueryDenomsFromCreatorRequest defines the request structure for the +// DenomsFromCreator gRPC query. +message QueryDenomsFromCreatorRequest { + string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; +} + +// QueryDenomsFromCreatorRequest defines the response structure for the +// DenomsFromCreator gRPC query. +message QueryDenomsFromCreatorResponse { + repeated string denoms = 1 [ (gogoproto.moretags) = "yaml:\"denoms\"" ]; +} diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/test.proto b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/test.proto new file mode 100644 index 000000000..c1b3e9a28 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/test.proto @@ -0,0 +1,6 @@ +syntax = "proto2"; + +message Fruit { + optional string name = 1; + optional float weight = 2; +} \ No newline at end of file diff --git a/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/tx.proto b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/tx.proto new file mode 100644 index 000000000..3c2688ba5 --- /dev/null +++ b/smart-contracts/osmosis/contracts/fake-lst-adapter/tokenfactory/v1beta1/tx.proto @@ -0,0 +1,112 @@ +syntax = "proto3"; +package quasarlabs.quasarnode.tokenfactory.v1beta1; + +import "gogoproto/gogo.proto"; +import "cosmos/base/v1beta1/coin.proto"; +import "cosmos/bank/v1beta1/bank.proto"; + +option go_package = "github.com/quasarlabs/quasarnode/x/tokenfactory/types"; + +// Msg defines the tokefactory module's gRPC message service. +service Msg { + rpc CreateDenom(MsgCreateDenom) returns (MsgCreateDenomResponse); + rpc Mint(MsgMint) returns (MsgMintResponse); + rpc Burn(MsgBurn) returns (MsgBurnResponse); + rpc ChangeAdmin(MsgChangeAdmin) returns (MsgChangeAdminResponse); + rpc SetDenomMetadata(MsgSetDenomMetadata) + returns (MsgSetDenomMetadataResponse); + + // ForceTransfer is deactivated for now because we need to think through edge + // cases rpc ForceTransfer(MsgForceTransfer) returns + // (MsgForceTransferResponse); +} + +// MsgCreateDenom defines the message structure for the CreateDenom gRPC service +// method. It allows an account to create a new denom. It requires a sender +// address and a sub denomination. The (sender_address, sub_denomination) tuple +// must be unique and cannot be re-used. +// +// The resulting denom created is defined as +// . The resulting denom's admin is +// originally set to be the creator, but this can be changed later. The token +// denom does not indicate the current admin. +message MsgCreateDenom { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + // subdenom can be up to 44 "alphanumeric" characters long. + string subdenom = 2 [ (gogoproto.moretags) = "yaml:\"subdenom\"" ]; +} + +// MsgCreateDenomResponse is the return value of MsgCreateDenom +// It returns the full string of the newly created denom +message MsgCreateDenomResponse { + string new_token_denom = 1 + [ (gogoproto.moretags) = "yaml:\"new_token_denom\"" ]; +} + +// MsgMint is the sdk.Msg type for allowing an admin account to mint +// more of a token. For now, we only support minting to the sender account +message MsgMint { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; + string mintToAddress = 3 + [ (gogoproto.moretags) = "yaml:\"mint_to_address\"" ]; +} + +message MsgMintResponse {} + +// MsgBurn is the sdk.Msg type for allowing an admin account to burn +// a token. For now, we only support burning from the sender account. +message MsgBurn { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.base.v1beta1.Coin amount = 2 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false + ]; + string burnFromAddress = 3 + [ (gogoproto.moretags) = "yaml:\"burn_from_address\"" ]; +} + +message MsgBurnResponse {} + +// MsgChangeAdmin is the sdk.Msg type for allowing an admin account to reassign +// adminship of a denom to a new account +message MsgChangeAdmin { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + string denom = 2 [ (gogoproto.moretags) = "yaml:\"denom\"" ]; + string new_admin = 3 [ (gogoproto.moretags) = "yaml:\"new_admin\"" ]; +} + +// MsgChangeAdminResponse defines the response structure for an executed +// MsgChangeAdmin message. +message MsgChangeAdminResponse {} + +// message MsgForceTransfer { +// string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; +// cosmos.base.v1beta1.Coin amount = 2 [ +// (gogoproto.moretags) = "yaml:\"amount\"", +// (gogoproto.nullable) = false +// ]; +// string transferFromAddress = 3 +// [ (gogoproto.moretags) = "yaml:\"transfer_from_address\"" ]; +// string transferToAddress = 4 +// [ (gogoproto.moretags) = "yaml:\"transfer_to_address\"" ]; +// } + +// message MsgForceTransferResponse {} + +// MsgSetDenomMetadata is the sdk.Msg type for allowing an admin account to set +// the denom's bank metadata +message MsgSetDenomMetadata { + string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; + cosmos.bank.v1beta1.Metadata metadata = 2 [ + (gogoproto.moretags) = "yaml:\"metadata\"", + (gogoproto.nullable) = false + ]; +} + +// MsgSetDenomMetadataResponse defines the response structure for an executed +// MsgSetDenomMetadata message. +message MsgSetDenomMetadataResponse {} \ No newline at end of file diff --git a/smart-contracts/contracts/intergamm-bindings-test/.cargo/config b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/.cargo/config.toml similarity index 66% rename from smart-contracts/contracts/intergamm-bindings-test/.cargo/config rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/.cargo/config.toml index 336b618a1..40ea033cf 100644 --- a/smart-contracts/contracts/intergamm-bindings-test/.cargo/config +++ b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/.cargo/config.toml @@ -1,4 +1,4 @@ [alias] wasm = "build --release --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" +schema = "run --bin schema --features=schema" diff --git a/smart-contracts/contracts/lst-adapter-osmosis/Cargo.toml b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/Cargo.toml similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/Cargo.toml rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/Cargo.toml diff --git a/smart-contracts/contracts/lst-adapter-osmosis/README.md b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/README.md similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/README.md rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/README.md diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/execute_msg.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/execute_msg.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/execute_msg.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/execute_msg.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/instantiate_msg.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/instantiate_msg.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/instantiate_msg.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/instantiate_msg.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/migrate_msg.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/migrate_msg.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/migrate_msg.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/migrate_msg.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/module-schema.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/module-schema.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/module-schema.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/module-schema.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/query_msg.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/query_msg.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/query_msg.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/query_msg.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/execute.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/execute.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/execute.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/execute.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/instantiate.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/instantiate.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/instantiate.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/instantiate.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/migrate.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/migrate.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/migrate.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/migrate.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/query.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/query.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/query.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/query.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_balance_in_underlying.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_balance_in_underlying.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_balance_in_underlying.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_balance_in_underlying.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_base_admin.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_base_admin.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_base_admin.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_base_admin.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_base_config.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_base_config.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_base_config.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_base_config.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_claimable.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_claimable.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_claimable.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_claimable.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_denoms.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_denoms.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_denoms.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_denoms.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_ibc_config.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_ibc_config.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_ibc_config.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_ibc_config.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_module_data.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_module_data.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_module_data.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_module_data.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_oracle.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_oracle.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_oracle.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_oracle.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_owner.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_owner.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_owner.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_owner.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_pending_unbonds.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_pending_unbonds.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_pending_unbonds.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_pending_unbonds.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_redemption_rate.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_redemption_rate.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_redemption_rate.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_redemption_rate.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_top_level_owner.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_top_level_owner.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_top_level_owner.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_top_level_owner.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_vault.json b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_vault.json similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/schema/raw/response_to_vault.json rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/schema/raw/response_to_vault.json diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/bin/schema.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/bin/schema.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/bin/schema.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/bin/schema.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/contract.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/contract.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/contract.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/contract.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/error.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/error.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/error.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/error.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/lib.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/lib.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/lib.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/lib.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/msg.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/msg.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/msg.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/msg.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/state.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/state.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/state.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/state.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/fake_stride_oracle/mod.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/fake_stride_oracle/mod.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/tests/fake_stride_oracle/mod.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/fake_stride_oracle/mod.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/ibc_setup.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/ibc_setup.rs similarity index 95% rename from smart-contracts/contracts/lst-adapter-osmosis/src/tests/ibc_setup.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/ibc_setup.rs index b17a74d42..7ca7fbe31 100644 --- a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/ibc_setup.rs +++ b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/ibc_setup.rs @@ -11,6 +11,7 @@ use abstract_std::objects::UncheckedChannelEntry; use abstract_std::objects::{account::AccountTrace, chain_name::ChainName, AccountId}; use abstract_std::ICS20; use cosmwasm_std::Decimal; +use cw_orch::environment::Environment; use cw_orch::mock::cw_multi_test::MockApiBech32; use cw_orch::mock::MockBase; use cw_orch::{anyhow, prelude::*}; @@ -57,8 +58,8 @@ pub fn create_test_remote_account, ) -> Result<(), InterchainError> { // First we register client and host respectively - let chain1_id = abstr.ibc.client.get_chain().chain_id(); + let chain1_id = abstr.ibc.client.environment().chain_id(); let chain1_name = ChainName::from_chain_id(&chain1_id); - let chain2_id = dest.ibc.client.get_chain().chain_id(); + let chain2_id = dest.ibc.client.environment().chain_id(); let chain2_name = ChainName::from_chain_id(&chain2_id); // First, we register the host with the client. @@ -163,9 +164,9 @@ pub fn ibc_abstract_setup>( // Deploying abstract and the IBC abstract logic let abstr_origin = - Abstract::deploy_on(origin_chain.clone(), origin_chain.sender().to_string())?; + Abstract::deploy_on(origin_chain.clone(), origin_chain.sender_addr().to_string())?; let abstr_remote = - Abstract::deploy_on(remote_chain.clone(), remote_chain.sender().to_string())?; + Abstract::deploy_on(remote_chain.clone(), remote_chain.sender_addr().to_string())?; // Deploying polytone on both chains Polytone::deploy_on(origin_chain.clone(), None)?; @@ -201,18 +202,18 @@ pub fn create_app(sender_balance: Vec, vault: Option) -> anyhow::R let vault = if let Some(vault) = vault { mock.chain(OSMOSIS)?.addr_make(vault) } else { - mock.chain(OSMOSIS)?.sender() + mock.chain(OSMOSIS)?.sender_addr() }; - let owner = mock.chain(OSMOSIS)?.sender(); + let owner = mock.chain(OSMOSIS)?.sender_addr(); if !sender_balance.is_empty() { mock.chain(OSMOSIS)? - .set_balance(&mock.chain(OSMOSIS)?.sender(), sender_balance)?; + .set_balance(&mock.chain(OSMOSIS)?.sender_addr(), sender_balance)?; } let app = LstAdapterInterface::new( LST_ADAPTER_OSMOSIS_ID, - abstr_origin.version_control.get_chain().clone(), + abstr_origin.version_control.environment().clone(), ); abstr_origin.version_control.claim_namespace( diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/mod.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/mod.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/tests/mod.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/mod.rs diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/unbond.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/unbond.rs similarity index 98% rename from smart-contracts/contracts/lst-adapter-osmosis/src/tests/unbond.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/unbond.rs index c82a1659f..865c6f1b2 100644 --- a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/unbond.rs +++ b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/unbond.rs @@ -269,7 +269,7 @@ fn test_claim_multiple_deposits_and_random_donation() -> anyhow::Result<()> { assert_eq!(app.balance_in_underlying()?, expected_contract_balance); assert!(app.claim().is_ok()); - let claimed = osmosis.query_balance(&osmosis.sender(), DENOM)?; + let claimed = osmosis.query_balance(&osmosis.sender_addr(), DENOM)?; assert_eq!(claimed, redeemable0 + donation); assert_eq!(app.balance_in_underlying()?, redeemable1); @@ -303,7 +303,7 @@ fn test_claim_works_unbond_is_finished_and_funds_are_available() -> anyhow::Resu assert_eq!(app.balance_in_underlying()?, total_redeem_amount); assert!(app.claim().is_ok()); - let balance = osmosis.query_balance(&osmosis.sender(), DENOM)?; + let balance = osmosis.query_balance(&osmosis.sender_addr(), DENOM)?; assert_eq!(balance, underlying_balance); let expected_contract_balance = Uint128::zero(); diff --git a/smart-contracts/contracts/lst-adapter-osmosis/src/tests/update.rs b/smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/update.rs similarity index 100% rename from smart-contracts/contracts/lst-adapter-osmosis/src/tests/update.rs rename to smart-contracts/osmosis/contracts/lst-adapter-osmosis/src/tests/update.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/.cargo/config.toml b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/.cargo/config.toml similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/.cargo/config.toml rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/.cargo/config.toml diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/Cargo.toml b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/Cargo.toml similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/Cargo.toml rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/Cargo.toml diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/README.md b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/README.md similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/README.md rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/README.md diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/execute_msg.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/execute_msg.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/execute_msg.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/execute_msg.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/instantiate_msg.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/instantiate_msg.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/instantiate_msg.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/instantiate_msg.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/migrate_msg.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/migrate_msg.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/migrate_msg.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/migrate_msg.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/module-schema.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/module-schema.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/module-schema.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/module-schema.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/query_msg.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/query_msg.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/query_msg.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/query_msg.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/execute.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/execute.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/execute.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/execute.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/instantiate.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/instantiate.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/instantiate.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/instantiate.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/migrate.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/migrate.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/migrate.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/migrate.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/query.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/query.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/query.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/query.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_admin.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_admin.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_admin.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_admin.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_config.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_config.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_config.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_base_config.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_config.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_config.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_config.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_config.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_module_data.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_module_data.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_module_data.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_module_data.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_top_level_owner.json b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_top_level_owner.json similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_top_level_owner.json rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/schema/raw/response_to_top_level_owner.json diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/bin/schema.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/bin/schema.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/bin/schema.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/bin/schema.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/contract.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/contract.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/contract.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/contract.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/error.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/error.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/error.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/error.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/execute.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/execute.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/execute.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/execute.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/instantiate.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/instantiate.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/instantiate.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/instantiate.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/migrate.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/migrate.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/migrate.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/migrate.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/mod.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/mod.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/mod.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/mod.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/query.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/query.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/handlers/query.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/handlers/query.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/lib.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/lib.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/lib.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/lib.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/msg.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/msg.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/msg.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/msg.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/replies/mod.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/replies/mod.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/replies/mod.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/replies/mod.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/replies/swap.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/replies/swap.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/replies/swap.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/replies/swap.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/src/state.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/state.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/src/state.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/src/state.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/tests/fake_lst_adapter/mod.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/tests/fake_lst_adapter/mod.rs similarity index 100% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/tests/fake_lst_adapter/mod.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/tests/fake_lst_adapter/mod.rs diff --git a/smart-contracts/contracts/lst-dex-adapter-osmosis/tests/integration.rs b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/tests/integration.rs similarity index 99% rename from smart-contracts/contracts/lst-dex-adapter-osmosis/tests/integration.rs rename to smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/tests/integration.rs index f48435f3b..7510528ed 100644 --- a/smart-contracts/contracts/lst-dex-adapter-osmosis/tests/integration.rs +++ b/smart-contracts/osmosis/contracts/lst-dex-adapter-osmosis/tests/integration.rs @@ -30,7 +30,7 @@ impl TestEnv { mut funds: Vec, ) -> anyhow::Result> { let mock = MockBech32::new_with_chain_id("mock", "juno-1"); - let sender = mock.sender(); + let sender = mock.sender_addr(); let namespace = Namespace::new(MY_NAMESPACE)?; let abs_client = AbstractClient::builder(mock.clone()).build()?; diff --git a/smart-contracts/contracts/merkle-incentives/.cargo/config b/smart-contracts/osmosis/contracts/merkle-incentives/.cargo/config.toml similarity index 74% rename from smart-contracts/contracts/merkle-incentives/.cargo/config rename to smart-contracts/osmosis/contracts/merkle-incentives/.cargo/config.toml index be65ef401..ee729a48c 100644 --- a/smart-contracts/contracts/merkle-incentives/.cargo/config +++ b/smart-contracts/osmosis/contracts/merkle-incentives/.cargo/config.toml @@ -2,5 +2,5 @@ wasm = "build --release --lib --target wasm32-unknown-unknown" unit-test = "test --lib" schema = "run --bin schema" -test-tube = "test --features test-tube -- --include-ignored --test-threads=1" +test-tube = "test --test test-tube --features test-tube -- --test-threads=1" test-tube-build = "build --release --lib --target wasm32-unknown-unknown --target-dir ./test-tube-build" diff --git a/smart-contracts/contracts/merkle-incentives/Cargo.toml b/smart-contracts/osmosis/contracts/merkle-incentives/Cargo.toml similarity index 89% rename from smart-contracts/contracts/merkle-incentives/Cargo.toml rename to smart-contracts/osmosis/contracts/merkle-incentives/Cargo.toml index c10323134..fe2c3f273 100644 --- a/smart-contracts/contracts/merkle-incentives/Cargo.toml +++ b/smart-contracts/osmosis/contracts/merkle-incentives/Cargo.toml @@ -10,6 +10,11 @@ crate-type = ["cdylib", "rlib"] [[bin]] name = "schema" +[[test]] +name = "test-tube" +path = "tests/merkle.rs" +required-features = ["test-tube"] + [features] backtraces = ["cosmwasm-std/backtraces"] library = [] diff --git a/smart-contracts/contracts/merkle-incentives/README.md b/smart-contracts/osmosis/contracts/merkle-incentives/README.md similarity index 100% rename from smart-contracts/contracts/merkle-incentives/README.md rename to smart-contracts/osmosis/contracts/merkle-incentives/README.md diff --git a/smart-contracts/contracts/merkle-incentives/schema/merkle-incentives.json b/smart-contracts/osmosis/contracts/merkle-incentives/schema/merkle-incentives.json similarity index 100% rename from smart-contracts/contracts/merkle-incentives/schema/merkle-incentives.json rename to smart-contracts/osmosis/contracts/merkle-incentives/schema/merkle-incentives.json diff --git a/smart-contracts/contracts/merkle-incentives/schema/raw/execute.json b/smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/execute.json similarity index 100% rename from smart-contracts/contracts/merkle-incentives/schema/raw/execute.json rename to smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/execute.json diff --git a/smart-contracts/contracts/merkle-incentives/schema/raw/instantiate.json b/smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/instantiate.json similarity index 100% rename from smart-contracts/contracts/merkle-incentives/schema/raw/instantiate.json rename to smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/instantiate.json diff --git a/smart-contracts/contracts/merkle-incentives/schema/raw/query.json b/smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/query.json similarity index 100% rename from smart-contracts/contracts/merkle-incentives/schema/raw/query.json rename to smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/query.json diff --git a/smart-contracts/contracts/merkle-incentives/schema/raw/response_to_admin_query.json b/smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/response_to_admin_query.json similarity index 100% rename from smart-contracts/contracts/merkle-incentives/schema/raw/response_to_admin_query.json rename to smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/response_to_admin_query.json diff --git a/smart-contracts/contracts/merkle-incentives/schema/raw/response_to_incentives_query.json b/smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/response_to_incentives_query.json similarity index 100% rename from smart-contracts/contracts/merkle-incentives/schema/raw/response_to_incentives_query.json rename to smart-contracts/osmosis/contracts/merkle-incentives/schema/raw/response_to_incentives_query.json diff --git a/smart-contracts/contracts/merkle-incentives/src/admin/execute.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/admin/execute.rs similarity index 97% rename from smart-contracts/contracts/merkle-incentives/src/admin/execute.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/admin/execute.rs index dd309d7c8..df9281dfd 100644 --- a/smart-contracts/contracts/merkle-incentives/src/admin/execute.rs +++ b/smart-contracts/osmosis/contracts/merkle-incentives/src/admin/execute.rs @@ -89,7 +89,7 @@ mod tests { fn test_update_merkle_root_valid() { let mut deps = mock_dependencies(); let env = mock_env(); - let info = mock_info("admin", &vec![]); + let info = mock_info("admin", &[]); // Set incentives admin INCENTIVES_ADMIN @@ -112,7 +112,7 @@ mod tests { fn test_update_merkle_root_invalid() { let mut deps = mock_dependencies(); let env = mock_env(); - let info = mock_info("admin", &vec![]); + let info = mock_info("admin", &[]); // Set incentives admin INCENTIVES_ADMIN diff --git a/smart-contracts/contracts/merkle-incentives/src/admin/helpers.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/admin/helpers.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/admin/helpers.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/admin/helpers.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/admin/mod.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/admin/mod.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/admin/mod.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/admin/mod.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/admin/query.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/admin/query.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/admin/query.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/admin/query.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/bin/schema.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/bin/schema.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/bin/schema.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/bin/schema.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/contract.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/contract.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/contract.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/contract.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/error.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/error.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/error.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/error.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/helpers.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/helpers.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/helpers.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/helpers.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/incentives/execute.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/execute.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/incentives/execute.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/execute.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/incentives/helpers.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/helpers.rs similarity index 97% rename from smart-contracts/contracts/merkle-incentives/src/incentives/helpers.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/helpers.rs index dbd73c555..fa20e9de0 100644 --- a/smart-contracts/contracts/merkle-incentives/src/incentives/helpers.rs +++ b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/helpers.rs @@ -116,7 +116,7 @@ mod tests { for proof in &proof { if proof.len() == 32 { let mut arr = [0u8; 32]; - arr.copy_from_slice(&proof); + arr.copy_from_slice(proof); proof_hashes.push(arr); } else { eprintln!("Error: Hash is not 32 bytes."); @@ -277,7 +277,7 @@ mod tests { #[test] fn test_verify_success() { verify_proof( - &MERKLE_ROOT_STRING.to_string(), + MERKLE_ROOT_STRING, get_proof_hashes(), &[0usize], 10usize, @@ -289,7 +289,7 @@ mod tests { #[test] fn test_verify_bad_root() { let result = verify_proof( - &MERKLE_ROOT_INVALID_STRING.to_string(), + MERKLE_ROOT_INVALID_STRING, get_proof_hashes(), &[0usize], 10usize, @@ -302,7 +302,7 @@ mod tests { #[test] fn test_verify_bad_claim() { let result = verify_proof( - &MERKLE_ROOT_STRING.to_string(), + MERKLE_ROOT_STRING, get_proof_hashes(), &[0usize], 10usize, diff --git a/smart-contracts/contracts/merkle-incentives/src/incentives/mod.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/mod.rs similarity index 98% rename from smart-contracts/contracts/merkle-incentives/src/incentives/mod.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/mod.rs index 52d743d2d..704115547 100644 --- a/smart-contracts/contracts/merkle-incentives/src/incentives/mod.rs +++ b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/mod.rs @@ -173,8 +173,8 @@ mod tests { amount: Uint128::from(100u128), }]); - assert_eq!(false, coin_vec2.le(&coin_vec)); - assert_eq!(false, coin_vec2.ge(&coin_vec)); + assert!(!coin_vec2.le(&coin_vec)); + assert!(!coin_vec2.ge(&coin_vec)); let coin_vec = CoinVec(vec![Coin { denom: "uusd".to_string(), @@ -211,8 +211,8 @@ mod tests { }]); // coin vec should not be gt or lt coin vec 2 as this case should not pass through - assert_eq!(false, coin_vec.lt(&coin_vec2)); - assert_eq!(false, coin_vec.gt(&coin_vec2)); + assert!(!coin_vec.lt(&coin_vec2)); + assert!(!coin_vec.gt(&coin_vec2)); } #[test] diff --git a/smart-contracts/contracts/merkle-incentives/src/incentives/query.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/query.rs similarity index 98% rename from smart-contracts/contracts/merkle-incentives/src/incentives/query.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/query.rs index 9eb48e091..e07cbbe14 100644 --- a/smart-contracts/contracts/merkle-incentives/src/incentives/query.rs +++ b/smart-contracts/osmosis/contracts/merkle-incentives/src/incentives/query.rs @@ -107,7 +107,7 @@ mod tests { fn test_query_merkle_root() { let mut deps = mock_dependencies(); let env = mock_env(); - let info = mock_info("admin", &vec![]); + let info = mock_info("admin", &[]); // Set incentives admin INCENTIVES_ADMIN diff --git a/smart-contracts/contracts/merkle-incentives/src/lib.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/lib.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/lib.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/lib.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/msg.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/msg.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/msg.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/msg.rs diff --git a/smart-contracts/contracts/merkle-incentives/src/state.rs b/smart-contracts/osmosis/contracts/merkle-incentives/src/state.rs similarity index 100% rename from smart-contracts/contracts/merkle-incentives/src/state.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/src/state.rs diff --git a/smart-contracts/contracts/merkle-incentives/tests/merkle.rs b/smart-contracts/osmosis/contracts/merkle-incentives/tests/merkle.rs similarity index 92% rename from smart-contracts/contracts/merkle-incentives/tests/merkle.rs rename to smart-contracts/osmosis/contracts/merkle-incentives/tests/merkle.rs index 2df4b5da5..4504f868e 100644 --- a/smart-contracts/contracts/merkle-incentives/tests/merkle.rs +++ b/smart-contracts/osmosis/contracts/merkle-incentives/tests/merkle.rs @@ -77,28 +77,16 @@ fn merkle_complete_cycle_works() { .unwrap(); let leaves_str = vec![ - format!("{}900000000ugauge", accounts[0].address().to_string()).to_string(), - format!("{}9000000000ugauge", accounts[0].address().to_string()).to_string(), - format!("{}90000000000ugauge", accounts[0].address().to_string()).to_string(), - format!("{}900000000000ugauge", accounts[0].address().to_string()).to_string(), - format!("{}9000000000000ugauge", accounts[0].address().to_string()).to_string(), - format!("{}90000000000000ugauge", accounts[0].address().to_string()).to_string(), - format!("{}900000000000000ugauge", accounts[0].address().to_string()).to_string(), - format!( - "{}9000000000900000ugauge", - accounts[0].address().to_string() - ) - .to_string(), - format!( - "{}90000000009000000ugauge", - accounts[0].address().to_string() - ) - .to_string(), - format!( - "{}900000000090000000ugauge", - accounts[0].address().to_string() - ) - .to_string(), + format!("{}900000000ugauge", accounts[0].address()).to_string(), + format!("{}9000000000ugauge", accounts[0].address()).to_string(), + format!("{}90000000000ugauge", accounts[0].address()).to_string(), + format!("{}900000000000ugauge", accounts[0].address()).to_string(), + format!("{}9000000000000ugauge", accounts[0].address()).to_string(), + format!("{}90000000000000ugauge", accounts[0].address()).to_string(), + format!("{}900000000000000ugauge", accounts[0].address()).to_string(), + format!("{}9000000000900000ugauge", accounts[0].address()).to_string(), + format!("{}90000000009000000ugauge", accounts[0].address()).to_string(), + format!("{}900000000090000000ugauge", accounts[0].address()).to_string(), ]; let leaves = leaves_str @@ -187,7 +175,7 @@ fn merkle_complete_cycle_works() { for proof in &claim_account.proof { if proof.len() == 32 { let mut arr = [0u8; 32]; - arr.copy_from_slice(&proof); + arr.copy_from_slice(proof); proof_hashes.push(arr); } else { eprintln!("Error: Hash is not 32 bytes."); @@ -205,7 +193,7 @@ fn merkle_complete_cycle_works() { total_leaves_count: 10usize, }), &[], - &accounts.get(index).unwrap(), + accounts.get(index).unwrap(), ) .unwrap(); @@ -220,7 +208,7 @@ fn merkle_complete_cycle_works() { claim_account .coins .coins() - .get(0) + .first() .unwrap() .amount .to_string() diff --git a/smart-contracts/contracts/multihop-router/.cargo/config b/smart-contracts/osmosis/contracts/range-middleware/.cargo/config similarity index 100% rename from smart-contracts/contracts/multihop-router/.cargo/config rename to smart-contracts/osmosis/contracts/range-middleware/.cargo/config diff --git a/smart-contracts/contracts/range-middleware/Cargo.toml b/smart-contracts/osmosis/contracts/range-middleware/Cargo.toml similarity index 100% rename from smart-contracts/contracts/range-middleware/Cargo.toml rename to smart-contracts/osmosis/contracts/range-middleware/Cargo.toml diff --git a/smart-contracts/contracts/range-middleware/README.md b/smart-contracts/osmosis/contracts/range-middleware/README.md similarity index 100% rename from smart-contracts/contracts/range-middleware/README.md rename to smart-contracts/osmosis/contracts/range-middleware/README.md diff --git a/smart-contracts/contracts/range-middleware/schema/range-middleware.json b/smart-contracts/osmosis/contracts/range-middleware/schema/range-middleware.json similarity index 100% rename from smart-contracts/contracts/range-middleware/schema/range-middleware.json rename to smart-contracts/osmosis/contracts/range-middleware/schema/range-middleware.json diff --git a/smart-contracts/contracts/range-middleware/schema/raw/execute.json b/smart-contracts/osmosis/contracts/range-middleware/schema/raw/execute.json similarity index 100% rename from smart-contracts/contracts/range-middleware/schema/raw/execute.json rename to smart-contracts/osmosis/contracts/range-middleware/schema/raw/execute.json diff --git a/smart-contracts/contracts/range-middleware/schema/raw/instantiate.json b/smart-contracts/osmosis/contracts/range-middleware/schema/raw/instantiate.json similarity index 100% rename from smart-contracts/contracts/range-middleware/schema/raw/instantiate.json rename to smart-contracts/osmosis/contracts/range-middleware/schema/raw/instantiate.json diff --git a/smart-contracts/contracts/range-middleware/schema/raw/query.json b/smart-contracts/osmosis/contracts/range-middleware/schema/raw/query.json similarity index 100% rename from smart-contracts/contracts/range-middleware/schema/raw/query.json rename to smart-contracts/osmosis/contracts/range-middleware/schema/raw/query.json diff --git a/smart-contracts/contracts/range-middleware/schema/raw/response_to_admin_query.json b/smart-contracts/osmosis/contracts/range-middleware/schema/raw/response_to_admin_query.json similarity index 100% rename from smart-contracts/contracts/range-middleware/schema/raw/response_to_admin_query.json rename to smart-contracts/osmosis/contracts/range-middleware/schema/raw/response_to_admin_query.json diff --git a/smart-contracts/contracts/range-middleware/schema/raw/response_to_range_query.json b/smart-contracts/osmosis/contracts/range-middleware/schema/raw/response_to_range_query.json similarity index 100% rename from smart-contracts/contracts/range-middleware/schema/raw/response_to_range_query.json rename to smart-contracts/osmosis/contracts/range-middleware/schema/raw/response_to_range_query.json diff --git a/smart-contracts/contracts/range-middleware/src/admin/execute.rs b/smart-contracts/osmosis/contracts/range-middleware/src/admin/execute.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/admin/execute.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/admin/execute.rs diff --git a/smart-contracts/contracts/range-middleware/src/admin/helpers.rs b/smart-contracts/osmosis/contracts/range-middleware/src/admin/helpers.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/admin/helpers.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/admin/helpers.rs diff --git a/smart-contracts/contracts/range-middleware/src/admin/mod.rs b/smart-contracts/osmosis/contracts/range-middleware/src/admin/mod.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/admin/mod.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/admin/mod.rs diff --git a/smart-contracts/contracts/range-middleware/src/admin/query.rs b/smart-contracts/osmosis/contracts/range-middleware/src/admin/query.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/admin/query.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/admin/query.rs diff --git a/smart-contracts/contracts/range-middleware/src/bin/schema.rs b/smart-contracts/osmosis/contracts/range-middleware/src/bin/schema.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/bin/schema.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/bin/schema.rs diff --git a/smart-contracts/contracts/range-middleware/src/contract.rs b/smart-contracts/osmosis/contracts/range-middleware/src/contract.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/contract.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/contract.rs diff --git a/smart-contracts/contracts/range-middleware/src/error.rs b/smart-contracts/osmosis/contracts/range-middleware/src/error.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/error.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/error.rs diff --git a/smart-contracts/contracts/range-middleware/src/helpers.rs b/smart-contracts/osmosis/contracts/range-middleware/src/helpers.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/helpers.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/helpers.rs diff --git a/smart-contracts/contracts/range-middleware/src/lib.rs b/smart-contracts/osmosis/contracts/range-middleware/src/lib.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/lib.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/lib.rs diff --git a/smart-contracts/contracts/range-middleware/src/msg.rs b/smart-contracts/osmosis/contracts/range-middleware/src/msg.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/msg.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/msg.rs diff --git a/smart-contracts/contracts/range-middleware/src/range/execute.rs b/smart-contracts/osmosis/contracts/range-middleware/src/range/execute.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/range/execute.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/range/execute.rs diff --git a/smart-contracts/contracts/range-middleware/src/range/helpers.rs b/smart-contracts/osmosis/contracts/range-middleware/src/range/helpers.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/range/helpers.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/range/helpers.rs diff --git a/smart-contracts/contracts/range-middleware/src/range/mod.rs b/smart-contracts/osmosis/contracts/range-middleware/src/range/mod.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/range/mod.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/range/mod.rs diff --git a/smart-contracts/contracts/range-middleware/src/range/query.rs b/smart-contracts/osmosis/contracts/range-middleware/src/range/query.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/range/query.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/range/query.rs diff --git a/smart-contracts/contracts/range-middleware/src/state.rs b/smart-contracts/osmosis/contracts/range-middleware/src/state.rs similarity index 100% rename from smart-contracts/contracts/range-middleware/src/state.rs rename to smart-contracts/osmosis/contracts/range-middleware/src/state.rs diff --git a/smart-contracts/contracts/airdrop/.cargo/config b/smart-contracts/osmosis/contracts/token-burner/.cargo/config similarity index 100% rename from smart-contracts/contracts/airdrop/.cargo/config rename to smart-contracts/osmosis/contracts/token-burner/.cargo/config diff --git a/smart-contracts/contracts/token-burner/Cargo.toml b/smart-contracts/osmosis/contracts/token-burner/Cargo.toml similarity index 100% rename from smart-contracts/contracts/token-burner/Cargo.toml rename to smart-contracts/osmosis/contracts/token-burner/Cargo.toml diff --git a/smart-contracts/contracts/token-burner/README.md b/smart-contracts/osmosis/contracts/token-burner/README.md similarity index 100% rename from smart-contracts/contracts/token-burner/README.md rename to smart-contracts/osmosis/contracts/token-burner/README.md diff --git a/smart-contracts/contracts/token-burner/examples/schema.rs b/smart-contracts/osmosis/contracts/token-burner/examples/schema.rs similarity index 100% rename from smart-contracts/contracts/token-burner/examples/schema.rs rename to smart-contracts/osmosis/contracts/token-burner/examples/schema.rs diff --git a/smart-contracts/contracts/token-burner/src/contract.rs b/smart-contracts/osmosis/contracts/token-burner/src/contract.rs similarity index 100% rename from smart-contracts/contracts/token-burner/src/contract.rs rename to smart-contracts/osmosis/contracts/token-burner/src/contract.rs diff --git a/smart-contracts/contracts/token-burner/src/error.rs b/smart-contracts/osmosis/contracts/token-burner/src/error.rs similarity index 100% rename from smart-contracts/contracts/token-burner/src/error.rs rename to smart-contracts/osmosis/contracts/token-burner/src/error.rs diff --git a/smart-contracts/contracts/token-burner/src/lib.rs b/smart-contracts/osmosis/contracts/token-burner/src/lib.rs similarity index 100% rename from smart-contracts/contracts/token-burner/src/lib.rs rename to smart-contracts/osmosis/contracts/token-burner/src/lib.rs diff --git a/smart-contracts/contracts/token-burner/src/msg.rs b/smart-contracts/osmosis/contracts/token-burner/src/msg.rs similarity index 100% rename from smart-contracts/contracts/token-burner/src/msg.rs rename to smart-contracts/osmosis/contracts/token-burner/src/msg.rs diff --git a/smart-contracts/contracts/token-burner/src/query.rs b/smart-contracts/osmosis/contracts/token-burner/src/query.rs similarity index 100% rename from smart-contracts/contracts/token-burner/src/query.rs rename to smart-contracts/osmosis/contracts/token-burner/src/query.rs diff --git a/smart-contracts/contracts/token-burner/src/state.rs b/smart-contracts/osmosis/contracts/token-burner/src/state.rs similarity index 100% rename from smart-contracts/contracts/token-burner/src/state.rs rename to smart-contracts/osmosis/contracts/token-burner/src/state.rs diff --git a/smart-contracts/justfile b/smart-contracts/osmosis/justfile similarity index 100% rename from smart-contracts/justfile rename to smart-contracts/osmosis/justfile diff --git a/smart-contracts/packages/quasar-types/Cargo.toml b/smart-contracts/osmosis/packages/quasar-types/Cargo.toml similarity index 100% rename from smart-contracts/packages/quasar-types/Cargo.toml rename to smart-contracts/osmosis/packages/quasar-types/Cargo.toml diff --git a/smart-contracts/packages/quasar-types/src/abstract_sdk.rs b/smart-contracts/osmosis/packages/quasar-types/src/abstract_sdk.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/abstract_sdk.rs rename to smart-contracts/osmosis/packages/quasar-types/src/abstract_sdk.rs diff --git a/smart-contracts/packages/quasar-types/src/callback.rs b/smart-contracts/osmosis/packages/quasar-types/src/callback.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/callback.rs rename to smart-contracts/osmosis/packages/quasar-types/src/callback.rs diff --git a/smart-contracts/packages/quasar-types/src/curve.rs b/smart-contracts/osmosis/packages/quasar-types/src/curve.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/curve.rs rename to smart-contracts/osmosis/packages/quasar-types/src/curve.rs diff --git a/smart-contracts/packages/quasar-types/src/error.rs b/smart-contracts/osmosis/packages/quasar-types/src/error.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/error.rs rename to smart-contracts/osmosis/packages/quasar-types/src/error.rs diff --git a/smart-contracts/packages/quasar-types/src/ibc.rs b/smart-contracts/osmosis/packages/quasar-types/src/ibc.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ibc.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ibc.rs diff --git a/smart-contracts/packages/quasar-types/src/ica/handshake.rs b/smart-contracts/osmosis/packages/quasar-types/src/ica/handshake.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ica/handshake.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ica/handshake.rs diff --git a/smart-contracts/packages/quasar-types/src/ica/mod.rs b/smart-contracts/osmosis/packages/quasar-types/src/ica/mod.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ica/mod.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ica/mod.rs diff --git a/smart-contracts/packages/quasar-types/src/ica/pack.rs b/smart-contracts/osmosis/packages/quasar-types/src/ica/pack.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ica/pack.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ica/pack.rs diff --git a/smart-contracts/packages/quasar-types/src/ica/packet.rs b/smart-contracts/osmosis/packages/quasar-types/src/ica/packet.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ica/packet.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ica/packet.rs diff --git a/smart-contracts/packages/quasar-types/src/ica/traits.rs b/smart-contracts/osmosis/packages/quasar-types/src/ica/traits.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ica/traits.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ica/traits.rs diff --git a/smart-contracts/packages/quasar-types/src/ica/unpack.rs b/smart-contracts/osmosis/packages/quasar-types/src/ica/unpack.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/ica/unpack.rs rename to smart-contracts/osmosis/packages/quasar-types/src/ica/unpack.rs diff --git a/smart-contracts/packages/quasar-types/src/icq.rs b/smart-contracts/osmosis/packages/quasar-types/src/icq.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/icq.rs rename to smart-contracts/osmosis/packages/quasar-types/src/icq.rs diff --git a/smart-contracts/packages/quasar-types/src/lib.rs b/smart-contracts/osmosis/packages/quasar-types/src/lib.rs similarity index 93% rename from smart-contracts/packages/quasar-types/src/lib.rs rename to smart-contracts/osmosis/packages/quasar-types/src/lib.rs index ac5fb0b86..6e4123a11 100644 --- a/smart-contracts/packages/quasar-types/src/lib.rs +++ b/smart-contracts/osmosis/packages/quasar-types/src/lib.rs @@ -5,6 +5,7 @@ pub mod error; pub mod ibc; pub mod ica; pub mod icq; +pub mod pool_pair; pub mod query; pub mod queue; pub mod stride; diff --git a/smart-contracts/osmosis/packages/quasar-types/src/pool_pair.rs b/smart-contracts/osmosis/packages/quasar-types/src/pool_pair.rs new file mode 100644 index 000000000..b6af3a8c2 --- /dev/null +++ b/smart-contracts/osmosis/packages/quasar-types/src/pool_pair.rs @@ -0,0 +1,66 @@ +use cosmwasm_std::Coin; + +#[derive(Debug)] +pub struct PoolPair { + pub base: S, + pub quote: T, +} + +impl PoolPair { + pub fn new(base: S, quote: T) -> Self { + Self { base, quote } + } +} + +pub trait Contains { + fn contains(&self, value: T) -> bool; +} + +impl Contains<&str> for PoolPair { + fn contains(&self, value: &str) -> bool { + value == self.base || value == self.quote + } +} + +impl Contains<&str> for PoolPair { + fn contains(&self, value: &str) -> bool { + value == self.base.denom || value == self.quote.denom + } +} + +#[allow(clippy::unnecessary_to_owned)] +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::coin; + + #[test] + fn test_string_pair() { + let base = "base".to_string(); + let quote = "quote".to_string(); + let pair = PoolPair::new(base.clone(), quote.clone()); + assert_eq!(base, pair.base); + assert_eq!(quote, pair.quote); + + assert!(pair.contains(&base)); + assert!(pair.contains("e)); + assert!(pair.contains(base.as_str())); + assert!(!pair.contains(&"other".to_string())); + assert!(!pair.contains("other")); + } + + #[test] + fn test_coin_pair() { + let base = coin(123u128, "base"); + let quote = coin(456u128, "quote"); + let pair = PoolPair::new(base.clone(), quote.clone()); + assert_eq!(base, pair.base); + assert_eq!(quote, pair.quote); + + assert!(pair.contains(&base.denom)); + assert!(pair.contains("e.denom)); + assert!(pair.contains(base.denom.as_str())); + assert!(!pair.contains(&"other".to_string())); + assert!(!pair.contains("other")); + } +} diff --git a/smart-contracts/packages/quasar-types/src/query.rs b/smart-contracts/osmosis/packages/quasar-types/src/query.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/query.rs rename to smart-contracts/osmosis/packages/quasar-types/src/query.rs diff --git a/smart-contracts/packages/quasar-types/src/queue.rs b/smart-contracts/osmosis/packages/quasar-types/src/queue.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/queue.rs rename to smart-contracts/osmosis/packages/quasar-types/src/queue.rs diff --git a/smart-contracts/packages/quasar-types/src/stride.rs b/smart-contracts/osmosis/packages/quasar-types/src/stride.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/stride.rs rename to smart-contracts/osmosis/packages/quasar-types/src/stride.rs diff --git a/smart-contracts/packages/quasar-types/src/traits.rs b/smart-contracts/osmosis/packages/quasar-types/src/traits.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/traits.rs rename to smart-contracts/osmosis/packages/quasar-types/src/traits.rs diff --git a/smart-contracts/packages/quasar-types/src/types.rs b/smart-contracts/osmosis/packages/quasar-types/src/types.rs similarity index 100% rename from smart-contracts/packages/quasar-types/src/types.rs rename to smart-contracts/osmosis/packages/quasar-types/src/types.rs diff --git a/smart-contracts/rust-toolchain.toml b/smart-contracts/osmosis/rust-toolchain.toml similarity index 100% rename from smart-contracts/rust-toolchain.toml rename to smart-contracts/osmosis/rust-toolchain.toml diff --git a/smart-contracts/packages/intergamm-bindings/.cargo/config b/smart-contracts/packages/intergamm-bindings/.cargo/config deleted file mode 100644 index 7c61b07e3..000000000 --- a/smart-contracts/packages/intergamm-bindings/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" \ No newline at end of file diff --git a/smart-contracts/packages/intergamm-bindings/Cargo.toml b/smart-contracts/packages/intergamm-bindings/Cargo.toml deleted file mode 100644 index 17eb4e217..000000000 --- a/smart-contracts/packages/intergamm-bindings/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "intergamm-bindings" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-std = { workspace = true } -sw-storage-plus = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -thiserror = { workspace = true } \ No newline at end of file diff --git a/smart-contracts/packages/intergamm-bindings/example/schema.rs b/smart-contracts/packages/intergamm-bindings/example/schema.rs deleted file mode 100644 index e7e293535..000000000 --- a/smart-contracts/packages/intergamm-bindings/example/schema.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use osmo_bindings::{ - FullDenomResponse, OsmosisMsg, OsmosisQuery, PoolStateResponse, SpotPriceResponse, SwapResponse, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(OsmosisMsg), &out_dir); - export_schema(&schema_for!(OsmosisQuery), &out_dir); -} \ No newline at end of file diff --git a/smart-contracts/packages/intergamm-bindings/src/error.rs b/smart-contracts/packages/intergamm-bindings/src/error.rs deleted file mode 100644 index b24134f49..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/error.rs +++ /dev/null @@ -1,13 +0,0 @@ -use cosmwasm_std::StdError; -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum ContractError { - #[error("{0}")] - Std(#[from] StdError), - - #[error("Unauthorized")] - Unauthorized { sender: String, expected: String }, - // Add any other custom errors you like here. - // Look at https://docs.rs/thiserror/1.0.21/thiserror/ for details. -} diff --git a/smart-contracts/packages/intergamm-bindings/src/helper.rs b/smart-contracts/packages/intergamm-bindings/src/helper.rs deleted file mode 100644 index 0925e98b1..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/helper.rs +++ /dev/null @@ -1,167 +0,0 @@ -use cosmwasm_std::{ - Addr, Attribute, Deps, DepsMut, Env, Order, Reply, Response, StdError, StdResult, Storage, - SubMsg, SubMsgResponse, -}; - -use crate::{ - error::ContractError, - msg::{AckResponse, AckValue, IntergammMsg}, - state::{ACKS, CALLBACKADDRESS, PENDINGACKS, REPLIES}, -}; - -pub fn set_callback_addr(deps: DepsMut, callback_addr: &str) -> Result<(), ContractError> { - Ok(CALLBACKADDRESS.save(deps.storage, &deps.api.addr_validate(callback_addr)?)?) -} - -pub fn check_callback_addr(deps: Deps, sender: Addr) -> Result<(), ContractError> { - let callback = CALLBACKADDRESS.load(deps.storage)?; - if sender != callback { - return Err(ContractError::Unauthorized { - sender: sender.to_string(), - expected: callback.to_string(), - }); - } - Ok(()) -} - -pub fn create_intergamm_msg( - storage: &mut dyn Storage, - msg: IntergammMsg, -) -> Result, StdError> { - let last = REPLIES.range(storage, None, None, Order::Descending).next(); - let mut id: u64 = 0; - if let Some(val) = last { - id = val?.0; - } - // register the message in the replies for handling - REPLIES.save(storage, id, &msg)?; - Ok(Response::new().add_submessage(SubMsg::reply_always(msg, id))) -} - -pub fn ack( - deps: DepsMut, - sequence: u64, - error: &Option, - response: &Option, -) -> Result<(), ContractError> { - ACKS.save( - deps.storage, - sequence, - &AckValue { - error: error.clone(), - response: response.clone(), - }, - )?; - PENDINGACKS.remove(deps.storage, sequence); - Ok(()) -} - -// handle_reply provides a basic handle function for responses to intergamm messages -// the acks map is the map where -pub fn handle_reply(store: &mut dyn Storage, env: Env, msg: Reply) -> StdResult { - let res = msg.result.into_result(); - if let Ok(ok) = res { - // do something with the ok msg - let original = REPLIES.load(store, msg.id)?; - match original { - IntergammMsg::SendToken { - destination_local_zone_id, - receiver: _, - coin: _, - } => Ok(Response::new() - .add_attribute("send_token", "sender") - .add_attribute("destination", destination_local_zone_id)), - IntergammMsg::TestScenario { scenario } => { - Ok(Response::new().add_attribute("testing scenario", scenario)) - } - IntergammMsg::RegisterIcaOnZone { zone_id } => Ok(Response::new() - .add_attribute("register_interchain_account", env.contract.address) - .add_attribute("zone_id", zone_id)), - IntergammMsg::JoinSwapExternAmountIn { - ref connection_id, - timeout_timestamp: _, - pool_id: _, - share_out_min_amount: _, - token_in: _, - } => store_pending_ack(ok, connection_id, store, &original), - IntergammMsg::JoinPool { - ref connection_id, - timeout_timestamp: _, - pool_id: _, - share_out_amount: _, - token_in_maxs: _, - } => store_pending_ack(ok, connection_id, store, &original), - IntergammMsg::LockTokens { - ref connection_id, - timeout_timestamp: _, - duration: _, - coins: _, - } => store_pending_ack(ok, connection_id, store, &original), - IntergammMsg::ExitSwapExternAmountOut { - ref connection_id, - timeout_timestamp: _, - pool_id: _, - share_in_amount: _, - token_out_mins: _, - } => store_pending_ack(ok, connection_id, store, &original), - IntergammMsg::BeginUnlocking { - ref connection_id, - timeout_timestamp: _, - id: _, - coins: _, - } => store_pending_ack(ok, connection_id, store, &original), - IntergammMsg::ExitPool { - ref connection_id, - timeout_timestamp: _, - pool_id: _, - share_in_amount: _, - token_out_mins: _, - } => store_pending_ack(ok, connection_id, store, &original), - } - } else { - Err(StdError::GenericErr { - msg: format!("reply status: {}", res.unwrap_err()), - }) - } -} - -fn store_pending_ack( - msg: SubMsgResponse, - connection_id: &str, - store: &mut dyn Storage, - original: &IntergammMsg, -) -> Result { - // to get the sequence number, we look for the event type send_packet under the key packet_sequence and register the sequence number - let e = msg - .events - .iter() - .find(|e| e.ty == "send_packet") - .ok_or_else(|| StdError::GenericErr { - msg: "packet event not found".into(), - })?; - - // we do some sanity checks here to see if the attributes of the packet correspond with the intergamm msg - if connection_id != find_attr(&e.attributes, "packet_connection")?.value { - return Err(StdError::GenericErr { - msg: "connection_id is not equal to packet connection".into(), - }); - } - let seq = find_attr(&e.attributes, "packet_sequence")?; - - let s = seq.value.parse::().map_err(|e| StdError::ParseErr { - target_type: "u64".into(), - msg: e.to_string(), - })?; - - PENDINGACKS.save(store, s, original)?; - Ok(Response::new().add_attribute("added pending ack", s.to_string())) -} - -fn find_attr<'a>(attributes: &'a [Attribute], key: &str) -> Result<&'a Attribute, StdError> { - attributes - .iter() - .find(|attr| attr.key == key) - .ok_or_else(|| StdError::GenericErr { - msg: format!("packet does not containt attribute {key}"), - }) -} diff --git a/smart-contracts/packages/intergamm-bindings/src/lib.rs b/smart-contracts/packages/intergamm-bindings/src/lib.rs deleted file mode 100644 index b73d70eec..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod error; -pub mod helper; -pub mod msg; -mod querier; -mod query; -pub mod state; -pub mod types; diff --git a/smart-contracts/packages/intergamm-bindings/src/msg.rs b/smart-contracts/packages/intergamm-bindings/src/msg.rs deleted file mode 100644 index 1304d72aa..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/msg.rs +++ /dev/null @@ -1,106 +0,0 @@ -use cosmwasm_std::{Coin, CosmosMsg, CustomMsg, Uint256, Uint64}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -/// A number of Custom messages that can call into the intergamm bindings -pub enum IntergammMsg { - SendToken { - destination_local_zone_id: String, - receiver: String, - coin: Coin, - }, - TestScenario { - scenario: String, - }, - RegisterIcaOnZone { - zone_id: String, - }, - JoinPool { - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_out_amount: i64, - token_in_maxs: Vec, - }, - ExitPool { - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_in_amount: i64, - token_out_mins: Vec, - }, - LockTokens { - connection_id: String, - timeout_timestamp: u64, - duration: u64, - coins: Vec, - }, - JoinSwapExternAmountIn { - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_out_min_amount: i64, - token_in: Coin, - }, - ExitSwapExternAmountOut { - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_in_amount: i64, - token_out_mins: Coin, - }, - BeginUnlocking { - connection_id: String, - timeout_timestamp: u64, - id: u64, - coins: Vec, - }, -} - -impl IntergammMsg {} - -impl From for CosmosMsg { - fn from(msg: IntergammMsg) -> CosmosMsg { - CosmosMsg::Custom(msg) - } -} - -impl CustomMsg for IntergammMsg {} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub struct AckValue { - pub error: Option, - pub response: Option, -} - -// AckResponse is the response message received by an intergamm ack message, see quasarnode/x/intergamm/types for the corresponding types -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum AckResponse { - JoinSwapExternAmountIn { - #[serde(rename = "shareOutAmount")] - share_out_amount: Uint256, - }, - ExitSwapExternAmountOut { - #[serde(rename = "shareInAmount")] - share_in_amount: Uint256, - }, - JoinSwapShareAmountOut { - #[serde(rename = "tokenInAmount")] - token_in_amount: Uint256, - }, - ExitSwapShareAmountIn { - #[serde(rename = "tokenOutAmount")] - token_out_amount: Uint256, - }, - LockTokens { - #[serde(rename = "ID")] - id: Uint64, - }, - BeginUnlocking { - #[serde(rename = "Success")] - succes: bool, - }, -} diff --git a/smart-contracts/packages/intergamm-bindings/src/querier.rs b/smart-contracts/packages/intergamm-bindings/src/querier.rs deleted file mode 100644 index 8b1378917..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/querier.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/smart-contracts/packages/intergamm-bindings/src/query.rs b/smart-contracts/packages/intergamm-bindings/src/query.rs deleted file mode 100644 index 8b1378917..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/query.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/smart-contracts/packages/intergamm-bindings/src/state.rs b/smart-contracts/packages/intergamm-bindings/src/state.rs deleted file mode 100644 index 99bd19ab3..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/state.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::msg::{AckValue, IntergammMsg}; -use cosmwasm_std::Addr; -use cw_storage_plus::{Item, Map}; - -pub const REPLIES: Map = Map::new("intergamm-replies"); - -pub const PENDINGACKS: Map = Map::new("pending_acks"); - -pub const ACKS: Map = Map::new("acks"); - -pub const CALLBACKADDRESS: Item = Item::new("callback_address"); diff --git a/smart-contracts/packages/intergamm-bindings/src/types.rs b/smart-contracts/packages/intergamm-bindings/src/types.rs deleted file mode 100644 index 5a77d3844..000000000 --- a/smart-contracts/packages/intergamm-bindings/src/types.rs +++ /dev/null @@ -1,10 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct IntergammAck { - sequence: u64, - error: Option, - response: Option, -} diff --git a/smart-contracts/packages/osmosis-helpers/Cargo.toml b/smart-contracts/packages/osmosis-helpers/Cargo.toml deleted file mode 100644 index dc758dbe5..000000000 --- a/smart-contracts/packages/osmosis-helpers/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "osmosis-helpers" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -# Quasar packages -osmo-bindings = "0.6.0" \ No newline at end of file diff --git a/smart-contracts/packages/osmosis-helpers/src/lib.rs b/smart-contracts/packages/osmosis-helpers/src/lib.rs deleted file mode 100644 index 2bbc1254f..000000000 --- a/smart-contracts/packages/osmosis-helpers/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -mod osmosis; diff --git a/smart-contracts/packages/osmosis-helpers/src/osmosis.rs b/smart-contracts/packages/osmosis-helpers/src/osmosis.rs deleted file mode 100644 index 75e780691..000000000 --- a/smart-contracts/packages/osmosis-helpers/src/osmosis.rs +++ /dev/null @@ -1,3 +0,0 @@ -use osmo_bindings::{OsmosisMsg, OsmosisQuery}; - -pub fn join_pool(pool_id: u64) {} diff --git a/smart-contracts/packages/quasar-bindings/.cargo/config b/smart-contracts/packages/quasar-bindings/.cargo/config deleted file mode 100644 index 7c61b07e3..000000000 --- a/smart-contracts/packages/quasar-bindings/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" -schema = "run --example schema" \ No newline at end of file diff --git a/smart-contracts/packages/quasar-bindings/Cargo.toml b/smart-contracts/packages/quasar-bindings/Cargo.toml deleted file mode 100644 index 412b0b73d..000000000 --- a/smart-contracts/packages/quasar-bindings/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "quasar-bindings" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-std = { workspace = true } -sw-storage-plus = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -serde_json = { workspace = true } -thiserror = { workspace = true } diff --git a/smart-contracts/packages/quasar-bindings/example/schema.rs b/smart-contracts/packages/quasar-bindings/example/schema.rs deleted file mode 100644 index e7e293535..000000000 --- a/smart-contracts/packages/quasar-bindings/example/schema.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, remove_schemas, schema_for}; - -use osmo_bindings::{ - FullDenomResponse, OsmosisMsg, OsmosisQuery, PoolStateResponse, SpotPriceResponse, SwapResponse, -}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(OsmosisMsg), &out_dir); - export_schema(&schema_for!(OsmosisQuery), &out_dir); -} \ No newline at end of file diff --git a/smart-contracts/packages/quasar-bindings/src/lib.rs b/smart-contracts/packages/quasar-bindings/src/lib.rs deleted file mode 100644 index 7cdea3198..000000000 --- a/smart-contracts/packages/quasar-bindings/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub mod msg; -pub mod querier; -pub mod query; -pub mod types; - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert_eq!(result, 4); - } -} diff --git a/smart-contracts/packages/quasar-bindings/src/msg.rs b/smart-contracts/packages/quasar-bindings/src/msg.rs deleted file mode 100644 index 989ea59e4..000000000 --- a/smart-contracts/packages/quasar-bindings/src/msg.rs +++ /dev/null @@ -1,76 +0,0 @@ -use cosmwasm_std::{Coin, CosmosMsg, CustomMsg}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -/// A number of Custom messages that can call into the quasar bindings -pub enum QuasarMsg { - TestScenario { - creator: String, - scenario: String, - }, - SendToken { - creator: String, - destination_local_zone_id: String, - sender: String, - receiver: String, - coin: Coin, - }, - OsmosisJoinPool { - creator: String, - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_out_amount: i64, - token_in_maxs: Vec, - }, - OsmosisExitPool { - creator: String, - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_in_amount: i64, - token_out_mins: Vec, - }, - OsmosisLockTokens { - creator: String, - connection_id: String, - timeout_timestamp: u64, - duration: u64, - coins: Vec, - }, - OsmosisBeginUnlocking { - creator: String, - connection_id: String, - timeout_timestamp: u64, - id: u64, - coins: Vec, - }, - OsmosisJoinSwapExternAmountIn { - creator: String, - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_out_min_amount: i64, - token_in: Coin, - }, - OsmosisExitSwapExternAmountOut { - creator: String, - connection_id: String, - timeout_timestamp: u64, - pool_id: u64, - share_in_amount: i64, - token_out_mins: Coin, - }, -} - -impl QuasarMsg {} - -impl From for CosmosMsg { - fn from(msg: QuasarMsg) -> CosmosMsg { - CosmosMsg::Custom(msg) - } -} - -impl CustomMsg for QuasarMsg {} diff --git a/smart-contracts/packages/quasar-bindings/src/querier.rs b/smart-contracts/packages/quasar-bindings/src/querier.rs deleted file mode 100644 index 98f0d529a..000000000 --- a/smart-contracts/packages/quasar-bindings/src/querier.rs +++ /dev/null @@ -1,38 +0,0 @@ -use cosmwasm_std::{QuerierWrapper, QueryRequest, StdResult}; - -use crate::{ - query::{OraclePricesResponse, OsmosisPoolResponse, OsmosisPoolsResponse, QuasarQuery}, - types::PageRequest, -}; - -/// This is a helper wrapper to easily use our custom queries -pub struct QuasarQuerier<'a> { - querier: &'a QuerierWrapper<'a, QuasarQuery>, -} - -impl<'a> QuasarQuerier<'a> { - pub fn new(querier: &'a QuerierWrapper) -> Self { - QuasarQuerier { querier } - } - - pub fn osmosis_pools( - &self, - pagination: Option, - ) -> StdResult { - let query = QuasarQuery::OsmosisPools { pagination }; - let request: QueryRequest = QuasarQuery::into(query); - self.querier.query(&request) - } - - pub fn osmosis_pool(&self, pool_id: String) -> StdResult { - let query = QuasarQuery::OsmosisPoolInfo { pool_id }; - let request: QueryRequest = QuasarQuery::into(query); - self.querier.query(&request) - } - - pub fn oracle_prices(&self) -> StdResult { - let query = QuasarQuery::OraclePrices {}; - let request: QueryRequest = QuasarQuery::into(query); - self.querier.query(&request) - } -} diff --git a/smart-contracts/packages/quasar-bindings/src/query.rs b/smart-contracts/packages/quasar-bindings/src/query.rs deleted file mode 100644 index 3fd84c0ba..000000000 --- a/smart-contracts/packages/quasar-bindings/src/query.rs +++ /dev/null @@ -1,37 +0,0 @@ -#![allow(non_snake_case)] - -use cosmwasm_std::CustomQuery; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use crate::types::{DecCoin, OsmosisPool, PageRequest, PageResponse}; - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -/// A number of Custom quer that can call into the quasar bindings -pub enum QuasarQuery { - OsmosisPools { pagination: Option }, - OsmosisPoolInfo { pool_id: String }, - OraclePrices {}, -} - -impl CustomQuery for QuasarQuery {} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct OsmosisPoolsResponse { - pub pools: Option>, - pub pagination: Option, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct OsmosisPoolResponse { - pub pool: Option, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct OraclePricesResponse { - pub prices: Vec, - pub updated_at_height: i64, -} diff --git a/smart-contracts/packages/quasar-bindings/src/types.rs b/smart-contracts/packages/quasar-bindings/src/types.rs deleted file mode 100644 index 905a4685f..000000000 --- a/smart-contracts/packages/quasar-bindings/src/types.rs +++ /dev/null @@ -1,114 +0,0 @@ -#![allow(non_snake_case)] - -use std::time::Duration; - -use cosmwasm_std::{Coin, Decimal, Timestamp, Uint256}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Debug)] -#[serde(rename_all = "snake_case")] -pub struct PageRequest { - /// key is a value returned in PageResponse.next_key to begin - /// querying the next page most efficiently. Only one of offset or key - /// should be set. - pub key: Vec, - /// offset is a numeric offset that can be used when key is unavailable. - /// It is less efficient than using key. Only one of offset or key should - /// be set. - pub offset: u64, - /// limit is the total number of results to be returned in the result page. - /// If left empty it will default to a value to be set by each app. - pub limit: u64, - /// count_total is set to true to indicate that the result set should include - /// a count of the total number of items available for pagination in UIs. - /// count_total is only respected when offset is used. It is ignored when key - /// is set. - pub count_total: bool, - /// reverse is set to true if results are to be returned in the descending order. - /// - /// Since: cosmos-sdk 0.43 - pub reverse: bool, -} - -impl PageRequest { - pub fn with_key(key: Vec) -> Self { - Self { - key, - offset: 0, - limit: 0, - count_total: false, - reverse: false, - } - } - - pub fn with_offset(offset: u64) -> Self { - Self { - key: vec![], - offset, - limit: 0, - count_total: false, - reverse: false, - } - } -} - -#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug, JsonSchema)] -pub struct PageResponse { - /// next_key is the key to be passed to PageRequest.key to - /// query the next page most efficiently - pub next_key: Vec, - /// total is total number of results available if PageRequest.count_total - /// was set, its value is undefined otherwise - pub total: u64, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct DecCoin { - pub amount: Decimal, - pub denom: String, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct OsmosisPoolMetrics { - pub apy: Decimal, - pub tvl: Decimal, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct PoolAsset { - pub token: Coin, - pub weight: Uint256, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct SmoothWeightChangeParams { - pub start_time: Timestamp, - pub duration: Duration, - pub pool_asset: Vec, - pub target_pool_weights: Vec, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct PoolParams { - pub swap_fee: Decimal, - pub exit_fee: Decimal, - pub smooth_weight_change_params: Option, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct OsmosisBalancerPool { - pub address: String, - pub id: u64, - pub pool_params: PoolParams, - pub future_pool_governer: Option, - pub total_shares: Coin, - pub pool_assets: Vec, - pub total_weight: Uint256, -} - -#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)] -pub struct OsmosisPool { - pub pool_info: OsmosisBalancerPool, - pub metrics: OsmosisPoolMetrics, -} diff --git a/smart-contracts/packages/quasar-traits/Cargo.lock b/smart-contracts/packages/quasar-traits/Cargo.lock deleted file mode 100644 index d921f5020..000000000 --- a/smart-contracts/packages/quasar-traits/Cargo.lock +++ /dev/null @@ -1,622 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-utils" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" -dependencies = [ - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quasar-traits" -version = "0.1.0" -dependencies = [ - "cosmwasm-std", - "cw20", - "schemars", - "serde", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/smart-contracts/packages/quasar-traits/Cargo.toml b/smart-contracts/packages/quasar-traits/Cargo.toml deleted file mode 100644 index e67437d14..000000000 --- a/smart-contracts/packages/quasar-traits/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "quasar-traits" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-std = { workspace = true } -sw-storage-plus = { workspace = true } -schemars = { workspace = true } -serde = { workspace = true } -cw20 = { workspace = true } diff --git a/smart-contracts/packages/quasar-traits/src/lib.rs b/smart-contracts/packages/quasar-traits/src/lib.rs deleted file mode 100644 index f6ac8fc7b..000000000 --- a/smart-contracts/packages/quasar-traits/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod traits; diff --git a/smart-contracts/packages/quasar-traits/src/traits.rs b/smart-contracts/packages/quasar-traits/src/traits.rs deleted file mode 100644 index e7499d52b..000000000 --- a/smart-contracts/packages/quasar-traits/src/traits.rs +++ /dev/null @@ -1,20 +0,0 @@ -use cosmwasm_std::{Decimal, Uint128}; -use std::fmt::Debug; - -/// ShareDistributor is the trait describing the logic behind distributing shares within a quasar vault. -/// A share distributor does not allow for preferential treatment of certain addresses. Preferential -/// treatment has to be done at contract level. -/// deposit_funds() and withdraw_funds() should be reversible at the same state. -pub trait Curve: Debug { - /// price returns the current price from the curve. Equal to f(x) on the curve - /// The state of the curve should be updated afterwards by the caller - fn price(&self, supply: &Uint128) -> Decimal; - /// deposit() calculates the amount of shares that should be given out in exchange for deposit - /// amount of tokens. Equal to F(x) - /// The state of the curve should be updated afterwards by the caller - fn deposit(&self, deposit: &Uint128) -> Uint128; - /// withdraw() calculates the amount of funds that should be returned in exchange for - /// shares amount of shares under the current state in perfect circumstances. equal to F^-1(x) - /// The state of the curve should be updated afterwards by the caller - fn withdraw(&self, shares: &Uint128) -> Uint128; -} diff --git a/smart-contracts/packages/share-distributor/Cargo.lock b/smart-contracts/packages/share-distributor/Cargo.lock deleted file mode 100644 index c6dd4f27e..000000000 --- a/smart-contracts/packages/share-distributor/Cargo.lock +++ /dev/null @@ -1,633 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-utils" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw20" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb782b8f110819a4eb5dbbcfed25ffba49ec16bbe32b4ad8da50a5ce68fec05" -dependencies = [ - "cosmwasm-std", - "cw-utils", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quasar-traits" -version = "0.1.0" -dependencies = [ - "cosmwasm-std", - "cw20", - "schemars", - "serde", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "share-distributor" -version = "0.1.0" -dependencies = [ - "cosmwasm-std", - "cw20", - "quasar-traits", - "schemars", - "serde", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/smart-contracts/packages/share-distributor/Cargo.toml b/smart-contracts/packages/share-distributor/Cargo.toml deleted file mode 100644 index 768307075..000000000 --- a/smart-contracts/packages/share-distributor/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "share-distributor" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cosmwasm-std = { workspace = true } -schemars = { workspace = true } -cw20 = { workspace = true } -serde = { workspace = true } - -# Quasar packages -quasar-traits = { version = "0.1.0", path = "../quasar-traits" } \ No newline at end of file diff --git a/smart-contracts/packages/share-distributor/src/dumbdistributor.rs b/smart-contracts/packages/share-distributor/src/dumbdistributor.rs deleted file mode 100644 index 7b40ff6e3..000000000 --- a/smart-contracts/packages/share-distributor/src/dumbdistributor.rs +++ /dev/null @@ -1,103 +0,0 @@ -use cosmwasm_std::{StdError, Uint128}; -use quasar_traits::traits::ShareDistributor; -use cw20::Cw20Coin; -use serde::{Deserialize, Serialize}; -use schemars::JsonSchema; -/// DumbDistributor is a simple implementation of the ShareDistributor trait, it returns 1 share -/// per cw20 coin. This should probably not be used in any production environment, but is useful for -/// demonstration purposes. -/// The test distributor_does_not_work_uneven_amounts() demonstrates what is wrong with this implementation. -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct DumbDistributor {} - -impl ShareDistributor for DumbDistributor { - fn deposit_funds(&mut self, deposit: &Vec, state: &Vec) -> Result { - if deposit.len() != state.len() { - return Err(StdError::GenericErr { msg:"deposit and state must be the same length".into()}); - } - if deposit.len() != 2 { - return Err(StdError::GenericErr { msg:"deposit can only be two tokens".into()}); - } - if state.len() != 2 { - return Err(StdError::GenericErr { msg:"state can only be two tokens".into()}); - } - if eq_token(&deposit, &state) { - return Err(StdError::GenericErr { msg:"deposit and state must contain same tokens".into()}); - } - Ok(deposit.iter().fold(Uint128::zero(), |acc, coin| { - acc + Uint128::from(coin.amount) - })) - } - - // distribute shares on a 1:1 basis, this is silly, never do this in an actual contract. Actual implementation - // probably needs to support some state withing the contract or the distributor. - fn withdraw_funds(&mut self, shares: &Uint128, state: &Vec) -> Result, StdError> { - if state.len() != 2 { - return Err(StdError::GenericErr { msg:"state can only be two tokens".into()}); - } - if shares > &state[0].amount || shares > &state[1].amount { - return Err(StdError::GenericErr { msg: "not enough funds".to_string() }); - } - let amount1 = if *shares % Uint128::from(2 as u8) == Uint128::zero() { - *shares / Uint128::from(2 as u8) - } else { - (*shares / Uint128::from(2 as u8)) + Uint128::from(1 as u8) - }; - let token1 = Cw20Coin { - address: state[0].clone().address, - amount: amount1 - }; - let token2 = Cw20Coin { - address: state[1].clone().address, - amount: *shares / Uint128::from(2 as u8) - }; - Ok(vec![token1, token2]) - } -} - -impl DumbDistributor { - pub fn new() -> DumbDistributor { - DumbDistributor{} - } -} - -fn eq_token(a: &Vec, b: &Vec) -> bool { - if a[0].address != b[0].address || a[0].address != b[1].address { - return false; - } - if a[1].address != b[0].address || a[1].address != b[1].address { - return false; - } - true -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn distributor_works_even_amounts() { - let funds = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(100) }, Cw20Coin{ address: "another_token".to_string(), amount: Uint128::new(100)}]; - let state = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(10000) }, Cw20Coin{ address: "another_token".to_string(), amount: Uint128::new(10000)}]; - let mut dist = DumbDistributor::new(); - - let shares = dist.deposit_funds(&funds, &state).unwrap(); - assert_eq!(shares, Uint128::new(200)); - let withdraw = dist.withdraw_funds(&shares, &state).unwrap(); - assert_eq!(withdraw, funds) - } - - #[test] - fn distributor_does_not_work_uneven_amounts() { - let funds = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(100) }, Cw20Coin{ address: "another_token".to_string(), amount: Uint128::new(101)}]; - let state = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(10000) }, Cw20Coin{ address: "another_token".to_string(), amount: Uint128::new(10000)}]; - let mut dist = DumbDistributor::new(); - - // Here we see why this is a bad implementation, we can deposit funds at some state, and not - // get the same amount of shares when we withdraw funds at that same state - let shares = dist.deposit_funds(&funds, &state).unwrap(); - assert_eq!(shares, Uint128::new(201)); - let withdraw = dist.withdraw_funds(&shares, &state).unwrap(); - assert_ne!(withdraw, funds) - } -} \ No newline at end of file diff --git a/smart-contracts/packages/share-distributor/src/lib.rs b/smart-contracts/packages/share-distributor/src/lib.rs deleted file mode 100644 index 39d2c73b0..000000000 --- a/smart-contracts/packages/share-distributor/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod dumbdistributor; -pub mod single_token; \ No newline at end of file diff --git a/smart-contracts/packages/share-distributor/src/single_token.rs b/smart-contracts/packages/share-distributor/src/single_token.rs deleted file mode 100644 index 4a77d8624..000000000 --- a/smart-contracts/packages/share-distributor/src/single_token.rs +++ /dev/null @@ -1,103 +0,0 @@ -use cosmwasm_std::{OverflowError, OverflowOperation, StdError, Uint128}; -use cw20::Cw20Coin; -use quasar_traits::traits::ShareDistributor; -use serde::{Deserialize, Serialize}; -use schemars::JsonSchema; - -#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)] -pub struct SingleToken {} - -impl ShareDistributor for SingleToken { - fn deposit_funds(&mut self, deposit: &Vec, state: &Vec) -> Result { - if state.len() != 1 || deposit.len() != 1{ - return Err(StdError::GenericErr {msg: "state can only be a single token".to_string()}) - } - // make sure that we can add the deposited funds to the state later - if deposit[0].amount.checked_add(state[0].amount).is_err() { - return Err(StdError::Overflow { source: OverflowError { - operation: OverflowOperation::Add, - operand1: deposit[0].amount.to_string(), - operand2: state[0].amount.to_string() - } }) - } - Ok(deposit[0].amount) - } - - fn withdraw_funds(&mut self, shares: &Uint128, state: &Vec) -> Result, StdError> { - if state.len() != 1 { - return Err(StdError::GenericErr {msg: "state can only be a single token".to_string()}) - } - // if we have more shares than funds in the current state of the contract, we return an error - if shares > &state[0].amount { - return Err(StdError::GenericErr { msg: "not enough funds in state for amount of shares".to_string() }) - } - Ok(vec![Cw20Coin{address: state[0].clone().address, amount: shares.clone()}]) - } -} - -impl SingleToken { - pub fn new() -> SingleToken { - SingleToken{} - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn multiple_tokens_fail() { - let funds = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(100) }, Cw20Coin{ address: "another_token".to_string(), amount: Uint128::new(100)}]; - let state = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(10000) }, Cw20Coin{ address: "another_token".to_string(), amount: Uint128::new(10000)}]; - let mut dist = SingleToken::new(); - - let shares = dist.deposit_funds(&funds, &state).unwrap_err(); - assert_eq!(shares, StdError::GenericErr { msg: "state can only be a single token".to_string() }); - let withdraw = dist.withdraw_funds(&Uint128::new(200), &state).unwrap_err(); - assert_eq!(withdraw, StdError::GenericErr { msg: "state can only be a single token".to_string() }); - } - - #[test] - fn insufficient_managed_funds_fail() { - let funds = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(100) }]; - let state = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(10) }]; - let mut dist = SingleToken::new(); - - // We should be able to deposit more funds - let shares = dist.deposit_funds(&funds, &state).unwrap(); - assert_eq!(shares, Uint128::new(100)); - // we should not be able to deposit more funds - let withdraw = dist.withdraw_funds(&Uint128::new(200), &state).unwrap_err(); - assert_eq!(withdraw, StdError::GenericErr { msg: "not enough funds in state for amount of shares".to_string() }); - } - - #[test] - fn distributor_does_not_overflow() { - let funds = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::MAX }]; - let state = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::MAX }]; - let mut dist = SingleToken::new(); - - - let shares = dist.deposit_funds(&funds, &state).unwrap_err(); - assert_eq!(shares, StdError::Overflow { source: OverflowError { - operation: OverflowOperation::Add, - operand1: funds[0].amount.to_string(), - operand2: state[0].amount.to_string() - } }); - let withdraw = dist.withdraw_funds(&Uint128::MAX, &state).unwrap(); - assert_eq!(withdraw, funds); - } - - #[test] - fn distributor_works() { - let funds = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(100) }]; - let state = vec![Cw20Coin{ address: "some_token".to_string(), amount: Uint128::new(1000) }]; - let mut dist = SingleToken::new(); - - - let shares = dist.deposit_funds(&funds, &state).unwrap(); - assert_eq!(shares, Uint128::new(100)); - let withdraw = dist.withdraw_funds(&shares, &state).unwrap(); - assert_eq!(withdraw, funds); - } -} \ No newline at end of file diff --git a/smart-contracts/qmonitor/.babelrc b/smart-contracts/qmonitor/.babelrc deleted file mode 100644 index 64363362b..000000000 --- a/smart-contracts/qmonitor/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@babel/preset-flow"] -} diff --git a/smart-contracts/qmonitor/.gitignore b/smart-contracts/qmonitor/.gitignore deleted file mode 100644 index abc446e20..000000000 --- a/smart-contracts/qmonitor/.gitignore +++ /dev/null @@ -1,105 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port -build diff --git a/smart-contracts/qmonitor/LICENSE b/smart-contracts/qmonitor/LICENSE deleted file mode 100644 index 9aac8d127..000000000 --- a/smart-contracts/qmonitor/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Muon Labs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/smart-contracts/qmonitor/package-lock.json b/smart-contracts/qmonitor/package-lock.json deleted file mode 100644 index a8b06aa43..000000000 --- a/smart-contracts/qmonitor/package-lock.json +++ /dev/null @@ -1,7235 +0,0 @@ -{ - "name": "qmonitor", - "version": "0.1.5", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "qmonitor", - "version": "0.1.5", - "license": "ISC", - "dependencies": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/cosmwasm-stargate": "^0.30.1", - "@cosmjs/stargate": "^0.30.1", - "blessed": "^0.1.81", - "chalk": "^4.1.2", - "osmojs": "^15.0.5", - "react-blessed": "^0.7.2", - "typescript": "^5.0.3" - }, - "bin": { - "qmonitor": "dist/root.js" - }, - "devDependencies": { - "@babel/cli": "^7.19.3", - "@babel/core": "^7.20.2", - "@babel/preset-env": "^7.20.2", - "@babel/preset-flow": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/register": "^7.18.9", - "@types/blessed": "^0.1.19", - "@types/node": "^18.11.9", - "@types/react": "^18.0.24", - "@types/react-blessed": "^0.7.3", - "ts-node-dev": "^2.0.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/cli": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.19.3.tgz", - "integrity": "sha512-643/TybmaCAe101m2tSVHi9UKpETXP9c/Ff4mD2tAwkdP6esKIfaauZFc67vGEM6r9fekbEGid+sZhbEnSe3dg==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.8", - "commander": "^4.0.1", - "convert-source-map": "^1.1.0", - "fs-readdir-recursive": "^1.1.0", - "glob": "^7.2.0", - "make-dir": "^2.1.0", - "slash": "^2.0.0" - }, - "bin": { - "babel": "bin/babel.js", - "babel-external-helpers": "bin/babel-external-helpers.js" - }, - "engines": { - "node": ">=6.9.0" - }, - "optionalDependencies": { - "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", - "chokidar": "^3.4.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-flow": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", - "dev": true, - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz", - "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-flow-strip-types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/register": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.18.9.tgz", - "integrity": "sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.5", - "source-map-support": "^0.5.16" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", - "dependencies": { - "regenerator-runtime": "^0.13.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@confio/ics23": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", - "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", - "dependencies": { - "@noble/hashes": "^1.0.0", - "protobufjs": "^6.8.8" - } - }, - "node_modules/@cosmjs/amino": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.30.1.tgz", - "integrity": "sha512-yNHnzmvAlkETDYIpeCTdVqgvrdt1qgkOXwuRVi8s27UKI5hfqyE9fJ/fuunXE6ZZPnKkjIecDznmuUOMrMvw4w==", - "dependencies": { - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1" - } - }, - "node_modules/@cosmjs/cosmwasm-stargate": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.30.1.tgz", - "integrity": "sha512-W/6SLUCJAJGBN+sJLXouLZikVgmqDd9LCdlMzQaxczcCHTWeJAmRvOiZGSZaSy3shw/JN1qc6g6PKpvTVgj10A==", - "dependencies": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/proto-signing": "^0.30.1", - "@cosmjs/stargate": "^0.30.1", - "@cosmjs/tendermint-rpc": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0", - "pako": "^2.0.2" - } - }, - "node_modules/@cosmjs/crypto": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.30.1.tgz", - "integrity": "sha512-rAljUlake3MSXs9xAm87mu34GfBLN0h/1uPPV6jEwClWjNkAMotzjC0ab9MARy5FFAvYHL3lWb57bhkbt2GtzQ==", - "dependencies": { - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "node_modules/@cosmjs/encoding": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.30.1.tgz", - "integrity": "sha512-rXmrTbgqwihORwJ3xYhIgQFfMSrwLu1s43RIK9I8EBudPx3KmnmyAKzMOVsRDo9edLFNuZ9GIvysUCwQfq3WlQ==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/json-rpc": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.30.1.tgz", - "integrity": "sha512-pitfC/2YN9t+kXZCbNuyrZ6M8abnCC2n62m+JtU9vQUfaEtVsgy+1Fk4TRQ175+pIWSdBMFi2wT8FWVEE4RhxQ==", - "dependencies": { - "@cosmjs/stream": "^0.30.1", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/math": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.30.1.tgz", - "integrity": "sha512-yaoeI23pin9ZiPHIisa6qqLngfnBR/25tSaWpkTm8Cy10MX70UF5oN4+/t1heLaM6SSmRrhk3psRkV4+7mH51Q==", - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@cosmjs/proto-signing": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.30.1.tgz", - "integrity": "sha512-tXh8pPYXV4aiJVhTKHGyeZekjj+K9s2KKojMB93Gcob2DxUjfKapFYBMJSgfKPuWUPEmyr8Q9km2hplI38ILgQ==", - "dependencies": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0" - } - }, - "node_modules/@cosmjs/socket": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.30.1.tgz", - "integrity": "sha512-r6MpDL+9N+qOS/D5VaxnPaMJ3flwQ36G+vPvYJsXArj93BjgyFB7BwWwXCQDzZ+23cfChPUfhbINOenr8N2Kow==", - "dependencies": { - "@cosmjs/stream": "^0.30.1", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/stargate": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.30.1.tgz", - "integrity": "sha512-RdbYKZCGOH8gWebO7r6WvNnQMxHrNXInY/gPHPzMjbQF6UatA6fNM2G2tdgS5j5u7FTqlCI10stNXrknaNdzog==", - "dependencies": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/proto-signing": "^0.30.1", - "@cosmjs/stream": "^0.30.1", - "@cosmjs/tendermint-rpc": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/stream": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.30.1.tgz", - "integrity": "sha512-Fg0pWz1zXQdoxQZpdHRMGvUH5RqS6tPv+j9Eh7Q953UjMlrwZVo0YFLC8OTf/HKVf10E4i0u6aM8D69Q6cNkgQ==", - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.30.1.tgz", - "integrity": "sha512-Z3nCwhXSbPZJ++v85zHObeUggrEHVfm1u18ZRwXxFE9ZMl5mXTybnwYhczuYOl7KRskgwlB+rID0WYACxj4wdQ==", - "dependencies": { - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/json-rpc": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/socket": "^0.30.1", - "@cosmjs/stream": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/utils": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.30.1.tgz", - "integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@nicolo-ribaudo/chokidar-2": { - "version": "2.1.8-no-fsevents.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", - "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", - "dev": true, - "optional": true - }, - "node_modules/@noble/hashes": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", - "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@osmonauts/lcd": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@osmonauts/lcd/-/lcd-0.8.0.tgz", - "integrity": "sha512-k7m2gAVnXc0H4m/eTq4z/8A6hFrr3MPS9wnLV4Xu9/K/WYltCnp2PpiObZm+feZUPK/svES6hxIQeO1bODLx8g==", - "dependencies": { - "@babel/runtime": "^7.19.0", - "axios": "0.27.2" - } - }, - "node_modules/@osmonauts/lcd/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "node_modules/@types/blessed": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@types/blessed/-/blessed-0.1.19.tgz", - "integrity": "sha512-r4qnseYWBsi/kxo5AAlCS22EnTXFbGpnvuXUubJikVeRnYB3e5HwV3NtcwJ0Sk5KOGaLvo9Rtwb8hzxfbqbQPg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "node_modules/@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.0.24", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.24.tgz", - "integrity": "sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q==", - "dev": true, - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-blessed": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@types/react-blessed/-/react-blessed-0.7.3.tgz", - "integrity": "sha512-tPbpUp8YYg8vbgSw+x4puin6q8QLNcXd+FQ69o4U7WXOmkM8zlQOXaASOnvBMXWHZ85Nzz/DK2QCDsqVEfxNIA==", - "dev": true, - "dependencies": { - "@types/blessed": "*", - "@types/react": "*" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true - }, - "node_modules/@types/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==", - "dev": true - }, - "node_modules/@types/strip-json-comments": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", - "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==", - "bin": { - "blessed": "bin/tput.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cosmjs-types": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.7.2.tgz", - "integrity": "sha512-vf2uLyktjr/XVAgEq0DjMxeAWh1yYREe7AMHDKd7EiHVqxBPCaBS+qEEQUkXbR9ndnckqr1sUG8BQhazh4X5lA==", - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dynamic-dedupe": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", - "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", - "dev": true, - "dependencies": { - "xtend": "^4.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/libsodium": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.11.tgz", - "integrity": "sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A==" - }, - "node_modules/libsodium-wrappers": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz", - "integrity": "sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q==", - "dependencies": { - "libsodium": "^0.7.11" - } - }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/osmojs": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/osmojs/-/osmojs-15.0.5.tgz", - "integrity": "sha512-BguDCH004JlMo4LGgpoHXUcthepWyrHz38R5jeicCDhjIO3sR6XRTRpFPOK2FMPAh32mGFMAXK/ElnPPCPRn/g==", - "dependencies": { - "@babel/runtime": "^7.19.0", - "@cosmjs/amino": "0.29.3", - "@cosmjs/proto-signing": "0.29.3", - "@cosmjs/stargate": "0.29.3", - "@cosmjs/tendermint-rpc": "^0.29.3", - "@osmonauts/lcd": "^0.8.0", - "long": "^5.2.0", - "protobufjs": "^6.11.3" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/amino": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.3.tgz", - "integrity": "sha512-BFz1++ERerIggiFc7iGHhGe1CeV3rCv8BvkoBQTBN/ZwzHOaKvqQj8smDlRGlQxX3HWlTwgiLN2A+OB5yX4ZRw==", - "dependencies": { - "@cosmjs/crypto": "^0.29.3", - "@cosmjs/encoding": "^0.29.3", - "@cosmjs/math": "^0.29.3", - "@cosmjs/utils": "^0.29.3" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dependencies": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/encoding": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.29.5.tgz", - "integrity": "sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/json-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz", - "integrity": "sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==", - "dependencies": { - "@cosmjs/stream": "^0.29.5", - "xstream": "^11.14.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/proto-signing": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.29.3.tgz", - "integrity": "sha512-Ai3l9THjMOrLJ4Ebn1Dgptwg6W5ZIRJqtnJjijHhGwTVC1WT0WdYU3aMZ7+PwubcA/cA1rH4ZTK7jrfYbra63g==", - "dependencies": { - "@cosmjs/amino": "^0.29.3", - "@cosmjs/crypto": "^0.29.3", - "@cosmjs/encoding": "^0.29.3", - "@cosmjs/math": "^0.29.3", - "@cosmjs/utils": "^0.29.3", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/proto-signing/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/osmojs/node_modules/@cosmjs/socket": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.29.5.tgz", - "integrity": "sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==", - "dependencies": { - "@cosmjs/stream": "^0.29.5", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/stargate": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.29.3.tgz", - "integrity": "sha512-455TgXStCi6E8KDjnhDAM8wt6aLSjobH4Dixvd7Up1DfCH6UB9NkC/G0fMJANNcNXMaM4wSX14niTXwD1d31BA==", - "dependencies": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.29.3", - "@cosmjs/encoding": "^0.29.3", - "@cosmjs/math": "^0.29.3", - "@cosmjs/proto-signing": "^0.29.3", - "@cosmjs/stream": "^0.29.3", - "@cosmjs/tendermint-rpc": "^0.29.3", - "@cosmjs/utils": "^0.29.3", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/stargate/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/osmojs/node_modules/@cosmjs/stream": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.29.5.tgz", - "integrity": "sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==", - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/tendermint-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz", - "integrity": "sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==", - "dependencies": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/json-rpc": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/socket": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/osmojs/node_modules/@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==" - }, - "node_modules/osmojs/node_modules/cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/osmojs/node_modules/cosmjs-types/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/osmojs/node_modules/long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-blessed": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/react-blessed/-/react-blessed-0.7.2.tgz", - "integrity": "sha512-5ubdFLrkSq5B9dmE9mYxHm9pbY8V+jaiqNCRv791Wf5qzdZKZKhzFBPRBamEgROJPUNDvPCPF25LZ3Lhmm0E/w==", - "dependencies": { - "react-reconciler": "^0.26.1" - }, - "peerDependencies": { - "blessed": ">=0.1.81 <0.2.0", - "react": ">=17.0.1 <18.0.0", - "react-devtools-core": ">=4.10.1 <5.0.0" - }, - "peerDependenciesMeta": { - "blessed": { - "optional": true - }, - "react-devtools-core": { - "optional": true - } - } - }, - "node_modules/react-reconciler": { - "version": "0.26.2", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz", - "integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "react": "^17.0.2" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readonly-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", - "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node-dev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", - "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.1", - "dynamic-dedupe": "^0.3.0", - "minimist": "^1.2.6", - "mkdirp": "^1.0.4", - "resolve": "^1.0.0", - "rimraf": "^2.6.1", - "source-map-support": "^0.5.12", - "tree-kill": "^1.2.2", - "ts-node": "^10.4.0", - "tsconfig": "^7.0.0" - }, - "bin": { - "ts-node-dev": "lib/bin.js", - "tsnd": "lib/bin.js" - }, - "engines": { - "node": ">=0.8.0" - }, - "peerDependencies": { - "node-notifier": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/tsconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", - "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", - "dev": true, - "dependencies": { - "@types/strip-bom": "^3.0.0", - "@types/strip-json-comments": "0.0.30", - "strip-bom": "^3.0.0", - "strip-json-comments": "^2.0.0" - } - }, - "node_modules/typescript": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", - "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xstream": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", - "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", - "dependencies": { - "globalthis": "^1.0.1", - "symbol-observable": "^2.0.3" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/cli": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.19.3.tgz", - "integrity": "sha512-643/TybmaCAe101m2tSVHi9UKpETXP9c/Ff4mD2tAwkdP6esKIfaauZFc67vGEM6r9fekbEGid+sZhbEnSe3dg==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.8", - "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", - "chokidar": "^3.4.0", - "commander": "^4.0.1", - "convert-source-map": "^1.1.0", - "fs-readdir-recursive": "^1.1.0", - "glob": "^7.2.0", - "make-dir": "^2.1.0", - "slash": "^2.0.0" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", - "dev": true - }, - "@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "requires": { - "@babel/types": "^7.20.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - } - }, - "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-flow": "^7.18.6" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", - "dev": true, - "requires": { - "@babel/plugin-transform-react-jsx": "^7.18.6" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - } - }, - "@babel/preset-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz", - "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-flow-strip-types": "^7.18.6" - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" - } - }, - "@babel/register": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.18.9.tgz", - "integrity": "sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.5", - "source-map-support": "^0.5.16" - } - }, - "@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", - "requires": { - "regenerator-runtime": "^0.13.10" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@confio/ics23": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", - "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", - "requires": { - "@noble/hashes": "^1.0.0", - "protobufjs": "^6.8.8" - } - }, - "@cosmjs/amino": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.30.1.tgz", - "integrity": "sha512-yNHnzmvAlkETDYIpeCTdVqgvrdt1qgkOXwuRVi8s27UKI5hfqyE9fJ/fuunXE6ZZPnKkjIecDznmuUOMrMvw4w==", - "requires": { - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1" - } - }, - "@cosmjs/cosmwasm-stargate": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.30.1.tgz", - "integrity": "sha512-W/6SLUCJAJGBN+sJLXouLZikVgmqDd9LCdlMzQaxczcCHTWeJAmRvOiZGSZaSy3shw/JN1qc6g6PKpvTVgj10A==", - "requires": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/proto-signing": "^0.30.1", - "@cosmjs/stargate": "^0.30.1", - "@cosmjs/tendermint-rpc": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0", - "pako": "^2.0.2" - } - }, - "@cosmjs/crypto": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.30.1.tgz", - "integrity": "sha512-rAljUlake3MSXs9xAm87mu34GfBLN0h/1uPPV6jEwClWjNkAMotzjC0ab9MARy5FFAvYHL3lWb57bhkbt2GtzQ==", - "requires": { - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "@cosmjs/encoding": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.30.1.tgz", - "integrity": "sha512-rXmrTbgqwihORwJ3xYhIgQFfMSrwLu1s43RIK9I8EBudPx3KmnmyAKzMOVsRDo9edLFNuZ9GIvysUCwQfq3WlQ==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "@cosmjs/json-rpc": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.30.1.tgz", - "integrity": "sha512-pitfC/2YN9t+kXZCbNuyrZ6M8abnCC2n62m+JtU9vQUfaEtVsgy+1Fk4TRQ175+pIWSdBMFi2wT8FWVEE4RhxQ==", - "requires": { - "@cosmjs/stream": "^0.30.1", - "xstream": "^11.14.0" - } - }, - "@cosmjs/math": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.30.1.tgz", - "integrity": "sha512-yaoeI23pin9ZiPHIisa6qqLngfnBR/25tSaWpkTm8Cy10MX70UF5oN4+/t1heLaM6SSmRrhk3psRkV4+7mH51Q==", - "requires": { - "bn.js": "^5.2.0" - } - }, - "@cosmjs/proto-signing": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.30.1.tgz", - "integrity": "sha512-tXh8pPYXV4aiJVhTKHGyeZekjj+K9s2KKojMB93Gcob2DxUjfKapFYBMJSgfKPuWUPEmyr8Q9km2hplI38ILgQ==", - "requires": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0" - } - }, - "@cosmjs/socket": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.30.1.tgz", - "integrity": "sha512-r6MpDL+9N+qOS/D5VaxnPaMJ3flwQ36G+vPvYJsXArj93BjgyFB7BwWwXCQDzZ+23cfChPUfhbINOenr8N2Kow==", - "requires": { - "@cosmjs/stream": "^0.30.1", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stargate": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.30.1.tgz", - "integrity": "sha512-RdbYKZCGOH8gWebO7r6WvNnQMxHrNXInY/gPHPzMjbQF6UatA6fNM2G2tdgS5j5u7FTqlCI10stNXrknaNdzog==", - "requires": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/proto-signing": "^0.30.1", - "@cosmjs/stream": "^0.30.1", - "@cosmjs/tendermint-rpc": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "cosmjs-types": "^0.7.1", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stream": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.30.1.tgz", - "integrity": "sha512-Fg0pWz1zXQdoxQZpdHRMGvUH5RqS6tPv+j9Eh7Q953UjMlrwZVo0YFLC8OTf/HKVf10E4i0u6aM8D69Q6cNkgQ==", - "requires": { - "xstream": "^11.14.0" - } - }, - "@cosmjs/tendermint-rpc": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.30.1.tgz", - "integrity": "sha512-Z3nCwhXSbPZJ++v85zHObeUggrEHVfm1u18ZRwXxFE9ZMl5mXTybnwYhczuYOl7KRskgwlB+rID0WYACxj4wdQ==", - "requires": { - "@cosmjs/crypto": "^0.30.1", - "@cosmjs/encoding": "^0.30.1", - "@cosmjs/json-rpc": "^0.30.1", - "@cosmjs/math": "^0.30.1", - "@cosmjs/socket": "^0.30.1", - "@cosmjs/stream": "^0.30.1", - "@cosmjs/utils": "^0.30.1", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "@cosmjs/utils": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.30.1.tgz", - "integrity": "sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g==" - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@nicolo-ribaudo/chokidar-2": { - "version": "2.1.8-no-fsevents.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", - "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", - "dev": true, - "optional": true - }, - "@noble/hashes": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz", - "integrity": "sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==" - }, - "@osmonauts/lcd": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@osmonauts/lcd/-/lcd-0.8.0.tgz", - "integrity": "sha512-k7m2gAVnXc0H4m/eTq4z/8A6hFrr3MPS9wnLV4Xu9/K/WYltCnp2PpiObZm+feZUPK/svES6hxIQeO1bODLx8g==", - "requires": { - "@babel/runtime": "^7.19.0", - "axios": "0.27.2" - }, - "dependencies": { - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - } - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "@types/blessed": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@types/blessed/-/blessed-0.1.19.tgz", - "integrity": "sha512-r4qnseYWBsi/kxo5AAlCS22EnTXFbGpnvuXUubJikVeRnYB3e5HwV3NtcwJ0Sk5KOGaLvo9Rtwb8hzxfbqbQPg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "@types/node": { - "version": "18.11.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", - "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==" - }, - "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true - }, - "@types/react": { - "version": "18.0.24", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.24.tgz", - "integrity": "sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q==", - "dev": true, - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-blessed": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@types/react-blessed/-/react-blessed-0.7.3.tgz", - "integrity": "sha512-tPbpUp8YYg8vbgSw+x4puin6q8QLNcXd+FQ69o4U7WXOmkM8zlQOXaASOnvBMXWHZ85Nzz/DK2QCDsqVEfxNIA==", - "dev": true, - "requires": { - "@types/blessed": "*", - "@types/react": "*" - } - }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true - }, - "@types/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==", - "dev": true - }, - "@types/strip-json-comments": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", - "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", - "dev": true - }, - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==" - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "requires": { - "browserslist": "^4.21.4" - } - }, - "cosmjs-types": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.7.2.tgz", - "integrity": "sha512-vf2uLyktjr/XVAgEq0DjMxeAWh1yYREe7AMHDKd7EiHVqxBPCaBS+qEEQUkXbR9ndnckqr1sUG8BQhazh4X5lA==", - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "dynamic-dedupe": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", - "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", - "dev": true, - "requires": { - "xtend": "^4.0.0" - } - }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs-readdir-recursive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "requires": { - "define-properties": "^1.1.3" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "requires": {} - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "libsodium": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.11.tgz", - "integrity": "sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A==" - }, - "libsodium-wrappers": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz", - "integrity": "sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q==", - "requires": { - "libsodium": "^0.7.11" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "osmojs": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/osmojs/-/osmojs-15.0.5.tgz", - "integrity": "sha512-BguDCH004JlMo4LGgpoHXUcthepWyrHz38R5jeicCDhjIO3sR6XRTRpFPOK2FMPAh32mGFMAXK/ElnPPCPRn/g==", - "requires": { - "@babel/runtime": "^7.19.0", - "@cosmjs/amino": "0.29.3", - "@cosmjs/proto-signing": "0.29.3", - "@cosmjs/stargate": "0.29.3", - "@cosmjs/tendermint-rpc": "^0.29.3", - "@osmonauts/lcd": "^0.8.0", - "long": "^5.2.0", - "protobufjs": "^6.11.3" - }, - "dependencies": { - "@cosmjs/amino": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.3.tgz", - "integrity": "sha512-BFz1++ERerIggiFc7iGHhGe1CeV3rCv8BvkoBQTBN/ZwzHOaKvqQj8smDlRGlQxX3HWlTwgiLN2A+OB5yX4ZRw==", - "requires": { - "@cosmjs/crypto": "^0.29.3", - "@cosmjs/encoding": "^0.29.3", - "@cosmjs/math": "^0.29.3", - "@cosmjs/utils": "^0.29.3" - } - }, - "@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "requires": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "@cosmjs/encoding": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.29.5.tgz", - "integrity": "sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "@cosmjs/json-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz", - "integrity": "sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==", - "requires": { - "@cosmjs/stream": "^0.29.5", - "xstream": "^11.14.0" - } - }, - "@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "requires": { - "bn.js": "^5.2.0" - } - }, - "@cosmjs/proto-signing": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.29.3.tgz", - "integrity": "sha512-Ai3l9THjMOrLJ4Ebn1Dgptwg6W5ZIRJqtnJjijHhGwTVC1WT0WdYU3aMZ7+PwubcA/cA1rH4ZTK7jrfYbra63g==", - "requires": { - "@cosmjs/amino": "^0.29.3", - "@cosmjs/crypto": "^0.29.3", - "@cosmjs/encoding": "^0.29.3", - "@cosmjs/math": "^0.29.3", - "@cosmjs/utils": "^0.29.3", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0" - }, - "dependencies": { - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "@cosmjs/socket": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.29.5.tgz", - "integrity": "sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==", - "requires": { - "@cosmjs/stream": "^0.29.5", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stargate": { - "version": "0.29.3", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.29.3.tgz", - "integrity": "sha512-455TgXStCi6E8KDjnhDAM8wt6aLSjobH4Dixvd7Up1DfCH6UB9NkC/G0fMJANNcNXMaM4wSX14niTXwD1d31BA==", - "requires": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.29.3", - "@cosmjs/encoding": "^0.29.3", - "@cosmjs/math": "^0.29.3", - "@cosmjs/proto-signing": "^0.29.3", - "@cosmjs/stream": "^0.29.3", - "@cosmjs/tendermint-rpc": "^0.29.3", - "@cosmjs/utils": "^0.29.3", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - }, - "dependencies": { - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "@cosmjs/stream": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.29.5.tgz", - "integrity": "sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==", - "requires": { - "xstream": "^11.14.0" - } - }, - "@cosmjs/tendermint-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz", - "integrity": "sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==", - "requires": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/json-rpc": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/socket": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==" - }, - "cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - }, - "dependencies": { - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" - } - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-blessed": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/react-blessed/-/react-blessed-0.7.2.tgz", - "integrity": "sha512-5ubdFLrkSq5B9dmE9mYxHm9pbY8V+jaiqNCRv791Wf5qzdZKZKhzFBPRBamEgROJPUNDvPCPF25LZ3Lhmm0E/w==", - "requires": { - "react-reconciler": "^0.26.1" - } - }, - "react-reconciler": { - "version": "0.26.2", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz", - "integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "readonly-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", - "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", - "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==" - }, - "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - } - } - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "ts-node-dev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", - "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", - "dev": true, - "requires": { - "chokidar": "^3.5.1", - "dynamic-dedupe": "^0.3.0", - "minimist": "^1.2.6", - "mkdirp": "^1.0.4", - "resolve": "^1.0.0", - "rimraf": "^2.6.1", - "source-map-support": "^0.5.12", - "tree-kill": "^1.2.2", - "ts-node": "^10.4.0", - "tsconfig": "^7.0.0" - } - }, - "tsconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", - "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", - "dev": true, - "requires": { - "@types/strip-bom": "^3.0.0", - "@types/strip-json-comments": "0.0.30", - "strip-bom": "^3.0.0", - "strip-json-comments": "^2.0.0" - } - }, - "typescript": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", - "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "requires": {} - }, - "xstream": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", - "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", - "requires": { - "globalthis": "^1.0.1", - "symbol-observable": "^2.0.3" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/smart-contracts/qmonitor/package.json b/smart-contracts/qmonitor/package.json deleted file mode 100644 index 398772140..000000000 --- a/smart-contracts/qmonitor/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "qmonitor", - "version": "0.1.5", - "description": "", - "main": "dist/root.js", - "bin": "dist/root.js", - "scripts": { - "start": "node dist/index.js", - "dev": "ts-node-dev --respawn --transpile-only ./src", - "clean": "rm -rf ./build && rm -rf ./dist", - "build": "tsc && babel build -d dist", - "prepublish": "npm run build", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@cosmjs/amino": "^0.30.1", - "@cosmjs/cosmwasm-stargate": "^0.30.1", - "@cosmjs/stargate": "^0.30.1", - "blessed": "^0.1.81", - "chalk": "^4.1.2", - "osmojs": "^15.0.5", - "react-blessed": "^0.7.2", - "typescript": "^5.0.3" - }, - "devDependencies": { - "@babel/cli": "^7.19.3", - "@babel/core": "^7.20.2", - "@babel/preset-env": "^7.20.2", - "@babel/preset-flow": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/register": "^7.18.9", - "@types/blessed": "^0.1.19", - "@types/node": "^18.11.9", - "@types/react": "^18.0.24", - "@types/react-blessed": "^0.7.3", - "ts-node-dev": "^2.0.0" - } -} diff --git a/smart-contracts/qmonitor/src/App.tsx b/smart-contracts/qmonitor/src/App.tsx deleted file mode 100644 index 9e509edc7..000000000 --- a/smart-contracts/qmonitor/src/App.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { useAppContext } from './context/ScreenContext' -import Tabs from './partials/Tabs' -import Debug from './partials/Debug' -import EnvList from './partials/EnvList' -import Logs from './partials/Logs' -import MsgWindow from './partials/MsgWindow' -import { IS_DEBUG, SIDEBAR_WIDTH } from './utils/config' -import { getCenterColWidth } from './utils/windowUtils' -import InfoWindow from './partials/InfoWindow' - -// Rendering a simple centered box -const App = ({}) => { - const { width, height } = useAppContext() as { width: number; height: number } - - const firstColWidth = Math.floor(Math.min(width * 0.3, SIDEBAR_WIDTH)) - const secondColWidth = getCenterColWidth(width) - const lastColWidth = Math.floor(Math.min(width * 0.3, SIDEBAR_WIDTH)) - const secondColLeft = firstColWidth - // const lastColLeft = firstColWidth + secondColWidth - - return ( - - {/* - - - hello govnahs - */} - {/* */} - - - - - - - {/* - - - - - - {IS_DEBUG && } - */} - - ) -} - -export default App diff --git a/smart-contracts/qmonitor/src/Counter.tsx b/smart-contracts/qmonitor/src/Counter.tsx deleted file mode 100644 index b83c15478..000000000 --- a/smart-contracts/qmonitor/src/Counter.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useEffect, useRef, useState } from 'react' - -const Counter = (props: any) => { - const [count, setCount] = useState(0) - const [fontIndex, setFontIndex] = useState(0) - - const boxRef = useRef(null) - - useEffect(() => { - const timer = setTimeout(() => { - setFontIndex(fontIndex + 1) - // @ts-ignore - boxRef?.current.setScrollPerc(100) - }, 1000) - return () => clearTimeout(timer) - }, [fontIndex]) - - function handleCountButton () { - console.log('HERE!') - setCount(count + 1) - } - - const text = `You clicked ${count}\nstupid times, ${new Array(fontIndex) - .fill(`\nI love you ${fontIndex}`) - .join('')}` - return ( - <> - - {text} - - - - ) -} - -export default Counter diff --git a/smart-contracts/qmonitor/src/chain/Osmosis.ts b/smart-contracts/qmonitor/src/chain/Osmosis.ts deleted file mode 100644 index afc33fb90..000000000 --- a/smart-contracts/qmonitor/src/chain/Osmosis.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { OSMOSIS_RPC_NODE } from '../utils/config' -import { osmosis } from 'osmojs' - -const { createRPCQueryClient } = osmosis.ClientFactory - -let instance: OsmosisClient | undefined = undefined - -export class OsmosisClient { - rpcUrl: string - constructor() { - this.rpcUrl = OSMOSIS_RPC_NODE - } - - static getInstance(): OsmosisClient { - if (!instance) { - instance = new OsmosisClient() - // await instance.init() - } - return instance - } - - async init() { - // const client = await createRPCQueryClient({ rpcEndpoint: this.rpcUrl }) - } - - async getPoolInfo(poolId: string) { - const client = await createRPCQueryClient({ rpcEndpoint: this.rpcUrl }) - const response = await client.osmosis.gamm.v1beta1.pool({ - poolId, - }) - if (!response.pool) { - throw new Error('Pool not found') - } - - return osmosis.gamm.v1beta1.Pool.decode(response.pool.value) - } - - async getBalances(address: string) { - const client = await createRPCQueryClient({ rpcEndpoint: this.rpcUrl }) - const balance = await client.cosmos.bank.v1beta1.allBalances({ address }) - return balance - } - - async getLockedShares(address: string) { - const client = await createRPCQueryClient({ rpcEndpoint: this.rpcUrl }) - const response = await client.osmosis.lockup.accountLockedCoins({ - owner: address, - }) - - return response - } -} diff --git a/smart-contracts/qmonitor/src/chain/Quasar.ts b/smart-contracts/qmonitor/src/chain/Quasar.ts deleted file mode 100644 index a853ebbe7..000000000 --- a/smart-contracts/qmonitor/src/chain/Quasar.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate' -import { StargateClient } from '@cosmjs/stargate' -import { QUASAR_RPC_NODE } from '../utils/config' - -let instance: QuasarClient | undefined = undefined - -export class QuasarClient { - rpcUrl: string - constructor() { - this.rpcUrl = QUASAR_RPC_NODE - } - - static getInstance(): QuasarClient { - if (!instance) { - instance = new QuasarClient() - // await instance.init() - } - return instance - } - async init() { - // const client = await CosmWasmClient.connect(this.rpcUrl) - } - - async getBalances(address: string) { - const client = await StargateClient.connect(this.rpcUrl) - const balance = await client.getAllBalances(address) - return balance - } -} diff --git a/smart-contracts/qmonitor/src/chain/Querier.ts b/smart-contracts/qmonitor/src/chain/Querier.ts deleted file mode 100644 index ad18d08b0..000000000 --- a/smart-contracts/qmonitor/src/chain/Querier.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate' -import { Buffer } from 'buffer' -import { LpStrategyQueryClient } from '../contracts/LpStrategy.client' -import { VAULT_ADDRESS } from '../utils/config' - -import { BasicVaultQueryClient } from '../contracts/BasicVault.client' -import { PrimitiveConfig } from '../contracts/BasicVault.types' -import { InvestmentInfo } from '../contracts/BasicVault.types' - -let instance: Querier | null = null -let afterInitializationActions = [] as any[] - -export default class Querier { - rpcUrl: string - chainId: string - queryClient: CosmWasmClient | undefined - constructor(RPC_URL: string, CHAIN_ID: string) { - this.rpcUrl = RPC_URL - this.chainId = CHAIN_ID - } - - static async getInstance(rpcUrl: string, chainId: string): Promise { - if (!instance) { - instance = new Querier(rpcUrl, chainId) - await instance.init() - } - return instance - } - - async init() { - this.queryClient = await CosmWasmClient.connect(this.rpcUrl) - for (let action of afterInitializationActions) { - action() - } - } - - static onInit(action: any) { - afterInitializationActions.push(action) - } - - async getAllCodes() { - return this.queryClient!.getCodes() - } - - async getCodeDetails(code_id: number) { - return this.queryClient!.getCodeDetails(code_id) - } - - async getContractsFromCodeId(code_id: number) { - return this.queryClient!.getContracts(code_id) - } - - async getMetadataFromContract(address: string, code_id: number) { - let contract = await this.queryClient!.getContract(address) - let contractHistory = await this.queryClient!.getContractCodeHistory( - address, - ) - let code = await this.queryClient!.getCodeDetails(code_id) - let contractName = await this.queryClient!.queryContractRaw( - address, - Buffer.from('636F6E74726163745F696E666F', 'hex'), - ) - - let parsedName = '' - try { - let details = JSON.parse( - new TextDecoder().decode(contractName || undefined), - ) - parsedName = details.contract - } catch (e) { - console.log('Error parsing contract name', e) - } - - return { - contractName: parsedName, - contractAddress: address, - contractCodeId: code_id, - contractHistory: contractHistory, - contract: contract, - code: code, - } - } - - getQueryClient() { - if (!this.queryClient) throw new Error('Query client not initialized') - return this.queryClient - } - - getVaultQueryClient() { - let qClient = this.getQueryClient() - return new BasicVaultQueryClient(qClient, VAULT_ADDRESS) - } - - async getVaultCap() { - let vault = this.getVaultQueryClient() - return vault.getCap() - } - - async getVaultTokenInfo() { - let vault = this.getVaultQueryClient() - return vault.tokenInfo() - } - - async getVaultInvestmentInfo() { - let vault = this.getVaultQueryClient() - return vault.investment() - } - - getPrimitiveQueryClient(address: string) { - let qClient = this.getQueryClient() - return new LpStrategyQueryClient(qClient, address) - } - - async getPrimitiveLockStatus(address: string) { - let primitive = this.getPrimitiveQueryClient(address) - return primitive.lock() - } - - async getPrimitivePendingAcks(address: string) { - let primitive = this.getPrimitiveQueryClient(address) - return primitive.listPendingAcks() - } - - async getPrimitiveTrappedErrors(address: string) { - let primitive = this.getPrimitiveQueryClient(address) - return primitive.trappedErrors() - } - - async getPrimitiveIcaAddress(address: string) { - let primitive = this.getPrimitiveQueryClient(address) - return primitive.icaAddress() - } -} diff --git a/smart-contracts/qmonitor/src/context/ScreenContext.tsx b/smart-contracts/qmonitor/src/context/ScreenContext.tsx deleted file mode 100644 index 34a30b7e9..000000000 --- a/smart-contracts/qmonitor/src/context/ScreenContext.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { - createContext, - Dispatch, - SetStateAction, - useContext, - useEffect, - useState, -} from 'react' -import { TPosition } from '../utils/types' -import * as blessed from 'blessed' -import { saveMeta } from '../utils/fileUtils' -import { InvestmentInfo } from '../contracts/BasicVault.types' -import Querier from '../chain/Querier' -import { QUASAR_RPC_NODE } from '../utils/config' - -function defaultSetter() {} - -export interface SpawnCommand { - command: string - args: string[] - cwd: string - env?: { [key: string]: string } - callback?: (output: string) => void -} - -export interface MsgMetadata { - title: string - msg: string - funds: string -} - -export interface ContractInstanceMetadata { - address: string -} - -export interface CodeMetadata { - codeID: string - deployedContracts: ContractInstanceMetadata[] -} - -export interface ContractMetadata { - fileName: string - buildName: string // same as filename generally but with underscores - codes: CodeMetadata[] - initMsgs: MsgMetadata[] - executeMsgs: MsgMetadata[] - queryMsgs: MsgMetadata[] -} - -export type Tabs = 'vault' | 'prim_0' | 'prim_1' | 'prim_2' - -const AppContext = createContext({ - width: 0 as TPosition, - height: 0 as TPosition, - tab: 'vault' as Tabs, - investmentInfo: undefined as InvestmentInfo | undefined, - command: undefined as SpawnCommand | undefined, - logAppendContent: '' as string, - setWidth: defaultSetter as Dispatch>, - setHeight: defaultSetter as Dispatch>, - setTab: defaultSetter as Dispatch>, - setCommand: defaultSetter as Dispatch< - SetStateAction - >, - log: (..._args: any[]) => {}, -}) - -export function AppWrapper({ - screen, - children, -}: { - screen: blessed.Widgets.Screen - children?: any -}) { - const [width, setWidth] = useState(0) - const [height, setHeight] = useState(0) - const [tab, setTab] = useState('vault') - const [command, setCommand] = useState(undefined) - const [logAppendContent, setLogAppendContent] = useState('') - const [investmentInfo, setInvestmentInfo] = useState< - InvestmentInfo | undefined - >(undefined) - - useEffect(() => { - setWidth(screen.width) - setHeight(screen.height) - - screen.on('resize', (newScreen) => { - console.log({ newScreen }) - setWidth(screen.width) - setHeight(screen.height) - }) - }, []) - - async function loadInvesmentInfo() { - const querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - const investmentResponse = await querier.getVaultInvestmentInfo() - setInvestmentInfo(investmentResponse.info) - } - - // vault loading primitives - useEffect(() => { - Querier.onInit(() => { - loadInvesmentInfo() - }) - }, []) - - // useEffect(() => { - // if (contract && contract.fileName && env) { - // saveMeta(contract, env) - // } - // }, [contract]) - - let sharedState = { - width, - setWidth, - height, - setHeight, - tab, - setTab, - investmentInfo, - command, - setCommand, - logAppendContent, - log: (...args: string[]) => { - setLogAppendContent( - args - .map((a) => { - if (typeof a === 'object') return JSON.stringify(a) - return a - }) - .join(' ') + '\n', - ) - }, - } - - return ( - {children} - ) -} - -export function useAppContext() { - return useContext(AppContext) -} diff --git a/smart-contracts/qmonitor/src/contracts/BasicVault.client.ts b/smart-contracts/qmonitor/src/contracts/BasicVault.client.ts deleted file mode 100644 index 69b31a24f..000000000 --- a/smart-contracts/qmonitor/src/contracts/BasicVault.client.ts +++ /dev/null @@ -1,786 +0,0 @@ -/** - * This file was automatically generated by @cosmwasm/ts-codegen@0.24.0. - * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, - * and run the @cosmwasm/ts-codegen generate command to regenerate this file. - */ - -import { - CosmWasmClient, - SigningCosmWasmClient, - ExecuteResult, -} from '@cosmjs/cosmwasm-stargate' -import { StdFee } from '@cosmjs/amino' -import { - ExecuteMsg, - Uint128, - Timestamp, - Uint64, - Binary, - Expiration, - BondResponse, - StartUnbondResponse, - UnbondResponse, - PrimitiveInitMsg, - Decimal, - AssetInfoBaseForAddr, - Addr, - InstantiateMsg, - PrimitiveConfig, - InstantiateMsg1, - DistributionSchedule, - QueryMsg, - Coin, - VaultTokenInfoResponse, - AllowanceResponse, - BalanceResponse, - ClaimsResponse, - Claim, - DepositRatioResponse, - GetCapResponse, - Cap, - GetDebugResponse, - TvlInfoResponse, - PrimitiveInfo, - LpCache, - InvestmentResponse, - InvestmentInfo, - PendingBondsResponse, - BondingStub, - PendingUnbondsResponse, - Unbond, - UnbondingStub, - TokenInfoResponse, -} from './BasicVault.types' -export interface BasicVaultReadOnlyInterface { - contractAddress: string - claims: ({ address }: { address: string }) => Promise - getCap: () => Promise - investment: () => Promise - depositRatio: ({ funds }: { funds: Coin[] }) => Promise - pendingBonds: ({ - address, - }: { - address: string - }) => Promise - getTvlInfo: () => Promise - pendingUnbonds: ({ - address, - }: { - address: string - }) => Promise - getDebug: () => Promise - balance: ({ address }: { address: string }) => Promise - tokenInfo: () => Promise - additionalTokenInfo: () => Promise - allowance: ({ - owner, - spender, - }: { - owner: string - spender: string - }) => Promise -} -export class BasicVaultQueryClient implements BasicVaultReadOnlyInterface { - client: CosmWasmClient - contractAddress: string - - constructor(client: CosmWasmClient, contractAddress: string) { - this.client = client - this.contractAddress = contractAddress - this.claims = this.claims.bind(this) - this.getCap = this.getCap.bind(this) - this.investment = this.investment.bind(this) - this.depositRatio = this.depositRatio.bind(this) - this.pendingBonds = this.pendingBonds.bind(this) - this.getTvlInfo = this.getTvlInfo.bind(this) - this.pendingUnbonds = this.pendingUnbonds.bind(this) - this.getDebug = this.getDebug.bind(this) - this.balance = this.balance.bind(this) - this.tokenInfo = this.tokenInfo.bind(this) - this.additionalTokenInfo = this.additionalTokenInfo.bind(this) - this.allowance = this.allowance.bind(this) - } - - claims = async ({ - address, - }: { - address: string - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - claims: { - address, - }, - }) - } - getCap = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - get_cap: {}, - }) - } - investment = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - investment: {}, - }) - } - depositRatio = async ({ - funds, - }: { - funds: Coin[] - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - deposit_ratio: { - funds, - }, - }) - } - pendingBonds = async ({ - address, - }: { - address: string - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - pending_bonds: { - address, - }, - }) - } - getTvlInfo = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - get_tvl_info: {}, - }) - } - pendingUnbonds = async ({ - address, - }: { - address: string - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - pending_unbonds: { - address, - }, - }) - } - getDebug = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - get_debug: {}, - }) - } - balance = async ({ - address, - }: { - address: string - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - balance: { - address, - }, - }) - } - tokenInfo = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - token_info: {}, - }) - } - additionalTokenInfo = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - additional_token_info: {}, - }) - } - allowance = async ({ - owner, - spender, - }: { - owner: string - spender: string - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - allowance: { - owner, - spender, - }, - }) - } -} -export interface BasicVaultInterface extends BasicVaultReadOnlyInterface { - contractAddress: string - sender: string - bond: ( - { - recipient, - }: { - recipient?: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - unbond: ( - { - amount, - }: { - amount?: Uint128 - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - claim: ( - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - bondResponse: ( - { - bondId, - shareAmount, - }: { - bondId: string - shareAmount: Uint128 - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - startUnbondResponse: ( - { - unbondId, - unlockTime, - }: { - unbondId: string - unlockTime: Timestamp - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - unbondResponse: ( - { - unbondId, - }: { - unbondId: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - transfer: ( - { - amount, - recipient, - }: { - amount: Uint128 - recipient: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - burn: ( - { - amount, - }: { - amount: Uint128 - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - send: ( - { - amount, - contract, - msg, - }: { - amount: Uint128 - contract: string - msg: Binary - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - increaseAllowance: ( - { - amount, - expires, - spender, - }: { - amount: Uint128 - expires?: Expiration - spender: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - decreaseAllowance: ( - { - amount, - expires, - spender, - }: { - amount: Uint128 - expires?: Expiration - spender: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - transferFrom: ( - { - amount, - owner, - recipient, - }: { - amount: Uint128 - owner: string - recipient: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - sendFrom: ( - { - amount, - contract, - msg, - owner, - }: { - amount: Uint128 - contract: string - msg: Binary - owner: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - burnFrom: ( - { - amount, - owner, - }: { - amount: Uint128 - owner: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - clearCache: ( - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise -} -export class BasicVaultClient extends BasicVaultQueryClient - implements BasicVaultInterface { - client: SigningCosmWasmClient - sender: string - contractAddress: string - - constructor( - client: SigningCosmWasmClient, - sender: string, - contractAddress: string, - ) { - super(client, contractAddress) - this.client = client - this.sender = sender - this.contractAddress = contractAddress - this.bond = this.bond.bind(this) - this.unbond = this.unbond.bind(this) - this.claim = this.claim.bind(this) - this.bondResponse = this.bondResponse.bind(this) - this.startUnbondResponse = this.startUnbondResponse.bind(this) - this.unbondResponse = this.unbondResponse.bind(this) - this.transfer = this.transfer.bind(this) - this.burn = this.burn.bind(this) - this.send = this.send.bind(this) - this.increaseAllowance = this.increaseAllowance.bind(this) - this.decreaseAllowance = this.decreaseAllowance.bind(this) - this.transferFrom = this.transferFrom.bind(this) - this.sendFrom = this.sendFrom.bind(this) - this.burnFrom = this.burnFrom.bind(this) - this.clearCache = this.clearCache.bind(this) - } - - bond = async ( - { - recipient, - }: { - recipient?: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - bond: { - recipient, - }, - }, - fee, - memo, - funds, - ) - } - unbond = async ( - { - amount, - }: { - amount?: Uint128 - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - unbond: { - amount, - }, - }, - fee, - memo, - funds, - ) - } - claim = async ( - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - claim: {}, - }, - fee, - memo, - funds, - ) - } - bondResponse = async ( - { - bondId, - shareAmount, - }: { - bondId: string - shareAmount: Uint128 - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - bond_response: { - bond_id: bondId, - share_amount: shareAmount, - }, - }, - fee, - memo, - funds, - ) - } - startUnbondResponse = async ( - { - unbondId, - unlockTime, - }: { - unbondId: string - unlockTime: Timestamp - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - start_unbond_response: { - unbond_id: unbondId, - unlock_time: unlockTime, - }, - }, - fee, - memo, - funds, - ) - } - unbondResponse = async ( - { - unbondId, - }: { - unbondId: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - unbond_response: { - unbond_id: unbondId, - }, - }, - fee, - memo, - funds, - ) - } - transfer = async ( - { - amount, - recipient, - }: { - amount: Uint128 - recipient: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - transfer: { - amount, - recipient, - }, - }, - fee, - memo, - funds, - ) - } - burn = async ( - { - amount, - }: { - amount: Uint128 - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - burn: { - amount, - }, - }, - fee, - memo, - funds, - ) - } - send = async ( - { - amount, - contract, - msg, - }: { - amount: Uint128 - contract: string - msg: Binary - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - send: { - amount, - contract, - msg, - }, - }, - fee, - memo, - funds, - ) - } - increaseAllowance = async ( - { - amount, - expires, - spender, - }: { - amount: Uint128 - expires?: Expiration - spender: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - increase_allowance: { - amount, - expires, - spender, - }, - }, - fee, - memo, - funds, - ) - } - decreaseAllowance = async ( - { - amount, - expires, - spender, - }: { - amount: Uint128 - expires?: Expiration - spender: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - decrease_allowance: { - amount, - expires, - spender, - }, - }, - fee, - memo, - funds, - ) - } - transferFrom = async ( - { - amount, - owner, - recipient, - }: { - amount: Uint128 - owner: string - recipient: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - transfer_from: { - amount, - owner, - recipient, - }, - }, - fee, - memo, - funds, - ) - } - sendFrom = async ( - { - amount, - contract, - msg, - owner, - }: { - amount: Uint128 - contract: string - msg: Binary - owner: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - send_from: { - amount, - contract, - msg, - owner, - }, - }, - fee, - memo, - funds, - ) - } - burnFrom = async ( - { - amount, - owner, - }: { - amount: Uint128 - owner: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - burn_from: { - amount, - owner, - }, - }, - fee, - memo, - funds, - ) - } - clearCache = async ( - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - clear_cache: {}, - }, - fee, - memo, - funds, - ) - } -} diff --git a/smart-contracts/qmonitor/src/contracts/BasicVault.types.ts b/smart-contracts/qmonitor/src/contracts/BasicVault.types.ts deleted file mode 100644 index 5e4eeb0d7..000000000 --- a/smart-contracts/qmonitor/src/contracts/BasicVault.types.ts +++ /dev/null @@ -1,270 +0,0 @@ -/** -* This file was automatically generated by @cosmwasm/ts-codegen@0.24.0. -* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, -* and run the @cosmwasm/ts-codegen generate command to regenerate this file. -*/ - -export type ExecuteMsg = { - bond: { - recipient?: string | null; - }; -} | { - unbond: { - amount?: Uint128 | null; - }; -} | { - claim: {}; -} | { - bond_response: BondResponse; -} | { - start_unbond_response: StartUnbondResponse; -} | { - unbond_response: UnbondResponse; -} | { - transfer: { - amount: Uint128; - recipient: string; - }; -} | { - burn: { - amount: Uint128; - }; -} | { - send: { - amount: Uint128; - contract: string; - msg: Binary; - }; -} | { - increase_allowance: { - amount: Uint128; - expires?: Expiration | null; - spender: string; - }; -} | { - decrease_allowance: { - amount: Uint128; - expires?: Expiration | null; - spender: string; - }; -} | { - transfer_from: { - amount: Uint128; - owner: string; - recipient: string; - }; -} | { - send_from: { - amount: Uint128; - contract: string; - msg: Binary; - owner: string; - }; -} | { - burn_from: { - amount: Uint128; - owner: string; - }; -} | { - clear_cache: {}; -}; -export type Uint128 = string; -export type Timestamp = Uint64; -export type Uint64 = string; -export type Binary = string; -export type Expiration = { - at_height: number; -} | { - at_time: Timestamp; -} | { - never: {}; -}; -export interface BondResponse { - bond_id: string; - share_amount: Uint128; - [k: string]: unknown; -} -export interface StartUnbondResponse { - unbond_id: string; - unlock_time: Timestamp; - [k: string]: unknown; -} -export interface UnbondResponse { - unbond_id: string; - [k: string]: unknown; -} -export type PrimitiveInitMsg = { - l_p: InstantiateMsg; -}; -export type Decimal = string; -export type AssetInfoBaseForAddr = { - native: string; -} | { - cw20: Addr; -}; -export type Addr = string; -export interface InstantiateMsg { - base_denom: string; - expected_connection: string; - local_denom: string; - lock_period: number; - pool_denom: string; - pool_id: number; - quote_denom: string; - return_source_channel: string; - transfer_channel: string; -} -export interface PrimitiveConfig { - address: string; - init: PrimitiveInitMsg; - weight: Decimal; -} -export interface InstantiateMsg1 { - base_denom: string; - expected_connection: string; - local_denom: string; - lock_period: number; - pool_denom: string; - pool_id: number; - quote_denom: string; - return_source_channel: string; - transfer_channel: string; -} -export interface DistributionSchedule { - amount: Uint128; - end: number; - start: number; -} -export type QueryMsg = { - claims: { - address: string; - }; -} | { - get_cap: {}; -} | { - investment: {}; -} | { - deposit_ratio: { - funds: Coin[]; - }; -} | { - pending_bonds: { - address: string; - }; -} | { - get_tvl_info: {}; -} | { - pending_unbonds: { - address: string; - }; -} | { - get_debug: {}; -} | { - balance: { - address: string; - }; -} | { - token_info: {}; -} | { - additional_token_info: {}; -} | { - allowance: { - owner: string; - spender: string; - }; -}; -export interface Coin { - amount: Uint128; - denom: string; - [k: string]: unknown; -} -export interface VaultTokenInfoResponse { - creation_time: Timestamp; - decimals: number; - name: string; - symbol: string; - thesis: string; - total_supply: Uint128; -} -export interface AllowanceResponse { - allowance: Uint128; - expires: Expiration; - [k: string]: unknown; -} -export interface BalanceResponse { - balance: Uint128; -} -export interface ClaimsResponse { - claims: Claim[]; -} -export interface Claim { - amount: Uint128; - release_at: Expiration; -} -export interface DepositRatioResponse { - primitive_funding_amounts: Coin[]; - remainder: Coin[]; -} -export interface GetCapResponse { - cap: Cap; -} -export interface Cap { - cap_admin: Addr; - current: Uint128; - total: Uint128; -} -export interface GetDebugResponse { - debug: string; -} -export interface TvlInfoResponse { - primitives: PrimitiveInfo[]; -} -export interface PrimitiveInfo { - base_denom: string; - ica_address: string; - lp_denom: string; - lp_shares: LpCache; - quote_denom: string; -} -export interface LpCache { - d_unlocked_shares: Uint128; - locked_shares: Uint128; - w_unlocked_shares: Uint128; - [k: string]: unknown; -} -export interface InvestmentResponse { - info: InvestmentInfo; -} -export interface InvestmentInfo { - min_withdrawal: Uint128; - owner: Addr; - primitives: PrimitiveConfig[]; -} -export interface PendingBondsResponse { - pending_bond_ids: string[]; - pending_bonds: BondingStub[]; -} -export interface BondingStub { - address: string; - bond_response?: BondResponse | null; -} -export interface PendingUnbondsResponse { - pending_unbond_ids: string[]; - pending_unbonds: Unbond[]; -} -export interface Unbond { - shares: Uint128; - stub: UnbondingStub[]; -} -export interface UnbondingStub { - address: string; - unbond_funds: Coin[]; - unbond_response?: UnbondResponse | null; - unlock_time?: Timestamp | null; -} -export interface TokenInfoResponse { - decimals: number; - name: string; - symbol: string; - total_supply: Uint128; -} \ No newline at end of file diff --git a/smart-contracts/qmonitor/src/contracts/LpStrategy.client.ts b/smart-contracts/qmonitor/src/contracts/LpStrategy.client.ts deleted file mode 100644 index bd47cd436..000000000 --- a/smart-contracts/qmonitor/src/contracts/LpStrategy.client.ts +++ /dev/null @@ -1,634 +0,0 @@ -/** - * This file was automatically generated by @cosmwasm/ts-codegen@0.24.0. - * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, - * and run the @cosmwasm/ts-codegen generate command to regenerate this file. - */ - -import { - CosmWasmClient, - SigningCosmWasmClient, - ExecuteResult, -} from '@cosmjs/cosmwasm-stargate' -import { StdFee } from '@cosmjs/amino' -import { - ExecuteMsg, - Uint128, - Binary, - Timestamp, - Uint64, - UnlockOnly, - IbcPacketAckMsg, - IbcAcknowledgement, - IbcPacket, - IbcEndpoint, - IbcTimeout, - IbcTimeoutBlock, - InstantiateMsg, - QueryMsg, - Addr, - ChannelType, - Encoding, - TxType, - Version, - HandshakeState, - ChannelsResponse, - ChannelInfo, - IcaMetadata, - ConfigResponse, - Config, - GetQueuesResponse, - Bond, - StartUnbond, - Unbond, - IcaAddressResponse, - IcaBalanceResponse, - Coin, - IcaChannelResponse, - ListBondingClaimsResponse, - IbcMsgKind, - RawAmount, - IcaMessages, - FundPath, - ListPendingAcksResponse, - PendingBond, - OngoingDeposit, - PendingSingleUnbond, - PendingReturningUnbonds, - ReturningUnbond, - PendingReturningRecovery, - ReturningRecovery, - ListPrimitiveSharesResponse, - SubMsgKind, - ContractCallback, - Callback, - BankMsg, - ListRepliesResponse, - BondResponse, - StartUnbondResponse, - UnbondResponse, - ListUnbondingClaimsResponse, - IbcLock, - LockResponse, - Lock, - LpSharesResponse, - LpCache, - OsmoLockResponse, - PrimitiveSharesResponse, - SimulatedJoinResponse, - TrappedErrorsResponse, - Trap, - UnbondingClaimResponse, -} from './LpStrategy.types' -export interface LpStrategyReadOnlyInterface { - contractAddress: string - channels: () => Promise - config: () => Promise - icaAddress: () => Promise - lock: () => Promise - lpShares: () => Promise - primitiveShares: () => Promise - icaBalance: () => Promise - icaChannel: () => Promise - trappedErrors: () => Promise - unbondingClaim: ({ - addr, - id, - }: { - addr: Addr - id: string - }) => Promise - listUnbondingClaims: () => Promise - listBondingClaims: () => Promise - listPrimitiveShares: () => Promise - listPendingAcks: () => Promise - listReplies: () => Promise - osmoLock: () => Promise - simulatedJoin: () => Promise - getQueues: () => Promise -} -export class LpStrategyQueryClient implements LpStrategyReadOnlyInterface { - client: CosmWasmClient - contractAddress: string - - constructor(client: CosmWasmClient, contractAddress: string) { - this.client = client - this.contractAddress = contractAddress - this.channels = this.channels.bind(this) - this.config = this.config.bind(this) - this.icaAddress = this.icaAddress.bind(this) - this.lock = this.lock.bind(this) - this.lpShares = this.lpShares.bind(this) - this.primitiveShares = this.primitiveShares.bind(this) - this.icaBalance = this.icaBalance.bind(this) - this.icaChannel = this.icaChannel.bind(this) - this.trappedErrors = this.trappedErrors.bind(this) - this.unbondingClaim = this.unbondingClaim.bind(this) - this.listUnbondingClaims = this.listUnbondingClaims.bind(this) - this.listBondingClaims = this.listBondingClaims.bind(this) - this.listPrimitiveShares = this.listPrimitiveShares.bind(this) - this.listPendingAcks = this.listPendingAcks.bind(this) - this.listReplies = this.listReplies.bind(this) - this.osmoLock = this.osmoLock.bind(this) - this.simulatedJoin = this.simulatedJoin.bind(this) - this.getQueues = this.getQueues.bind(this) - } - - channels = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - channels: {}, - }) - } - config = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - config: {}, - }) - } - icaAddress = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - ica_address: {}, - }) - } - lock = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - lock: {}, - }) - } - lpShares = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - lp_shares: {}, - }) - } - primitiveShares = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - primitive_shares: {}, - }) - } - icaBalance = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - ica_balance: {}, - }) - } - icaChannel = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - ica_channel: {}, - }) - } - trappedErrors = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - trapped_errors: {}, - }) - } - unbondingClaim = async ({ - addr, - id, - }: { - addr: Addr - id: string - }): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - unbonding_claim: { - addr, - id, - }, - }) - } - listUnbondingClaims = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - list_unbonding_claims: {}, - }) - } - listBondingClaims = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - list_bonding_claims: {}, - }) - } - listPrimitiveShares = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - list_primitive_shares: {}, - }) - } - listPendingAcks = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - list_pending_acks: {}, - }) - } - listReplies = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - list_replies: {}, - }) - } - osmoLock = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - osmo_lock: {}, - }) - } - simulatedJoin = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - simulated_join: {}, - }) - } - getQueues = async (): Promise => { - return this.client.queryContractSmart(this.contractAddress, { - get_queues: {}, - }) - } -} -export interface LpStrategyInterface extends LpStrategyReadOnlyInterface { - contractAddress: string - sender: string - bond: ( - { - id, - }: { - id: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - startUnbond: ( - { - id, - shareAmount, - }: { - id: string - shareAmount: Uint128 - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - unbond: ( - { - id, - }: { - id: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - setDepositor: ( - { - depositor, - }: { - depositor: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - acceptReturningFunds: ( - { - id, - }: { - id: number - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - closeChannel: ( - { - channelId, - }: { - channelId: string - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - returnTransfer: ( - { - amount, - }: { - amount: Uint128 - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - ack: ( - { - ack, - }: { - ack: IbcPacketAckMsg - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - tryIcq: ( - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - unlock: ( - { - unlockOnly, - }: { - unlockOnly: UnlockOnly - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise - manualTimeout: ( - { - channel, - seq, - shouldUnlock, - }: { - channel: string - seq: number - shouldUnlock: boolean - }, - fee?: number | StdFee | 'auto', - memo?: string, - funds?: Coin[], - ) => Promise -} -export class LpStrategyClient extends LpStrategyQueryClient - implements LpStrategyInterface { - client: SigningCosmWasmClient - sender: string - contractAddress: string - - constructor( - client: SigningCosmWasmClient, - sender: string, - contractAddress: string, - ) { - super(client, contractAddress) - this.client = client - this.sender = sender - this.contractAddress = contractAddress - this.bond = this.bond.bind(this) - this.startUnbond = this.startUnbond.bind(this) - this.unbond = this.unbond.bind(this) - this.setDepositor = this.setDepositor.bind(this) - this.acceptReturningFunds = this.acceptReturningFunds.bind(this) - this.closeChannel = this.closeChannel.bind(this) - this.returnTransfer = this.returnTransfer.bind(this) - this.ack = this.ack.bind(this) - this.tryIcq = this.tryIcq.bind(this) - this.unlock = this.unlock.bind(this) - this.manualTimeout = this.manualTimeout.bind(this) - } - - bond = async ( - { - id, - }: { - id: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - bond: { - id, - }, - }, - fee, - memo, - funds, - ) - } - startUnbond = async ( - { - id, - shareAmount, - }: { - id: string - shareAmount: Uint128 - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - start_unbond: { - id, - share_amount: shareAmount, - }, - }, - fee, - memo, - funds, - ) - } - unbond = async ( - { - id, - }: { - id: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - unbond: { - id, - }, - }, - fee, - memo, - funds, - ) - } - setDepositor = async ( - { - depositor, - }: { - depositor: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - set_depositor: { - depositor, - }, - }, - fee, - memo, - funds, - ) - } - acceptReturningFunds = async ( - { - id, - }: { - id: number - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - accept_returning_funds: { - id, - }, - }, - fee, - memo, - funds, - ) - } - closeChannel = async ( - { - channelId, - }: { - channelId: string - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - close_channel: { - channel_id: channelId, - }, - }, - fee, - memo, - funds, - ) - } - returnTransfer = async ( - { - amount, - }: { - amount: Uint128 - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - return_transfer: { - amount, - }, - }, - fee, - memo, - funds, - ) - } - ack = async ( - { - ack, - }: { - ack: IbcPacketAckMsg - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - ack: { - ack, - }, - }, - fee, - memo, - funds, - ) - } - tryIcq = async ( - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - try_icq: {}, - }, - fee, - memo, - funds, - ) - } - unlock = async ( - { - unlockOnly, - }: { - unlockOnly: UnlockOnly - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - unlock: { - unlock_only: unlockOnly, - }, - }, - fee, - memo, - funds, - ) - } - manualTimeout = async ( - { - channel, - seq, - shouldUnlock, - }: { - channel: string - seq: number - shouldUnlock: boolean - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: Coin[], - ): Promise => { - return await this.client.execute( - this.sender, - this.contractAddress, - { - manual_timeout: { - channel, - seq, - should_unlock: shouldUnlock, - }, - }, - fee, - memo, - funds, - ) - } -} diff --git a/smart-contracts/qmonitor/src/contracts/LpStrategy.types.ts b/smart-contracts/qmonitor/src/contracts/LpStrategy.types.ts deleted file mode 100644 index 9669dffac..000000000 --- a/smart-contracts/qmonitor/src/contracts/LpStrategy.types.ts +++ /dev/null @@ -1,438 +0,0 @@ -/** -* This file was automatically generated by @cosmwasm/ts-codegen@0.24.0. -* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, -* and run the @cosmwasm/ts-codegen generate command to regenerate this file. -*/ - -export type ExecuteMsg = { - bond: { - id: string; - }; -} | { - start_unbond: { - id: string; - share_amount: Uint128; - }; -} | { - unbond: { - id: string; - }; -} | { - set_depositor: { - depositor: string; - }; -} | { - accept_returning_funds: { - id: number; - }; -} | { - close_channel: { - channel_id: string; - }; -} | { - return_transfer: { - amount: Uint128; - }; -} | { - ack: { - ack: IbcPacketAckMsg; - }; -} | { - try_icq: {}; -} | { - unlock: { - unlock_only: UnlockOnly; - }; -} | { - manual_timeout: { - channel: string; - seq: number; - should_unlock: boolean; - }; -}; -export type Uint128 = string; -export type Binary = string; -export type Timestamp = Uint64; -export type Uint64 = string; -export type UnlockOnly = "bond" | "start_unbond" | "unbond"; -export interface IbcPacketAckMsg { - acknowledgement: IbcAcknowledgement; - original_packet: IbcPacket; - [k: string]: unknown; -} -export interface IbcAcknowledgement { - data: Binary; - [k: string]: unknown; -} -export interface IbcPacket { - data: Binary; - dest: IbcEndpoint; - sequence: number; - src: IbcEndpoint; - timeout: IbcTimeout; - [k: string]: unknown; -} -export interface IbcEndpoint { - channel_id: string; - port_id: string; - [k: string]: unknown; -} -export interface IbcTimeout { - block?: IbcTimeoutBlock | null; - timestamp?: Timestamp | null; - [k: string]: unknown; -} -export interface IbcTimeoutBlock { - height: number; - revision: number; - [k: string]: unknown; -} -export interface InstantiateMsg { - base_denom: string; - expected_connection: string; - local_denom: string; - lock_period: number; - pool_denom: string; - pool_id: number; - quote_denom: string; - return_source_channel: string; - transfer_channel: string; -} -export type QueryMsg = { - channels: {}; -} | { - config: {}; -} | { - ica_address: {}; -} | { - lock: {}; -} | { - lp_shares: {}; -} | { - primitive_shares: {}; -} | { - ica_balance: {}; -} | { - ica_channel: {}; -} | { - trapped_errors: {}; -} | { - unbonding_claim: { - addr: Addr; - id: string; - }; -} | { - list_unbonding_claims: {}; -} | { - list_bonding_claims: {}; -} | { - list_primitive_shares: {}; -} | { - list_pending_acks: {}; -} | { - list_replies: {}; -} | { - osmo_lock: {}; -} | { - simulated_join: {}; -} | { - get_queues: {}; -}; -export type Addr = string; -export type ChannelType = { - icq: { - channel_ty: string; - [k: string]: unknown; - }; -} | { - ica: { - channel_ty: IcaMetadata; - counter_party_address?: string | null; - [k: string]: unknown; - }; -} | { - ics20: { - channel_ty: string; - [k: string]: unknown; - }; -}; -export type Encoding = "proto3"; -export type TxType = "sdk_multi_msg"; -export type Version = "ics27-1"; -export type HandshakeState = "init" | "try_open" | "open" | "closed"; -export interface ChannelsResponse { - channels: ChannelInfo[]; -} -export interface ChannelInfo { - channel_type: ChannelType; - connection_id: string; - counterparty_endpoint: IbcEndpoint; - handshake_state: HandshakeState; - id: string; - [k: string]: unknown; -} -export interface IcaMetadata { - controller_connection_id?: string | null; - encoding: Encoding; - host_connection_id?: string | null; - tx_type: TxType; - version: Version; - [k: string]: unknown; -} -export interface ConfigResponse { - config: Config; -} -export interface Config { - base_denom: string; - expected_connection: string; - local_denom: string; - lock_period: number; - pool_denom: string; - pool_id: number; - quote_denom: string; - return_source_channel: string; - transfer_channel: string; - [k: string]: unknown; -} -export interface GetQueuesResponse { - bond_queue: Bond[]; - pending_bond_queue: Bond[]; - start_unbond_queue: StartUnbond[]; - unbond_queue: Unbond[]; -} -export interface Bond { - amount: Uint128; - bond_id: string; - owner: Addr; - [k: string]: unknown; -} -export interface StartUnbond { - id: string; - owner: Addr; - primitive_shares: Uint128; - [k: string]: unknown; -} -export interface Unbond { - attempted: boolean; - id: string; - lp_shares: Uint128; - owner: Addr; - unlock_time: Timestamp; - [k: string]: unknown; -} -export interface IcaAddressResponse { - address: string; -} -export interface IcaBalanceResponse { - amount: Coin; -} -export interface Coin { - amount: Uint128; - denom: string; - [k: string]: unknown; -} -export interface IcaChannelResponse { - channel: string; -} -export interface ListBondingClaimsResponse { - bonds: { - [k: string]: [string, Uint128]; - }; -} -export type IbcMsgKind = "icq" | { - transfer: { - amount: Uint128; - pending: PendingBond; - [k: string]: unknown; - }; -} | { - ica: IcaMessages; -}; -export type RawAmount = { - local_denom: Uint128; -} | { - lp_shares: Uint128; -}; -export type IcaMessages = { - join_swap_extern_amount_in: PendingBond; -} | { - lock_tokens: [PendingBond, Uint128]; -} | { - begin_unlocking: [PendingSingleUnbond[], Uint128]; -} | { - exit_pool: PendingReturningUnbonds; -} | { - return_transfer: PendingReturningUnbonds; -} | { - recovery_exit_pool: PendingReturningRecovery; -} | { - recovery_return_transfer: PendingReturningRecovery; -}; -export type FundPath = { - bond: { - id: string; - [k: string]: unknown; - }; -} | { - unbond: { - id: string; - [k: string]: unknown; - }; -}; -export interface ListPendingAcksResponse { - pending: { - [k: string]: IbcMsgKind; - }; -} -export interface PendingBond { - bonds: OngoingDeposit[]; - [k: string]: unknown; -} -export interface OngoingDeposit { - bond_id: string; - claim_amount: Uint128; - owner: Addr; - raw_amount: RawAmount; - [k: string]: unknown; -} -export interface PendingSingleUnbond { - id: string; - lp_shares: Uint128; - owner: Addr; - primitive_shares: Uint128; - [k: string]: unknown; -} -export interface PendingReturningUnbonds { - unbonds: ReturningUnbond[]; - [k: string]: unknown; -} -export interface ReturningUnbond { - amount: RawAmount; - id: string; - owner: Addr; - [k: string]: unknown; -} -export interface PendingReturningRecovery { - returning: ReturningRecovery[]; - trapped_id: number; - [k: string]: unknown; -} -export interface ReturningRecovery { - amount: RawAmount; - id: FundPath; - owner: Addr; - [k: string]: unknown; -} -export interface ListPrimitiveSharesResponse { - shares: { - [k: string]: Uint128; - }; -} -export type SubMsgKind = { - ibc: [IbcMsgKind, string]; -} | { - ack: [number, string]; -} | { - callback: ContractCallback; -}; -export type ContractCallback = { - callback: { - amount?: Uint128 | null; - callback: Callback; - owner: Addr; - [k: string]: unknown; - }; -} | { - bank: { - bank_msg: BankMsg; - unbond_id: string; - [k: string]: unknown; - }; -}; -export type Callback = { - bond_response: BondResponse; -} | { - start_unbond_response: StartUnbondResponse; -} | { - unbond_response: UnbondResponse; -}; -export type BankMsg = { - send: { - amount: Coin[]; - to_address: string; - [k: string]: unknown; - }; -} | { - burn: { - amount: Coin[]; - [k: string]: unknown; - }; -}; -export interface ListRepliesResponse { - replies: { - [k: string]: SubMsgKind; - }; -} -export interface BondResponse { - bond_id: string; - share_amount: Uint128; - [k: string]: unknown; -} -export interface StartUnbondResponse { - unbond_id: string; - unlock_time: Timestamp; - [k: string]: unknown; -} -export interface UnbondResponse { - unbond_id: string; - [k: string]: unknown; -} -export interface ListUnbondingClaimsResponse { - unbonds: { - [k: string]: [string, Unbond]; - }; -} -export type IbcLock = "locked" | "unlocked"; -export interface LockResponse { - lock: Lock; -} -export interface Lock { - bond: IbcLock; - recovery: IbcLock; - start_unbond: IbcLock; - unbond: IbcLock; - [k: string]: unknown; -} -export interface LpSharesResponse { - lp_shares: LpCache; -} -export interface LpCache { - d_unlocked_shares: Uint128; - locked_shares: Uint128; - w_unlocked_shares: Uint128; - [k: string]: unknown; -} -export interface OsmoLockResponse { - lock_id: number; -} -export interface PrimitiveSharesResponse { - total: Uint128; -} -export interface SimulatedJoinResponse { - amount?: Uint128 | null; - result?: Uint128 | null; -} -export interface TrappedErrorsResponse { - errors: { - [k: string]: Trap; - }; -} -export interface Trap { - error: string; - last_succesful: boolean; - step: IbcMsgKind; - [k: string]: unknown; -} -export interface UnbondingClaimResponse { - unbond?: Unbond | null; -} \ No newline at end of file diff --git a/smart-contracts/qmonitor/src/index.ts b/smart-contracts/qmonitor/src/index.ts deleted file mode 100644 index a4748b8e3..000000000 --- a/smart-contracts/qmonitor/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ - -require('./root.tsx') diff --git a/smart-contracts/qmonitor/src/partials/Debug.tsx b/smart-contracts/qmonitor/src/partials/Debug.tsx deleted file mode 100644 index 3d97716c7..000000000 --- a/smart-contracts/qmonitor/src/partials/Debug.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useAppContext } from '../context/ScreenContext' - -const Debug = ({}) => { - const { width, height } = useAppContext() - - return ( - - {`width: ${width} height: ${height}`} - - ) -} - -export default Debug diff --git a/smart-contracts/qmonitor/src/partials/InfoWindow.tsx b/smart-contracts/qmonitor/src/partials/InfoWindow.tsx deleted file mode 100644 index c1f0ab2d0..000000000 --- a/smart-contracts/qmonitor/src/partials/InfoWindow.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { useEffect, useState } from 'react' -import Querier from '../chain/Querier' -import { QUASAR_RPC_NODE } from '../utils/config' -import { useAppContext } from '../context/ScreenContext' -import { TPosition } from '../utils/types' -import VaultInfoWindow from './InfoWindow/VaultInfoWindow' -import PrimitiveInfoWindow from './InfoWindow/PrimitiveInfoWindow' - -const InfoWindow = ({ height }: { height: TPosition }) => { - const { tab, investmentInfo } = useAppContext() - - return ( - <> - {!tab.startsWith('prim') ? ( - - ) : ( - - )} - - ) -} - -export default InfoWindow diff --git a/smart-contracts/qmonitor/src/partials/InfoWindow/PrimitiveInfoWindow.tsx b/smart-contracts/qmonitor/src/partials/InfoWindow/PrimitiveInfoWindow.tsx deleted file mode 100644 index 9aa14334f..000000000 --- a/smart-contracts/qmonitor/src/partials/InfoWindow/PrimitiveInfoWindow.tsx +++ /dev/null @@ -1,190 +0,0 @@ -import { useEffect, useState } from 'react' -import Querier from '../../chain/Querier' -import { QUASAR_RPC_NODE } from '../../utils/config' -import { useAppContext } from '../../context/ScreenContext' -import { TPosition } from '../../utils/types' -import { assert } from 'console' -import { InstantiateMsg } from '../../contracts/BasicVault.types' -import { OsmosisClient } from '../../chain/Osmosis' -import chalk = require('chalk') -import { QuasarClient } from '../../chain/Quasar' - -const PrimitiveInfoWindow = ({ height }: { height: TPosition }) => { - const { tab, investmentInfo } = useAppContext() - - const [lockStatus, setLockStatus] = useState('loading...') - const [pendingAcks, setPendingAcks] = useState('loading...') - const [trappedErrors, setTrappedErrors] = useState('loading...') - const [quasarBalance, setQuasarBalance] = useState('loading...') - const [osmoAddress, setOsmoAddress] = useState('loading...') - const [osmoBalance, setOsmoBalance] = useState('loading...') - const [osmoLockedShares, setOsmoLockedShares] = useState('loading...') - - let pidx = Number.parseInt(tab.split('_')[1]) - - assert(pidx >= 0) - - if (!investmentInfo) { - throw new Error('investmentInfo is not loaded') - } - - async function loadIcaAddress() { - let querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - let icaAddress = await querier.getPrimitiveIcaAddress( - investmentInfo!.primitives[pidx].address, - ) - setOsmoAddress(icaAddress.address) - } - - async function loadOsmoBalance() { - let querier = await OsmosisClient.getInstance() - let balance = await querier.getBalances(osmoAddress) - setOsmoBalance(balance.balances.map((b) => b.amount + b.denom).join(', ')) - } - - async function loadOsmoLockedShares() { - let querier = await OsmosisClient.getInstance() - let lockedShares = await querier.getLockedShares(osmoAddress) - setOsmoLockedShares( - lockedShares.coins.map((b) => b.amount + b.denom).join(', '), - ) - } - - async function loadQuasarBalances() { - let querier = await QuasarClient.getInstance() - let balances = await querier.getBalances( - investmentInfo!.primitives[pidx].address, - ) - - setQuasarBalance(balances.map((b) => b.amount + b.denom).join(', ')) - } - - async function loadLockedStatus() { - let querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - let status = await querier.getPrimitiveLockStatus( - investmentInfo!.primitives[pidx].address, - ) - let lockType = Object.keys(status.lock).find( - (l) => status.lock[l] === 'locked', - ) - setLockStatus( - lockType ? chalk.red(`locked (${lockType})`) : chalk.green('unlocked'), - ) - } - - async function loadPendingAcks() { - let querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - let pendingAcks = await querier.getPrimitivePendingAcks( - investmentInfo!.primitives[pidx].address, - ) - setPendingAcks(Object.keys(pendingAcks.pending).length.toString()) - } - - async function loadTrappedErrors() { - let querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - let trappedErrors = await querier.getPrimitiveTrappedErrors( - investmentInfo!.primitives[pidx].address, - ) - setTrappedErrors(Object.keys(trappedErrors.errors).length.toString()) - } - - function pollPrimitiveState() { - let interval = setInterval(() => { - loadLockedStatus() - loadPendingAcks() - loadTrappedErrors() - }, 5000) - - return () => { - clearInterval(interval) - } - } - - useEffect(() => { - // reset state when tab changes - setLockStatus('loading...') - setPendingAcks('loading...') - setTrappedErrors('loading...') - setQuasarBalance('loading...') - setOsmoAddress('loading...') - setOsmoBalance('loading...') - setOsmoLockedShares('loading...') - - return pollPrimitiveState() - }, [tab]) - - async function loadOsmoDetails() { - try { - await loadOsmoBalance() - await loadOsmoLockedShares() - await loadQuasarBalances() - } catch (e) { - console.error('OOF:', osmoAddress, e) - } - } - - useEffect(() => { - loadIcaAddress() - .then(() => OsmosisClient.getInstance()) - .catch((e) => { - console.error(e) - }) - if (osmoAddress === 'loading...') return - loadOsmoDetails() - }, [osmoAddress, tab]) - - return ( - - - {`qsr address: ${investmentInfo.primitives[pidx].address}`} - - - {`weight in vault: ${investmentInfo.primitives[pidx].weight}`} - - - - {`osmo address: ${osmoAddress}`} - - - {`osmo balance: ${osmoBalance}`} - - - {`osmo locked shares: ${osmoLockedShares}`} - - - {`quasar balance: ${quasarBalance}`} - - - - {`lock status: ${lockStatus}`} - - - {`pending acks: ${pendingAcks}`} - - - {`trapped errors: ${trappedErrors}`} - - - {Object.keys(investmentInfo.primitives[pidx].init.l_p).map((k, i) => { - return ( - - {`${k}: ${ - investmentInfo.primitives[pidx].init.l_p[ - k as keyof InstantiateMsg - ] - }`} - - ) - })} - - ) -} - -export default PrimitiveInfoWindow diff --git a/smart-contracts/qmonitor/src/partials/InfoWindow/VaultInfoWindow.tsx b/smart-contracts/qmonitor/src/partials/InfoWindow/VaultInfoWindow.tsx deleted file mode 100644 index 4d9fa9ded..000000000 --- a/smart-contracts/qmonitor/src/partials/InfoWindow/VaultInfoWindow.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { useEffect, useState } from 'react' -import Querier from '../../chain/Querier' -import { QUASAR_RPC_NODE } from '../../utils/config' -import { useAppContext } from '../../context/ScreenContext' -import { TPosition } from '../../utils/types' - -const VaultInfoWindow = ({ height }: { height: TPosition }) => { - const { tab, investmentInfo } = useAppContext() - - const [cap, setCap] = useState('loading...') - const [totalCap, setTotalCap] = useState('loading...') - const [capAdmin, setCapAdmin] = useState('loading...') - const [name, setName] = useState('loading...') - const [symbol, setSymbol] = useState('loading...') - const [decimals, setDecimals] = useState('loading...') - const [totalSupply, setTotalSupply] = useState('loading...') - - async function loadCap() { - let querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - let vcap = await querier.getVaultCap() - setCap(vcap.cap.current) - setTotalCap(vcap.cap.total) - setCapAdmin(vcap.cap.cap_admin) - } - - async function loadTokenInfo() { - let querier = await Querier.getInstance(QUASAR_RPC_NODE, 'quasar-1') - let tokenInfo = await querier.getVaultTokenInfo() - setName(tokenInfo.name) - setSymbol(tokenInfo.symbol) - setDecimals(tokenInfo.decimals.toString()) - setTotalSupply(tokenInfo.total_supply) - } - - useEffect(() => { - loadCap() - // idk why but it works like this only: - setTimeout(() => loadTokenInfo(), 700) - }, []) - - return ( - - - {`current cap: ${cap}`} - - - {`cap limit: ${totalCap}`} - - - {`cap admin: ${capAdmin}`} - - - - {`name: ${name}`} - - - {`symbol: ${symbol}`} - - - {`decimals: ${decimals}`} - - - {`total supply: ${totalSupply}`} - - - ) -} - -export default VaultInfoWindow diff --git a/smart-contracts/qmonitor/src/partials/Logs.tsx b/smart-contracts/qmonitor/src/partials/Logs.tsx deleted file mode 100644 index 225dafddf..000000000 --- a/smart-contracts/qmonitor/src/partials/Logs.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import * as chalk from 'chalk' -import { ChildProcessWithoutNullStreams, spawn } from 'child_process' -import { useEffect, useRef, useState } from 'react' -import { SpawnCommand, useAppContext } from '../context/ScreenContext' -import { saveCommandToHistory } from '../utils/fileUtils' -import { TPosition } from '../utils/types' - -let currentCommandOutput = '' - -let outs: { - [key: string]: ChildProcessWithoutNullStreams -} = {} -function hashCommand (cmd: SpawnCommand) { - return `${cmd.command}${cmd.args.join('')}${cmd.cwd}` -} -function spawnOrGetFunction (cmd: SpawnCommand) { - saveCommandToHistory(JSON.stringify(cmd, null, 2)) - - const hash = hashCommand(cmd) - if (outs[hash]) return outs[hash] - outs[hash] = spawn(cmd.command, cmd.args, { - cwd: cmd.cwd, - env: { - ...process.env, - ...cmd.env - } - }) - return outs[hash] -} - -const Logs = ({ height, top }: { height: TPosition; top: TPosition }) => { - const { command, setCommand, logAppendContent, log } = useAppContext() - const [output, setOutput] = useState('') - - const logBoxRef = useRef(null) - - useEffect(() => { - // new command entrypoint - if (command) { - let out = spawnOrGetFunction(command) - - attachListeners(out) - return () => removeListeners(out) - } - }, [command]) - - useEffect(() => { - setOutput(output + logAppendContent) - scrollToBottom() - }, [logAppendContent]) - - function appendHandler (data: any) { - setOutput(output + data.toString()) - currentCommandOutput += data.toString() - scrollToBottom() - } - - function closeHandler () { - const savedOutput = (' ' + currentCommandOutput).slice(1) - // log('here1') - // log(savedOutput) - // log('here2') - setTimeout(() => { - if (command?.callback) command?.callback(savedOutput) - }, 100) - // reset - setCommand(undefined) - currentCommandOutput = '' - if (command) { - const hash = hashCommand(command) - delete outs[hash] - } - } - - function attachListeners (out: any) { - out.stdout.on('data', appendHandler) - out.stderr.on('data', appendHandler) - out.stderr.on('close', closeHandler) - } - - function removeListeners (out: any) { - out.stdout.off('data', appendHandler) - out.stderr.off('data', appendHandler) - out.stderr.off('close', closeHandler) - } - - function scrollToBottom () { - // @ts-ignore - logBoxRef.current?.setScrollPerc(100) - } - - useEffect(() => { - if (command) { - let out = spawnOrGetFunction(command) - attachListeners(out) - return () => removeListeners(out) - } - }, [output]) - - return ( - - {output} - - ) -} - -export default Logs diff --git a/smart-contracts/qmonitor/src/partials/MsgWindow.tsx b/smart-contracts/qmonitor/src/partials/MsgWindow.tsx deleted file mode 100644 index a84652ac6..000000000 --- a/smart-contracts/qmonitor/src/partials/MsgWindow.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import * as fs from 'fs' -import { useEffect, useState } from 'react' -import { useAppContext } from '../context/ScreenContext' -import { getContractDetails } from '../utils/fileUtils' -import { TPosition } from '../utils/types' -import { getCenterColWidth } from '../utils/windowUtils' -import CodeWindow from './MsgWindow/CodeWindow' -import ContractInstanceWindow from './MsgWindow/ContractInstanceWindow' -import ContractWindow from './MsgWindow/ContractWindow' - -const MsgWindow = ({ height }: { height: TPosition }) => { - const { - contract, - setContract, - codeId, - setCodeId, - contractInstanceAddress, - command, - setCommand, - width, - env, - log - } = useAppContext() - const [contractDetails, setContractDetails] = useState<{ - wasm: fs.Stats | null - optimized: fs.Stats | null - }>() - - useEffect(() => { - if (contract) { - try { - setContractDetails(getContractDetails(contract.buildName)) - } catch (e) { - console.log(e) - } - } - }, [contract, command]) - - // const centerColWidth = getCenterColWidth(width as number) - // // const buttonLeft = Math.max(centerColWidth * 0.3, 20) - // const buttonLeft = Math.floor(Math.max(centerColWidth * 0.45, 20)) - - function renderActiveWindow () { - if (contract && !codeId) - return - else if (codeId && !contractInstanceAddress) return - else if (contractInstanceAddress) return - } - - return ( - - {renderActiveWindow()} - - ) -} - -//â”” -export default MsgWindow diff --git a/smart-contracts/qmonitor/src/partials/MsgWindow/CodeWindow.tsx b/smart-contracts/qmonitor/src/partials/MsgWindow/CodeWindow.tsx deleted file mode 100644 index ba8abaa35..000000000 --- a/smart-contracts/qmonitor/src/partials/MsgWindow/CodeWindow.tsx +++ /dev/null @@ -1,348 +0,0 @@ -import * as chalk from 'chalk' -import { useEffect, useRef, useState } from 'react' -import { DetailedBlessedProps, TextareaElement } from 'react-blessed' -import { - ContractMetadata, - CodeMetadata, - useAppContext, - MsgMetadata -} from '../../context/ScreenContext' -import { getEnv } from '../../utils/commandUtils' -import { getActiveCode, getCWD } from '../../utils/fileUtils' - -const CodeWindow = () => { - const { - contract, - setContract, - codeId, - setCodeId, - setContractInstanceAddress, - command, - setCommand, - width, - env, - log - } = useAppContext() - - const [view, setView] = useState<'saved-msgs' | 'new-msg'>( - contract?.initMsgs.length ? 'saved-msgs' : 'new-msg' - ) - const [activeMsg, setActiveMsg] = useState(null) - - const msgTitle = useRef(null) - const input = useRef(null) - const funds = useRef(null) - - const saveInitMsg = () => { - // @ts-ignore - const title = msgTitle.current.getValue() - // @ts-ignore - const msg = input.current.getValue() - // @ts-ignore - const funds = funds.current.getValue() - - log(`saving new msg: ${title}`) - - if (contract && contract.fileName && codeId && env) { - setContract({ - ...contract, - initMsgs: - activeMsg === null - ? [ - ...contract.initMsgs, - { - title, - msg, - funds - } - ] - : contract.initMsgs.map((m, i) => { - if (i === activeMsg) return { title, msg, funds } - return m - }) - }) - - setView('saved-msgs') - setActiveMsg(null) - } else { - log('error saving msg: contract, codeId, or env not set for some reason') - } - } - - const deleteMsg = (i: number) => { - if (contract && contract.fileName && codeId && env) { - setContract({ - ...contract, - initMsgs: contract.initMsgs.filter((_, j) => j !== i) - }) - } else { - log( - 'error deleting msg: contract, codeId, or env not set for some reason' - ) - } - } - - function listContractsByCodeCallback (output: string) { - if (!output) return - log(output) - - const contracts = JSON.parse(output.split('\n')[0]).contracts - const contractAddress = contracts[contracts.length - 1] - - log(chalk.bold(chalk.red('deployed contract address: ' + contractAddress))) - setContract({ - ...contract!, - codes: contract!.codes.map(codeMeta => { - if (codeMeta.codeID === codeId) { - return { - ...codeMeta, - deployedContracts: [ - ...codeMeta.deployedContracts, - { - address: contractAddress, - executeMsgs: [], - queryMsgs: [] - } - ] - } - } - return codeMeta - }) - }) - setContractInstanceAddress(contractAddress) - } - - function initCallback (_output: string) { - if (!_output) return - // log("here23") - // var stack = new Error().stack - // log(stack) - // log(_output) - log('init complete, fetching contract address...') - const envConfig = getEnv(env) - - setCommand({ - command: envConfig.command, - args: [ - 'query', - 'wasm', - 'list-contract-by-code', - codeId, - '--output', - 'json', - '--node', - envConfig.node - ], - cwd: getCWD(), - callback: listContractsByCodeCallback - }) - } - - const sendInitMsg = (i: number) => { - if (contract && contract.fileName && codeId && env) { - const msg = contract.initMsgs[i] - const envConfig = getEnv(env) - const funds = msg.funds - - setCommand({ - command: envConfig.command, - args: [ - 'tx', - 'wasm', - 'instantiate', - codeId, - msg.msg, - '--from', - envConfig.keyName, - '--label', - msg.title, - '--gas-prices', - envConfig.feeAmount + envConfig.feeDenom, - '--gas', - 'auto', - '--gas-adjustment', - '1.3', - '-b', - 'block', - '-y', - '--no-admin', - '--node', - envConfig.node, - '--chain-id', - envConfig.chainId, - ...(funds ? ['--amount', funds] : []) - ], - cwd: getCWD(), - callback: initCallback - }) - } else { - log('error sending msg: contract, codeId, or env not set for some reason') - } - } - - useEffect(() => { - if (msgTitle.current && input.current && funds.current) { - // @ts-ignore - msgTitle.current.setValue(`${contract?.fileName}'s init message`) - // @ts-ignore - msgTitle.current.key(['escape', 'C-c'], () => { - // @ts-ignore - msgTitle.current.cancel() - }) - - // @ts-ignore - funds.current.key(['escape', 'C-c'], () => { - // @ts-ignore - funds.current.cancel() - }) - // @ts-ignore - input.current.key(['escape', 'C-c'], () => { - // @ts-ignore - input.current.cancel() - }) - } - }, []) - - useEffect(() => { - if (activeMsg !== null && view === 'new-msg') { - const msg = contract!.initMsgs[activeMsg] - log(`loading msg ${activeMsg}: ${msg.title}`) - // @ts-ignore - msgTitle.current.setValue(msg.title) - // @ts-ignore - input.current.setValue(msg.msg) - // @ts-ignore - funds.current.setValue(msg.funds) - } - }, [activeMsg, view]) - - return ( - - - {chalk.bold(`Code ID: ${codeId} Init Msg`) + - chalk.gray(' (press esc if stuck)')} - - {view === 'new-msg' ? ( - <> - -