diff --git a/.github/workflows/ci-anchor-test.yml b/.github/workflows/ci-anchor-test.yml index 534505048..55e905098 100644 --- a/.github/workflows/ci-anchor-test.yml +++ b/.github/workflows/ci-anchor-test.yml @@ -2,7 +2,7 @@ name: Anchor Test on: push: - branches: [main, v*.*, acam/soteria-audit*] + branches: [main, v*.*] permissions: contents: read @@ -10,8 +10,8 @@ permissions: env: CARGO_TERM_COLOR: always - SOLANA_VERSION: 1.8.12 - ANCHOR_VERSION: 0.21.0 + SOLANA_VERSION: 1.8.16 + ANCHOR_VERSION: 0.24.2 CLUSTER: "devnet" DEVNET_RPC: https://api.devnet.solana.com # DEVNET_FAUCET: "9B5XszUGdMaxCZ7uSQhPzdks5ZQSmWxrmzCSvtJ6Ns6g" @@ -41,6 +41,7 @@ env: TEST_CI_BTC: "test_ci_btc" TEST_CI_ETH: "test_ci_eth" TEST_CI_REBALANCING: "test_ci_rebalancing" + TEST_CI_QUOTE_MINT_REDEEM: "test_ci_quote_mint_redeem" concurrency: group: environment-${{ github.ref }} @@ -83,25 +84,16 @@ jobs: solana --version solana config set -u d solana config set --url ${{ env.DEVNET_RPC}} - # Install Yarn - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - - name: Yarn Cache - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-modules- - name: Node 14 installation uses: actions/setup-node@v2 with: node-version: "14" - cache: "yarn" - registry-url: 'https://npm.pkg.github.com' - scope: "@UXDProtocol" - always-auth: true + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- # Create Keypair - name: Create Runner keypair and funds it run: | @@ -128,13 +120,9 @@ jobs: ./target/release ./target/bpfel-unknown-unknown key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} - - name: Create NPMRC - run: | - echo "@uxdprotocol:registry=https://npm.pkg.github.com" >> ~/.npmrc - echo "//npm.pkg.github.com/:_authToken=${{ env.NODE_AUTH_TOKEN }}" >> ~/.npmrc - name: Upgrade resident program with latest code run: | - yarn install + npm ci --ignore-scripts ./scripts/swap_ci_resident_program_id.sh npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} build solana program deploy ./target/deploy/uxd.so --program-id ${{ env.RESIDENT_PROGRAM_KEYPAIR }} --upgrade-authority ${{ env.CI_DEPLOYMENT_AUTHORITY_WALLET_PATH }} -v @@ -142,120 +130,6 @@ jobs: run: | solana transfer --keypair ${{ env.RUNNER_WALLET_PATH }} ${{ env.BANK_WALLET_PATH }} $(echo $(solana balance --keypair ${{ env.RUNNER_WALLET_PATH }} | awk '{print $1}') - ${{ env.TRANSACTION_FEE_OFFSET }} | bc) - # This deploy a fresh program and run all tests from test_ci_fresh.ts - # - # anchor-test-mango-depository-integration-fresh: - # name: Anchor Test Deploying a fresh program instance and running light generic tests - # runs-on: ubuntu-latest - # needs: [market-maker-bots] - # steps: - # # Checkout - # - uses: actions/checkout@v2 - # # Install Rust - # - name: Rust toolchain installation - # uses: actions-rs/toolchain@v1 - # with: - # toolchain: nightly - # override: true - # profile: minimal - # # Install solana - # - name: Cache Solana Tool Suite - # uses: actions/cache@v2 - # id: cache-solana - # with: - # path: | - # ~/.cache/solana/ - # ~/.local/share/solana/ - # key: solana-${{ runner.os }}-v0000-${{ env.SOLANA_VERSION }} - # - name: install solana - # if: steps.cache-solana.outputs.cache-hit != 'true' - # run: | - # sudo apt-get update - # sudo apt-get install -y pkg-config build-essential libudev-dev - # sh -c "$(curl -sSfL https://release.solana.com/v${{ env.SOLANA_VERSION }}/install)" - # - name: Add Solana to PATH - # run: echo "/home/runner/.local/share/solana/install/active_release/bin:$PATH" >> $GITHUB_PATH - # - name: Setup solana - # run: | - # solana --version - # solana config set -u d - # solana config set --url ${{ env.DEVNET_RPC}} - # # Install Yarn - # - name: Get yarn cache directory path - # id: yarn-cache-dir-path - # run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - # - name: Yarn Cache - # uses: actions/cache@v2 - # with: - # path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - # key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - # restore-keys: | - # ${{ runner.os }}-modules- - # - name: Node 14 installation - # uses: actions/setup-node@v2 - # with: - # node-version: "14" - # cache: "yarn" - # registry-url: 'https://npm.pkg.github.com' - # scope: "@UXDProtocol" - # always-auth: true - # # Create Keypair - # - name: Create Runner keypair and funds it - # run: | - # solana-keygen new -o ${{ env.RUNNER_WALLET_PATH }} --no-passphrase --silent - # solana transfer --keypair ${{ env.BANK_WALLET_PATH }} $(solana-keygen pubkey ${{ env.RUNNER_WALLET_PATH }}) ${{ env.RUNNER_FUNDING_AMOUNT }} --allow-unfunded-recipient - # solana balance - # # Cargo caching - # - name: Cache Cargo registry + index - # uses: actions/cache@v2 - # id: cache-anchor - # with: - # path: | - # ~/.cargo/bin/ - # ~/.cargo/registry/index/ - # ~/.cargo/registry/cache/ - # ~/.cargo/git/db/ - # key: cargo-${{ runner.os }}-v0000-${{ hashFiles('**/Cargo.lock') }} - # - name: Cache target folder - # uses: actions/cache@v2 - # id: cache-programs - # with: - # path: | - # ./target/debug - # ./target/release - # ./target/bpfel-unknown-unknown - # key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} - # - name: Create NPMRC - # run: | - # echo "@uxdprotocol:registry=https://npm.pkg.github.com" >> ~/.npmrc - # echo "//npm.pkg.github.com/:_authToken=${{ env.NODE_AUTH_TOKEN }}" >> ~/.npmrc - # # Checkout Mango Client - # - name: Checkout MangoClient-v3 - # uses: actions/checkout@v2 - # with: - # repository: blockworks-foundation/mango-client-v3 - # path: /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - # - name: Start Market Making bot for the perp - # run: | - # cd /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - # yarn install - # GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} yarn keeper & - # GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} MANGO_ACCOUNT_PUBKEY=${{ env.MANGO_ACCOUNT_MM_SOL }} MARKET=SOL yarn mm & - # GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} MANGO_ACCOUNT_PUBKEY=${{ env.MANGO_ACCOUNT_MM_BTC }} MARKET=BTC yarn mm & - # GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} MANGO_ACCOUNT_PUBKEY=${{ env.MANGO_ACCOUNT_MM_ETH }} MARKET=ETH yarn mm & - # cd - - # - name: Yarn install + run tests - # run: | - # yarn install - # ./scripts/reset_program_id.sh - # sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_FRESH }}/g" ./Anchor.toml - # npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} test --skip-local-validator - # - name: Close deployed program - # run: solana program close $(solana-keygen pubkey ./target/deploy/uxd-keypair.json) --recipient ${{ env.BANK_WALLET_PATH }} - # - name: Returning funded runner wallet SOLs to the bank - # run: | - # solana transfer --keypair ${{ env.RUNNER_WALLET_PATH }} ${{ env.BANK_WALLET_PATH }} $(echo $(solana balance --keypair ${{ env.RUNNER_WALLET_PATH }} | awk '{print $1}') - ${{ env.TRANSACTION_FEE_OFFSET }} | bc) - anchor-test-mango-depository-SOL: name: Test SOL MangoDepository against the resident program runs-on: ubuntu-latest @@ -292,25 +166,16 @@ jobs: solana --version solana config set -u d solana config set --url ${{ env.DEVNET_RPC}} - # Install Yarn - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - - name: Yarn Cache - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-modules- - name: Node 14 installation uses: actions/setup-node@v2 with: node-version: "14" - cache: "yarn" - registry-url: 'https://npm.pkg.github.com' - scope: "@UXDProtocol" - always-auth: true + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- # Create Keypair - name: Create Runner keypair and funds it run: | @@ -337,28 +202,34 @@ jobs: ./target/release ./target/bpfel-unknown-unknown key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} - - name: Create NPMRC - run: | - echo "@uxdprotocol:registry=https://npm.pkg.github.com" >> ~/.npmrc - echo "//npm.pkg.github.com/:_authToken=${{ env.NODE_AUTH_TOKEN }}" >> ~/.npmrc - # Checkout Mango Client - - name: Checkout MangoClient-v3 - uses: actions/checkout@v2 - with: - repository: blockworks-foundation/mango-client-v3 - path: /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - - name: Start Keeper and Market Making bot for the perp - run: | - cd /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - yarn install - GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} yarn keeper & - GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} MANGO_ACCOUNT_PUBKEY=${{ env.MANGO_ACCOUNT_MM_SOL }} MARKET=SOL yarn mm & - cd - + # # Market Making + # - uses: actions/checkout@v3 + # - name: Set up Python 3.10 + # uses: actions/setup-python@v3 + # with: + # python-version: "3.10" + # - name: Install dependencies and run marketmaker + # run: | + # sudo apt install direnv + # mkdir mmfolder + # cd mmfolder + # python -m venv .venv + # touch .envrc + # echo 'CURRENT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"' > .envrc + # echo -e '\nexport PATH=$CURRENT_DIRECTORY/.venv/bin:$PATH:$CURRENT_DIRECTORY/.venv/lib/python3.9/site-packages/bin' >> .envrc + # direnv allow + # cat .envrc + # python -m pip install --upgrade pip + # touch requirements.txt && echo mango-explorer > requirements.txt + # pip install -r requirements.txt + # mango-explorer-version + # marketmaker --name "UXD-SOL-MM" --market SOL-PERP --oracle-provider pyth --chain ratios --ratios-spread 0.005 --chain ratios --ratios-position-size 0.2 --chain fixedspread --fixedspread-value 0.1 --order-type LIMIT --log-level INFO --cluster-name devnet --account ${{ env.MANGO_ACCOUNT_MM_SOL }} & + # cd - - name: Anchor Test (skip build and deploy) run: | - yarn install + npm ci --ignore-scripts ./scripts/swap_ci_resident_program_id.sh - sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_SOL }}/g" ./Anchor.toml + sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_SOL }}/g" ./Anchor.toml npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} test --skip-local-validator --skip-build --skip-deploy - name: Returning funded runner wallet SOLs to the bank run: | @@ -400,25 +271,16 @@ jobs: solana --version solana config set -u d solana config set --url ${{ env.DEVNET_RPC}} - # Install Yarn - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - - name: Yarn Cache - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-modules- - name: Node 14 installation uses: actions/setup-node@v2 with: node-version: "14" - cache: "yarn" - registry-url: 'https://npm.pkg.github.com' - scope: "@UXDProtocol" - always-auth: true + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- # Create Keypair - name: Create Runner keypair and funds it run: | @@ -445,26 +307,31 @@ jobs: ./target/release ./target/bpfel-unknown-unknown key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} - - name: Create NPMRC - run: | - echo "@uxdprotocol:registry=https://npm.pkg.github.com" >> ~/.npmrc - echo "//npm.pkg.github.com/:_authToken=${{ env.NODE_AUTH_TOKEN }}" >> ~/.npmrc - # Checkout Mango Client - - name: Checkout MangoClient-v3 - uses: actions/checkout@v2 - with: - repository: blockworks-foundation/mango-client-v3 - path: /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - - name: Start Keeper and Market Making bot for the perp - run: | - cd /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - yarn install - GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} yarn keeper & - GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} MANGO_ACCOUNT_PUBKEY=${{ env.MANGO_ACCOUNT_MM_BTC }} MARKET=BTC yarn mm & - cd - + # # Market Making + # - uses: actions/checkout@v3 + # - name: Set up Python 3.10 + # uses: actions/setup-python@v3 + # with: + # python-version: "3.10" + # - name: Install dependencies and run marketmaker + # run: | + # sudo apt install direnv + # mkdir mmfolder + # cd mmfolder + # python -m venv .venv + # touch .envrc + # echo 'CURRENT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"' > .envrc + # echo -e '\nexport PATH=$CURRENT_DIRECTORY/.venv/bin:$PATH:$CURRENT_DIRECTORY/.venv/lib/python3.9/site-packages/bin' >> .envrc + # direnv allow + # python -m pip install --upgrade pip + # touch requirements.txt && echo mango-explorer > requirements.txt + # pip install -r requirements.txt + # mango-explorer-version + # marketmaker --name "UXD-BTC-MM" --market BTC-PERP --oracle-provider pyth --chain ratios --ratios-spread 0.005 --chain ratios --ratios-position-size 0.2 --chain fixedspread --fixedspread-value 0.1 --order-type LIMIT --log-level INFO --cluster-name devnet --account ${{ env.MANGO_ACCOUNT_MM_BTC }} & + # cd - - name: Anchor Test (skip build and deploy) run: | - yarn install + npm ci --ignore-scripts ./scripts/swap_ci_resident_program_id.sh sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_BTC }}/g" ./Anchor.toml npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} test --skip-local-validator --skip-build --skip-deploy @@ -509,25 +376,16 @@ jobs: solana --version solana config set -u d solana config set --url ${{ env.DEVNET_RPC}} - # Install Yarn - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - - name: Yarn Cache - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-modules- - name: Node 14 installation uses: actions/setup-node@v2 with: node-version: "14" - cache: "yarn" - registry-url: 'https://npm.pkg.github.com' - scope: "@UXDProtocol" - always-auth: true + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- # Create Keypair - name: Create Runner keypair and funds it run: | @@ -554,26 +412,32 @@ jobs: ./target/release ./target/bpfel-unknown-unknown key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} - - name: Create NPMRC - run: | - echo "@uxdprotocol:registry=https://npm.pkg.github.com" >> ~/.npmrc - echo "//npm.pkg.github.com/:_authToken=${{ env.NODE_AUTH_TOKEN }}" >> ~/.npmrc - # Checkout Mango Client - - name: Checkout MangoClient-v3 - uses: actions/checkout@v2 - with: - repository: blockworks-foundation/mango-client-v3 - path: /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - - name: Start Keeper and Market Making bot for the perp - run: | - cd /home/runner/work/uxd-program/uxd-program/third-party-dependencies/mango-client-v3 - yarn install - GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} yarn keeper & - GROUP=devnet.2 CLUSTER=${{ env.CLUSTER }} KEYPAIR=${{ env.RUNNER_WALLET_PATH }} MANGO_ACCOUNT_PUBKEY=${{ env.MANGO_ACCOUNT_MM_ETH }} MARKET=ETH yarn mm & - cd - + # # Market Making + # - uses: actions/checkout@v3 + # - name: Set up Python 3.10 + # uses: actions/setup-python@v3 + # with: + # python-version: "3.10" + # - name: Install dependencies and run marketmaker + # run: | + # sudo apt install direnv + # mkdir mmfolder + # cd mmfolder + # python -m venv .venv + # touch .envrc + # echo 'CURRENT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"' > .envrc + # echo -e '\nexport PATH=$CURRENT_DIRECTORY/.venv/bin:$PATH:$CURRENT_DIRECTORY/.venv/lib/python3.9/site-packages/bin' >> .envrc + # direnv allow + # cat .envrc + # python -m pip install --upgrade pip + # touch requirements.txt && echo mango-explorer > requirements.txt + # pip install -r requirements.txt + # mango-explorer-version + # marketmaker --name "UXD-ETH-MM" --market ETH-PERP --oracle-provider pyth --chain ratios --ratios-spread 0.005 --chain ratios --ratios-position-size 0.2 --chain fixedspread --fixedspread-value 0.1 --order-type LIMIT --log-level INFO --cluster-name devnet --account ${{ env.MANGO_ACCOUNT_MM_ETH }} & + # cd - - name: Anchor Test (skip build and deploy) run: | - yarn install + npm ci --ignore-scripts ./scripts/swap_ci_resident_program_id.sh sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_ETH }}/g" ./Anchor.toml npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} test --skip-local-validator --skip-build --skip-deploy @@ -618,25 +482,99 @@ jobs: solana --version solana config set -u d solana config set --url ${{ env.DEVNET_RPC}} - # Install Yarn - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn config get cacheFolder)" - - name: Yarn Cache + - name: Node 14 installation + uses: actions/setup-node@v2 + with: + node-version: "14" + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- + # Create Keypair + - name: Create Runner keypair and funds it + run: | + solana-keygen new -o ${{ env.RUNNER_WALLET_PATH }} --no-passphrase --silent + solana transfer --keypair ${{ env.BANK_WALLET_PATH }} $(solana-keygen pubkey ${{ env.RUNNER_WALLET_PATH }}) 1 --allow-unfunded-recipient + solana balance + # Cargo caching + - name: Cache Cargo registry + index + uses: actions/cache@v2 + id: cache-anchor + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: cargo-${{ runner.os }}-v0000-${{ hashFiles('**/Cargo.lock') }} + - name: Cache target folder uses: actions/cache@v2 + id: cache-programs with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-modules- + path: | + ./target/debug + ./target/release + ./target/bpfel-unknown-unknown + key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} + - name: Anchor Test (skip build and deploy) + run: | + npm ci --ignore-scripts + ./scripts/swap_ci_resident_program_id.sh + sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_REBALANCING }}/g" ./Anchor.toml + npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} test --skip-local-validator --skip-build --skip-deploy + - name: Returning funded runner wallet SOLs to the bank + run: | + solana transfer --keypair ${{ env.RUNNER_WALLET_PATH }} ${{ env.BANK_WALLET_PATH }} $(echo $(solana balance --keypair ${{ env.RUNNER_WALLET_PATH }} | awk '{print $1}') - ${{ env.TRANSACTION_FEE_OFFSET }} | bc) + + + anchor-test-mango-depository-quote-mint-redeem: + name: Test Quote mint redeem MangoDepository (SOL, BTC, ETH) against the resident program + runs-on: ubuntu-latest + needs: [anchor-build-and-deploy, anchor-test-mango-depository-SOL, anchor-test-mango-depository-BTC, anchor-test-mango-depository-ETH] + steps: + # Checkout + - uses: actions/checkout@v2 + # Install Rust + - name: Rust toolchain installation + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + profile: minimal + # Install solana + - name: Cache Solana Tool Suite + uses: actions/cache@v2 + id: cache-solana + with: + path: | + ~/.cache/solana/ + ~/.local/share/solana/ + key: solana-${{ runner.os }}-v0000-${{ env.SOLANA_VERSION }} + - name: install solana + if: steps.cache-solana.outputs.cache-hit != 'true' + run: | + sudo apt-get update + sudo apt-get install -y pkg-config build-essential libudev-dev + sh -c "$(curl -sSfL https://release.solana.com/v${{ env.SOLANA_VERSION }}/install)" + - name: Add Solana to PATH + run: echo "/home/runner/.local/share/solana/install/active_release/bin:$PATH" >> $GITHUB_PATH + - name: Setup solana + run: | + solana --version + solana config set -u d + solana config set --url ${{ env.DEVNET_RPC}} - name: Node 14 installation uses: actions/setup-node@v2 with: node-version: "14" - cache: "yarn" - registry-url: 'https://npm.pkg.github.com' - scope: "@UXDProtocol" - always-auth: true + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.npm + key: npm-${{ hashFiles('package-lock.json') }} + restore-keys: npm- # Create Keypair - name: Create Runner keypair and funds it run: | @@ -663,15 +601,11 @@ jobs: ./target/release ./target/bpfel-unknown-unknown key: solana-${{ runner.os }}-v0000-${{ hashFiles('**/programs/**/*.rs') }}-${{ hashFiles('**/programs/**/*.toml') }} - - name: Create NPMRC - run: | - echo "@uxdprotocol:registry=https://npm.pkg.github.com" >> ~/.npmrc - echo "//npm.pkg.github.com/:_authToken=${{ env.NODE_AUTH_TOKEN }}" >> ~/.npmrc - name: Anchor Test (skip build and deploy) run: | - yarn install + npm ci --ignore-scripts ./scripts/swap_ci_resident_program_id.sh - sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_REBALANCING }}/g" ./Anchor.toml + sed -i.bak "s/${{ env.TEST_DEV }}/${{ env.TEST_CI_QUOTE_MINT_REDEEM }}/g" ./Anchor.toml npx @project-serum/anchor-cli@${{ env.ANCHOR_VERSION }} test --skip-local-validator --skip-build --skip-deploy - name: Returning funded runner wallet SOLs to the bank run: | diff --git a/.github/workflows/ci-cargo-lint-test.yml b/.github/workflows/ci-cargo-lint-test.yml index e986871fe..4cbb972c7 100644 --- a/.github/workflows/ci-cargo-lint-test.yml +++ b/.github/workflows/ci-cargo-lint-test.yml @@ -2,11 +2,11 @@ name: Lint and Test on: push: - branches: [main, v*.*, acam/soteria-audit*] + branches: [main, v*.*] env: CARGO_TERM_COLOR: always - SOLANA_VERSION: 1.9.7 + SOLANA_VERSION: 1.8.16 RUST_TOOLCHAIN: nightly-2022-02-01 defaults: diff --git a/.github/workflows/ci-soteria-audit.yml b/.github/workflows/ci-soteria-audit.yml new file mode 100644 index 000000000..cc11e35f8 --- /dev/null +++ b/.github/workflows/ci-soteria-audit.yml @@ -0,0 +1,22 @@ +name: Soteria Audit + # Update to match your branch names and requirements +on: + push: + branches: [main, v*.*] + pull_request: + branches: [main, v*.*] + +jobs: + audit: + runs-on: ubuntu-latest + steps: + - name: Check-out the repository + uses: actions/checkout@v2 + - name: Soteria Audit + continue-on-error: false # set to true if you don't want to fail jobs + uses: silas-x/soteria-action@main + with: # remove if not passing arguments below + # solana-version: "1.9.14" # not required + run-mode: "-analyzeAll" # not required + cargo-com: "." # not required + program-path: "." # not required \ No newline at end of file diff --git a/.github/workflows/ci-soteria.yml b/.github/workflows/ci-soteria.yml deleted file mode 100644 index 5e9ad49cd..000000000 --- a/.github/workflows/ci-soteria.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Soteria Scan - -on: - push: - branches: [main] - pull_request: - branches: [main] - -env: - CARGO_TERM_COLOR: always - SOLANA_VERSION: 1.9.7 - -jobs: - build: - name: Soteria - runs-on: ubuntu-latest - steps: - - name: Check-out repo - uses: actions/checkout@v2 - - - name: Cache Solana binaries - uses: actions/cache@v2 - id: solana-cache - with: - path: | - ~/.cache/solana - ~/.local/share/solana - ~/.rustup - key: solana-${{ env.SOLANA_VERSION }} - - - name: Cache build dependencies - uses: Swatinem/rust-cache@v1 - with: - target-dir: .coderrect/build - - - name: Install Solana - if: steps.solana-cache.outputs.cache-hit != 'true' - run: | - echo Installing Solana v${{ env.SOLANA_VERSION }}... - sh -c "$(curl -sSfL https://release.solana.com/v${{ env.SOLANA_VERSION }}/install)" - echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH - export PATH="/home/runner/.local/share/solana/install/active_release/bin:$PATH" - echo Installing bpf toolchain... - (cd /home/runner/.local/share/solana/install/active_release/bin/sdk/bpf/scripts; ./install.sh) - shell: bash - - - name: Install Soteria - run: | - echo Installing Soteria... - sh -c "$(curl -k https://supercompiler.xyz/install)" - export PATH=$PWD/soteria-linux-develop/bin/:$PATH - echo "$PWD/soteria-linux-develop/bin" >> $GITHUB_PATH - shell: bash - - - name: Run Soteria # Not failing for the time being - run: soteria -analyzeAll . || exit 0 - shell: bash \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4695a6c94..98eb1a2e7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ test-ledger/ /programs/uxd/.coderrect/** /programs/uxd/target/** /programs/uxd/Cargo.lock -yarn-error.log programs/uxd/src/lib.rs.bak .gitignore Anchor.toml.bak @@ -27,3 +26,4 @@ scripts/swap_ci_resident_program_id.sh.bak .github/workflows/ci-anchor-test.yml.bak docker-target/ /**/.DS_Store +.history/ \ No newline at end of file diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 9eee2cd0e..000000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -@uxdprotocol:registry=https://npm.pkg.github.com \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..06f0385e0 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,16 @@ +const modifiedConfig = { + arrowParens: 'avoid', + bracketSpacing: true, + quoteProps: 'as-needed', + semi: false, + tabWidth: 2, + trailingComma: 'none', + useTabs: false, + singleQuote: true, + jsxSingleQuote: true, + spaceBeforeFunctionParen: false, + printWidth: 100, + bracketSameLine: true +} + +module.exports = modifiedConfig diff --git a/.vscode/settings.json b/.vscode/settings.json index 2fe426478..472180b4d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,6 +29,7 @@ "Marketv", "mngo", "mochawesome", + "MSRM", "NPMRC", "orderbook", "oustanding", @@ -55,6 +56,6 @@ "thiserror", "Tjpk", "UXDATA", - "WSOLATA" + "WSOLATA", ] } \ No newline at end of file diff --git a/Anchor.toml b/Anchor.toml index 03161cb99..6db900702 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,20 +1,25 @@ [provider] -cluster = "devnet" +cluster = "mainnet" wallet = "~/.config/solana/id.json" -[programs.mainnet] -uxd = "UXD8m9cvwk4RcSxnX2HZ9VudQCEeDH6fRnB4CAP57Dr" +# [programs.mainnet] +# uxd = "UXD8m9cvwk4RcSxnX2HZ9VudQCEeDH6fRnB4CAP57Dr" + +[programs.mainnet] # internal mainnet program address +uxd = "EmXCGBmeZ7vTZu1NcuR5Cod8438aQdghhVa69zcBVF23" [programs.devnet] -uxd = "BA67esrWE7cPzQWtAftaTbrVWtmHZJ1PbbBBpZgpjH4p" +uxd = "H4fDUuiTmRNrUVCaswDNFXAe1vR2UEgpdV8iQkzEn2C3" [registry] url = "https://anchor.projectserum.com" [scripts] # The quick version for development - Keep this version as the CI swap this line for its needs -# test = "yarn ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_development.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-test_integration --trace-warnings" +# test = "npx ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_development.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-test_integration --trace-warnings" # Sol only version -test = "yarn ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_ci_sol.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-test_integration --trace-warnings" +# test = "npx ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_ci_sol.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-test_integration --trace-warnings" # Longer version -# test = "yarn ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_integration.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-test_integration --trace-warnings" +# test = "npx ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_integration.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-t +# Mainnet testing +test = "npx ts-mocha --require tests/fixtures.ts -p ./tsconfig.json -t 500000 tests/test_mainnet_msol.ts --reporter mochawesome --require mochawesome/register --reporter-options quiet=true,reportTitle=uxdprogram-test_integration --trace-warnings" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a1afc08..d41098c20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,20 @@ # CHANGELOG +## [Unreleased] + +- Use place_perp_order_v2 to save computing and reduce composability issues +- Pass a limit_price in place of the slippage to ensure execution price match user expectations +- Add `01` support (mint/redeem/depositories creation) +- Remove init_if_needed (and remove Rent and Associated Token Program from inputs) +- Updates Anchor to version 0.24.2 + ## v3.0.2 (audit report fixes Soteria) Deployed: Mar 31, 2022 at 08:50:52 UTC | Slot: 127,530,926 1. Remove un needed passthrough accounts through the app to save computing -## v3.0.0 (audited Soteria) +## v3.0.1 (audited Soteria) Deployed: | Slot: diff --git a/Cargo.lock b/Cargo.lock index 88eef50e0..0a836b108 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,7 +8,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.4", + "getrandom 0.2.6", "once_cell", "version_check", ] @@ -30,11 +30,11 @@ checksum = "6b2d54853319fd101b8dd81de382bcbf3e03410a64d8928bbee85a3e7dcde483" [[package]] name = "anchor-attribute-access-control" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8573731461c6e39febd16026fe95cbc99955585b08acddc0baaeefb803da191b" +checksum = "a9b75d05b6b4ac9d95bb6e3b786b27d3a708c4c5a87c92ffaa25bbe9ae4c5d91" dependencies = [ - "anchor-syn 0.21.0", + "anchor-syn", "anyhow", "proc-macro2", "quote", @@ -42,42 +42,13 @@ dependencies = [ "syn", ] -[[package]] -name = "anchor-attribute-access-control" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb45cc9d1ce72e5eda341126de495a2c3810108c2333c6f3b4e09d99605f3f48" -dependencies = [ - "anchor-syn 0.22.1", - "anyhow", - "proc-macro2", - "quote", - "regex", - "syn", -] - -[[package]] -name = "anchor-attribute-account" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537c6e7014f727f3396759f73a847bdbca92379499d918c99ae1c7075d6d32e3" -dependencies = [ - "anchor-syn 0.21.0", - "anyhow", - "bs58 0.4.0", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "anchor-attribute-account" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16406bd1c27ff4ebdca4f5d5b09b7952f4d161f25094243e09355797c6bddaa6" +checksum = "485351a6d8157750d10d88c8e256f1bf8339262b2220ae9125aed3471309b5de" dependencies = [ - "anchor-syn 0.22.1", + "anchor-syn", "anyhow", "bs58 0.4.0", "proc-macro2", @@ -88,58 +59,22 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fce62e28b84fe3622044d5777e6962cf090049ef45d1bc29d0fbbc027b848d8" -dependencies = [ - "anchor-syn 0.21.0", - "proc-macro2", - "syn", -] - -[[package]] -name = "anchor-attribute-constant" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d347ce462ceba4473d216bab2c9d0d9702a027d25e93b5376d8d8593d9e13de0" +checksum = "dc632c540913dd051a78b00587cc47f57013d303163ddfaf4fa18717f7ccc1e0" dependencies = [ - "anchor-syn 0.22.1", + "anchor-syn", "proc-macro2", "syn", ] [[package]] name = "anchor-attribute-error" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd2fe5dd4d1e82ff9d0b948170ab4ad3b12fa16ad6f45a3a3ce4dd97e543935" +checksum = "3b5bd1dcfa7f3bc22dacef233d70a9e0bee269c4ac484510662f257cba2353a1" dependencies = [ - "anchor-syn 0.21.0", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "anchor-attribute-error" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "354582d796f8309252d18f787f0e49df8ab6fdfe48f838f059f001ee2f04b5c8" -dependencies = [ - "anchor-syn 0.22.1", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "anchor-attribute-event" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd23a6c92e0d7ee6378aef4e95596976008eb3a0be100ac832b7b3eaf240" -dependencies = [ - "anchor-syn 0.21.0", - "anyhow", + "anchor-syn", "proc-macro2", "quote", "syn", @@ -147,11 +82,11 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2e218dd8a446993463e38c00159349ae25aa76076191cde0ba460c9c65a180" +checksum = "6c6f9e6ce551ac9a177a45c99a65699a860c9e95fac68675138af1246e2591b0" dependencies = [ - "anchor-syn 0.22.1", + "anchor-syn", "anyhow", "proc-macro2", "quote", @@ -160,11 +95,11 @@ dependencies = [ [[package]] name = "anchor-attribute-interface" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8567efb892ec10df7cb479dc0246257f896b2de1406c6901621d5437080fc041" +checksum = "d104aa17418cb329ed7418b227e083d5f326a27f26ce98f5d92e33da62a5f459" dependencies = [ - "anchor-syn 0.21.0", + "anchor-syn", "anyhow", "heck", "proc-macro2", @@ -172,40 +107,13 @@ dependencies = [ "syn", ] -[[package]] -name = "anchor-attribute-interface" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e1e536e15b13e3168cf878a90b1bd2dfff1b4c8c9475be4b87f71b20cf8e85d" -dependencies = [ - "anchor-syn 0.22.1", - "anyhow", - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "anchor-attribute-program" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8674fa15f24b311451294595034617b96348faed14c821fe191183d46258af" -dependencies = [ - "anchor-syn 0.21.0", - "anyhow", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "anchor-attribute-program" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6519b3ac626c1bd9df407fe22ec6a283f4b1067ee7f3be896ca580be510b7196" +checksum = "b6831b920b173c004ddf7ae1167d1d25e9f002ffcb1773bbc5c7ce532a4441e1" dependencies = [ - "anchor-syn 0.22.1", + "anchor-syn", "anyhow", "proc-macro2", "quote", @@ -214,11 +122,11 @@ dependencies = [ [[package]] name = "anchor-attribute-state" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3921cd5b29b8fe7ff10368a5dd8398f37b1dabef489d18a01a4befd86ce09d6" +checksum = "cde147b10c71d95dc679785db0b5f3abac0091f789167aa62ac0135e2f54e8b9" dependencies = [ - "anchor-syn 0.21.0", + "anchor-syn", "anyhow", "proc-macro2", "quote", @@ -226,38 +134,27 @@ dependencies = [ ] [[package]] -name = "anchor-attribute-state" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e6a21070bcb053f092a1a9054924e8a1b5afd68f7317d0138327401ac154e1" -dependencies = [ - "anchor-syn 0.22.1", - "anyhow", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "anchor-derive-accounts" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41be15286b4fc2753cd2dab130ca7c87d81a2817adb7d0af5316715ddf4b46" +name = "anchor-comp" +version = "0.2.3" +source = "git+https://github.com/UXDProtocol/anchor-comp?branch=mango_msol#2a07948f05ebd511585c14dad39fa4e00718f315" dependencies = [ - "anchor-syn 0.21.0", - "anyhow", - "proc-macro2", - "quote", - "syn", + "anchor-lang", + "mango", + "marinade-finance", + "marinade-onchain-helper", + "serum_dex", + "solana-program", + "spl-governance", + "spl-token", ] [[package]] name = "anchor-derive-accounts" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a65890c2132f30a3ff160fb83f74e0a0454f904f46f1c9be38d3e94c2d06ed" +checksum = "9cde98a0e1a56046b040ff591dfda391f88917af2b6487d02b45093c05be3514" dependencies = [ - "anchor-syn 0.22.1", + "anchor-syn", "anyhow", "proc-macro2", "quote", @@ -266,47 +163,23 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4300d151a09cb0c0775cdd63100040c8dba325b406c55ffb4f845f4b78d9e9b" -dependencies = [ - "anchor-attribute-access-control 0.21.0", - "anchor-attribute-account 0.21.0", - "anchor-attribute-constant 0.21.0", - "anchor-attribute-error 0.21.0", - "anchor-attribute-event 0.21.0", - "anchor-attribute-interface 0.21.0", - "anchor-attribute-program 0.21.0", - "anchor-attribute-state 0.21.0", - "anchor-derive-accounts 0.21.0", +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a85dd2c5e29e20c7f4701a43724d6cd5406d0ee5694705522e43da0f26542a84" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-interface", + "anchor-attribute-program", + "anchor-attribute-state", + "anchor-derive-accounts", "arrayref", "base64 0.13.0", "bincode", - "borsh", - "bytemuck", - "solana-program", - "thiserror", -] - -[[package]] -name = "anchor-lang" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef066f4bc0cb4080ff6244b6a66ef31b6077e0302738b365ca894540f5b7dcf8" -dependencies = [ - "anchor-attribute-access-control 0.22.1", - "anchor-attribute-account 0.22.1", - "anchor-attribute-constant 0.22.1", - "anchor-attribute-error 0.22.1", - "anchor-attribute-event 0.22.1", - "anchor-attribute-interface 0.22.1", - "anchor-attribute-program 0.22.1", - "anchor-attribute-state 0.22.1", - "anchor-derive-accounts 0.22.1", - "arrayref", - "base64 0.13.0", - "bincode", - "borsh", + "borsh 0.9.3", "bytemuck", "solana-program", "thiserror", @@ -314,11 +187,11 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc245f1d18992ad44236dc15717a9875e1184a164b931c506ba9dc7a2258804f" +checksum = "0188c33b4a3c124c4e593f2b440415aaea70a7650fac6ba0772395385d71c003" dependencies = [ - "anchor-lang 0.21.0", + "anchor-lang", "solana-program", "spl-associated-token-account", "spl-token", @@ -326,28 +199,9 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c8a4e39f655a9e32037c238f51f09b168a7d56ab6a2727777da81849559c77c" -dependencies = [ - "anyhow", - "bs58 0.3.1", - "heck", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "serde", - "serde_json", - "sha2", - "syn", - "thiserror", -] - -[[package]] -name = "anchor-syn" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "506cb44e4e895f917566c7a0554e487a001041d82dd3ae9f1f37ae7f20f86222" +checksum = "03549dc2eae0b20beba6333b14520e511822a6321cdb1760f841064a69347316" dependencies = [ "anyhow", "bs58 0.3.1", @@ -364,9 +218,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.53" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "arrayref" @@ -484,29 +338,85 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "borsh" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b13fa9bf62be34702e5ee4526aff22530ae22fe34a0c4290d30d5e4e782e6" +dependencies = [ + "borsh-derive 0.7.2", +] + [[package]] name = "borsh" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" dependencies = [ - "borsh-derive", + "borsh-derive 0.9.3", "hashbrown", ] +[[package]] +name = "borsh-derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6aaa45f8eec26e4bf71e7e5492cf53a91591af8f871f422d550e7cc43f6b927" +dependencies = [ + "borsh-derive-internal 0.7.2", + "borsh-schema-derive-internal 0.7.2", + "proc-macro2", + "syn", +] + +[[package]] +name = "borsh-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307f3740906bac2c118a8122fe22681232b244f1369273e45f1156b45c43d2dd" +dependencies = [ + "borsh-derive-internal 0.8.2", + "borsh-schema-derive-internal 0.8.2", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn", +] + [[package]] name = "borsh-derive" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", "proc-macro-crate 0.1.5", "proc-macro2", "syn", ] +[[package]] +name = "borsh-derive-internal" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61621b9d3cca65cc54e2583db84ef912d59ae60d2f04ba61bc0d7fc57556bda2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2104c73179359431cc98e016998f2f23bc7a05bc53e79741bcba705f30047bc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "borsh-derive-internal" version = "0.9.3" @@ -518,6 +428,28 @@ dependencies = [ "syn", ] +[[package]] +name = "borsh-schema-derive-internal" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b38abfda570837b0949c2c7ebd31417e15607861c23eacb2f668c69f6f3bf7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae29eb8418fcd46f723f8691a2ac06857d31179d33d2f2d91eb13967de97c728" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "borsh-schema-derive-internal" version = "0.9.3" @@ -559,18 +491,18 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.7.3" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" +checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" +checksum = "562e382481975bc61d11275ac5e62a19abd00b0547d99516a415336f183dcd0e" dependencies = [ "proc-macro2", "quote", @@ -623,9 +555,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" dependencies = [ "libc", ] @@ -833,9 +765,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -937,9 +869,9 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ "wasm-bindgen", ] @@ -958,9 +890,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.118" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" +checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" [[package]] name = "libsecp256k1" @@ -1012,28 +944,29 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if", ] [[package]] name = "mango" -version = "3.4.2" -source = "git+https://github.com/blockworks-foundation/mango-v3#527844e85be7970f15e56887cb1ebe3dbf39f3d4" +version = "3.4.6" +source = "git+https://github.com/blockworks-foundation/mango-v3?tag=v3.4.6#b6f30798c3a32af1c3db87219ed036036ea07cdc" dependencies = [ - "anchor-lang 0.22.1", + "anchor-lang", "arrayref", "bincode", "bs58 0.4.0", @@ -1045,6 +978,7 @@ dependencies = [ "mango-logs", "mango-macro", "num_enum", + "pyth-client", "safe-transmute", "serde", "serum_dex", @@ -1059,7 +993,7 @@ dependencies = [ [[package]] name = "mango-common" version = "3.0.0" -source = "git+https://github.com/blockworks-foundation/mango-v3#527844e85be7970f15e56887cb1ebe3dbf39f3d4" +source = "git+https://github.com/blockworks-foundation/mango-v3?tag=v3.4.6#b6f30798c3a32af1c3db87219ed036036ea07cdc" dependencies = [ "bytemuck", "solana-program", @@ -1068,16 +1002,16 @@ dependencies = [ [[package]] name = "mango-logs" version = "0.1.0" -source = "git+https://github.com/blockworks-foundation/mango-v3#527844e85be7970f15e56887cb1ebe3dbf39f3d4" +source = "git+https://github.com/blockworks-foundation/mango-v3?tag=v3.4.6#b6f30798c3a32af1c3db87219ed036036ea07cdc" dependencies = [ - "anchor-lang 0.22.1", + "anchor-lang", "base64 0.13.0", ] [[package]] name = "mango-macro" version = "3.0.0" -source = "git+https://github.com/blockworks-foundation/mango-v3#527844e85be7970f15e56887cb1ebe3dbf39f3d4" +source = "git+https://github.com/blockworks-foundation/mango-v3?tag=v3.4.6#b6f30798c3a32af1c3db87219ed036036ea07cdc" dependencies = [ "bytemuck", "mango-common", @@ -1087,6 +1021,28 @@ dependencies = [ "syn", ] +[[package]] +name = "marinade-finance" +version = "0.1.0" +source = "git+https://github.com/UXDProtocol/liquid-staking-program#467a599a6dc3aa38de1e6f54f8f9c2542288b28a" +dependencies = [ + "anchor-lang", + "anchor-spl", + "bincode", + "spl-token", +] + +[[package]] +name = "marinade-onchain-helper" +version = "0.1.0" +source = "git+https://github.com/UXDProtocol/marinade-onchain-helper#d0308387addf4eeff465dd656581e9f5ded0c2bc" +dependencies = [ + "anchor-lang", + "anchor-spl", + "marinade-finance", + "solana-program", +] + [[package]] name = "memchr" version = "2.4.1" @@ -1133,20 +1089,20 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "720d3ea1055e4e4574c0c0b0f8c3fd4f24c4cdaf465948206dea090b57b526ad" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d992b768490d7fe0d8586d9b5745f6c49f557da6d81dc982b1d167ad4edbb21" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ - "proc-macro-crate 1.1.2", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn", @@ -1154,9 +1110,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "opaque-debug" @@ -1191,9 +1147,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" [[package]] name = "pest" @@ -1221,9 +1177,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dada8c9981fcf32929c3c0f0cd796a9284aca335565227ed88c83babb1d43dc" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ "thiserror", "toml", @@ -1255,9 +1211,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] @@ -1295,6 +1251,22 @@ dependencies = [ "tempfile", ] +[[package]] +name = "pyth-client" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f779e98b8c8016d0c1409247a204bd4fcdea8b67ceeef545f04e324d66c49e52" +dependencies = [ + "borsh 0.9.3", + "borsh-derive 0.9.3", + "bytemuck", + "num-derive", + "num-traits", + "serde", + "solana-program", + "thiserror", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1318,9 +1290,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -1384,7 +1356,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.4", + "getrandom 0.2.6", ] [[package]] @@ -1407,18 +1379,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", @@ -1442,9 +1414,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.22.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d37baa70cf8662d2ba1c1868c5983dda16ef32b105cce41fb5c47e72936a90b3" +checksum = "22dc69eadbf0ee2110b8d20418c0c6edbaefec2811c4963dc17b6344e11fe0f8" dependencies = [ "arrayvec", "num-traits", @@ -1453,14 +1425,20 @@ dependencies = [ [[package]] name = "rust_decimal_macros" -version = "1.22.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "184abaf7b434800e1a5a8aad3ebc8cd7498df33af72d65371d797a264713a59b" +checksum = "a4c70be9367d4bc095d10b48d41b819d09ed4dafc528765a144d32ed1d530654" dependencies = [ "quote", "rust_decimal", ] +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + [[package]] name = "rustc_version" version = "0.3.3" @@ -1476,7 +1454,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.5", + "semver 1.0.7", ] [[package]] @@ -1526,9 +1504,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0486718e92ec9a68fbed73bb5ef687d71103b142595b406835649bebd33f72c7" +checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" [[package]] name = "semver-parser" @@ -1581,8 +1559,8 @@ dependencies = [ [[package]] name = "serum_dex" -version = "0.4.0" -source = "git+https://github.com/blockworks-foundation/serum-dex.git#3104f424ee38a415418a1cdef67970771f832857" +version = "0.5.5" +source = "git+https://github.com/blockworks-foundation/serum-dex.git?rev=7f55a5ef5f7937b74381a3124021a261cd7d7283#7f55a5ef5f7937b74381a3124021a261cd7d7283" dependencies = [ "arrayref", "bincode", @@ -1635,9 +1613,9 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "solana-frozen-abi" -version = "1.9.13" +version = "1.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34c9effc54db26704db05c474254e50a69fbd4c527df13aead8c8e38db127d7c" +checksum = "c8db0d37f7c345c6417898e675d218d76a1ce6d3bd57584d7f463d48badf1541" dependencies = [ "bs58 0.4.0", "bv", @@ -1655,9 +1633,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.9.13" +version = "1.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d343b3e8f168d009365acc13654ebbecbcd7d98e7100eaf9fdcd2a59a2d99706" +checksum = "023560984c7f16a53e280866c177d1ad45225614356224c1ade671de16424466" dependencies = [ "proc-macro2", "quote", @@ -1667,9 +1645,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.9.13" +version = "1.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aea113f74b8ace6baf51256daf9d5228b6c65a774fe21a4416dd7e270d5dd4" +checksum = "57cb0a4ef4dd740397addf5fa50d9dff572371fd47df2bdecc5fb530546490e2" dependencies = [ "env_logger", "lazy_static", @@ -1678,16 +1656,16 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.9.13" +version = "1.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b838bfabf09050f5f66cadf5e486fd415242165f06c9f9aed45162efb68c711" +checksum = "9654224bf5d4c6d80f68c3c996683b389693af1c69103af667c683180bad6c5e" dependencies = [ "base64 0.13.0", "bincode", "bitflags", "blake3", - "borsh", - "borsh-derive", + "borsh 0.9.3", + "borsh-derive 0.9.3", "bs58 0.4.0", "bv", "bytemuck", @@ -1721,9 +1699,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.9.13" +version = "1.9.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25759d80a81f0303b2827344b365f886a74306fa6af7c898921333d04d1c99b" +checksum = "bac8cb60eb2e4c85d76ea1f0429dfc0e8b4ba7834e9d69695bb3164f3966e16d" dependencies = [ "bs58 0.4.0", "proc-macro2", @@ -1734,12 +1712,77 @@ dependencies = [ [[package]] name = "spl-associated-token-account" -version = "1.0.3" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490" +dependencies = [ + "borsh 0.9.3", + "solana-program", + "spl-token", +] + +[[package]] +name = "spl-governance" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab3e781972cd03348c14217739ddf946ab5324c32a85392237cf3ab9492df7a" +dependencies = [ + "arrayref", + "bincode", + "borsh 0.9.3", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-program", + "spl-governance-addin-api", + "spl-governance-tools", + "spl-token", + "thiserror", +] + +[[package]] +name = "spl-governance-addin-api" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df620226aed88689457ef18a80dfed709721365bee0bf8c843dcef30279d5fc" +dependencies = [ + "borsh 0.9.3", + "solana-program", + "spl-governance-tools", +] + +[[package]] +name = "spl-governance-tools" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428" +checksum = "6a206f0837415046d919f3075d6b3af9bd3f1f707c887898c335a6210b194627" dependencies = [ + "arrayref", + "bincode", + "borsh 0.9.3", + "num-derive", + "num-traits", + "serde", + "serde_derive", "solana-program", "spl-token", + "thiserror", +] + +[[package]] +name = "spl-math" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ecdd22720b9e5ab578a862928f5010ca197419502bdace600ccd5d23dae9352" +dependencies = [ + "borsh 0.7.2", + "borsh-derive 0.8.2", + "num-derive", + "num-traits", + "solana-program", + "thiserror", + "uint", ] [[package]] @@ -1775,7 +1818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "534d4b2d45907427fc8d2cd151465cfaee3709c4742491734bc34e5a458ebd09" dependencies = [ "bincode", - "borsh", + "borsh 0.9.3", "bytemuck", "byteorder", "quick-protobuf", @@ -1791,7 +1834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e2d89875ff72d12ea7918d6ccd82d1ac5eab54b3a9d1bd7356fa6905801aa72" dependencies = [ "bincode", - "borsh", + "borsh 0.9.3", "byteorder", "quick-protobuf", ] @@ -1803,7 +1846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac1d68193aa1669e34d16087db0f96e6597d2f78868378aabc1387b8b29172e" dependencies = [ "bincode", - "borsh", + "borsh 0.9.3", "bytemuck", "byteorder", "quick-protobuf", @@ -1815,9 +1858,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.82" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -1840,9 +1883,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ "winapi-util", ] @@ -1869,9 +1912,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] @@ -1888,6 +1931,18 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +[[package]] +name = "uint" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db035e67dfaf7edd9aebfe8676afcd63eed53c8a4044fed514c8cccf1835177" +dependencies = [ + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", +] + [[package]] name = "unicode-segmentation" version = "1.9.0" @@ -1902,17 +1957,20 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "uxd" -version = "3.0.2" +version = "3.1.0" dependencies = [ - "anchor-lang 0.21.0", + "anchor-comp", + "anchor-lang", "anchor-spl", "fixed", "mango", - "num_enum", + "marinade-finance", + "marinade-onchain-helper", + "num-traits", "proptest", "solana-program", + "spl-math", "spl-token", - "thiserror", ] [[package]] @@ -1944,9 +2002,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1954,9 +2012,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static", @@ -1969,9 +2027,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1979,9 +2037,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ "proc-macro2", "quote", @@ -1992,15 +2050,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", @@ -2048,9 +2106,9 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zeroize" diff --git a/Cargo.toml b/Cargo.toml index cf1624066..a10528ba1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ members = [ "programs/*" ] +[profile.test] +overflow-checks = false + # Might lengthen the build process but improve computing usage. Use sccache to offset [profile.release] lto = "fat" diff --git a/README.md b/README.md index b1ad25b5b..459241dbc 100644 --- a/README.md +++ b/README.md @@ -17,46 +17,38 @@ It currently sits at: _____ -## Where to start? +## UXDProtocol business knowledge -In this readme, you can skip to Program Architecture section, or directly go to the lib.rs file to see the code comments (about each instruction and it's inputs). If you want to learn more about the high level concept of UXDProtocol, the [UXDProtocol Git book](https://docs.uxd.fi/uxdprotocol/) is available. -_____ - -## Known shortcomings - -### Composability risk with MangoMarkets (and DEX in general) - -As we are built on top of DEXes, we are vulnerable to them changing code or behavior. As such, we have our unit test / ci running on their repositories. -In the future we will try to implement a place perp order v2 to return the order book exploration logic back to the mango repository. [PR on Mango Market](https://github.com/blockworks-foundation/mango-v3/pull/124) +## Running tests -### Rebalancing (lite for now) +### Rust unit tests -Current rebalancing is a bit convoluted, but we are limited computing wise and # of input account wise, as it needs to be an atomic instruction. -Later on it won't requires any external input (except to pay for fees in order to keep the system closed). +```Zsh +$> cargo test && cargo build-bpf && cargo test-bpf +``` -### Slippage and limit price +### E2E Tests -Currently we only take the slippage as parameter, and we execute at market price +/- slippage at the time of execution of the instruction. -This can be fixed easily and is planned, but other items were prioritized, will probably make it in a next minor release right after v3.0.0) +In order to have the environment ready to host test, the mango market devnet must be running as expected. To do so we must run market making bots and the Keeper, from [MangoClientV3](https://github.com/blockworks-foundation/mango-client-v3) repo or [mango-explorer](https://github.com/blockworks-foundation/mango-explorer/blob/main/docs/MarketmakingOrderChain.md). +Keeper does the cranking (settle orders), and MM bots ensure that the order book is coherent. -_____ +When test are failing due to odd reasons, first thing to do is to check the [MangoMarkets V3](https://devnet.mango.markets/?name=SOL-PERP) market state. Verify that the order book is being updated, and run a market making bot. -## Running tests +(deprecated, see for updated way) -### Rust unit tests +A example script to run a maker maker for SOL/BTC/ETH markets on MangoMarketsv3 using mango-explorer is ```Zsh -$> cargo test && cargo build-bpf && cargo test-bpf -``` +#!/bin/sh -### E2E Tests +marketmaker --name "UXD-SOL-MM" --market SOL-PERP --oracle-provider pyth --chain ratios --ratios-spread 0.005 --chain ratios --ratios-position-size 0.02 --chain fixedspread --fixedspread-value 0.1 --order-type LIMIT --pulse-interval 30 --log-level INFO --cluster-name devnet --account 2s2hNn44RTWQsTEkBbpy8ieA8NtLBFQif3Q41BmfPu3a & -In order to have the environment ready to host test, the mango market devnet must be running as expected. To do so we must run market making bots and the Keeper, from [MangoClientV3](https://github.com/blockworks-foundation/mango-client-v3) repo. -Keep does the cranking (settle orders), and MM bots ensure that the order book is coherent. (Although sometimes it's still not coherent, as anyone can mess with it) +marketmaker --name "UXD-BTC-MM" --market BTC-PERP --oracle-provider pyth --chain ratios --ratios-spread 0.005 --chain ratios --ratios-position-size 0.02 --chain fixedspread --fixedspread-value 0.1 --order-type LIMIT --pulse-interval 30 --log-level INFO --cluster-name devnet --account 2s2hNn44RTWQsTEkBbpy8ieA8NtLBFQif3Q41BmfPu3a & -When test are failing due to odd reasons, first thing to do is to check the [MangoMarkets V3](https://devnet.mango.markets/?name=SOL-PERP) related perp (here for SOL-PERP). Verify that the order book is not borked with a weird stuck order or that the oracle price is not far away from the perp price for some reason. +marketmaker --name "UXD-ETH-MM" --market ETH-PERP --oracle-provider pyth --chain ratios --ratios-spread 0.005 --chain ratios --ratios-position-size 0.02 --chain fixedspread --fixedspread-value 0.1 --order-type LIMIT --pulse-interval 30 --log-level INFO --cluster-name devnet --account 2s2hNn44RTWQsTEkBbpy8ieA8NtLBFQif3Q41BmfPu3a +``` ```Zsh $> GROUP=devnet.2 CLUSTER=devnet KEYPAIR=$(cat /Users/acamill/.config/solana/id.json) yarn keeper @@ -84,13 +76,13 @@ If you made changes to the Rust code, you have to re-run the lengthy : $> anchor test ``` -Loop theses as many time as you want, and if you want a clean slate, just reset the program_id with the script again. +Loop theses as many time as you want, and if you want a clean slate, just reset the program_id with the script (`./script/reset_program_id.sh`). _____ ## Codebase org -The program is contained in `programs/uxd/`. +The program (smart contract) is contained in `programs/uxd/`. Its instructions are in `programs/uxd/src/instructions/`. The project follows the code org as done in [Jet protocol](https://github.com/jet-lab/jet-v1) codebase. @@ -99,19 +91,17 @@ The project uses `Anchor` for safety, maintainability and readability. The project relies on `Mango Markets` [program](https://github.com/blockworks-foundation/mango-v3), a decentralized derivative exchange platform build on Solana, and controlled by a DAO. -This program contains 2 set of instructions, one permissionned and one permissionless +This program contains 2 set of instructions, one permissionned and one permissionless. Permissionned instruction are called by [our DAO](https://governance.uxd.fi/dao/UXP). _____ ## Program Architecture -![uxd schema](uxd.jpg) - The initial state is initialized through calling `initializeController`, from there a mint is created for Redeemable, the signer is kept as the administrative authority, and that's it. -It owns the Redeemable Mint currently. In the future there could be added instruction to transfer Authority/Mint to another program for migration purposes, if needs be. +The `Controller` owns the Redeemable Mint. There is only a single `Controller` that can ever exists due to the chosen seed derivation. -Each `Depository` is used to `mint()` and `redeem()` Redeemable tokens with a specific collateral mint, and to do so each instantiate a Mango PDA that is used to deposit/withdraw collateral to mango and open/close short perp. +Each `Depository` is used to `mint()` and `redeem()` Redeemable (UXD) tokens with a specific collateral mint, and to do so each instantiate a MangoAccount PDA that is used to deposit/withdraw collateral to mango and open/close short perp. ## Admin instructions @@ -142,11 +132,15 @@ Change the value of the global supply cap (virtual, not on the mint) for the Red Change the value of the Mango Depositories operations (Mint/Redeem) Redeemable cap, prevent minting/redeeming over this limit. +### `SetMangoDepositoryQuoteMintAndRedeemFee` + +Change the value of the Mango Depositories quote redeem/mint fee. + ## User instructions They allow end users to mint and redeem redeemable tokens, they are permissionless. -### `mint_uxd` +### `MintWithMangoDepository` Send collateral to the `Depository` taking that given mint Estimate how much fill we can get to know how much collateral need to be actually deposited to mango to improve efficiency @@ -155,7 +149,11 @@ Check that the position was fully opened else abort Deduct perp opening fees from the quote amount Mint equivalent amount of UXD to user (as the value of the short perp - taker fees) -### `redeem_uxd` +### `QuoteRedeemFromMangoDepository` + +Similar to classic mint but only available when the DN position PnL is negative. Takes USDC (quote) as input, erase some negative PnL balance and mint equivalent UXD amount. + +### `RedeemFromMangoDepository` User send an amount of UXD to a given `Depository` We calculate how much collateral that's worth, provided the user slippage and the perp price from Mango @@ -166,6 +164,10 @@ We burn the same value of UXD from what the user sent We withdraw the collateral amount equivalent to the perp short that has been closed previously (post taxes calculation) We send that back to the user (and his remaining UXD are back too, if any) +### `QuoteMintWithMangoDepository` + +Similar to classic redeem but only available when the DN position PnL is positive. Takes UXD as input, returns some USDC (quote) from the positive PnL balance. + ### `RebalanceMangoDepositoryLite` Convert any paper profits from the short perp part of the delta neutral position back into the delta neutral position, either increasing or decreasing it's size. @@ -187,7 +189,7 @@ It's quite unstable to test on devnet with typescript, and expect MangoMarkets o The CI strategy for E2E : -- use the ci-resident-program (``) (call ./scripts/swap_ci_resident_program.sh) +- use the ci-resident-program (call ./scripts/swap_ci_resident_program.sh) - use it's upgrade authority stored in `target/deploy/ci-resident-upgrade-authority.json` for deployment - upgrade program - run the market making bots diff --git a/design/msol.md b/design/msol.md new file mode 100644 index 000000000..d5bda6ea3 --- /dev/null +++ b/design/msol.md @@ -0,0 +1,31 @@ +# mSOL program design +Here is the high level program design for keeping part of the SOL collateral of UXD as mSOL and how to maintain a constant liquidity ratio. + +Reward harvesting would be expected to add in the second stage of the whole mSOL implementation. (probably by regularly drawing mSOL from the Dex Depository Account, TBC) +___ +## changes for state + +added a new `msol_config` account state. +```Zsh +pub struct MSolConfig { + ... + pub depository: Pubkey, + pub controller: Pubkey, + pub enabled: bool, + pub target_liquidity_ratio: u16, + ... +} +``` +Authority of the controller must create a MSolConfig first for one of it's depository before running the mSOL/SOL swap instructions. This state is intentionally decoupled with the depository. Several reason of this implementation, +1. to avoid any prior execution of the permissionless call for the swap ixs before specifying the target liquidity ratio +2. having a `MSolConfig` on depository state is wasting space for most cases, since it's only useful for depository with collateral mint as SOL +3. no modifying of existing depository related instructions +___ +## changes for instructions +### permissionned ixns: +### `create_depository_msol_config` +To initialize `msol_config` account, specify the `target_liquidity_ratio` and setup it's relationship to the `controller` and `depository`, could only called by the controller's authority. For each `depository`, there could only hv one `msol_config` created. +### `enable_msol_swap` +Updated the `msol_config` state, set whether the mSOL/SOL swap is allowed +### `set_msol_liquidity_ratio` +Updated the `msol_config` state, set the SOL liquidity ratio \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..c512c692a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5229 @@ +{ + "name": "uxd-program", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "license": "SEE LICENSE IN LICENSE.MD", + "dependencies": { + "@blockworks-foundation/mango-client": "^3.4.5", + "@marinade.finance/marinade-ts-sdk": "3.0.0", + "@project-serum/anchor": "0.24.2", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "1.42.0", + "@uxd-protocol/uxd-client": "2.0.0-beta.3" + }, + "devDependencies": { + "@types/chai": "^4.3.0", + "@types/mocha": "^9.1.0", + "chai": "^4.3.6", + "mocha": "^9.2.1", + "mochawesome": "^7.0.1", + "ts-mocha": "^9.0.2", + "typescript": "^4.5.5" + } + }, + "node_modules/@babel/runtime": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", + "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@blockworks-foundation/mango-client": { + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.4.8.tgz", + "integrity": "sha512-veV3tfUfSZ8gN2I0u2gCj+dSQcD0QB1Imo2XuUdv0IUKb4Um8KoBxxpv1fxVHQ2J5RRSCYNW6DhPiNEnZYhbXg==", + "license": "MIT", + "dependencies": { + "@project-serum/anchor": "^0.21.0", + "@project-serum/serum": "0.13.55", + "@project-serum/sol-wallet-adapter": "^0.2.0", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.37.1", + "big.js": "^6.1.1", + "bn.js": "^5.1.0", + "buffer-layout": "^1.2.1", + "cross-fetch": "^3.1.5", + "dotenv": "^10.0.0", + "toformat": "^2.0.0", + "yargs": "^17.0.1" + } + }, + "node_modules/@blockworks-foundation/mango-client/node_modules/@project-serum/anchor": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz", + "integrity": "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.4", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@blockworks-foundation/mango-client/node_modules/@project-serum/sol-wallet-adapter": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz", + "integrity": "sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g==", + "license": "Apache-2.0", + "dependencies": { + "bs58": "^4.0.1", + "eventemitter3": "^4.0.7" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.5.0" + } + }, + "node_modules/@blockworks-foundation/mango-client/node_modules/@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/sha2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", + "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@marinade.finance/marinade-ts-sdk/-/marinade-ts-sdk-3.0.0.tgz", + "integrity": "sha512-Ip/U+Yy8fP+FuY09raZOYLew/eSrL09Dxm79e5gwCv58h7TcvdtXOSzh6cLOxHqeaBPsyffMc+pvoUsFcw+WWA==", + "dependencies": { + "@project-serum/anchor": "^0.18.2", + "@solana/spl-token": "^0.1.8", + "borsh": "^0.6.0", + "bs58": "^5.0.0" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk/node_modules/@project-serum/anchor": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.18.2.tgz", + "integrity": "sha512-uyjiN/3Ipp+4hrZRm/hG18HzGLZyvP790LXrCsGO3IWxSl28YRhiGEpKnZycfMW94R7nxdUoE3wY67V+ZHSQBQ==", + "dependencies": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.0", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk/node_modules/@project-serum/anchor/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk/node_modules/borsh": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.6.0.tgz", + "integrity": "sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q==", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk/node_modules/borsh/node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk/node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/@marinade.finance/marinade-ts-sdk/node_modules/bs58/node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/@project-serum/anchor": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz", + "integrity": "sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.5", + "@solana/web3.js": "^1.36.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@project-serum/borsh": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz", + "integrity": "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.2.0" + } + }, + "node_modules/@project-serum/serum": { + "version": "0.13.55", + "resolved": "https://registry.npmjs.org/@project-serum/serum/-/serum-0.13.55.tgz", + "integrity": "sha512-SPQ4NsuNbBJO3mLGnTYbjt47WCXoNIcW2C9xv0gNXyG62dxgONsAEEgErKv1gT34hWCMPsXFSpatnX6ppriq7w==", + "license": "MIT", + "dependencies": { + "@project-serum/anchor": "^0.11.1", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@project-serum/serum/node_modules/@project-serum/anchor": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.11.1.tgz", + "integrity": "sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.0", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@project-serum/serum/node_modules/@project-serum/anchor/node_modules/@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@solana/buffer-layout": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", + "license": "MIT", + "dependencies": { + "buffer": "~6.0.3" + }, + "engines": { + "node": ">=5.10" + } + }, + "node_modules/@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "dependencies": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/buffer-layout/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@solana/spl-token": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@solana/spl-token/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/@solana/web3.js": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.42.0.tgz", + "integrity": "sha512-QqGh5DWzrgsWRx4sCPDQIm3390b7buPR16tZI61slQaQwJ2ymrSXPQCe4PPTJEIlzGjCV3dkn2vpT2R32BfK2Q==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "cross-fetch": "^3.1.4", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@types/chai": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "12.20.49", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.49.tgz", + "integrity": "sha512-5e6QNb9bkeh4Hni4ktLqUZuUqnGTX/kou2aZkXyxtuYaHXgBm+In1SHR9V+7kDzWzjB08KC2uqt2doDi7cuAAA==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/@uxd-protocol/uxd-client": { + "version": "2.0.0-beta.3", + "resolved": "https://registry.npmjs.org/@uxd-protocol/uxd-client/-/uxd-client-2.0.0-beta.3.tgz", + "integrity": "sha512-YIr2zY0eNRvoD8OuVy0Gx1uhXQHk31xKqV53OhKKrmJwYIUJsC4qXWO7aOGO4lcTCOz76zFu5go4DGTGj/RNvA==", + "license": "MIT", + "dependencies": { + "@blockworks-foundation/mango-client": "3.4.5", + "@project-serum/anchor": "0.24.2", + "@solana/spl-token": "0.1.8", + "@solana/web3.js": "1.39.1", + "@zero_one/client": "^0.8.7", + "camelcase": "5.3.1" + } + }, + "node_modules/@uxd-protocol/uxd-client/node_modules/@blockworks-foundation/mango-client": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.4.5.tgz", + "integrity": "sha512-RQ8WAcUMKtV72TGZ3qLFqcZW17WbDyDMcnCZrzSHp0rWpuThXcKb17/YBJY7TugVRvc6JnV1aJtlibI/oF15Gw==", + "license": "MIT", + "dependencies": { + "@project-serum/anchor": "^0.21.0", + "@project-serum/serum": "0.13.55", + "@project-serum/sol-wallet-adapter": "^0.2.0", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.31.0", + "big.js": "^6.1.1", + "bn.js": "^5.1.0", + "buffer-layout": "^1.2.1", + "cross-fetch": "^3.1.5", + "dotenv": "^10.0.0", + "toformat": "^2.0.0", + "yargs": "^17.0.1" + } + }, + "node_modules/@uxd-protocol/uxd-client/node_modules/@blockworks-foundation/mango-client/node_modules/@project-serum/anchor": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz", + "integrity": "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.4", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@uxd-protocol/uxd-client/node_modules/@blockworks-foundation/mango-client/node_modules/@project-serum/anchor/node_modules/@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@uxd-protocol/uxd-client/node_modules/@blockworks-foundation/mango-client/node_modules/@project-serum/sol-wallet-adapter": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz", + "integrity": "sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g==", + "license": "Apache-2.0", + "dependencies": { + "bs58": "^4.0.1", + "eventemitter3": "^4.0.7" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@solana/web3.js": "^1.5.0" + } + }, + "node_modules/@uxd-protocol/uxd-client/node_modules/@solana/web3.js": { + "version": "1.39.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.39.1.tgz", + "integrity": "sha512-Q7XnWTAiU7n7GcoINDAAMLO7CJHpm5kPK46HKwJi2x0cusHQ3WFa7QEp6aPzH7tuf7yl/Kw1lYitcwTVOvqARA==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "cross-fetch": "^3.1.4", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@zero_one/client": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/@zero_one/client/-/client-0.8.7.tgz", + "integrity": "sha512-6YmwOZ4aNE5MWLW8nsLQxhtgA/6gq7JL49UgZTL6S1yETLeKUVuesWRfrLj9EZ2YfN/pxOdVmBA+KOAESowiAA==", + "license": "Apache-2.0", + "dependencies": { + "@project-serum/anchor": "^0.20.1", + "@solana/spl-token": "^0.1.8", + "@zero_one/lite-serum": "^0.1.1", + "bn.js": "^5.2.0", + "buffer-layout": "^1.2.2", + "decimal.js": "^10.3.1" + }, + "peerDependencies": { + "@solana/web3.js": "^1.31.0" + } + }, + "node_modules/@zero_one/client/node_modules/@project-serum/anchor": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.20.1.tgz", + "integrity": "sha512-2TuBmGUn9qeYz6sJINJlElrBuPsaUAtYyUsJ3XplEBf1pczrANAgs5ceJUFzdiqGEWLn+84ObSdBeChT/AXYFA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@zero_one/client/node_modules/@project-serum/anchor/node_modules/@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/@zero_one/lite-serum": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@zero_one/lite-serum/-/lite-serum-0.1.1.tgz", + "integrity": "sha512-Xo54bHM3KiDaOo436tlMf09DnezgKJD8zY9VUndtgUFwkZB1107MO84AGorZ/dZ5UrbXm6k21P96thexwJKtnA==", + "license": "MIT", + "dependencies": { + "@project-serum/anchor": "^0.11.1", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@zero_one/lite-serum/node_modules/@project-serum/anchor": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.11.1.tgz", + "integrity": "sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.0", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@zero_one/lite-serum/node_modules/@project-serum/anchor/node_modules/@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "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, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "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, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "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" + } + ], + "license": "MIT" + }, + "node_modules/big.js": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bigjs" + } + }, + "node_modules/bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bindings": "^1.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "license": "MIT" + }, + "node_modules/borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "license": "Apache-2.0", + "dependencies": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "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": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "license": "MIT" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "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, + "license": "MIT" + }, + "node_modules/buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", + "license": "MIT", + "engines": { + "node": ">=4.5" + } + }, + "node_modules/bufferutil": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "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/chalk/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "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/" + } + ], + "license": "MIT", + "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/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "license": "MIT", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug/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, + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "license": "MIT", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==", + "license": "MIT" + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz", + "integrity": "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==", + "license": "MIT", + "dependencies": { + "traverse-chain": "~0.1.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true, + "license": "ISC" + }, + "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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fsu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz", + "integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==", + "dev": true, + "license": "MIT" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/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, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true, + "license": "ISC" + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.x" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "license": "ISC", + "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==", + "license": "ISC" + }, + "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, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true, + "license": "ISC" + }, + "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==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/jayson": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "license": "MIT", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==", + "license": "MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "license": "ISC" + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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, + "license": "ISC" + }, + "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==", + "license": "ISC" + }, + "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": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mochawesome": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.3.tgz", + "integrity": "sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "diff": "^5.0.0", + "json-stringify-safe": "^5.0.1", + "lodash.isempty": "^4.4.0", + "lodash.isfunction": "^3.0.9", + "lodash.isobject": "^3.0.2", + "lodash.isstring": "^4.0.1", + "mochawesome-report-generator": "^6.2.0", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "mocha": ">=7" + } + }, + "node_modules/mochawesome-report-generator": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz", + "integrity": "sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "dateformat": "^4.5.1", + "escape-html": "^1.0.3", + "fs-extra": "^10.0.0", + "fsu": "^1.1.1", + "lodash.isfunction": "^3.0.9", + "opener": "^1.5.2", + "prop-types": "^15.7.2", + "tcomb": "^3.2.17", + "tcomb-validation": "^3.3.0", + "validator": "^13.6.0", + "yargs": "^17.2.1" + }, + "bin": { + "marge": "bin/cli.js" + } + }, + "node_modules/mochawesome-report-generator/node_modules/yargs": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", + "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mochawesome-report-generator/node_modules/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "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, + "license": "MIT", + "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": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz", + "integrity": "sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==", + "license": "(MIT AND Zlib)" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rpc-websockets": { + "version": "7.4.18", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.18.tgz", + "integrity": "sha512-bVu+4qM5CkGVlTqJa6FaAxLbb5uRnyH4te7yjFvoCzbnif7PT4BcvXtNTprHlNvsH+/StB81zUQicxMrUrIomA==", + "license": "LGPL-3.0-only", + "dependencies": { + "@babel/runtime": "^7.17.2", + "eventemitter3": "^4.0.7", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/kozjak" + }, + "optionalDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + } + }, + "node_modules/rpc-websockets/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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, + "license": "BSD-3-Clause", + "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, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tcomb": { + "version": "3.2.29", + "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", + "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tcomb-validation": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", + "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tcomb": "^3.0.0" + } + }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==", + "license": "MIT" + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "license": "MIT" + }, + "node_modules/traverse-chain": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", + "integrity": "sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE=", + "license": "MIT" + }, + "node_modules/ts-mocha": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz", + "integrity": "sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-node": "7.0.1" + }, + "bin": { + "ts-mocha": "bin/ts-mocha" + }, + "engines": { + "node": ">= 6.X.X" + }, + "optionalDependencies": { + "tsconfig-paths": "^3.5.0" + }, + "peerDependencies": { + "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X" + } + }, + "node_modules/ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "bin": { + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "license": "0BSD" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", + "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "license": "MIT", + "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/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/runtime": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", + "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@blockworks-foundation/mango-client": { + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.4.8.tgz", + "integrity": "sha512-veV3tfUfSZ8gN2I0u2gCj+dSQcD0QB1Imo2XuUdv0IUKb4Um8KoBxxpv1fxVHQ2J5RRSCYNW6DhPiNEnZYhbXg==", + "requires": { + "@project-serum/anchor": "^0.21.0", + "@project-serum/serum": "0.13.55", + "@project-serum/sol-wallet-adapter": "^0.2.0", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.37.1", + "big.js": "^6.1.1", + "bn.js": "^5.1.0", + "buffer-layout": "^1.2.1", + "cross-fetch": "^3.1.5", + "dotenv": "^10.0.0", + "toformat": "^2.0.0", + "yargs": "^17.0.1" + }, + "dependencies": { + "@project-serum/anchor": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz", + "integrity": "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==", + "requires": { + "@project-serum/borsh": "^0.2.4", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + } + }, + "@project-serum/sol-wallet-adapter": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz", + "integrity": "sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g==", + "requires": { + "bs58": "^4.0.1", + "eventemitter3": "^4.0.7" + } + }, + "@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + } + } + }, + "@ethersproject/bytes": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" + }, + "@ethersproject/sha2": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz", + "integrity": "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==", + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "hash.js": "1.1.7" + } + }, + "@marinade.finance/marinade-ts-sdk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@marinade.finance/marinade-ts-sdk/-/marinade-ts-sdk-3.0.0.tgz", + "integrity": "sha512-Ip/U+Yy8fP+FuY09raZOYLew/eSrL09Dxm79e5gwCv58h7TcvdtXOSzh6cLOxHqeaBPsyffMc+pvoUsFcw+WWA==", + "requires": { + "@project-serum/anchor": "^0.18.2", + "@solana/spl-token": "^0.1.8", + "borsh": "^0.6.0", + "bs58": "^5.0.0" + }, + "dependencies": { + "@project-serum/anchor": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.18.2.tgz", + "integrity": "sha512-uyjiN/3Ipp+4hrZRm/hG18HzGLZyvP790LXrCsGO3IWxSl28YRhiGEpKnZycfMW94R7nxdUoE3wY67V+ZHSQBQ==", + "requires": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.0", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "dependencies": { + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "requires": { + "base-x": "^3.0.2" + } + } + } + }, + "borsh": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.6.0.tgz", + "integrity": "sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q==", + "requires": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + }, + "dependencies": { + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "requires": { + "base-x": "^3.0.2" + } + } + } + }, + "bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "requires": { + "base-x": "^4.0.0" + }, + "dependencies": { + "base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + } + } + } + } + }, + "@project-serum/anchor": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz", + "integrity": "sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA==", + "requires": { + "@project-serum/borsh": "^0.2.5", + "@solana/web3.js": "^1.36.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + } + }, + "@project-serum/borsh": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz", + "integrity": "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==", + "requires": { + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + } + }, + "@project-serum/serum": { + "version": "0.13.55", + "resolved": "https://registry.npmjs.org/@project-serum/serum/-/serum-0.13.55.tgz", + "integrity": "sha512-SPQ4NsuNbBJO3mLGnTYbjt47WCXoNIcW2C9xv0gNXyG62dxgONsAEEgErKv1gT34hWCMPsXFSpatnX6ppriq7w==", + "requires": { + "@project-serum/anchor": "^0.11.1", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "dependencies": { + "@project-serum/anchor": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.11.1.tgz", + "integrity": "sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA==", + "requires": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.0", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "dependencies": { + "@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + } + } + } + } + }, + "@solana/buffer-layout": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz", + "integrity": "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==", + "requires": { + "buffer": "~6.0.3" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } + } + }, + "@solana/buffer-layout-utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz", + "integrity": "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==", + "requires": { + "@solana/buffer-layout": "^4.0.0", + "@solana/web3.js": "^1.32.0", + "bigint-buffer": "^1.1.5", + "bignumber.js": "^9.0.1" + } + }, + "@solana/spl-token": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", + "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", + "requires": { + "@babel/runtime": "^7.10.5", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.0", + "buffer": "6.0.3", + "buffer-layout": "^1.2.0", + "dotenv": "10.0.0" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } + } + }, + "@solana/web3.js": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.42.0.tgz", + "integrity": "sha512-QqGh5DWzrgsWRx4sCPDQIm3390b7buPR16tZI61slQaQwJ2ymrSXPQCe4PPTJEIlzGjCV3dkn2vpT2R32BfK2Q==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "@solana/buffer-layout-utils": "^0.2.0", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "cross-fetch": "^3.1.4", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + }, + "@types/chai": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz", + "integrity": "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==", + "dev": true + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true, + "optional": true + }, + "@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", + "dev": true + }, + "@types/node": { + "version": "12.20.49", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.49.tgz", + "integrity": "sha512-5e6QNb9bkeh4Hni4ktLqUZuUqnGTX/kou2aZkXyxtuYaHXgBm+In1SHR9V+7kDzWzjB08KC2uqt2doDi7cuAAA==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, + "@types/ws": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", + "requires": { + "@types/node": "*" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@uxd-protocol/uxd-client": { + "version": "2.0.0-beta.3", + "resolved": "https://registry.npmjs.org/@uxd-protocol/uxd-client/-/uxd-client-2.0.0-beta.3.tgz", + "integrity": "sha512-YIr2zY0eNRvoD8OuVy0Gx1uhXQHk31xKqV53OhKKrmJwYIUJsC4qXWO7aOGO4lcTCOz76zFu5go4DGTGj/RNvA==", + "requires": { + "@blockworks-foundation/mango-client": "3.4.5", + "@project-serum/anchor": "0.24.2", + "@solana/spl-token": "0.1.8", + "@solana/web3.js": "1.39.1", + "@zero_one/client": "^0.8.7", + "camelcase": "5.3.1" + }, + "dependencies": { + "@blockworks-foundation/mango-client": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.4.5.tgz", + "integrity": "sha512-RQ8WAcUMKtV72TGZ3qLFqcZW17WbDyDMcnCZrzSHp0rWpuThXcKb17/YBJY7TugVRvc6JnV1aJtlibI/oF15Gw==", + "requires": { + "@project-serum/anchor": "^0.21.0", + "@project-serum/serum": "0.13.55", + "@project-serum/sol-wallet-adapter": "^0.2.0", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.31.0", + "big.js": "^6.1.1", + "bn.js": "^5.1.0", + "buffer-layout": "^1.2.1", + "cross-fetch": "^3.1.5", + "dotenv": "^10.0.0", + "toformat": "^2.0.0", + "yargs": "^17.0.1" + }, + "dependencies": { + "@project-serum/anchor": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz", + "integrity": "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==", + "requires": { + "@project-serum/borsh": "^0.2.4", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "cross-fetch": "^3.1.5", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "dependencies": { + "@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + } + } + }, + "@project-serum/sol-wallet-adapter": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz", + "integrity": "sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g==", + "requires": { + "bs58": "^4.0.1", + "eventemitter3": "^4.0.7" + } + } + } + }, + "@solana/web3.js": { + "version": "1.39.1", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.39.1.tgz", + "integrity": "sha512-Q7XnWTAiU7n7GcoINDAAMLO7CJHpm5kPK46HKwJi2x0cusHQ3WFa7QEp6aPzH7tuf7yl/Kw1lYitcwTVOvqARA==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "cross-fetch": "^3.1.4", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + } + } + }, + "@zero_one/client": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/@zero_one/client/-/client-0.8.7.tgz", + "integrity": "sha512-6YmwOZ4aNE5MWLW8nsLQxhtgA/6gq7JL49UgZTL6S1yETLeKUVuesWRfrLj9EZ2YfN/pxOdVmBA+KOAESowiAA==", + "requires": { + "@project-serum/anchor": "^0.20.1", + "@solana/spl-token": "^0.1.8", + "@zero_one/lite-serum": "^0.1.1", + "bn.js": "^5.2.0", + "buffer-layout": "^1.2.2", + "decimal.js": "^10.3.1" + }, + "dependencies": { + "@project-serum/anchor": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.20.1.tgz", + "integrity": "sha512-2TuBmGUn9qeYz6sJINJlElrBuPsaUAtYyUsJ3XplEBf1pczrANAgs5ceJUFzdiqGEWLn+84ObSdBeChT/AXYFA==", + "requires": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.2", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "dependencies": { + "@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + } + } + } + } + }, + "@zero_one/lite-serum": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@zero_one/lite-serum/-/lite-serum-0.1.1.tgz", + "integrity": "sha512-Xo54bHM3KiDaOo436tlMf09DnezgKJD8zY9VUndtgUFwkZB1107MO84AGorZ/dZ5UrbXm6k21P96thexwJKtnA==", + "requires": { + "@project-serum/anchor": "^0.11.1", + "@solana/spl-token": "^0.1.6", + "@solana/web3.js": "^1.21.0", + "bn.js": "^5.1.2", + "buffer-layout": "^1.2.0" + }, + "dependencies": { + "@project-serum/anchor": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.11.1.tgz", + "integrity": "sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA==", + "requires": { + "@project-serum/borsh": "^0.2.2", + "@solana/web3.js": "^1.17.0", + "base64-js": "^1.5.1", + "bn.js": "^5.1.2", + "bs58": "^4.0.1", + "buffer-layout": "^1.2.0", + "camelcase": "^5.3.1", + "crypto-hash": "^1.3.0", + "eventemitter3": "^4.0.7", + "find": "^0.3.0", + "js-sha256": "^0.9.0", + "pako": "^2.0.3", + "snake-case": "^3.0.4", + "toml": "^3.0.0" + }, + "dependencies": { + "@solana/web3.js": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz", + "integrity": "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==", + "requires": { + "@babel/runtime": "^7.12.5", + "@ethersproject/sha2": "^5.5.0", + "@solana/buffer-layout": "^4.0.0", + "bigint-buffer": "^1.1.5", + "bn.js": "^5.0.0", + "borsh": "^0.7.0", + "bs58": "^4.0.1", + "buffer": "6.0.1", + "fast-stable-stringify": "^1.0.0", + "jayson": "^3.4.4", + "js-sha3": "^0.8.0", + "node-fetch": "2", + "rpc-websockets": "^7.4.2", + "secp256k1": "^4.0.2", + "superstruct": "^0.14.2", + "tweetnacl": "^1.0.0" + } + } + } + } + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "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" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "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 + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big.js": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz", + "integrity": "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==" + }, + "bigint-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz", + "integrity": "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==", + "requires": { + "bindings": "^1.3.0" + } + }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + }, + "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 + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "borsh": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz", + "integrity": "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==", + "requires": { + "bn.js": "^5.2.0", + "bs58": "^4.0.0", + "text-encoding-utf-8": "^1.0.2" + } + }, + "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": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "buffer": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", + "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "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 + }, + "buffer-layout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", + "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" + }, + "bufferutil": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz", + "integrity": "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "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" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.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==" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "requires": { + "node-fetch": "2.6.7" + } + }, + "crypto-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz", + "integrity": "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==" + }, + "dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "dev": true + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "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 + } + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, + "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==" + } + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, + "fast-stable-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz", + "integrity": "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "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": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find/-/find-0.3.0.tgz", + "integrity": "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==", + "requires": { + "traverse-chain": "~0.1.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "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 + }, + "fsu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz", + "integrity": "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "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" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "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" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "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-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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": {} + }, + "jayson": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz", + "integrity": "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==", + "requires": { + "@types/connect": "^3.4.33", + "@types/express-serve-static-core": "^4.17.9", + "@types/lodash": "^4.14.159", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "lodash": "^4.17.20", + "uuid": "^8.3.2", + "ws": "^7.4.5" + } + }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", + "dev": true + }, + "lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true + }, + "lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "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 + }, + "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": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", + "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "mocha": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", + "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "4.2.1", + "ms": "2.1.3", + "nanoid": "3.3.1", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, + "mochawesome": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.3.tgz", + "integrity": "sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "diff": "^5.0.0", + "json-stringify-safe": "^5.0.1", + "lodash.isempty": "^4.4.0", + "lodash.isfunction": "^3.0.9", + "lodash.isobject": "^3.0.2", + "lodash.isstring": "^4.0.1", + "mochawesome-report-generator": "^6.2.0", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2" + } + }, + "mochawesome-report-generator": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz", + "integrity": "sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==", + "dev": true, + "requires": { + "chalk": "^4.1.2", + "dateformat": "^4.5.1", + "escape-html": "^1.0.3", + "fs-extra": "^10.0.0", + "fsu": "^1.1.1", + "lodash.isfunction": "^3.0.9", + "opener": "^1.5.2", + "prop-types": "^15.7.2", + "tcomb": "^3.2.17", + "tcomb-validation": "^3.3.0", + "validator": "^13.6.0", + "yargs": "^17.2.1" + }, + "dependencies": { + "yargs": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", + "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "dev": true + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" + }, + "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": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "pako": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz", + "integrity": "sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "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" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "rpc-websockets": { + "version": "7.4.18", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.18.tgz", + "integrity": "sha512-bVu+4qM5CkGVlTqJa6FaAxLbb5uRnyH4te7yjFvoCzbnif7PT4BcvXtNTprHlNvsH+/StB81zUQicxMrUrIomA==", + "requires": { + "@babel/runtime": "^7.17.2", + "bufferutil": "^4.0.1", + "eventemitter3": "^4.0.7", + "utf-8-validate": "^5.0.2", + "uuid": "^8.3.2", + "ws": "^8.5.0" + }, + "dependencies": { + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "requires": {} + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "optional": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "superstruct": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", + "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tcomb": { + "version": "3.2.29", + "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", + "integrity": "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==", + "dev": true + }, + "tcomb-validation": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", + "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", + "dev": true, + "requires": { + "tcomb": "^3.0.0" + } + }, + "text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "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" + } + }, + "toformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", + "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + }, + "toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "traverse-chain": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz", + "integrity": "sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE=" + }, + "ts-mocha": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz", + "integrity": "sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw==", + "dev": true, + "requires": { + "ts-node": "7.0.1", + "tsconfig-paths": "^3.5.0" + } + }, + "ts-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "dev": true, + "requires": { + "arrify": "^1.0.0", + "buffer-from": "^1.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "source-map-support": "^0.5.6", + "yn": "^2.0.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "optional": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "utf-8-validate": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz", + "integrity": "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "requires": {} + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "dependencies": { + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" + } + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 6e57cc67a..4b479f645 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,12 @@ { "license": "SEE LICENSE IN LICENSE.MD", "dependencies": { - "@project-serum/anchor": "^0.21.0", + "@blockworks-foundation/mango-client": "^3.4.5", + "@marinade.finance/marinade-ts-sdk": "3.0.0", + "@project-serum/anchor": "0.24.2", "@solana/spl-token": "^0.1.8", - "@solana/web3.js": "^1.35.0", - "@uxdprotocol/uxd-client": "=5.0.16" + "@solana/web3.js": "1.42.0", + "@uxd-protocol/uxd-client": "2.0.0-beta.3" }, "devDependencies": { "@types/chai": "^4.3.0", diff --git a/programs/uxd/Cargo.toml b/programs/uxd/Cargo.toml index e364053bf..ee04a8960 100644 --- a/programs/uxd/Cargo.toml +++ b/programs/uxd/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "uxd" -version = "3.0.2" +version = "3.1.0" authors = ["acammm "] description = "UXDProtocol Program, managing a redeemable mint backed by a delta neutral position." edition = "2021" +rust-version = "1.56" [lib] crate-type = ["cdylib", "lib"] @@ -15,19 +16,23 @@ no-idl = [] no-log-ix-name = [] cpi = ["no-entrypoint"] test-bpf = [] -default = ["development"] # `anchor build -- --no-default-features --features production` to override +default = ["internal"] # `anchor build -- --no-default-features --features production` to override production = [] development = [] +internal = [] [dependencies] solana-program = "^1.8.0" -spl-token = { version = "^3.3.0", features = ["no-entrypoint"] } -mango = { version = "3.4.2", git = "https://github.com/blockworks-foundation/mango-v3", features = ["no-entrypoint"] } -anchor-lang = { version = "0.21.0", features = ["init-if-needed"] } -anchor-spl = "0.21.0" +spl-token = { version = "3.3.0", features = ["no-entrypoint"] } +mango = { tag = "v3.4.6", git = "https://github.com/blockworks-foundation/mango-v3", features = ["no-entrypoint"] } +anchor-lang = "0.24.2" +anchor-spl = "0.24.2" +anchor-comp = { branch = "mango_msol", git = "https://github.com/UXDProtocol/anchor-comp", default-features = false, features = ["no-entrypoint", "production"] } fixed = "^1.9.0" -thiserror = "^1.0.30" -num_enum = "^0.5.6" +num-traits = "0.2.14" +spl-math = { version = "0.1.0", features = ["no-entrypoint"] } +marinade-finance = { git = "https://github.com/UXDProtocol/liquid-staking-program", features = ["no-entrypoint"] } +marinade-onchain-helper = { git = "https://github.com/UXDProtocol/marinade-onchain-helper" } [dev-dependencies] proptest = "1.0.0" diff --git a/programs/uxd/proptest-regressions/test/mango_utils/test_order_delta.txt b/programs/uxd/proptest-regressions/test/mango_utils/test_order_delta.txt new file mode 100644 index 000000000..6113cd342 --- /dev/null +++ b/programs/uxd/proptest-regressions/test/mango_utils/test_order_delta.txt @@ -0,0 +1,8 @@ +# 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 d3a30e394d2deaed6eb8457f240faa5a808e391803a83b5a2414ed218f567ef9 # shrinks to taker_base = 0, taker_quote = 0, base_position = 0, quote_position = 0, taker_base_post = 0, taker_quote_post = -1, base_position_post = 0, quote_position_post = 0, quote_lot_size = 1 +cc be8c5f3656786c8c0afd633e28b28ecb1322f4d8736610a11407df79232387e1 # shrinks to taker_base = 0, taker_quote = 0, base_position = 0, quote_position = 0, taker_base_post = 0, taker_quote_post = 0, base_position_post = -1, quote_position_post = 0, base_lot_size = 1 diff --git a/programs/uxd/proptest-regressions/test/mango_utils/test_perp_account_utils.txt b/programs/uxd/proptest-regressions/test/mango_utils/test_perp_account_utils.txt new file mode 100644 index 000000000..f5e8e815d --- /dev/null +++ b/programs/uxd/proptest-regressions/test/mango_utils/test_perp_account_utils.txt @@ -0,0 +1,7 @@ +# 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 f009ebd31264c6d8dd237af9fee7e7e002f49a907db7b7b329aac7372e8eb26b # shrinks to taker_base = 7986054603602732001, base_position = 1237317433252043807 diff --git a/programs/uxd/proptest-regressions/test/mango_utils/test_quote_mintable.txt b/programs/uxd/proptest-regressions/test/mango_utils/test_quote_mintable.txt new file mode 100644 index 000000000..284a526c6 --- /dev/null +++ b/programs/uxd/proptest-regressions/test/mango_utils/test_quote_mintable.txt @@ -0,0 +1,7 @@ +# 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 f47abe819f5930622a594940e9ad7cd8526f8c0d6713f3d7d869d145a1f6d73a # shrinks to perp_unrealized_pnl = 0, quote_minted = -18446744073709551616 diff --git a/programs/uxd/src/error.rs b/programs/uxd/src/error.rs index 2be6b028c..3235ec359 100644 --- a/programs/uxd/src/error.rs +++ b/programs/uxd/src/error.rs @@ -1,231 +1,94 @@ -use crate::UxdResult; -use crate::MAX_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP; -use crate::MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP; -use anchor_lang::prelude::error; -use anchor_lang::prelude::ProgramError; -use mango::error::MangoError; -use num_enum::IntoPrimitive; -use thiserror::Error; +use anchor_lang::prelude::*; -#[repr(u8)] -#[derive(Debug, Clone, Eq, PartialEq, Copy)] -pub enum SourceFileId { - InstructionInitializeController = 0, - InstructionSetRedeemableGlobalSupplyCap = 1, - InstructionSetMangoDepositoriesRedeemableSoftCap = 2, - InstructionRegisterMangoDepository = 3, - InstructionMangoDexMintWithMangoDepository = 4, - InstructionMangoDexRedeemFromMangoDepository = 5, - InstructionMangoDexDepositInsuranceToMangoDepository = 6, - InstructionMangoDexWithdrawInsuranceFromMangoDepository = 7, - MangoProgramAnchorMango = 8, - MangoProgramDeposit = 9, - MangoProgramInitMangoAccount = 10, - MangoProgramPlacePerpOrder = 11, - MangoProgramWithdraw = 12, - MangoUtilsLimitUtils = 13, - MangoUtilsOrderDelta = 14, - MangoUtilsOrder = 15, - MangoUtilsPerpAccountUtils = 16, - MangoUtilsPerpInfo = 17, - StateController = 18, - StateMangoDepository = 19, - Error = 20, - Lib = 21, - InstructionMangoDexRebalanceMangoDepositoryLite = 22, - InstructionMangoDexMigrateMangoDepositoryToV2 = 23, -} - -impl std::fmt::Display for SourceFileId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - SourceFileId::InstructionInitializeController => { - write!(f, "src/instructions/initialize_controller.rs") - } - SourceFileId::InstructionSetRedeemableGlobalSupplyCap => { - write!(f, "src/instructions/set_redeemable_global_supply_cap.rs") - } - SourceFileId::InstructionSetMangoDepositoriesRedeemableSoftCap => { - write!( - f, - "src/instructions/set_mango_depositories_redeemable_soft_cap.rs" - ) - } - SourceFileId::InstructionRegisterMangoDepository => { - write!(f, "src/instructions/register_mango_depository.rs") - } - SourceFileId::InstructionMangoDexMintWithMangoDepository => { - write!( - f, - "src/instructions/mango_dex/mint_with_mango_depository.rs" - ) - } - SourceFileId::InstructionMangoDexRedeemFromMangoDepository => { - write!( - f, - "src/instructions/mango_dex/redeem_from_mango_depository.rs" - ) - } - SourceFileId::InstructionMangoDexDepositInsuranceToMangoDepository => { - write!( - f, - "src/instructions/mango_dex/deposit_insurance_to_mango_depository.rs" - ) - } - SourceFileId::InstructionMangoDexWithdrawInsuranceFromMangoDepository => { - write!( - f, - "src/instructions/mango_dex/withdraw_insurance_from_mango_depository.rs" - ) - } - SourceFileId::MangoProgramAnchorMango => { - write!(f, "src/mango_program/anchor_mango.rs") - } - SourceFileId::MangoProgramDeposit => { - write!(f, "src/mango_program/deposit.rs") - } - SourceFileId::MangoProgramInitMangoAccount => { - write!(f, "src/mango_program/init_mango_account.rs") - } - SourceFileId::MangoProgramPlacePerpOrder => { - write!(f, "src/mango_program/place_perp_order.rs") - } - SourceFileId::MangoProgramWithdraw => { - write!(f, "src/mango_program/withdraw.rs") - } - SourceFileId::MangoUtilsLimitUtils => { - write!(f, "src/mango_utils/limit_utils.rs") - } - SourceFileId::MangoUtilsOrderDelta => { - write!(f, "src/mango_utils/order_delta.rs") - } - SourceFileId::MangoUtilsOrder => { - write!(f, "src/mango_utils/order.rs") - } - SourceFileId::MangoUtilsPerpAccountUtils => { - write!(f, "src/mango_utils/perp_account_utils.rs") - } - SourceFileId::MangoUtilsPerpInfo => { - write!(f, "src/mango_utils/perp_info.rs") - } - SourceFileId::StateController => { - write!(f, "src/state/controller.rs") - } - SourceFileId::StateMangoDepository => { - write!(f, "src/state/mango_depository.rs") - } - SourceFileId::Error => { - write!(f, "src/error.rs") - } - SourceFileId::Lib => { - write!(f, "src/lib.rs") - } - SourceFileId::InstructionMangoDexRebalanceMangoDepositoryLite => { - write!( - f, - "src/instructions/mango_dex/rebalance_mango_depository_lite.rs" - ) - } - SourceFileId::InstructionMangoDexMigrateMangoDepositoryToV2 => { - write!( - f, - "src/instructions/mango_dex/migrate_mango_depository_to_v2.rs" - ) - } - } - } -} - -#[derive(Error, Debug, PartialEq, Eq)] +#[error_code] pub enum UxdError { - #[error(transparent)] - ProgramError(#[from] ProgramError), - #[error("{uxd_error_code}; {source_file_id}:{line}")] - UxdErrorCode { - uxd_error_code: UxdErrorCode, - line: u32, - source_file_id: SourceFileId, - }, -} - -// GENERIC PROGRAM ERRORS -#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] -#[repr(u32)] -pub enum UxdErrorCode { - #[error("The redeemable mint decimals must be between 0 and 9 (inclusive).")] - InvalidRedeemableMintDecimals = 0, - #[error("Redeemable global supply above {}.", MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP)] + /// Program errors + /// + #[msg("The redeemable mint decimals must be between 0 and 9 (inclusive).")] + InvalidRedeemableMintDecimals, + #[msg("Redeemable global supply above.")] InvalidRedeemableGlobalSupplyCap, - #[error("The associated mango root bank index cannot be found for the deposited coin..")] + #[msg("The associated mango root bank index cannot be found for the deposited coin..")] RootBankIndexNotFound, - #[error("The slippage value is invalid. Must be in the [0...1000] range points.")] - InvalidSlippage, - #[error("Could not fill the order given order book state and provided slippage.")] + #[msg("The provided limit_price value is invalid, must be > 0")] + InvalidLimitPrice, + #[msg("Could not fill the order given order book state and provided slippage.")] EffectiveOrderPriceBeyondLimitPrice, - #[error("Collateral amount must be > 0 in order to mint.")] + #[msg("Collateral amount cannot be 0")] InvalidCollateralAmount, - #[error("The balance of the collateral ATA is not enough to fulfill the mint operation.")] - InsufficientCollateralAmount, - #[error("The redeemable amount for redeem must be superior to 0.")] + #[msg("Quote amount must be > 0 in order to mint.")] + InvalidQuoteAmount, + #[msg("Redeemable amount must be > 0 in order to redeem.")] InvalidRedeemableAmount, - #[error("The balance of the redeemable ATA is not enough to fulfill the redeem operation.")] + #[msg("The balance of the collateral ATA is not enough to fulfill the mint operation.")] + InsufficientCollateralAmount, + #[msg("The balance of the quote ATA is not enough to fulfil the mint operation.")] + InsufficientQuoteAmountMint, + #[msg("The balance of the redeemable ATA is not enough to fulfil the redeem operation.")] + InsufficientRedeemableAmountMint, + #[msg("The balance of the redeemable ATA is not enough to fulfill the redeem operation.")] InsufficientRedeemableAmount, - #[error("The perp position could not be fully filled with the provided slippage.")] + #[msg("The perp position could not be fully filled with the provided slippage.")] PerpOrderPartiallyFilled, - #[error("Minting amount would go past the Redeemable Global Supply Cap.")] - RedeemableGlobalSupplyCapReached = 10, - #[error("Operation not allowed due to being over the Redeemable soft Cap.")] + #[msg("Minting amount would go past the Redeemable Global Supply Cap.")] + RedeemableGlobalSupplyCapReached, + #[msg("Operation not allowed due to being over the Mango Redeemable soft Cap.")] MangoDepositoriesSoftCapOverflow, - #[error("Cannot register more mango depositories, the limit has been reached.")] + #[msg("Cannot register more mango depositories, the limit has been reached.")] MaxNumberOfMangoDepositoriesRegisteredReached, - #[error("The amount to withdraw from the Insurance Fund must be superior to zero..")] + #[msg("The amount to withdraw from the Insurance Fund must be superior to zero..")] InvalidInsuranceAmount, - #[error("The Insurance ATA from authority doesn't have enough balance.")] - InsufficientAuthorityInsuranceAmount, - #[error("The rebalanced amount must be superior to zero..")] + #[msg("The Quote ATA from authority doesn't have enough balance.")] + InsufficientAuthorityQuoteAmount, + #[msg("The rebalanced amount must be superior to zero..")] InvalidRebalancedAmount, - #[error("Insufficient order book depth for order.")] + #[msg("Insufficient order book depth for order.")] InsufficientOrderBookDepth, - #[error("The executed order size does not match the expected one.")] + #[msg("The executed order size does not match the expected one.")] InvalidExecutedOrderSize, - #[error("Could not find the perp market index for the given collateral.")] - MangoPerpMarketIndexNotFound, - #[error( - "Mango depositories redeemable soft cap above {}.", - MAX_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP - )] + #[msg("Mango depositories redeemable soft cap above.")] InvalidMangoDepositoriesRedeemableSoftCap, - #[error("Quote_lot_delta can't be 0.")] - InvalidQuoteDelta = 20, - #[error("The perp order wasn't executed in the right direction.")] + #[msg("Quote_lot_delta can't be 0.")] + InvalidQuoteDelta, + #[msg("The perp order wasn't executed in the right direction.")] InvalidOrderDirection, - #[error("Math error.")] + #[msg("Math error.")] MathError, - #[error("The order couldn't be executed with the provided slippage.")] + #[msg("The order couldn't be executed with the provided slippage.")] SlippageReached, - #[error("The rebalancing amount must be above 0.")] + #[msg("The rebalancing amount must be above 0.")] InvalidRebalancingAmount, - #[error("The Quote amount in the provided user_quote ATA must be >= max_amount_rebalancing.")] + #[msg("The Quote amount in the provided user_quote ATA must be >= max_amount_rebalancing.")] InsufficientQuoteAmount, - #[error("The PnL polarity provided is not the same as the perp position's one.")] + #[msg("The PnL polarity provided is not the same as the perp position's one.")] InvalidPnlPolarity, - #[error("The rebalanced amount doesn't match the expected rebalance amount.")] + #[msg("The rebalanced amount doesn't match the expected rebalance amount.")] RebalancingError, - #[error("A bump was expected but is missing.")] + #[msg("A bump was expected but is missing.")] BumpError, - #[error("The order is below size is below the min lot size.")] + #[msg("The order is below size is below the min lot size.")] OrderSizeBelowMinLotSize, - #[error("The collateral delta post perp order doesn't match the planned one.")] + #[msg("The collateral delta post perp order doesn't match the planned one.")] InvalidCollateralDelta, - #[error("The order quantity is below contract_size of the perp market.")] + #[msg("The perp market index could not be found for this MangoMarkets Pair.")] + MangoPerpMarketIndexNotFound, + #[msg("Could not load the provided MangoGroup account.")] + InvalidMangoGroup, + #[msg("The order quantity is below contract_size of the perp market.")] QuantityBelowContractSize, - #[error("MangoErrorCode::Default Check the source code for more info")] - Default = u32::MAX, -} + #[msg("The amount trying to be quote minted is larger than quote mintable.")] + QuoteAmountTooHigh, + #[msg("The amount trying to be quote redeemed is larger than quote redeemable.")] + RedeemableAmountTooHigh, + #[msg("Minting is disabled for the current depository")] + MintingDisabled, + #[msg("Minting is already disabled/enabled")] + MintingAlreadyDisabledOrEnabled, + #[msg("Msol swapping is disabled")] + MSolSwappingDisabled, -// ANCHOR IDL ERRORS -#[error(offset = 200)] -pub enum UxdIdlErrorCode { + /// Anchor DSL related errors + /// #[msg("Only the Program initializer authority can access this instructions.")] InvalidAuthority, #[msg("The Depository's controller doesn't match the provided Controller.")] @@ -236,111 +99,30 @@ pub enum UxdIdlErrorCode { InvalidCollateralMint, #[msg("The provided quote mint does not match the depository's quote mint.")] InvalidQuoteMint, - #[msg("The authority's Quote ATA's mint does not match the Depository's one.")] - InvalidAuthorityQuoteATAMint, #[msg("The Mango Account isn't the Depository one.")] InvalidMangoAccount, #[msg("The Redeemable Mint provided does not match the Controller's one.")] InvalidRedeemableMint, -} - -impl From for ProgramError { - fn from(e: UxdError) -> ProgramError { - match e { - UxdError::ProgramError(pe) => pe, - UxdError::UxdErrorCode { - uxd_error_code, - line: _, - source_file_id: _, - } => ProgramError::Custom(uxd_error_code.into()), - } - } -} - -impl From for UxdError { - fn from(me: MangoError) -> Self { - let pe: ProgramError = me.into(); - pe.into() - } -} - -#[inline] -pub fn check_assert( - cond: bool, - uxd_error_code: UxdErrorCode, - line: u32, - source_file_id: SourceFileId, -) -> UxdResult<()> { - if cond { - Ok(()) - } else { - Err(UxdError::UxdErrorCode { - uxd_error_code, - line, - source_file_id, - }) - } -} - -#[macro_export] -macro_rules! declare_check_assert_macros { - ($source_file_id:expr) => { - #[allow(unused_macros)] - macro_rules! check { - ($cond:expr, $err:expr) => { - check_assert($cond, $err, line!(), $source_file_id) - }; - } - - #[allow(unused_macros)] - macro_rules! check_eq { - ($x:expr, $y:expr, $err:expr) => { - check_assert($x == $y, $err, line!(), $source_file_id) - }; - } - - #[allow(unused_macros)] - macro_rules! throw { - () => { - UxdError::UxdErrorCode { - uxd_error_code: UxdErrorCode::Default, - line: line!(), - source_file_id: $source_file_id, - } - }; - } - - #[allow(unused_macros)] - macro_rules! throw_err { - ($err:expr) => { - UxdError::UxdErrorCode { - uxd_error_code: $err, - line: line!(), - source_file_id: $source_file_id, - } - }; - } + #[msg("The provided perp_market is not the one tied to this Depository.")] + InvalidDexMarket, + #[msg("The provided token account is not owner by the expected party.")] + InvalidOwner, + #[msg("The max base quantity must be above 0.")] + InvalidMaxBaseQuantity, + #[msg("The max quote quantity must be above 0.")] + InvalidMaxQuoteQuantity, - #[allow(unused_macros)] - macro_rules! math_err { - () => { - UxdError::UxdErrorCode { - uxd_error_code: UxdErrorCode::MathError, - line: line!(), - source_file_id: $source_file_id, - } - }; - } + #[msg("Target liquidity ratio for msol config exceed 100%")] + TargetLiquidityRatioExceedMax, + #[msg("SOL/mSOL swap has already enabled / disabled")] + InvalidEnablingMsolSwap, + #[msg("Must use native mint for setting msol config")] + InvalidNonNativeMintUsed, + #[msg("Must use native mint for passthrough account")] + InvalidNonNativeMintAtaUsed, + #[msg("Must use msol for passthrough account")] + InvalidNonMSolMintAtaUsed, - #[allow(unused_macros)] - macro_rules! bump_err { - () => { - UxdError::UxdErrorCode { - uxd_error_code: UxdErrorCode::BumpError, - line: line!(), - source_file_id: $source_file_id, - } - }; - } - }; + #[msg("Default - Check the source code for more info")] + Default, } diff --git a/programs/uxd/src/events.rs b/programs/uxd/src/events.rs index 020113f3f..36e7744d2 100644 --- a/programs/uxd/src/events.rs +++ b/programs/uxd/src/events.rs @@ -1,6 +1,5 @@ -use anchor_lang::prelude::*; - use crate::instructions::rebalance_mango_depository_lite::PnlPolarity; +use anchor_lang::prelude::*; // - Global Events ------------------------------------------------------------ @@ -91,31 +90,9 @@ pub struct SetMangoDepositoryRedeemableSoftCapEvent { pub redeemable_soft_cap: u64, } -// - Mango Depositories ------------------------------------------------------- - -/// Event called in [instructions::mango_dex::deposit_insurance_to_mango_depository::handler]. -#[event] -pub struct DepositInsuranceToMangoDepositoryEvent { - /// The controller version. - #[index] - pub version: u8, - /// The controller. - #[index] - pub controller: Pubkey, - /// The depository. - #[index] - pub depository: Pubkey, - // The insurance mint. - pub insurance_mint: Pubkey, - // The insurance mint decimals. - pub insurance_mint_decimals: u8, - // The deposited amount in native units. - pub deposited_amount: u64, -} - -/// Event called in [instructions::mango_dex::deposit_insurance_to_mango_depository::handler]. +/// Event called in [instructions::*::deposit_insurance_to_*_depository::handler]. #[event] -pub struct DepositInsuranceToMangoDepositoryEventV2 { +pub struct DepositInsuranceToDepositoryEvent { /// The controller version. #[index] pub version: u8, @@ -153,9 +130,9 @@ pub struct WithdrawInsuranceFromMangoDepositoryEvent { pub withdrawn_amount: u64, } -/// Event called in [instructions::mango_dex::withdraw_insurance_from_mango_depository::handler]. +// Event called in [instructions::*_dex::withdraw_insurance_from_*_depository::handler]. #[event] -pub struct WithdrawInsuranceFromMangoDepositoryEventV2 { +pub struct WithdrawInsuranceFromDepositoryEvent { /// The controller version. #[index] pub version: u8, @@ -188,19 +165,19 @@ pub struct MintWithMangoDepositoryEvent { /// The user making the call. #[index] pub user: Pubkey, - // The collateral amount in native units. + // The collateral amount in native units. (input) pub collateral_amount: u64, - // The user selected slippage. - pub slippage: u32, + // The user provided limit_price. (input) + pub limit_price: f32, // The different deltas after successful minting operation. - pub collateral_delta: u64, - pub redeemable_delta: u64, - pub fee_delta: u64, + pub base_delta: i64, + pub quote_delta: i64, + pub fee_delta: i64, } -/// Event called in [instructions::mango_dex::redeem_from_mango_depository::handler]. +/// Event called in [instructions::*_dex::redeem_from_*_depository::handler]. #[event] -pub struct RedeemFromMangoDepositoryEvent { +pub struct RedeemFromDepositoryEvent { /// The controller version. #[index] pub version: u8, @@ -213,14 +190,14 @@ pub struct RedeemFromMangoDepositoryEvent { /// The user making the call. #[index] pub user: Pubkey, - // The redeemable amount in native units. + // The redeemable amount in native units. (input) pub redeemable_amount: u64, - // The user selected slippage. - pub slippage: u32, + // The user provided limit_price. (input) + pub limit_price: f32, // The different deltas after successful minting operation. - pub collateral_delta: u64, - pub redeemable_delta: u64, - pub fee_delta: u64, + pub base_delta: i64, + pub quote_delta: i64, + pub fee_delta: i64, } /// Event called in [instructions::rebalance_mango_depository_lite::handler]. @@ -241,16 +218,35 @@ pub struct RebalanceMangoDepositoryLiteEvent { /// The user making the call. #[index] pub user: Pubkey, - // The polarity of the rebalancing operation + // The polarity of the rebalancing operation. (input) pub polarity: PnlPolarity, // The desired rebalancing amount in Quote native units. (input) pub rebalancing_amount: u64, // The actual rebalancing amount in Quote native units. pub rebalanced_amount: u64, - // The user selected slippage. - pub slippage: u32, + // The user provided limit_price. (input) + pub limit_price: f32, // The different deltas after successful rebalancing operation. - pub collateral_delta: u64, - pub quote_delta: u64, - pub fee_delta: u64, + pub base_delta: i64, + pub quote_delta: i64, + pub fee_delta: i64, +} + +/// Event called in [instructions::create_depository_msol_config::handler]. +#[event] +pub struct CreateDepositoryMSolConfigEvent { + /// The controller version. + #[index] + pub version: u8, + /// The msol config created. + #[index] + pub msol_config: Pubkey, + /// The controller. + #[index] + pub controller: Pubkey, + /// The depository. + #[index] + pub depository: Pubkey, + pub enabled: bool, + pub target_liquidity_ratio: u16, } diff --git a/programs/uxd/src/instructions/initialize_controller.rs b/programs/uxd/src/instructions/initialize_controller.rs index fbe9a5259..8628a9c66 100644 --- a/programs/uxd/src/instructions/initialize_controller.rs +++ b/programs/uxd/src/instructions/initialize_controller.rs @@ -1,13 +1,9 @@ -use crate::declare_check_assert_macros; -use crate::error::check_assert; -use crate::error::SourceFileId; +use crate::error::UxdError; use crate::events::InitializeControllerEvent; use crate::Controller; -use crate::UxdError; -use crate::UxdErrorCode; -use crate::UxdResult; use crate::CONTROLLER_ACCOUNT_VERSION; use crate::CONTROLLER_NAMESPACE; +use crate::CONTROLLER_SPACE; use crate::DEFAULT_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP; use crate::DEFAULT_REDEEMABLE_GLOBAL_SUPPLY_CAP; use crate::REDEEMABLE_MINT_NAMESPACE; @@ -16,8 +12,6 @@ use anchor_lang::prelude::*; use anchor_spl::token::Mint; use anchor_spl::token::Token; -declare_check_assert_macros!(SourceFileId::InstructionInitializeController); - /// Takes 7 accounts - 4 used locally - 0 for CPI - 2 Programs - 1 Sysvar #[derive(Accounts)] #[instruction( @@ -37,8 +31,9 @@ pub struct InitializeController<'info> { seeds = [CONTROLLER_NAMESPACE], bump, payer = payer, + space = CONTROLLER_SPACE )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #4 The redeemable mint managed by the `controller` instance #[account( @@ -62,32 +57,37 @@ pub struct InitializeController<'info> { pub rent: Sysvar<'info, Rent>, } -pub fn handler(ctx: Context, redeemable_mint_decimals: u8) -> UxdResult { +pub fn handler(ctx: Context, redeemable_mint_decimals: u8) -> Result<()> { + let controller = &mut ctx.accounts.controller.load_init()?; let redeemable_mint_unit = 10_u64 .checked_pow(redeemable_mint_decimals.into()) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; - ctx.accounts.controller.bump = *ctx.bumps.get("controller").ok_or(bump_err!())?; - ctx.accounts.controller.redeemable_mint_bump = - *ctx.bumps.get("redeemable_mint").ok_or(bump_err!())?; - ctx.accounts.controller.version = CONTROLLER_ACCOUNT_VERSION; - ctx.accounts.controller.authority = ctx.accounts.authority.key(); - ctx.accounts.controller.redeemable_mint = ctx.accounts.redeemable_mint.key(); - ctx.accounts.controller.redeemable_mint_decimals = redeemable_mint_decimals; + controller.bump = *ctx + .bumps + .get("controller") + .ok_or_else(|| error!(UxdError::BumpError))?; + controller.redeemable_mint_bump = *ctx + .bumps + .get("redeemable_mint") + .ok_or_else(|| error!(UxdError::BumpError))?; + controller.version = CONTROLLER_ACCOUNT_VERSION; + controller.authority = ctx.accounts.authority.key(); + controller.redeemable_mint = ctx.accounts.redeemable_mint.key(); + controller.redeemable_mint_decimals = redeemable_mint_decimals; // Default to 1 Million redeemable total cap - ctx.accounts.controller.redeemable_global_supply_cap = DEFAULT_REDEEMABLE_GLOBAL_SUPPLY_CAP + controller.redeemable_global_supply_cap = DEFAULT_REDEEMABLE_GLOBAL_SUPPLY_CAP .checked_mul(redeemable_mint_unit.into()) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; // Default to 10 Thousand redeemable per mint/redeem - ctx.accounts - .controller - .mango_depositories_redeemable_soft_cap = DEFAULT_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP - .checked_mul(redeemable_mint_unit) - .ok_or(math_err!())?; - ctx.accounts.controller.redeemable_circulating_supply = u128::MIN; + controller.mango_depositories_redeemable_soft_cap = + DEFAULT_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP + .checked_mul(redeemable_mint_unit) + .ok_or_else(|| error!(UxdError::MathError))?; + controller.redeemable_circulating_supply = u128::MIN; emit!(InitializeControllerEvent { - version: ctx.accounts.controller.version, + version: controller.version, controller: ctx.accounts.controller.key(), authority: ctx.accounts.authority.key(), }); @@ -97,11 +97,11 @@ pub fn handler(ctx: Context, redeemable_mint_decimals: u8) // Validate input arguments impl<'info> InitializeController<'info> { // Asserts that the redeemable mint decimals is between 0 and 9. - pub fn validate(&self, decimals: u8) -> ProgramResult { - check!( + pub fn validate(&self, decimals: u8) -> Result<()> { + require!( decimals <= SOLANA_MAX_MINT_DECIMALS, - UxdErrorCode::InvalidRedeemableMintDecimals - )?; + UxdError::InvalidRedeemableMintDecimals + ); Ok(()) } } diff --git a/programs/uxd/src/instructions/mango_dex/deposit_insurance_to_mango_depository.rs b/programs/uxd/src/instructions/mango_dex/deposit_insurance_to_mango_depository.rs index e497bc286..a6a2f53a0 100644 --- a/programs/uxd/src/instructions/mango_dex/deposit_insurance_to_mango_depository.rs +++ b/programs/uxd/src/instructions/mango_dex/deposit_insurance_to_mango_depository.rs @@ -1,24 +1,17 @@ -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; -use crate::events::DepositInsuranceToMangoDepositoryEventV2; -use crate::mango_program; -use crate::AccountingEvent; +use crate::error::UxdError; +use crate::events::DepositInsuranceToDepositoryEvent; use crate::Controller; use crate::MangoDepository; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MANGO_ACCOUNT_NAMESPACE; use crate::MANGO_DEPOSITORY_NAMESPACE; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; use anchor_lang::prelude::*; -use anchor_spl::token::Mint; use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; -declare_check_assert_macros!(SourceFileId::InstructionMangoDexDepositInsuranceToMangoDepository); - -/// Takes 14 accounts - 7 used locally - 5 for MangoMarkets CPI - 2 Programs +/// Takes 12 accounts #[derive(Accounts)] pub struct DepositInsuranceToMangoDepository<'info> { /// #1 Authored call accessible only to the signer matching Controller.authority @@ -27,90 +20,86 @@ pub struct DepositInsuranceToMangoDepository<'info> { /// #2 The top level UXDProgram on chain account managing the redeemable mint #[account( seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump, - has_one = authority @UxdIdlErrorCode::InvalidAuthority, + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #3 UXDProgram on chain account bound to a Controller instance /// The `MangoDepository` manages a MangoAccount for a single Collateral #[account( mut, - seeds = [MANGO_DEPOSITORY_NAMESPACE, collateral_mint.key().as_ref()], - bump = depository.bump, - has_one = controller @UxdIdlErrorCode::InvalidController, - constraint = controller.registered_mango_depositories.contains(&depository.key()) @UxdIdlErrorCode::InvalidDepository - )] - pub depository: Box>, - - /// #4 The collateral mint used by the `depository` instance - #[account( - constraint = collateral_mint.key() == depository.collateral_mint @UxdIdlErrorCode::InvalidCollateralMint + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, )] - pub collateral_mint: Box>, + pub depository: AccountLoader<'info, MangoDepository>, - /// #5 The quote mint used by the `depository` instance - #[account( - constraint = quote_mint.key() == depository.quote_mint @UxdIdlErrorCode::InvalidQuoteMint - )] - pub quote_mint: Box>, - - /// #6 The `authority`'s ATA for the `quote_mint` + /// #4 The `authority`'s ATA for the `quote_mint` /// Will be debited during this call #[account( mut, - associated_token::mint = quote_mint, - associated_token::authority = authority, + constraint = authority_quote.mint == depository.load()?.quote_mint @UxdError::InvalidQuoteMint, + constraint = &authority_quote.owner == authority.key @UxdError::InvalidOwner, )] pub authority_quote: Box>, - /// #7 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// #5 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered #[account( mut, - seeds = [MANGO_ACCOUNT_NAMESPACE, collateral_mint.key().as_ref()], - bump = depository.mango_account_bump, - constraint = depository.mango_account == depository_mango_account.key() @UxdIdlErrorCode::InvalidMangoAccount, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, )] - pub depository_mango_account: AccountInfo<'info>, + pub mango_account: AccountInfo<'info>, - /// #8 [MangoMarkets CPI] Index grouping perp and spot markets - pub mango_group: AccountInfo<'info>, + /// #6 [MangoMarkets CPI] Index grouping perp and spot markets + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, - /// #9 [MangoMarkets CPI] Cache - pub mango_cache: AccountInfo<'info>, + /// #7 [MangoMarkets CPI] Cache + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, - /// #10 [MangoMarkets CPI] Root Bank for the `depository`'s `quote_mint` - pub mango_root_bank: AccountInfo<'info>, + /// #8 [MangoMarkets CPI] Root Bank for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank: UncheckedAccount<'info>, - /// #11 [MangoMarkets CPI] Node Bank for the `depository`'s `quote_mint` + /// #9 [MangoMarkets CPI] Node Bank for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_node_bank: AccountInfo<'info>, + pub mango_node_bank: UncheckedAccount<'info>, - /// #12 [MangoMarkets CPI] Vault for the `depository`'s `quote_mint` + /// #10 [MangoMarkets CPI] Vault for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_vault: Account<'info, TokenAccount>, + pub mango_vault: UncheckedAccount<'info>, - /// #13 Token Program + /// #11 Token Program pub token_program: Program<'info, Token>, - /// #14 MangoMarketv3 Program - pub mango_program: Program<'info, mango_program::Mango>, + /// #12 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, } -pub fn handler( - ctx: Context, - amount: u64, // native units -) -> UxdResult { - let collateral_mint = ctx.accounts.collateral_mint.key(); +pub fn handler(ctx: Context, amount: u64) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let collateral_mint = depository.collateral_mint; + let depository_bump = depository.bump; + drop(depository); let depository_signer_seeds: &[&[&[u8]]] = &[&[ MANGO_DEPOSITORY_NAMESPACE, collateral_mint.as_ref(), - &[ctx.accounts.depository.bump], + &[depository_bump], ]]; // - 1 [DEPOSIT INSURANCE TO MANGO] --------------------------------------- - mango_program::deposit( + mango_markets_v3::deposit( ctx.accounts .into_deposit_to_mango_context() .with_signer(depository_signer_seeds), @@ -118,14 +107,19 @@ pub fn handler( )?; // - 2 [UPDATE ACCOUNTING] ------------------------------------------------ - ctx.accounts.update_accounting(amount)?; - - emit!(DepositInsuranceToMangoDepositoryEventV2 { - version: ctx.accounts.controller.version, + let depository = &mut ctx.accounts.depository.load_mut()?; + depository.insurance_amount_deposited = depository + .insurance_amount_deposited + .checked_add(amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + + let controller = ctx.accounts.controller.load()?; + emit!(DepositInsuranceToDepositoryEvent { + version: controller.version, controller: ctx.accounts.controller.key(), depository: ctx.accounts.depository.key(), - quote_mint: ctx.accounts.depository.quote_mint, - quote_mint_decimals: ctx.accounts.depository.quote_mint_decimals, + quote_mint: depository.quote_mint, + quote_mint_decimals: depository.quote_mint_decimals, deposited_amount: amount, }); @@ -135,16 +129,15 @@ pub fn handler( impl<'info> DepositInsuranceToMangoDepository<'info> { pub fn into_deposit_to_mango_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Deposit<'info>> { - let cpi_accounts = mango_program::Deposit { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.authority.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank.to_account_info(), - mango_node_bank: self.mango_node_bank.to_account_info(), - mango_vault: self.mango_vault.to_account_info(), - token_program: self.token_program.to_account_info(), + root_bank: self.mango_root_bank.to_account_info(), + node_bank: self.mango_node_bank.to_account_info(), + vault: self.mango_vault.to_account_info(), owner_token_account: self.authority_quote.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); @@ -152,23 +145,14 @@ impl<'info> DepositInsuranceToMangoDepository<'info> { } } -// Additional convenience methods related to the inputted accounts -impl<'info> DepositInsuranceToMangoDepository<'info> { - fn update_accounting(&mut self, insurance_delta: u64) -> ProgramResult { - self.depository - .update_insurance_amount_deposited(&AccountingEvent::Deposit, insurance_delta)?; - Ok(()) - } -} - // Validate input arguments impl<'info> DepositInsuranceToMangoDepository<'info> { - pub fn validate(&self, amount: u64) -> ProgramResult { - check!(amount > 0, UxdErrorCode::InvalidInsuranceAmount)?; - check!( + pub fn validate(&self, amount: u64) -> Result<()> { + require!(amount != 0, UxdError::InvalidInsuranceAmount); + require!( self.authority_quote.amount >= amount, - UxdErrorCode::InsufficientAuthorityInsuranceAmount - )?; + UxdError::InsufficientAuthorityQuoteAmount + ); Ok(()) } } diff --git a/programs/uxd/src/instructions/mango_dex/disable_depository_minting.rs b/programs/uxd/src/instructions/mango_dex/disable_depository_minting.rs new file mode 100644 index 000000000..0bccbfcf6 --- /dev/null +++ b/programs/uxd/src/instructions/mango_dex/disable_depository_minting.rs @@ -0,0 +1,49 @@ +use crate::error::UxdError; +use crate::Controller; +use crate::MangoDepository; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use anchor_lang::prelude::*; + +/// Takes 3 accounts +#[derive(Accounts)] +pub struct DisableDepositoryMinting<'info> { + /// #1 Authored call accessible only to the signer matching Controller.authority + pub authority: Signer<'info>, + + /// #2 The top level UXDProgram on chain account managing the redeemable mint + #[account( + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #3 UXDProgram on chain account bound to a Controller instance + /// The `MangoDepository` manages a MangoAccount for a single Collateral + #[account( + mut, + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + )] + pub depository: AccountLoader<'info, MangoDepository>, +} + +pub fn handler(ctx: Context, disable: bool) -> Result<()> { + let depository = &mut ctx.accounts.depository.load_mut()?; + depository.minting_disabled = disable; + Ok(()) +} + +// Validate input arguments +impl<'info> DisableDepositoryMinting<'info> { + pub fn validate(&self, disable_minting: bool) -> Result<()> { + require!( + self.depository.load()?.minting_disabled != disable_minting, + UxdError::MintingAlreadyDisabledOrEnabled + ); + Ok(()) + } +} diff --git a/programs/uxd/src/instructions/mango_dex/mint_with_mango_depository.rs b/programs/uxd/src/instructions/mango_dex/mint_with_mango_depository.rs index 7eb1b1e1b..07654dbd7 100644 --- a/programs/uxd/src/instructions/mango_dex/mint_with_mango_depository.rs +++ b/programs/uxd/src/instructions/mango_dex/mint_with_mango_depository.rs @@ -1,43 +1,32 @@ -use crate::check_assert; -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; -use crate::events::MintWithMangoDepositoryEvent; -use crate::mango_program; -use crate::mango_utils::check_perp_order_fully_filled; +use crate::MANGO_PERP_MAX_FILL_EVENTS; +// use crate::events::MintWithMangoDepositoryEvent2; use crate::mango_utils::derive_order_delta; -use crate::mango_utils::limit_price; use crate::mango_utils::price_to_lot_price; use crate::mango_utils::total_perp_base_lot_position; -use crate::mango_utils::Order; use crate::mango_utils::PerpInfo; use crate::validate_perp_market_mint_matches_depository_collateral_mint; -use crate::AccountingEvent; use crate::Controller; use crate::MangoDepository; use crate::UxdError; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MANGO_ACCOUNT_NAMESPACE; use crate::MANGO_DEPOSITORY_NAMESPACE; use crate::REDEEMABLE_MINT_NAMESPACE; -use crate::SLIPPAGE_BASIS; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; use anchor_lang::prelude::*; -use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token; use anchor_spl::token::Mint; use anchor_spl::token::MintTo; use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use fixed::types::I80F48; +use mango::matching::OrderType; use mango::matching::Side; use mango::state::MangoAccount; use mango::state::PerpAccount; -declare_check_assert_macros!(SourceFileId::InstructionMangoDexMintWithMangoDepository); - -/// Takes 23 accounts - 9 used locally - 9 for MangoMarkets CPI - 4 Programs - 1 Sysvar +/// Takes 20 accounts #[derive(Accounts)] pub struct MintWithMangoDepository<'info> { /// #1 Public call accessible to any user @@ -51,169 +40,164 @@ pub struct MintWithMangoDepository<'info> { #[account( mut, seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump + bump = controller.load()?.bump, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository, + has_one = redeemable_mint @UxdError::InvalidRedeemableMint )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #4 UXDProgram on chain account bound to a Controller instance. /// The `MangoDepository` manages a MangoAccount for a single Collateral. #[account( mut, - seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.collateral_mint.as_ref()], - bump = depository.bump, - has_one = controller @UxdIdlErrorCode::InvalidController, - constraint = controller.registered_mango_depositories.contains(&depository.key()) @UxdIdlErrorCode::InvalidDepository + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, )] - pub depository: Box>, + pub depository: AccountLoader<'info, MangoDepository>, /// #5 The redeemable mint managed by the `controller` instance /// Tokens will be minted during this instruction #[account( mut, seeds = [REDEEMABLE_MINT_NAMESPACE], - bump = controller.redeemable_mint_bump, - constraint = redeemable_mint.key() == controller.redeemable_mint @UxdIdlErrorCode::InvalidRedeemableMint + bump = controller.load()?.redeemable_mint_bump, )] pub redeemable_mint: Box>, - /// #6 The collateral mint and used by the `depository` instance - #[account( - constraint = collateral_mint.key() == depository.collateral_mint @UxdIdlErrorCode::InvalidCollateralMint - )] - pub collateral_mint: Box>, - - /// #7 The `user`'s ATA for the `depository` `collateral_mint` + /// #6 The `user`'s TA for the `depository` `collateral_mint` /// Will be debited during this instruction #[account( mut, - associated_token::mint = collateral_mint, - associated_token::authority = user, + constraint = user_collateral.mint == depository.load()?.collateral_mint @UxdError::InvalidCollateralMint, + constraint = &user_collateral.owner == user.key @UxdError::InvalidOwner, )] pub user_collateral: Box>, - /// #8 The `user`'s ATA for the `controller`'s `redeemable_mint` + /// #7 The `user`'s TA for the `controller`'s `redeemable_mint` /// Will be credited during this instruction #[account( - init_if_needed, - associated_token::mint = redeemable_mint, - associated_token::authority = user, - payer = payer, + mut, + constraint = user_redeemable.mint == controller.load()?.redeemable_mint @UxdError::InvalidRedeemableMint, + constraint = &user_redeemable.owner == user.key @UxdError::InvalidOwner, )] pub user_redeemable: Box>, - /// #9 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// #8 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered #[account( mut, - seeds = [MANGO_ACCOUNT_NAMESPACE, depository.collateral_mint.as_ref()], - bump = depository.mango_account_bump, - constraint = depository.mango_account == depository_mango_account.key() @UxdIdlErrorCode::InvalidMangoAccount, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, )] - pub depository_mango_account: AccountInfo<'info>, + pub mango_account: AccountInfo<'info>, - /// #10 [MangoMarkets CPI] Index grouping perp and spot markets - pub mango_group: AccountInfo<'info>, + /// #9 [MangoMarkets CPI] Index grouping perp and spot markets + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, - /// #11 [MangoMarkets CPI] Cache - pub mango_cache: AccountInfo<'info>, + /// #10 [MangoMarkets CPI] Cache + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, - /// #12 [MangoMarkets CPI] Root Bank for the `depository`'s `collateral_mint` - pub mango_root_bank: AccountInfo<'info>, + /// #11 [MangoMarkets CPI] Root Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank: UncheckedAccount<'info>, - /// #13 [MangoMarkets CPI] Node Bank for the `depository`'s `collateral_mint` + /// #12 [MangoMarkets CPI] Node Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_node_bank: AccountInfo<'info>, + pub mango_node_bank: UncheckedAccount<'info>, - /// #14 [MangoMarkets CPI] Vault for the `depository`'s `collateral_mint` + /// #13 [MangoMarkets CPI] Vault for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_vault: AccountInfo<'info>, + pub mango_vault: UncheckedAccount<'info>, - /// #15 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market + /// #14 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_perp_market: AccountInfo<'info>, + pub mango_perp_market: UncheckedAccount<'info>, - /// #16 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook bids + /// #15 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook bids + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_bids: AccountInfo<'info>, + pub mango_bids: UncheckedAccount<'info>, - /// #17 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook asks + /// #16 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook asks + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_asks: AccountInfo<'info>, + pub mango_asks: UncheckedAccount<'info>, - /// #18 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market event queue + /// #17 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market event queue + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_event_queue: AccountInfo<'info>, + pub mango_event_queue: UncheckedAccount<'info>, - /// #19 System Program + /// #18 System Program pub system_program: Program<'info, System>, - /// #20 Token Program + /// #19 Token Program pub token_program: Program<'info, Token>, - /// #21 Associated Token Program - pub associated_token_program: Program<'info, AssociatedToken>, - - /// #22 MangoMarketv3 Program - pub mango_program: Program<'info, mango_program::Mango>, - - /// #23 Rent Sysvar - pub rent: Sysvar<'info, Rent>, + /// #20 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, } pub fn handler( ctx: Context, collateral_amount: u64, - slippage: u32, -) -> UxdResult { + limit_price: f32, +) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let collateral_mint = depository.collateral_mint; + let depository_bump = depository.bump; + drop(depository); + let depository_pda_signer: &[&[&[u8]]] = &[&[ MANGO_DEPOSITORY_NAMESPACE, - ctx.accounts.depository.collateral_mint.as_ref(), - &[ctx.accounts.depository.bump], + collateral_mint.as_ref(), + &[depository_bump], ]]; - let controller_pda_signer: &[&[&[u8]]] = - &[&[CONTROLLER_NAMESPACE, &[ctx.accounts.controller.bump]]]; + let controller_bump = ctx.accounts.controller.load()?.bump; + let controller_pda_signer: &[&[&[u8]]] = &[&[CONTROLLER_NAMESPACE, &[controller_bump]]]; // - 1 [FIND BEST ORDER FOR SHORT PERP POSITION] -------------------------- // - [Get MangoMarkets Collateral-Perp information] let perp_info = ctx.accounts.perpetual_info()?; + let contract_size = perp_info.base_lot_size; // - [Get the amount of Base Lots for the perp order (odd lots won't be processed)] - let base_lot_amount = I80F48::from_num(collateral_amount) - .checked_div(perp_info.base_lot_size) - .ok_or(math_err!())? - .floor(); + let max_base_quantity = I80F48::from_num(collateral_amount) + .checked_div(contract_size) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_floor() + .ok_or_else(|| error!(UxdError::MathError))?; - check!(base_lot_amount > 0, UxdErrorCode::QuantityBelowContractSize)?; - - // - [Define perp order] - // Note : Augment the delta neutral position, increasing short exposure, by selling perp. - // [BID: maker | ASK: taker (us, the caller)] - let taker_side = Side::Ask; - let limit_price = limit_price(perp_info.price, slippage, taker_side)?; - let limit_price_lot = price_to_lot_price(limit_price, &perp_info)?; - let perp_order = Order { - quantity: base_lot_amount.checked_to_num().ok_or(math_err!())?, - price: limit_price_lot.checked_to_num().ok_or(math_err!())?, // worth execution price - taker_side, - }; + require!( + !max_base_quantity.is_zero(), + UxdError::QuantityBelowContractSize + ); // - 2 [TRANSFER COLLATERAL TO MANGO (LONG)] ------------------------------ - // This value is verified after by checking if the perp order was fully filled // It's the amount we are depositing on the MangoAccount and that will be used as collateral // to open the short perp - let planned_collateral_delta = I80F48::from_num(perp_order.quantity) - .checked_mul(perp_info.base_lot_size) - .ok_or(math_err!())? + let collateral_deposited_amount = max_base_quantity + .checked_mul(contract_size) + .ok_or_else(|| error!(UxdError::MathError))? .checked_to_num() - .ok_or(math_err!())?; - msg!("planned_collateral_delta {}", planned_collateral_delta); + .ok_or_else(|| error!(UxdError::MathError))?; // - [MangoMarkets CPI - Deposit collateral to Depository MangoAccount] - mango_program::deposit( + mango_markets_v3::deposit( ctx.accounts .into_deposit_collateral_to_mango_context() .with_signer(depository_pda_signer), - planned_collateral_delta, + collateral_deposited_amount, )?; // - 3 [OPEN SHORT PERP] -------------------------------------------------- @@ -221,91 +205,103 @@ pub fn handler( // - [Perp account state PRE perp order] let pre_pa = ctx.accounts.perp_account(&perp_info)?; - // - [Base depository's position size in native units PRE perp opening (to calculate the % filled later on)] - let initial_base_position = total_perp_base_lot_position(&pre_pa)?; - + // Note : Augment the delta neutral position, increasing short exposure, by selling perp. + // [BID: maker | ASK: taker (us, the caller)] + let taker_side = Side::Ask; + let limit_price = + I80F48::checked_from_num(limit_price).ok_or_else(|| error!(UxdError::MathError))?; + let limit_price_lot = price_to_lot_price(limit_price, &perp_info)?; + let max_base_quantity_num = max_base_quantity.to_num(); // - [MangoMarkets CPI - Place perp order] - mango_program::place_perp_order( + mango_markets_v3::place_perp_order2( ctx.accounts .into_open_mango_short_perp_context() .with_signer(depository_pda_signer), - perp_order.price, - perp_order.quantity, + taker_side, + limit_price_lot.to_num(), + max_base_quantity_num, + i64::MAX, 0, - perp_order.taker_side, - mango::matching::OrderType::ImmediateOrCancel, + OrderType::ImmediateOrCancel, false, + None, + MANGO_PERP_MAX_FILL_EVENTS, )?; // - [Perp account state POST perp order] let post_pa = ctx.accounts.perp_account(&perp_info)?; // - [Checks that the order was fully filled (FoK)] - let post_perp_order_base_lot_position = total_perp_base_lot_position(&post_pa)?; - check_perp_order_fully_filled( - perp_order.quantity, - initial_base_position, - post_perp_order_base_lot_position, - )?; + check_perp_order_fully_filled(max_base_quantity_num, &pre_pa, &post_pa)?; // - 3 [CHECK REDEEMABLE SOFT CAP OVERFLOW] ------------------------------- // ensure current context is valid as the derive_order_delta is generic - check!( - pre_pa.taker_quote < post_pa.taker_quote, - UxdErrorCode::InvalidOrderDirection - )?; + require!( + pre_pa.taker_quote <= post_pa.taker_quote, + UxdError::InvalidOrderDirection + ); let order_delta = derive_order_delta(&pre_pa, &post_pa, &perp_info)?; msg!("order_delta {:?}", order_delta); + // The resulting UXD amount is equal to the quote delta minus the fees. + // By sending the amount less the fees, the user is paying them. let redeemable_delta = order_delta .quote .checked_sub(order_delta.fee) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; + let redeemable_mint_amount = redeemable_delta + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + ctx.accounts - .check_mango_depositories_redeemable_soft_cap_overflow(redeemable_delta)?; + .check_mango_depositories_redeemable_soft_cap_overflow(redeemable_mint_amount)?; - // validate that the planned collateral delta is equal to the order.collateral_delta - check!( - planned_collateral_delta == order_delta.collateral, - UxdErrorCode::InvalidCollateralDelta - )?; + let collateral_shorted_amount: u64 = order_delta + .base + .unsigned_abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + // validate that the deposited_collateral matches the amount shorted + require!( + collateral_deposited_amount == collateral_shorted_amount, + UxdError::InvalidCollateralDelta + ); // - 4 [MINTS THE HEDGED AMOUNT OF REDEEMABLE (minus fees)] ---------------- - token::mint_to( ctx.accounts .into_mint_redeemable_context() .with_signer(controller_pda_signer), - redeemable_delta, + redeemable_mint_amount, )?; // - [if ATA mint is WSOL, unwrap] - if ctx.accounts.depository.collateral_mint == spl_token::native_mint::id() { + if collateral_mint == spl_token::native_mint::id() { token::close_account(ctx.accounts.into_unwrap_wsol_by_closing_ata_context())?; } // - 5 [UPDATE ACCOUNTING] ------------------------------------------------ ctx.accounts.update_onchain_accounting( - order_delta.collateral, - redeemable_delta, - order_delta.fee, + collateral_shorted_amount.into(), + redeemable_mint_amount.into(), + order_delta.fee.to_num(), )?; // - 6 [CHECK GLOBAL REDEEMABLE SUPPLY CAP OVERFLOW] ---------------------- ctx.accounts.check_redeemable_global_supply_cap_overflow()?; - emit!(MintWithMangoDepositoryEvent { - version: ctx.accounts.controller.version, - controller: ctx.accounts.controller.key(), - depository: ctx.accounts.depository.key(), - user: ctx.accounts.user.key(), - collateral_amount, - slippage, - collateral_delta: order_delta.collateral, - redeemable_delta, - fee_delta: order_delta.fee, - }); + // emit!(MintWithMangoDepositoryEvent { + // version: controller.version, + // controller: controller.key(), + // depository: depository.key(), + // user: ctx.accounts.user.key(), + // collateral_amount, + // limit_price, + // base_delta: order_delta.base.to_num(), + // quote_delta: order_delta.quote.to_num(), + // fee_delta: order_delta.fee.to_num(), + // }); Ok(()) } @@ -313,16 +309,15 @@ pub fn handler( impl<'info> MintWithMangoDepository<'info> { pub fn into_deposit_collateral_to_mango_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Deposit<'info>> { - let cpi_accounts = mango_program::Deposit { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.user.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank.to_account_info(), - mango_node_bank: self.mango_node_bank.to_account_info(), - mango_vault: self.mango_vault.to_account_info(), - token_program: self.token_program.to_account_info(), + root_bank: self.mango_root_bank.to_account_info(), + node_bank: self.mango_node_bank.to_account_info(), + vault: self.mango_vault.to_account_info(), owner_token_account: self.user_collateral.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); @@ -331,16 +326,16 @@ impl<'info> MintWithMangoDepository<'info> { pub fn into_open_mango_short_perp_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::PlacePerpOrder<'info>> { - let cpi_accounts = mango_program::PlacePerpOrder { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::PlacePerpOrder2<'info>> { + let cpi_accounts = mango_markets_v3::PlacePerpOrder2 { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_perp_market: self.mango_perp_market.to_account_info(), - mango_bids: self.mango_bids.to_account_info(), - mango_asks: self.mango_asks.to_account_info(), - mango_event_queue: self.mango_event_queue.to_account_info(), + perp_market: self.mango_perp_market.to_account_info(), + bids: self.mango_bids.to_account_info(), + asks: self.mango_asks.to_account_info(), + event_queue: self.mango_event_queue.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) @@ -372,11 +367,11 @@ impl<'info> MintWithMangoDepository<'info> { // Additional convenience methods related to the inputted accounts impl<'info> MintWithMangoDepository<'info> { // Return general information about the perpetual related to the collateral in use - fn perpetual_info(&self) -> UxdResult { + fn perpetual_info(&self) -> Result { let perp_info = PerpInfo::new( &self.mango_group, &self.mango_cache, - &self.depository_mango_account, + &self.mango_account, self.mango_perp_market.key, self.mango_group.key, self.mango_program.key, @@ -386,81 +381,109 @@ impl<'info> MintWithMangoDepository<'info> { } // Return the PerpAccount that represent the account balances (Quote and Taker, Taker is the part that is waiting settlement) - fn perp_account(&self, perp_info: &PerpInfo) -> UxdResult { + fn perp_account(&self, perp_info: &PerpInfo) -> Result { // - loads Mango's accounts let mango_account = MangoAccount::load_checked( - &self.depository_mango_account, + &self.mango_account, self.mango_program.key, self.mango_group.key, - )?; + ) + .map_err(ProgramError::from)?; Ok(mango_account.perp_accounts[perp_info.market_index]) } // Ensure that the minted amount does not raise the Redeemable supply beyond the Global Redeemable Supply Cap - fn check_redeemable_global_supply_cap_overflow(&self) -> UxdResult { - check!( - self.controller.redeemable_circulating_supply - <= self.controller.redeemable_global_supply_cap, - UxdErrorCode::RedeemableGlobalSupplyCapReached - )?; + fn check_redeemable_global_supply_cap_overflow(&self) -> Result<()> { + let controller = self.controller.load()?; + require!( + controller.redeemable_circulating_supply <= controller.redeemable_global_supply_cap, + UxdError::RedeemableGlobalSupplyCapReached + ); Ok(()) } fn check_mango_depositories_redeemable_soft_cap_overflow( &self, redeemable_delta: u64, - ) -> UxdResult { - check!( - redeemable_delta <= self.controller.mango_depositories_redeemable_soft_cap, - UxdErrorCode::MangoDepositoriesSoftCapOverflow - )?; + ) -> Result<()> { + let controller = self.controller.load()?; + require!( + redeemable_delta <= controller.mango_depositories_redeemable_soft_cap, + UxdError::MangoDepositoriesSoftCapOverflow + ); Ok(()) } // Update the accounting in the Depository and Controller Accounts to reflect changes fn update_onchain_accounting( &mut self, - collateral_delta: u64, - redeemable_delta: u64, - fee_delta: u64, - ) -> UxdResult { + collateral_shorted_amount: u128, + redeemable_minted_amount: u128, + fee_amount: u128, + ) -> Result<()> { + let depository = &mut self.depository.load_mut()?; + let controller = &mut self.controller.load_mut()?; // Mango Depository - let event = AccountingEvent::Deposit; - self.depository - .update_collateral_amount_deposited(&event, collateral_delta)?; - self.depository - .update_redeemable_amount_under_management(&event, redeemable_delta)?; - self.depository - .update_total_amount_paid_taker_fee(fee_delta)?; + depository.collateral_amount_deposited = depository + .collateral_amount_deposited + .checked_add(collateral_shorted_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.redeemable_amount_under_management = depository + .redeemable_amount_under_management + .checked_add(redeemable_minted_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.total_amount_paid_taker_fee = depository + .total_amount_paid_taker_fee + .wrapping_add(fee_amount); // Controller - self.controller - .update_redeemable_circulating_supply(&event, redeemable_delta)?; + controller.redeemable_circulating_supply = controller + .redeemable_circulating_supply + .checked_add(redeemable_minted_amount) + .ok_or_else(|| error!(UxdError::MathError))?; Ok(()) } } +// Verify that the order quantity matches the base position delta +fn check_perp_order_fully_filled( + order_quantity: i64, + pre_pa: &PerpAccount, + post_pa: &PerpAccount, +) -> Result<()> { + let pre_position = total_perp_base_lot_position(pre_pa)?; + let post_position = total_perp_base_lot_position(post_pa)?; + let filled_amount = (post_position + .checked_sub(pre_position) + .ok_or_else(|| error!(UxdError::MathError))?) + .checked_abs() + .ok_or_else(|| error!(UxdError::MathError))?; + require!( + order_quantity == filled_amount, + UxdError::PerpOrderPartiallyFilled + ); + Ok(()) +} + // Validate input arguments impl<'info> MintWithMangoDepository<'info> { - pub fn validate(&self, collateral_amount: u64, slippage: u32) -> ProgramResult { - // Valid slippage check - check!( - (slippage > 0) && (slippage <= SLIPPAGE_BASIS), - UxdErrorCode::InvalidSlippage - )?; - - check!(collateral_amount > 0, UxdErrorCode::InvalidCollateralAmount)?; - check!( + pub fn validate(&self, collateral_amount: u64, limit_price: f32) -> Result<()> { + require!(limit_price > 0f32, UxdError::InvalidLimitPrice); + require!(collateral_amount != 0, UxdError::InvalidCollateralAmount); + require!( self.user_collateral.amount >= collateral_amount, - UxdErrorCode::InsufficientCollateralAmount - )?; + UxdError::InsufficientCollateralAmount + ); + require!( + !&self.depository.load()?.minting_disabled, + UxdError::MintingDisabled + ); validate_perp_market_mint_matches_depository_collateral_mint( &self.mango_group, self.mango_program.key, self.mango_perp_market.key, - &self.depository.collateral_mint, + &self.depository.load()?.collateral_mint, )?; - Ok(()) } } diff --git a/programs/uxd/src/instructions/mango_dex/mod.rs b/programs/uxd/src/instructions/mango_dex/mod.rs index ce8041aef..77e36ec9f 100644 --- a/programs/uxd/src/instructions/mango_dex/mod.rs +++ b/programs/uxd/src/instructions/mango_dex/mod.rs @@ -1,11 +1,17 @@ pub mod deposit_insurance_to_mango_depository; +pub mod disable_depository_minting; pub mod mint_with_mango_depository; +pub mod quote_mint_with_mango_depository; +pub mod quote_redeem_from_mango_depository; pub mod rebalance_mango_depository_lite; pub mod redeem_from_mango_depository; pub mod withdraw_insurance_from_mango_depository; pub use deposit_insurance_to_mango_depository::*; +pub use disable_depository_minting::*; pub use mint_with_mango_depository::*; +pub use quote_mint_with_mango_depository::*; +pub use quote_redeem_from_mango_depository::*; pub use rebalance_mango_depository_lite::*; pub use redeem_from_mango_depository::*; pub use withdraw_insurance_from_mango_depository::*; diff --git a/programs/uxd/src/instructions/mango_dex/quote_mint_with_mango_depository.rs b/programs/uxd/src/instructions/mango_dex/quote_mint_with_mango_depository.rs new file mode 100644 index 000000000..f4c8db7fe --- /dev/null +++ b/programs/uxd/src/instructions/mango_dex/quote_mint_with_mango_depository.rs @@ -0,0 +1,384 @@ +use crate::mango_utils::total_perp_base_lot_position; +use crate::mango_utils::PerpInfo; +use crate::validate_perp_market_mint_matches_depository_collateral_mint; +use crate::Controller; +use crate::MangoDepository; +use crate::UxdError; +use crate::BPS_UNIT_CONVERSION; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_ACCOUNT_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::REDEEMABLE_MINT_NAMESPACE; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; +use anchor_lang::prelude::*; +use anchor_spl::associated_token::AssociatedToken; +use anchor_spl::token; +use anchor_spl::token::Mint; +use anchor_spl::token::MintTo; +use anchor_spl::token::Token; +use anchor_spl::token::TokenAccount; +use fixed::types::I80F48; +use mango::state::MangoAccount; +use mango::state::PerpAccount; + +#[derive(Accounts)] +pub struct QuoteMintWithMangoDepository<'info> { + /// #1 Public call accessible to any user + pub user: Signer<'info>, + + /// #2 + #[account(mut)] + pub payer: Signer<'info>, + + /// #3 The top level UXDProgram on chain account managing the redeemable mint + #[account( + mut, + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #4 UXDProgram on chain account bound to a Controller instance. + /// The `MangoDepository` manages a MangoAccount for a single Collateral. + #[account( + mut, + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, + )] + pub depository: AccountLoader<'info, MangoDepository>, + + /// #5 The redeemable mint managed by the `controller` instance + /// Tokens will be minted during this instruction + #[account( + mut, + seeds = [REDEEMABLE_MINT_NAMESPACE], + bump = controller.load()?.redeemable_mint_bump, + constraint = redeemable_mint.key() == controller.load()?.redeemable_mint @UxdError::InvalidRedeemableMint + )] + pub redeemable_mint: Box>, + + /// #6 The `user`'s ATA for one the `mango depository`s `quote_mint` + /// Will be debited during this instruction + #[account( + mut, + constraint = user_quote.mint == depository.load()?.quote_mint, + constraint = user_quote.owner == *user.key, + )] + pub user_quote: Box>, + + /// #7 The `user`'s ATA for the `controller`'s `redeemable_mint` + /// Will be credited during this instruction + #[account( + mut, + constraint = user_redeemable.mint == controller.load()?.redeemable_mint, + constraint = user_redeemable.owner == *user.key, + )] + pub user_redeemable: Box>, + + /// #8 The MangoMarkets Account (MangoAccount) managed by the `depository` ****************** + /// CHECK : Seeds checked. Depository registered + #[account( + mut, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, + )] + pub mango_account: AccountInfo<'info>, + + /// #9 [MangoMarkets CPI] Index grouping perp and spot markets + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, + + /// #10 [MangoMarkets CPI] Cache + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, + + /// #11 [MangoMarkets CPI] Root Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank: UncheckedAccount<'info>, + + /// #12 [MangoMarkets CPI] Node Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_node_bank: UncheckedAccount<'info>, + + /// #13 [MangoMarkets CPI] Vault for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_vault: UncheckedAccount<'info>, + + /// #14 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_perp_market: UncheckedAccount<'info>, + + /// #15 System Program + pub system_program: Program<'info, System>, + + /// #16 Token Program + pub token_program: Program<'info, Token>, + + /// #17 Associated Token Program + pub associated_token_program: Program<'info, AssociatedToken>, + + /// #18 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, + + /// #19 Rent Sysvar + pub rent: Sysvar<'info, Rent>, +} + +pub fn handler(ctx: Context, quote_amount: u64) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let controller = &ctx.accounts.controller; + let depository_pda_signer: &[&[&[u8]]] = &[&[ + MANGO_DEPOSITORY_NAMESPACE, + depository.collateral_mint.as_ref(), + &[depository.bump], + ]]; + let controller_pda_signer: &[&[&[u8]]] = &[&[CONTROLLER_NAMESPACE, &[controller.load()?.bump]]]; + + // - [Get perp information] + let perp_info = ctx.accounts.perpetual_info()?; + + // - [Perp account state PRE perp order] + let pre_pa = ctx.accounts.perp_account(&perp_info)?; + + // - 1 [FIND CURRENT UNREALIZED PNL AMOUNT] ------------------------------- + + // - [find out current perp Unrealized PnL] + let contract_size = perp_info.base_lot_size; + // Note : Loose precision but an average value is fine here, we just want a value close to the current PnL + let perp_position_notional_size: i128 = + I80F48::from_num(total_perp_base_lot_position(&pre_pa)?) + .checked_mul(contract_size) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_mul(perp_info.price) + .ok_or_else(|| error!(UxdError::MathError))? + .abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + // The perp position unrealized PnL is equal to the outstanding amount of redeemable + // minus the perp position notional size in quote. + // Ideally they stay 1:1, to have the redeemable fully backed by the delta neutral + // position and no paper profits. + let redeemable_under_management = i128::try_from(depository.redeemable_amount_under_management) + .map_err(|_e| error!(UxdError::MathError))?; + + // Will not overflow as `perp_position_notional_size` and `redeemable_under_management` + // will vary together. + let perp_unrealized_pnl = I80F48::checked_from_num( + redeemable_under_management + .checked_sub(perp_position_notional_size) + .ok_or_else(|| error!(UxdError::MathError))?, + ) + .ok_or_else(|| error!(UxdError::MathError))?; + + // - 2 [FIND HOW MUCH REDEEMABLE CAN BE MINTED] --------------------------- + + // Get how much redeemable has already been minted with the quote mint + let quote_minted = depository.net_quote_minted; + + // Only allow quote minting if PnL is negative + require!( + perp_unrealized_pnl.is_negative(), + UxdError::InvalidPnlPolarity + ); + + let quote_mintable: u64 = calculate_quote_mintable(perp_unrealized_pnl, quote_minted)?; + + // Check to ensure we are not minting more than we allocate to resolve negative PnL + require!(quote_amount <= quote_mintable, UxdError::QuoteAmountTooHigh); + + // - 4 [DEPOSIT QUOTE MINT INTO MANGO ACCOUNT] ------------------------------- + mango_markets_v3::deposit( + ctx.accounts + .into_deposit_quote_to_mango_context() + .with_signer(depository_pda_signer), + quote_amount, + )?; + + // - 5 [MINT REDEEMABLE TO USER] ------------------------------------------ + let quote_mint_fee = depository.quote_mint_and_redeem_fee; + + drop(depository); + + // Math: 5 bps fee would equate to bps_minted_to_user + // being 9995 since 10000 - 5 = 9995 + let bps_minted_to_user: I80F48 = I80F48::checked_from_num(BPS_UNIT_CONVERSION) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_sub(quote_mint_fee.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + + // Math: Multiplies the quote_amount by how many BPS the user will get, + // but the units are still in units of BPS, not as a decimal, so then + // divide by the BPS_POW to get to the right order of magnitude. + let redeemable_mint_amount_less_fees: u64 = bps_minted_to_user + .checked_mul_int(quote_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_div_int(BPS_UNIT_CONVERSION.into()) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_floor() + .ok_or_else(|| error!(UxdError::MathError))? + .checked_to_num::() + .ok_or_else(|| error!(UxdError::MathError))?; + + token::mint_to( + ctx.accounts + .into_mint_redeemable_context() + .with_signer(controller_pda_signer), + redeemable_mint_amount_less_fees, + )?; + + // - 6 [UPDATE ACCOUNTING] ------------------------------------------------ + ctx.accounts + .update_onchain_accounting(quote_amount, redeemable_mint_amount_less_fees)?; + + // - 7 [CHECK GLOBAL REDEEMABLE SUPPLY CAP OVERFLOW] ---------------------- + ctx.accounts.check_redeemable_global_supply_cap_overflow()?; + + Ok(()) +} + +pub fn calculate_quote_mintable( + perp_unrealized_pnl: I80F48, + quote_minted: i128, +) -> Result { + let quote_mintable = perp_unrealized_pnl + .checked_sub( + I80F48::checked_from_num(quote_minted).ok_or_else(|| error!(UxdError::MathError))?, + ) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_abs() + .ok_or_else(|| error!(UxdError::MathError))?; + + quote_mintable + .checked_to_num::() + .ok_or_else(|| error!(UxdError::MathError)) +} + +impl<'info> QuoteMintWithMangoDepository<'info> { + pub fn into_deposit_quote_to_mango_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { + mango_group: self.mango_group.to_account_info(), + mango_account: self.mango_account.to_account_info(), + owner: self.user.to_account_info(), + mango_cache: self.mango_cache.to_account_info(), + root_bank: self.mango_root_bank.to_account_info(), + node_bank: self.mango_node_bank.to_account_info(), + vault: self.mango_vault.to_account_info(), + owner_token_account: self.user_quote.to_account_info(), + }; + let cpi_program = self.mango_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_mint_redeemable_context(&self) -> CpiContext<'_, '_, '_, 'info, MintTo<'info>> { + let cpi_program = self.token_program.to_account_info(); + let cpi_accounts = MintTo { + mint: self.redeemable_mint.to_account_info(), + to: self.user_redeemable.to_account_info(), + authority: self.controller.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) + } + + // Ensure that the minted amount does not raise the Redeemable supply beyond the Global Redeemable Supply Cap + fn check_redeemable_global_supply_cap_overflow(&self) -> Result<()> { + require!( + self.controller.load()?.redeemable_circulating_supply + <= self.controller.load()?.redeemable_global_supply_cap, + UxdError::RedeemableGlobalSupplyCapReached + ); + + Ok(()) + } + + // Update the accounting in the Depository and Controller Accounts to reflect changes + fn update_onchain_accounting( + &mut self, + quote_amount_deposited: u64, + redeemable_minted_amount: u64, + ) -> Result<()> { + let depository = &mut self.depository.load_mut()?; + let controller = &mut self.controller.load_mut()?; + let fees_accrued: u64 = quote_amount_deposited + .checked_sub(redeemable_minted_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + // Mango Depository + depository.net_quote_minted = depository + .net_quote_minted + .checked_add(quote_amount_deposited.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.redeemable_amount_under_management = depository + .redeemable_amount_under_management + .checked_add(redeemable_minted_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.total_quote_mint_and_redeem_fees = depository + .total_quote_mint_and_redeem_fees + .checked_add(fees_accrued.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + // Controller + controller.redeemable_circulating_supply = controller + .redeemable_circulating_supply + .checked_add(redeemable_minted_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + Ok(()) + } +} + +// Additional convenience methods related to the inputted accounts +impl<'info> QuoteMintWithMangoDepository<'info> { + // Return general information about the perpetual related to the collateral in use + fn perpetual_info(&self) -> Result { + let perp_info = PerpInfo::new( + &self.mango_group, + &self.mango_cache, + &self.mango_account, + self.mango_perp_market.key, + self.mango_group.key, + self.mango_program.key, + )?; + msg!("perp_info {:?}", perp_info); + Ok(perp_info) + } + + // Return the PerpAccount that represent the account balances (Quote and Taker, Taker is the part that is waiting settlement) + fn perp_account(&self, perp_info: &PerpInfo) -> Result { + // - loads Mango's accounts + let mango_account = MangoAccount::load_checked( + &self.mango_account, + self.mango_program.key, + self.mango_group.key, + ) + .map_err(ProgramError::from)?; + Ok(mango_account.perp_accounts[perp_info.market_index]) + } +} + +// Validate input arguments +impl<'info> QuoteMintWithMangoDepository<'info> { + pub fn validate(&self, quote_amount: u64) -> Result<()> { + require!(quote_amount != 0, UxdError::InvalidQuoteAmount); + require!( + self.user_quote.amount >= quote_amount, + UxdError::InsufficientQuoteAmountMint + ); + validate_perp_market_mint_matches_depository_collateral_mint( + &self.mango_group, + self.mango_program.key, + self.mango_perp_market.key, + &self.depository.load()?.collateral_mint, + )?; + + Ok(()) + } +} diff --git a/programs/uxd/src/instructions/mango_dex/quote_redeem_from_mango_depository.rs b/programs/uxd/src/instructions/mango_dex/quote_redeem_from_mango_depository.rs new file mode 100644 index 000000000..a0a6ef872 --- /dev/null +++ b/programs/uxd/src/instructions/mango_dex/quote_redeem_from_mango_depository.rs @@ -0,0 +1,395 @@ +use crate::mango_utils::total_perp_base_lot_position; +use crate::mango_utils::PerpInfo; +use crate::validate_perp_market_mint_matches_depository_collateral_mint; +use crate::Controller; +use crate::MangoDepository; +use crate::UxdError; +use crate::BPS_UNIT_CONVERSION; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_ACCOUNT_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::REDEEMABLE_MINT_NAMESPACE; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; +use anchor_lang::prelude::*; +use anchor_spl::associated_token::AssociatedToken; +use anchor_spl::token; +use anchor_spl::token::Burn; +use anchor_spl::token::Mint; +use anchor_spl::token::MintTo; +use anchor_spl::token::Token; +use anchor_spl::token::TokenAccount; +use fixed::types::I80F48; +use mango::state::MangoAccount; +use mango::state::PerpAccount; + +#[derive(Accounts)] +pub struct QuoteRedeemFromMangoDepository<'info> { + /// #1 Public call accessible to any user + pub user: Signer<'info>, + + /// #2 + #[account(mut)] + pub payer: Signer<'info>, + + /// #3 The top level UXDProgram on chain account managing the redeemable mint + #[account( + mut, + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + has_one = redeemable_mint, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #4 UXDProgram on chain account bound to a Controller instance. + /// The `MangoDepository` manages a MangoAccount for a single Collateral. + #[account( + mut, + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, + )] + pub depository: AccountLoader<'info, MangoDepository>, + + /// #5 The redeemable mint managed by the `controller` instance + /// Tokens will be minted during this instruction + #[account( + mut, + seeds = [REDEEMABLE_MINT_NAMESPACE], + bump = controller.load()?.redeemable_mint_bump, + )] + pub redeemable_mint: Box>, + + /// #6 The quote mint of the depository + #[account( + constraint = quote_mint.key() == depository.load()?.quote_mint, + )] + pub quote_mint: Box>, + + /// #7 The `user`'s ATA for one the `mango depository`s `quote_mint` + /// Will be credited during this instruction + #[account( + mut, + constraint = user_quote.mint == depository.load()?.quote_mint, + constraint = user_quote.owner == *user.key, + )] + pub user_quote: Box>, + + /// #8 The `user`'s ATA for the `controller`'s `redeemable_mint` + /// Will be debited during this instruction + #[account( + mut, + constraint = user_redeemable.mint == controller.load()?.redeemable_mint, + constraint = user_redeemable.owner == *user.key, + )] + pub user_redeemable: Box>, + + /// #9 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered + #[account( + mut, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, + )] + pub mango_account: AccountInfo<'info>, + + /// #10 [MangoMarkets CPI] Index grouping perp and spot markets + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, + + /// #11 [MangoMarkets CPI] Cache + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, + + /// #12 [MangoMarkets CPI] Signer PDA + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_signer: UncheckedAccount<'info>, + + /// #12 [MangoMarkets CPI] Root Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_root_bank: UncheckedAccount<'info>, + + /// #13 [MangoMarkets CPI] Node Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_node_bank: UncheckedAccount<'info>, + + /// #14 [MangoMarkets CPI] Vault for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_vault: UncheckedAccount<'info>, + + /// #15 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_perp_market: UncheckedAccount<'info>, + + /// #16 System Program + pub system_program: Program<'info, System>, + + /// #17 Token Program + pub token_program: Program<'info, Token>, + + /// #18 Associated Token Program + pub associated_token_program: Program<'info, AssociatedToken>, + + /// #19 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, + + /// #20 Rent Sysvar + pub rent: Sysvar<'info, Rent>, +} + +pub fn handler(ctx: Context, redeemable_amount: u64) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let depository_signer_seed: &[&[&[u8]]] = &[&[ + MANGO_DEPOSITORY_NAMESPACE, + depository.collateral_mint.as_ref(), + &[depository.bump], + ]]; + + // - [Get perp information] + let perp_info = ctx.accounts.perpetual_info()?; + + // - [Perp account state PRE perp order] + let pre_pa = ctx.accounts.perp_account(&perp_info)?; + + // - 1 [FIND CURRENT UNREALIZED PNL AMOUNT] ------------------------------- + + // - [find out current perp Unrealized PnL] + let contract_size = perp_info.base_lot_size; + // Note : Loose precision but an average value is fine here, we just want a value close to the current PnL + let perp_position_notional_size: i128 = + I80F48::from_num(total_perp_base_lot_position(&pre_pa)?) + .checked_mul(contract_size) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_mul(perp_info.price) + .ok_or_else(|| error!(UxdError::MathError))? + .abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + // The perp position unrealized PnL is equal to the outstanding amount of redeemable + // minus the perp position notional size in quote. + // Ideally they stay 1:1, to have the redeemable fully backed by the delta neutral + // position and no paper profits. + let redeemable_under_management = i128::try_from(depository.redeemable_amount_under_management) + .map_err(|_e| error!(UxdError::MathError))?; + + msg!( + "redeemable_under_management {}", + redeemable_under_management + ); + + // Will not overflow as `perp_position_notional_size` and `redeemable_under_management` + // will vary together. + let perp_unrealized_pnl = I80F48::checked_from_num( + redeemable_under_management + .checked_sub(perp_position_notional_size) + .ok_or_else(|| error!(UxdError::MathError))?, + ) + .ok_or_else(|| error!(UxdError::MathError))?; + msg!("perp_unrealized_pnl {}", perp_unrealized_pnl); + + // - 2 [FIND HOW MUCH REDEEMABLE CAN BE MINTED] --------------------------- + + // Get how much redeemable has already been minted with the quote mint + let quote_minted = depository.net_quote_minted; + + // Only allow quote redeeming if PnL is positive + require!( + perp_unrealized_pnl.is_positive(), + UxdError::InvalidPnlPolarity + ); + + let quote_redeemable: u64 = calculate_quote_redeemable(perp_unrealized_pnl, quote_minted)?; + + msg!("redeemable_amount {}", redeemable_amount); + msg!("quote_redeemable {}", quote_redeemable); + + // Check to ensure we are not redeeming more than we allocate to resolve positive PnL + require!( + redeemable_amount <= quote_redeemable, + UxdError::RedeemableAmountTooHigh + ); + + // - 3 [BURN USER'S REDEEMABLE] ------------------------------------------- + // Burn will fail if user does not have enough redeemable + token::burn( + ctx.accounts.into_burn_redeemable_context(), + redeemable_amount, + )?; + + // - 4 [WITHDRAW QUOTE MINT FROM MANGO ACCOUNT] --------------------------- + let quote_redeem_fee = depository.quote_mint_and_redeem_fee; + + // Math: 5 bps fee would equate to bps_redeemed_to_user + // being 9995 since 10000 - 5 = 9995 + let bps_redeemed_to_user: I80F48 = I80F48::checked_from_num(BPS_UNIT_CONVERSION) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_sub(quote_redeem_fee.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + + // Math: Multiplies the redeemable_amount by how many BPS the user will get + // but the units are still in units of BPS, not as a decimal, so then + // divide by the BPS_POW to get to the right order of magnitude. + let quote_withdraw_amount_less_fees: u64 = bps_redeemed_to_user + .checked_mul_int(redeemable_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_div_int(BPS_UNIT_CONVERSION.into()) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_floor() + .ok_or_else(|| error!(UxdError::MathError))? + .checked_to_num::() + .ok_or_else(|| error!(UxdError::MathError))?; + + mango_markets_v3::withdraw( + ctx.accounts + .into_withdraw_quote_mint_from_mango_context() + .with_signer(depository_signer_seed), + quote_withdraw_amount_less_fees, + false, + )?; + + // - 5 [UPDATE ACCOUNTING] ------------------------------------------------ + drop(depository); + ctx.accounts + .update_onchain_accounting(redeemable_amount, quote_withdraw_amount_less_fees)?; + + Ok(()) +} + +pub fn calculate_quote_redeemable( + perp_unrealized_pnl: I80F48, + quote_minted: i128, +) -> Result { + let quote_redeemable = perp_unrealized_pnl + .checked_abs() + .ok_or_else(|| error!(UxdError::MathError))? + .checked_add( + I80F48::checked_from_num(quote_minted) + .ok_or_else(|| error!(UxdError::MathError))? + ) + .ok_or_else(|| error!(UxdError::MathError))?; + quote_redeemable.checked_to_num::() + .ok_or_else(|| error!(UxdError::MathError)) +} + +impl<'info> QuoteRedeemFromMangoDepository<'info> { + pub fn into_burn_redeemable_context(&self) -> CpiContext<'_, '_, '_, 'info, Burn<'info>> { + let cpi_program = self.token_program.to_account_info(); + let cpi_accounts = Burn { + mint: self.redeemable_mint.to_account_info(), + authority: self.user.to_account_info(), + from: self.user_redeemable.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_withdraw_quote_mint_from_mango_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { + mango_group: self.mango_group.to_account_info(), + mango_account: self.mango_account.to_account_info(), + owner: self.depository.to_account_info(), + mango_cache: self.mango_cache.to_account_info(), + root_bank: self.mango_root_bank.to_account_info(), + node_bank: self.mango_node_bank.to_account_info(), + vault: self.mango_vault.to_account_info(), + token_account: self.user_quote.to_account_info(), + signer: self.mango_signer.to_account_info(), + }; + let cpi_program = self.mango_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_mint_redeemable_context(&self) -> CpiContext<'_, '_, '_, 'info, MintTo<'info>> { + let cpi_program = self.token_program.to_account_info(); + let cpi_accounts = MintTo { + mint: self.redeemable_mint.to_account_info(), + to: self.user_redeemable.to_account_info(), + authority: self.controller.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) + } + + // Update the accounting in the Depository and Controller Accounts to reflect changes + fn update_onchain_accounting( + &mut self, + redeemable_amount: u64, + quote_withdraw_amount: u64, + ) -> Result<()> { + let depository = &mut self.depository.load_mut()?; + let controller = &mut self.controller.load_mut()?; + let fees_accrued: u64 = redeemable_amount + .checked_sub(quote_withdraw_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + // Mango Depository + depository.net_quote_minted = depository + .net_quote_minted + .checked_sub(quote_withdraw_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.redeemable_amount_under_management = depository + .redeemable_amount_under_management + .checked_sub(redeemable_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.total_quote_mint_and_redeem_fees = depository + .total_quote_mint_and_redeem_fees + .checked_add(fees_accrued.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + // Controller + controller.redeemable_circulating_supply = controller + .redeemable_circulating_supply + .checked_sub(redeemable_amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + Ok(()) + } +} + +// Additional convenience methods related to the inputted accounts +impl<'info> QuoteRedeemFromMangoDepository<'info> { + // Return general information about the perpetual related to the collateral in use + fn perpetual_info(&self) -> Result { + let perp_info = PerpInfo::new( + &self.mango_group, + &self.mango_cache, + &self.mango_account, + self.mango_perp_market.key, + self.mango_group.key, + self.mango_program.key, + )?; + msg!("perp_info {:?}", perp_info); + Ok(perp_info) + } + + // Return the PerpAccount that represent the account balances (Quote and Taker, Taker is the part that is waiting settlement) + fn perp_account(&self, perp_info: &PerpInfo) -> Result { + // - loads Mango's accounts + let mango_account = MangoAccount::load_checked( + &self.mango_account, + self.mango_program.key, + self.mango_group.key, + ) + .map_err(ProgramError::from)?; + Ok(mango_account.perp_accounts[perp_info.market_index]) + } +} + +// Validate input arguments +impl<'info> QuoteRedeemFromMangoDepository<'info> { + pub fn validate(&self, redeemable_amount: u64) -> Result<()> { + require!(redeemable_amount != 0, UxdError::InvalidRedeemableAmount); + validate_perp_market_mint_matches_depository_collateral_mint( + &self.mango_group, + self.mango_program.key, + self.mango_perp_market.key, + &self.depository.load()?.collateral_mint, + )?; + + Ok(()) + } +} diff --git a/programs/uxd/src/instructions/mango_dex/rebalance_mango_depository_lite.rs b/programs/uxd/src/instructions/mango_dex/rebalance_mango_depository_lite.rs index f10f1e0fa..b3245ef14 100644 --- a/programs/uxd/src/instructions/mango_dex/rebalance_mango_depository_lite.rs +++ b/programs/uxd/src/instructions/mango_dex/rebalance_mango_depository_lite.rs @@ -1,45 +1,35 @@ -use crate::check_assert; -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; -use crate::error::UxdIdlErrorCode; -use crate::mango_program; -use crate::mango_utils::check_effective_order_price_versus_limit_price; -use crate::mango_utils::check_perp_order_fully_filled; +use crate::error::UxdError; +use crate::MANGO_PERP_MAX_FILL_EVENTS; +// use crate::events::RebalanceMangoDepositoryLiteEvent; use crate::mango_utils::derive_order_delta; -use crate::mango_utils::get_best_order_for_quote_lot_amount; +use crate::mango_utils::price_to_lot_price; use crate::mango_utils::total_perp_base_lot_position; -use crate::mango_utils::Order; use crate::mango_utils::PerpInfo; use crate::validate_perp_market_mint_matches_depository_collateral_mint; -use crate::AccountingEvent; use crate::Controller; use crate::MangoDepository; -use crate::UxdError; -use crate::UxdErrorCode; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MANGO_ACCOUNT_NAMESPACE; use crate::MANGO_DEPOSITORY_NAMESPACE; -use crate::SLIPPAGE_BASIS; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; use anchor_lang::prelude::*; -use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token; use anchor_spl::token::Mint; use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use fixed::types::I80F48; -use mango::matching::BookSide; +use mango::matching::OrderType; use mango::matching::Side; use mango::state::MangoAccount; use mango::state::PerpAccount; -use mango::state::PerpMarket; -declare_check_assert_macros!(SourceFileId::InstructionMangoDexRebalanceMangoDepositoryLite); - -/// Takes 27 accounts - 9 used locally - 13 for MangoMarkets CPI - 4 Programs - 1 Sysvar +/// Takes 25 accounts #[derive(Accounts)] pub struct RebalanceMangoDepositoryLite<'info> { /// #1 Public call accessible to any user + /// Note - Mut required for WSOL unwrapping + // #[account(mut)] pub user: Signer<'info>, /// #2 @@ -49,110 +39,124 @@ pub struct RebalanceMangoDepositoryLite<'info> { /// #3 The top level UXDProgram on chain account managing the redeemable mint #[account( seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump + bump = controller.load()?.bump, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository, )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #4 UXDProgram on chain account bound to a Controller instance /// The `MangoDepository` manages a MangoAccount for a single Collateral #[account( mut, - seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.collateral_mint.as_ref()], - bump = depository.bump, - has_one = controller @UxdIdlErrorCode::InvalidController, - constraint = controller.registered_mango_depositories.contains(&depository.key()) @UxdIdlErrorCode::InvalidDepository, + seeds = [MANGO_DEPOSITORY_NAMESPACE, collateral_mint.key().as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, + has_one = quote_mint @UxdError::InvalidQuoteMint, + has_one = collateral_mint @UxdError::InvalidCollateralMint )] - pub depository: Box>, + pub depository: AccountLoader<'info, MangoDepository>, /// #5 The collateral mint used by the `depository` instance - #[account( - constraint = collateral_mint.key() == depository.collateral_mint @UxdIdlErrorCode::InvalidCollateralMint - )] + /// Required to create the user_collateral ATA if needed pub collateral_mint: Box>, /// #6 The quote mint used by the `depository` instance - #[account( - constraint = quote_mint.key() == depository.quote_mint @UxdIdlErrorCode::InvalidQuoteMint - )] + /// Required to create the user_quote ATA if needed pub quote_mint: Box>, - /// #7 The `user`'s ATA for the `depository`'s `collateral_mint` + /// #7 The `user`'s TA for the `depository`'s `collateral_mint` /// Will be debited during this instruction when `Polarity` is positive /// Will be credited during this instruction when `Polarity` is negative #[account( - init_if_needed, - associated_token::mint = collateral_mint, - associated_token::authority = user, - payer = payer, + mut, + constraint = user_collateral.mint == depository.load()?.collateral_mint @UxdError::InvalidCollateralMint, + constraint = &user_collateral.owner == user.key @UxdError::InvalidOwner, )] pub user_collateral: Box>, - /// #8 The `user`'s ATA for the `depository`'s `quote_mint` + /// #8 The `user`'s TA for the `depository`'s `quote_mint` /// Will be credited during this instruction when `Polarity` is positive /// Will be debited during this instruction when `Polarity` is negative #[account( - init_if_needed, - associated_token::mint = quote_mint, - associated_token::authority = user, - payer = payer, + mut, + constraint = user_quote.mint == depository.load()?.quote_mint @UxdError::InvalidQuoteMint, + constraint = &user_quote.owner == user.key @UxdError::InvalidOwner, )] pub user_quote: Box>, /// #9 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered #[account( mut, - seeds = [MANGO_ACCOUNT_NAMESPACE, depository.collateral_mint.as_ref()], - bump = depository.mango_account_bump, - constraint = depository.mango_account == depository_mango_account.key() @UxdIdlErrorCode::InvalidMangoAccount, + seeds = [MANGO_ACCOUNT_NAMESPACE, collateral_mint.key().as_ref()], + bump = depository.load()?.mango_account_bump, )] - pub depository_mango_account: AccountInfo<'info>, + pub mango_account: AccountInfo<'info>, /// #10 [MangoMarkets CPI] Signer PDA - pub mango_signer: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_signer: UncheckedAccount<'info>, /// #11 [MangoMarkets CPI] Index grouping perp and spot markets - pub mango_group: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_group: UncheckedAccount<'info>, /// #12 [MangoMarkets CPI] Cache - pub mango_cache: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, /// #13 [MangoMarkets CPI] Root Bank for the `depository`'s `quote_mint` - pub mango_root_bank_quote: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank_quote: UncheckedAccount<'info>, /// #14 [MangoMarkets CPI] Node Bank for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_node_bank_quote: AccountInfo<'info>, + pub mango_node_bank_quote: UncheckedAccount<'info>, /// #15 [MangoMarkets CPI] Vault `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_vault_quote: AccountInfo<'info>, + pub mango_vault_quote: UncheckedAccount<'info>, /// #16 [MangoMarkets CPI] Root Bank for the `depository`'s `collateral_mint` - pub mango_root_bank_collateral: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank_collateral: UncheckedAccount<'info>, /// #17 [MangoMarkets CPI] Node Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_node_bank_collateral: AccountInfo<'info>, + pub mango_node_bank_collateral: UncheckedAccount<'info>, /// #18 [MangoMarkets CPI] Vault for `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_vault_collateral: AccountInfo<'info>, + pub mango_vault_collateral: UncheckedAccount<'info>, /// #19 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_perp_market: AccountInfo<'info>, + pub mango_perp_market: UncheckedAccount<'info>, /// #20 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook bids + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_bids: AccountInfo<'info>, + pub mango_bids: UncheckedAccount<'info>, /// #21 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook asks + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_asks: AccountInfo<'info>, + pub mango_asks: UncheckedAccount<'info>, /// #22 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market event queue + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_event_queue: AccountInfo<'info>, + pub mango_event_queue: UncheckedAccount<'info>, /// #23 System Program pub system_program: Program<'info, System>, @@ -160,26 +164,26 @@ pub struct RebalanceMangoDepositoryLite<'info> { /// #24 Token Program pub token_program: Program<'info, Token>, - /// #25 Associated Token Program - pub associated_token_program: Program<'info, AssociatedToken>, - - /// #26 MangoMarketv3 Program - pub mango_program: Program<'info, mango_program::Mango>, - - /// #27 Rent Sysvar - pub rent: Sysvar<'info, Rent>, + /// #25 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, } pub fn handler( ctx: Context, max_rebalancing_amount: u64, polarity: &PnlPolarity, - slippage: u32, -) -> UxdResult { + limit_price: f32, +) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let collateral_mint = depository.collateral_mint; + let depository_bump = depository.bump; + let redeemable_amount_under_management = depository.redeemable_amount_under_management; + drop(depository); + let depository_signer_seed: &[&[&[u8]]] = &[&[ MANGO_DEPOSITORY_NAMESPACE, - ctx.accounts.depository.collateral_mint.as_ref(), - &[ctx.accounts.depository.bump], + collateral_mint.as_ref(), + &[depository_bump], ]]; // - [Get perp information] @@ -191,48 +195,51 @@ pub fn handler( // - 1 [FIND CURRENT UNREALIZED PNL AMOUNT] // - [find out current perp Unrealized PnL] - let perp_contract_size = perp_info.base_lot_size; + let contract_size = perp_info.base_lot_size; // Note : Loose precision but an average value is fine here, we just want a value close to the current PnL let perp_position_notional_size: i128 = I80F48::from_num(total_perp_base_lot_position(&pre_pa)?) - .checked_mul(perp_contract_size) - .ok_or(math_err!())? + .checked_mul(contract_size) + .ok_or_else(|| error!(UxdError::MathError))? .checked_mul(perp_info.price) - .ok_or(math_err!())? + .ok_or_else(|| error!(UxdError::MathError))? .abs() .checked_to_num() - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; // The perp position unrealized PnL is equal to the outstanding amount of redeemable // minus the perp position notional size in quote. // Ideally they stay 1:1, to have the redeemable fully backed by the delta neutral // position and no paper profits. - let redeemable_under_management = - i128::try_from(ctx.accounts.depository.redeemable_amount_under_management) - .map_err(|_e| math_err!())?; + let redeemable_under_management = i128::try_from(redeemable_amount_under_management) + .map_err(|_e| error!(UxdError::MathError))?; // Will not overflow as `perp_position_notional_size` and `redeemable_under_management` // will vary together. let perp_unrealized_pnl = I80F48::checked_from_num( redeemable_under_management .checked_sub(perp_position_notional_size) - .ok_or(math_err!())?, + .ok_or_else(|| error!(UxdError::MathError))?, ) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; // Polarity parameter could be inferred, but is requested as input to prevent users // user rebalancing (swapping) in an undesired way, as the PnL could technically shift // between call and execution time. // This also filter out the case where `perp_unrealized_pnl` is 0 match polarity { - PnlPolarity::Positive => check!( - perp_unrealized_pnl.is_positive(), - UxdErrorCode::InvalidPnlPolarity - )?, - PnlPolarity::Negative => check!( - perp_unrealized_pnl.is_negative(), - UxdErrorCode::InvalidPnlPolarity - )?, + PnlPolarity::Positive => { + require!( + perp_unrealized_pnl.is_positive(), + UxdError::InvalidPnlPolarity + ); + } + PnlPolarity::Negative => { + require!( + perp_unrealized_pnl.is_negative(), + UxdError::InvalidPnlPolarity + ); + } } // - [rebalancing limited to `max_rebalancing_amount`, up to `perp_unrealized_pnl`] let requested_rebalancing_amount = I80F48::from_num(max_rebalancing_amount); @@ -240,10 +247,6 @@ pub fn handler( // - 2 [FIND BEST ORDER FOR SHORT PERP POSITION (depending of Polarity)] -- - // For now will just overdraft fees on top of the max_rebalancing_amount - // (instruction will fail if not enough). - // When more computing, use the commented code below - // - [Plan the rebalancing amount] // Note : Depending of the side, the fees don't come from the same place. // If the PnL is positive, it behaves like a redeem and the fees are taken @@ -252,33 +255,37 @@ pub fn handler( // If the PnL is negative, it behaves like the mint and the fees are taken // on the returned amount (here they aren't living in the delta neutral position // but simply on the spot QUOTE balance) - // let rebalancing_amount = match polarity { - // PnlPolarity::Positive => { - // // - [Find the max fees] - // let max_fee_amount = rebalancing_quote_amount - // .checked_mul(perp_info.effective_fee) - // .ok_or(math_err!())? - // .checked_ceil() - // .ok_or(math_err!())?; - - // // - [Get the amount of quote_lots for the perp order minus fees not to overflow max_rebalancing_amount] - // rebalancing_quote_amount - // .checked_sub(max_fee_amount) - // .ok_or(math_err!())? - // .checked_div(perp_info.quote_lot_size) - // .ok_or(math_err!())? - // .floor() - // } - // PnlPolarity::Negative => { - // - [Get the amount of quote_lots for the perp order] - let rebalancing_amount = rebalancing_quote_amount - .checked_div(perp_info.quote_lot_size) - .ok_or(math_err!())? - .floor(); - // } - // }; - - // - [Estimate the best perp order depending of polarity] + let rebalancing_amount = match polarity { + PnlPolarity::Positive => { + // - [Find the max fees] + let max_fee_amount = rebalancing_quote_amount + .checked_mul(perp_info.effective_fee) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_ceil() + .ok_or_else(|| error!(UxdError::MathError))?; + + // - [Get the amount of quote_lots for the perp order minus fees not to overflow max_rebalancing_amount] + rebalancing_quote_amount + .checked_sub(max_fee_amount) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_div(perp_info.quote_lot_size) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_floor() + .ok_or_else(|| error!(UxdError::MathError)) + } + PnlPolarity::Negative => { + // - [Get the amount of quote_lots for the perp order] + rebalancing_quote_amount + .checked_div(perp_info.quote_lot_size) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_floor() + .ok_or_else(|| error!(UxdError::MathError)) + } + }?; + + // - 3 [PlACE SHORT PERP] ------------------------------------------------- + + // - [Place perp order CPI to Mango Market v3] // Note : The caller is the Taker, the side depend of the PnL Polarity. let taker_side = match polarity { // Note : Augment the delta neutral position, increasing short exposure, by selling perp. @@ -288,49 +295,34 @@ pub fn handler( // [BID: taker (us, the caller) | ASK: maker] PnlPolarity::Negative => Side::Bid, }; - let quote_lot_amount = rebalancing_amount.checked_to_num().ok_or(math_err!())?; - let perp_order = ctx - .accounts - .find_best_order_in_book_for_quote_lot_amount(taker_side, quote_lot_amount)?; - - check!( - perp_order.quantity > 0, - UxdErrorCode::QuantityBelowContractSize - )?; - - // - [Checks that the best price found is within slippage range] - check_effective_order_price_versus_limit_price(&perp_info, &perp_order, slippage)?; + let max_quote_quantity = rebalancing_amount + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + let limit_price = + I80F48::checked_from_num(limit_price).ok_or_else(|| error!(UxdError::MathError))?; + let limit_price_lot = price_to_lot_price(limit_price, &perp_info)?; + let reduce_only = taker_side == Side::Bid; - // - 3 [PlACE SHORT PERP] ------------------------------------------------- - - // - [Base depository's position size in native units PRE perp order (to calculate the % filled later on)] - let initial_base_position = total_perp_base_lot_position(&pre_pa)?; + require!(max_quote_quantity != 0, UxdError::QuantityBelowContractSize); - // - [Place perp order CPI to Mango Market v3] - let reduce_only = perp_order.taker_side == Side::Bid; - mango_program::place_perp_order( + mango_markets_v3::place_perp_order2( ctx.accounts .into_place_perp_order_context() .with_signer(depository_signer_seed), - perp_order.price, - perp_order.quantity, + taker_side, + limit_price_lot.to_num(), + i64::MAX, + max_quote_quantity, 0, - perp_order.taker_side, - mango::matching::OrderType::ImmediateOrCancel, + OrderType::ImmediateOrCancel, reduce_only, + None, + MANGO_PERP_MAX_FILL_EVENTS, )?; // - [Perp account state POST perp order] let post_pa = ctx.accounts.perp_account(&perp_info)?; - // - [Checks that the order was fully filled] - let post_perp_order_base_lot_position = total_perp_base_lot_position(&post_pa)?; - check_perp_order_fully_filled( - perp_order.quantity, - initial_base_position, - post_perp_order_base_lot_position, - )?; - // - 4 [TRANSFER COLLATERAL/QUOTE TO MANGO (depending of Polarity)] ------- // - 5 [TRANSFER QUOTE/COLLATERAL TO USER (depending of Polarity)] -------- // Note : This is a workaround due to being limited by the number of accounts per instruction (~34) @@ -344,94 +336,122 @@ pub fn handler( // - [Calculate order deltas to proceed to transfers] // ensures current context make sense as the derive_order_delta is generic match polarity { - PnlPolarity::Positive => check!( - pre_pa.taker_quote < post_pa.taker_quote, - UxdErrorCode::InvalidOrderDirection - )?, - PnlPolarity::Negative => check!( - pre_pa.taker_quote > post_pa.taker_quote, - UxdErrorCode::InvalidOrderDirection - )?, + PnlPolarity::Positive => { + require!( + pre_pa.taker_quote <= post_pa.taker_quote, + UxdError::InvalidOrderDirection + ); + } + PnlPolarity::Negative => { + require!( + pre_pa.taker_quote >= post_pa.taker_quote, + UxdError::InvalidOrderDirection + ); + } }; let order_delta = derive_order_delta(&pre_pa, &post_pa, &perp_info)?; - + msg!("order_delta {:?}", order_delta); match polarity { PnlPolarity::Positive => { - // - 4 [DEPOSIT COLLATERAL ON MANGO] ------------------------------ - mango_program::deposit( + // - 4 [TRANSFER COLLATERAL TO MANGO] ----------------------------- + let collateral_deposit_amount = order_delta + .base + .unsigned_abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + // - [Deposit collateral to MangoAccount] + mango_markets_v3::deposit( ctx.accounts .into_deposit_user_collateral_to_mango_context() .with_signer(depository_signer_seed), - order_delta.collateral, + collateral_deposit_amount, )?; + // - 5 [TRANSFER QUOTE TO USER (Minus Taker Fees)] ---------------- - let quote_delta = order_delta + let quote_withdraw_amount = order_delta .quote .checked_sub(order_delta.fee) - .ok_or(math_err!())?; - // - [Withdraw mango quote to the user] - mango_program::withdraw( + .ok_or_else(|| error!(UxdError::MathError))? + .unsigned_abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + // - [Withdraw mango quote to the passthrough account] + mango_markets_v3::withdraw( ctx.accounts .into_withdraw_quote_from_mango_to_user_context() .with_signer(depository_signer_seed), - quote_delta, - false, + quote_withdraw_amount, + false, // Settle PNL before calling this IX if this fails + )?; + // - 6 [UPDATE ACCOUNTING] ------------------------------------------------ + ctx.accounts.update_onchain_accounting_positive_pnl( + collateral_deposit_amount.into(), + quote_withdraw_amount.into(), + order_delta.fee.abs().to_num(), )?; } PnlPolarity::Negative => { - // - 4 [DEPOSIT QUOTE TO MANGO (Plus Taker Fees)] ----------------- - let quote_delta = order_delta + // - 4 [TRANSFER QUOTE TO MANGO (Plus Taker Fees)] ---------------------------------- + let quote_deposit_amount = order_delta .quote .checked_add(order_delta.fee) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))? + .unsigned_abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; // - [Deposit quote to MangoAccount] - mango_program::deposit( + mango_markets_v3::deposit( ctx.accounts .into_deposit_user_quote_to_mango_context() .with_signer(depository_signer_seed), - quote_delta, + quote_deposit_amount, )?; + // - 5 [TRANSFER COLLATERAL TO USER] ------------------------------ - mango_program::withdraw( + let collateral_withdraw_amount = order_delta + .base + .unsigned_abs() + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + // - [Mango withdraw CPI] + mango_markets_v3::withdraw( ctx.accounts .into_withdraw_collateral_from_mango_to_user_context() .with_signer(depository_signer_seed), - order_delta.collateral, + collateral_withdraw_amount, false, )?; - // Note : Too short in computing for now. Add again later // - [If ATA mint is WSOL, unwrap] - // if ctx.accounts.depository.collateral_mint == spl_token::native_mint::id() { - // token::close_account(ctx.accounts.into_unwrap_wsol_by_closing_ata_context())?; - // } + if collateral_mint == spl_token::native_mint::id() { + token::close_account(ctx.accounts.into_unwrap_wsol_by_closing_ata_context())?; + } + + // - 6 [UPDATE ACCOUNTING] ------------------------------------------------ + ctx.accounts.update_onchain_accounting_negative_pnl( + collateral_withdraw_amount.into(), + quote_deposit_amount.into(), + order_delta.fee.abs().to_num(), + )?; } } - // - 6 [UPDATE ACCOUNTING] ------------------------------------------------ - - ctx.accounts.update_onchain_accounting( - order_delta.collateral, - order_delta.quote, - order_delta.fee, - polarity, - )?; - - // Note : Add later when computing limit is not an issue anymore // emit!(RebalanceMangoDepositoryLiteEvent { - // version: ctx.accounts.controller.version, - // depository_version: ctx.accounts.depository.version, - // controller: ctx.accounts.controller.key(), - // depository: ctx.accounts.depository.key(), + // version: controller.version, + // depository_version: depository.version, + // controller: controller.key(), + // depository: depository.key(), // user: ctx.accounts.user.key(), // polarity: polarity.clone(), // rebalancing_amount: max_rebalancing_amount, - // rebalanced_amount: rebalancing_quote_amount, - // slippage, - // collateral_delta: order_delta.collateral, - // quote_delta: order_delta.quote, - // fee_delta: order_delta.fee, + // rebalanced_amount: rebalancing_quote_amount.to_num(), + // limit_price, + // base_delta: order_delta.base.to_num(), + // quote_delta: order_delta.quote.to_num(), + // fee_delta: order_delta.fee.to_num(), // }); Ok(()) @@ -440,16 +460,15 @@ pub fn handler( impl<'info> RebalanceMangoDepositoryLite<'info> { pub fn into_deposit_user_collateral_to_mango_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Deposit<'info>> { - let cpi_accounts = mango_program::Deposit { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.user.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank_collateral.to_account_info(), - mango_node_bank: self.mango_node_bank_collateral.to_account_info(), - mango_vault: self.mango_vault_collateral.to_account_info(), - token_program: self.token_program.to_account_info(), + root_bank: self.mango_root_bank_collateral.to_account_info(), + node_bank: self.mango_node_bank_collateral.to_account_info(), + vault: self.mango_vault_collateral.to_account_info(), owner_token_account: self.user_collateral.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); @@ -458,16 +477,15 @@ impl<'info> RebalanceMangoDepositoryLite<'info> { pub fn into_deposit_user_quote_to_mango_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Deposit<'info>> { - let cpi_accounts = mango_program::Deposit { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.user.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank_quote.to_account_info(), - mango_node_bank: self.mango_node_bank_quote.to_account_info(), - mango_vault: self.mango_vault_quote.to_account_info(), - token_program: self.token_program.to_account_info(), + root_bank: self.mango_root_bank_quote.to_account_info(), + node_bank: self.mango_node_bank_quote.to_account_info(), + vault: self.mango_vault_quote.to_account_info(), owner_token_account: self.user_quote.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); @@ -476,18 +494,17 @@ impl<'info> RebalanceMangoDepositoryLite<'info> { pub fn into_withdraw_quote_from_mango_to_user_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Withdraw<'info>> { - let cpi_accounts = mango_program::Withdraw { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank_quote.to_account_info(), - mango_node_bank: self.mango_node_bank_quote.to_account_info(), - mango_vault: self.mango_vault_quote.to_account_info(), + root_bank: self.mango_root_bank_quote.to_account_info(), + node_bank: self.mango_node_bank_quote.to_account_info(), + vault: self.mango_vault_quote.to_account_info(), token_account: self.user_quote.to_account_info(), - mango_signer: self.mango_signer.to_account_info(), - token_program: self.token_program.to_account_info(), + signer: self.mango_signer.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) @@ -495,18 +512,17 @@ impl<'info> RebalanceMangoDepositoryLite<'info> { pub fn into_withdraw_collateral_from_mango_to_user_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Withdraw<'info>> { - let cpi_accounts = mango_program::Withdraw { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank_collateral.to_account_info(), - mango_node_bank: self.mango_node_bank_collateral.to_account_info(), - mango_vault: self.mango_vault_collateral.to_account_info(), + root_bank: self.mango_root_bank_collateral.to_account_info(), + node_bank: self.mango_node_bank_collateral.to_account_info(), + vault: self.mango_vault_collateral.to_account_info(), token_account: self.user_collateral.to_account_info(), - mango_signer: self.mango_signer.to_account_info(), - token_program: self.token_program.to_account_info(), + signer: self.mango_signer.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) @@ -514,16 +530,16 @@ impl<'info> RebalanceMangoDepositoryLite<'info> { pub fn into_place_perp_order_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::PlacePerpOrder<'info>> { - let cpi_accounts = mango_program::PlacePerpOrder { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::PlacePerpOrder2<'info>> { + let cpi_accounts = mango_markets_v3::PlacePerpOrder2 { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_perp_market: self.mango_perp_market.to_account_info(), - mango_bids: self.mango_bids.to_account_info(), - mango_asks: self.mango_asks.to_account_info(), - mango_event_queue: self.mango_event_queue.to_account_info(), + perp_market: self.mango_perp_market.to_account_info(), + bids: self.mango_bids.to_account_info(), + asks: self.mango_asks.to_account_info(), + event_queue: self.mango_event_queue.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) @@ -545,71 +561,68 @@ impl<'info> RebalanceMangoDepositoryLite<'info> { // Additional convenience methods related to the inputted accounts impl<'info> RebalanceMangoDepositoryLite<'info> { // Return general information about the perpetual related to the collateral in use - fn perpetual_info(&self) -> UxdResult { + fn perpetual_info(&self) -> Result { let perp_info = PerpInfo::new( &self.mango_group, &self.mango_cache, - &self.depository_mango_account, + &self.mango_account, self.mango_perp_market.key, self.mango_group.key, self.mango_program.key, )?; - // No computing left - // msg!("perp_info {:?}", perp_info); + msg!("perp_info {:?}", perp_info); Ok(perp_info) } // Return the PerpAccount that represent the account balances (Quote and Taker, Taker is the part that is waiting settlement) - fn perp_account(&self, perp_info: &PerpInfo) -> UxdResult { + fn perp_account(&self, perp_info: &PerpInfo) -> Result { // - loads Mango's accounts let mango_account = MangoAccount::load_checked( - &self.depository_mango_account, + &self.mango_account, self.mango_program.key, self.mango_group.key, - )?; + ) + .map_err(ProgramError::from)?; Ok(mango_account.perp_accounts[perp_info.market_index]) } - fn find_best_order_in_book_for_quote_lot_amount( - &self, - taker_side: Side, - quote_lot_amount: i64, - ) -> UxdResult { - let perp_market = PerpMarket::load_checked( - &self.mango_perp_market, - self.mango_program.key, - self.mango_group.key, - )?; - // Load the maker side of the book - let book_maker_side = match taker_side { - Side::Bid => { - BookSide::load_mut_checked(&self.mango_asks, self.mango_program.key, &perp_market) - } - Side::Ask => { - BookSide::load_mut_checked(&self.mango_bids, self.mango_program.key, &perp_market) - } - }?; - // Search for the best order to spend the given amount of quote lot - get_best_order_for_quote_lot_amount(book_maker_side, taker_side, quote_lot_amount) + fn update_onchain_accounting_negative_pnl( + &mut self, + collateral_withdrawn_amount: u128, + rebalanced_amount: u128, + fee_amount: u128, + ) -> Result<()> { + let depository = &mut self.depository.load_mut()?; + depository.collateral_amount_deposited = depository + .collateral_amount_deposited + .checked_sub(collateral_withdrawn_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.total_amount_rebalanced = depository + .total_amount_rebalanced + .wrapping_add(rebalanced_amount); + depository.total_amount_paid_taker_fee = depository + .total_amount_paid_taker_fee + .wrapping_add(fee_amount); + Ok(()) } - fn update_onchain_accounting( + fn update_onchain_accounting_positive_pnl( &mut self, - collateral_delta: u64, - quote_delta: u64, - fee_delta: u64, - polarity: &PnlPolarity, - ) -> UxdResult { - // Mango Depository - let event = match polarity { - PnlPolarity::Positive => AccountingEvent::Deposit, - PnlPolarity::Negative => AccountingEvent::Withdraw, - }; - self.depository - .update_collateral_amount_deposited(&event, collateral_delta)?; - self.depository.update_rebalanced_amount(quote_delta)?; - self.depository - .update_total_amount_paid_taker_fee(fee_delta)?; + collateral_deposited_amount: u128, + rebalanced_amount: u128, + fee_amount: u128, + ) -> Result<()> { + let depository = &mut self.depository.load_mut()?; + depository.collateral_amount_deposited = depository + .collateral_amount_deposited + .checked_add(collateral_deposited_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.total_amount_rebalanced = depository + .total_amount_rebalanced + .wrapping_add(rebalanced_amount); + depository.total_amount_paid_taker_fee = depository + .total_amount_paid_taker_fee + .wrapping_add(fee_amount); Ok(()) } } @@ -620,34 +633,29 @@ impl<'info> RebalanceMangoDepositoryLite<'info> { &self, max_rebalancing_amount: u64, polarity: &PnlPolarity, - slippage: u32, - ) -> ProgramResult { - // Valid slippage check - check!( - (slippage > 0) && (slippage <= SLIPPAGE_BASIS), - UxdErrorCode::InvalidSlippage - )?; - - // Rebalancing amount must be above 0 - check!( - max_rebalancing_amount > 0, - UxdErrorCode::InvalidRebalancingAmount - )?; + limit_price: f32, + ) -> Result<()> { + require!(limit_price > 0f32, UxdError::InvalidLimitPrice); + require!( + max_rebalancing_amount != 0, + UxdError::InvalidRebalancingAmount + ); - // Rebalancing amount must be above 0 match polarity { PnlPolarity::Positive => (), - PnlPolarity::Negative => check!( - self.user_quote.amount >= max_rebalancing_amount, - UxdErrorCode::InsufficientQuoteAmount - )?, - }; + PnlPolarity::Negative => { + require!( + self.user_quote.amount >= max_rebalancing_amount, + UxdError::InsufficientQuoteAmount + ); + } + } validate_perp_market_mint_matches_depository_collateral_mint( &self.mango_group, self.mango_program.key, self.mango_perp_market.key, - &self.depository.collateral_mint, + &self.depository.load()?.collateral_mint, )?; Ok(()) diff --git a/programs/uxd/src/instructions/mango_dex/redeem_from_mango_depository.rs b/programs/uxd/src/instructions/mango_dex/redeem_from_mango_depository.rs index ce23114bf..88bf0e3cd 100644 --- a/programs/uxd/src/instructions/mango_dex/redeem_from_mango_depository.rs +++ b/programs/uxd/src/instructions/mango_dex/redeem_from_mango_depository.rs @@ -1,29 +1,18 @@ -use crate::check_assert; -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; -use crate::mango_program; -use crate::mango_utils::check_effective_order_price_versus_limit_price; -use crate::mango_utils::check_perp_order_fully_filled; +use crate::error::UxdError; use crate::mango_utils::derive_order_delta; -use crate::mango_utils::get_best_order_for_quote_lot_amount; -use crate::mango_utils::total_perp_base_lot_position; -use crate::mango_utils::Order; +use crate::mango_utils::price_to_lot_price; use crate::mango_utils::PerpInfo; use crate::validate_perp_market_mint_matches_depository_collateral_mint; -use crate::AccountingEvent; use crate::Controller; use crate::MangoDepository; -use crate::UxdError; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MANGO_ACCOUNT_NAMESPACE; use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::MANGO_PERP_MAX_FILL_EVENTS; use crate::REDEEMABLE_MINT_NAMESPACE; -use crate::SLIPPAGE_BASIS; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; use anchor_lang::prelude::*; -use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token; use anchor_spl::token::Burn; use anchor_spl::token::CloseAccount; @@ -31,18 +20,18 @@ use anchor_spl::token::Mint; use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use fixed::types::I80F48; -use mango::matching::BookSide; +use mango::matching::OrderType; use mango::matching::Side; use mango::state::MangoAccount; use mango::state::PerpAccount; -use mango::state::PerpMarket; +use num_traits::identities::Zero; -declare_check_assert_macros!(SourceFileId::InstructionMangoDexRedeemFromMangoDepository); - -/// Takes 24 accounts - 9 used locally - 10 for MangoMarkets CPI - 4 Programs - 1 Sysvar +/// Takes 22 accounts #[derive(Accounts)] pub struct RedeemFromMangoDepository<'info> { /// #1 Public call accessible to any user + /// Note - Mut required for WSOL unwrapping + #[account(mut)] pub user: Signer<'info>, /// #2 @@ -53,25 +42,26 @@ pub struct RedeemFromMangoDepository<'info> { #[account( mut, seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump, + bump = controller.load()?.bump, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository, + has_one = redeemable_mint @UxdError::InvalidRedeemableMint )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #4 UXDProgram on chain account bound to a Controller instance. /// The `MangoDepository` manages a MangoAccount for a single Collateral. #[account( mut, - seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.collateral_mint.as_ref()], - bump = depository.bump, - has_one = controller @UxdIdlErrorCode::InvalidController, - constraint = controller.registered_mango_depositories.contains(&depository.key()) @UxdIdlErrorCode::InvalidDepository + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, + has_one = collateral_mint @UxdError::InvalidCollateralMint )] - pub depository: Box>, + pub depository: AccountLoader<'info, MangoDepository>, /// #5 The collateral mint used by the `depository` instance - #[account( - constraint = collateral_mint.key() == depository.collateral_mint @UxdIdlErrorCode::InvalidCollateralMint - )] + /// Required to create the user_collateral ATA if needed pub collateral_mint: Box>, /// #6 The redeemable mint managed by the `controller` instance @@ -79,18 +69,16 @@ pub struct RedeemFromMangoDepository<'info> { #[account( mut, seeds = [REDEEMABLE_MINT_NAMESPACE], - bump = controller.redeemable_mint_bump, - constraint = redeemable_mint.key() == controller.redeemable_mint @UxdIdlErrorCode::InvalidRedeemableMint + bump = controller.load()?.redeemable_mint_bump, )] pub redeemable_mint: Box>, /// #7 The `user`'s ATA for the `depository`'s `collateral_mint` /// Will be credited during this instruction #[account( - init_if_needed, - associated_token::mint = collateral_mint, - associated_token::authority = user, - payer = payer, + mut, + constraint = user_collateral.mint == depository.load()?.collateral_mint @UxdError::InvalidCollateralMint, + constraint = &user_collateral.owner == user.key @UxdError::InvalidOwner, )] pub user_collateral: Box>, @@ -98,55 +86,68 @@ pub struct RedeemFromMangoDepository<'info> { /// Will be debited during this instruction #[account( mut, - associated_token::mint = redeemable_mint, - associated_token::authority = user, + constraint = user_redeemable.mint == controller.load()?.redeemable_mint @UxdError::InvalidRedeemableMint, + constraint = &user_redeemable.owner == user.key @UxdError::InvalidOwner, )] pub user_redeemable: Box>, /// #9 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered #[account( mut, - seeds = [MANGO_ACCOUNT_NAMESPACE, depository.collateral_mint.as_ref()], - bump = depository.mango_account_bump, - constraint = depository.mango_account == depository_mango_account.key() @UxdIdlErrorCode::InvalidMangoAccount, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, )] - pub depository_mango_account: AccountInfo<'info>, + pub mango_account: AccountInfo<'info>, /// #10 [MangoMarkets CPI] Index grouping perp and spot markets - pub mango_group: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_group: UncheckedAccount<'info>, /// #11 [MangoMarkets CPI] Cache - pub mango_cache: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, /// #12 [MangoMarkets CPI] Signer PDA - pub mango_signer: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_signer: UncheckedAccount<'info>, /// #13 [MangoMarkets CPI] Root Bank for the `depository`'s `collateral_mint` - pub mango_root_bank: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank: UncheckedAccount<'info>, /// #14 [MangoMarkets CPI] Node Bank for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_node_bank: AccountInfo<'info>, + pub mango_node_bank: UncheckedAccount<'info>, /// #15 [MangoMarkets CPI] Vault for the `depository`'s `collateral_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_vault: AccountInfo<'info>, + pub mango_vault: UncheckedAccount<'info>, /// #16 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_perp_market: AccountInfo<'info>, + pub mango_perp_market: UncheckedAccount<'info>, /// #17 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook bids + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_bids: AccountInfo<'info>, + pub mango_bids: UncheckedAccount<'info>, /// #18 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market orderbook asks + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_asks: AccountInfo<'info>, + pub mango_asks: UncheckedAccount<'info>, /// #19 [MangoMarkets CPI] `depository`'s `collateral_mint` perp market event queue + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_event_queue: AccountInfo<'info>, + pub mango_event_queue: UncheckedAccount<'info>, /// #20 System Program pub system_program: Program<'info, System>, @@ -154,25 +155,24 @@ pub struct RedeemFromMangoDepository<'info> { /// #21 Token Program pub token_program: Program<'info, Token>, - /// #22 Associated Token Program - pub associated_token_program: Program<'info, AssociatedToken>, - - /// #23 MangoMarketv3 Program - pub mango_program: Program<'info, mango_program::Mango>, - - /// #24 Rent Sysvar - pub rent: Sysvar<'info, Rent>, + /// #22 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, } pub fn handler( ctx: Context, redeemable_amount: u64, - slippage: u32, -) -> UxdResult { + limit_price: f32, +) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let collateral_mint = depository.collateral_mint; + let depository_bump = depository.bump; + drop(depository); + let depository_signer_seed: &[&[&[u8]]] = &[&[ MANGO_DEPOSITORY_NAMESPACE, - ctx.accounts.depository.collateral_mint.as_ref(), - &[ctx.accounts.depository.bump], + collateral_mint.as_ref(), + &[depository_bump], ]]; // - 1 [CLOSE THE EQUIVALENT PERP SHORT ON MANGO] ------------------------- @@ -181,118 +181,124 @@ pub fn handler( let perp_info = ctx.accounts.perpetual_info()?; // - [Calculates the quantity of short to close] - let mut exposure_delta_in_quote_unit = I80F48::from_num(redeemable_amount); + let quote_exposure_delta = I80F48::from_num(redeemable_amount); // - [Find the max taker fees mango will take on the perp order and remove it from the exposure delta to be sure the amount order + fees don't overflow the redeemed amount] - let max_fee_amount = exposure_delta_in_quote_unit + let max_fee_amount = quote_exposure_delta .checked_mul(perp_info.effective_fee) - .ok_or(math_err!())? + .ok_or_else(|| error!(UxdError::MathError))? .checked_ceil() - .ok_or(math_err!())?; - exposure_delta_in_quote_unit = exposure_delta_in_quote_unit + .ok_or_else(|| error!(UxdError::MathError))?; + let quote_exposure_delta_minus_fees = quote_exposure_delta .checked_sub(max_fee_amount) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; // - [Perp account state PRE perp order] let pre_pa = ctx.accounts.perp_account(&perp_info)?; - // - [Base depository's position size in native units PRE perp opening (to calculate the % filled later on)] - let initial_base_lot_position = total_perp_base_lot_position(&pre_pa)?; - - // - [Find out how the best price and quantity for our order] - let exposure_delta_in_quote_lot_unit = exposure_delta_in_quote_unit + let max_quote_quantity: i64 = quote_exposure_delta_minus_fees .checked_div(perp_info.quote_lot_size) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))? + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + require!( + !max_quote_quantity.is_zero(), + UxdError::QuantityBelowContractSize + ); + // Note : Reduce the delta neutral position, increasing long exposure, by buying perp. // [BID: taker (us, the caller) | ASK: maker] let taker_side = Side::Bid; - let quote_lot_amount = exposure_delta_in_quote_lot_unit - .checked_to_num() - .ok_or(math_err!())?; - let best_order = ctx - .accounts - .get_best_order_for_quote_lot_amount_from_order_book(taker_side, quote_lot_amount)?; - - // - [Checks that the best price found is withing slippage range] - check_effective_order_price_versus_limit_price(&perp_info, &best_order, slippage)?; + let limit_price = + I80F48::checked_from_num(limit_price).ok_or_else(|| error!(UxdError::MathError))?; + let limit_price_lot = price_to_lot_price(limit_price, &perp_info)?; // - [CPI MangoMarkets - Place perp order] - mango_program::place_perp_order( + mango_markets_v3::place_perp_order2( ctx.accounts .into_close_mango_short_perp_context() .with_signer(depository_signer_seed), - best_order.price, - best_order.quantity, + taker_side, + limit_price_lot.to_num(), + i64::MAX, + max_quote_quantity, 0, - best_order.taker_side, - mango::matching::OrderType::ImmediateOrCancel, + OrderType::ImmediateOrCancel, true, + None, + MANGO_PERP_MAX_FILL_EVENTS, )?; // - [Perp account state POST perp order] let post_pa = ctx.accounts.perp_account(&perp_info)?; - // - [Checks that the order was fully filled (FoK)] - let post_perp_order_base_lot_position = total_perp_base_lot_position(&post_pa)?; - check_perp_order_fully_filled( - best_order.quantity, - initial_base_lot_position, - post_perp_order_base_lot_position, - )?; - // - 2 [BURN REDEEMABLES] ------------------------------------------------- - check!( - pre_pa.taker_quote > post_pa.taker_quote, - UxdErrorCode::InvalidOrderDirection - )?; + require!( + pre_pa.taker_quote >= post_pa.taker_quote, + UxdError::InvalidOrderDirection + ); let order_delta = derive_order_delta(&pre_pa, &post_pa, &perp_info)?; msg!("order_delta {:?}", order_delta); + // The resulting UXD amount is equal to the quote delta plus the fees. + // By burning the amount plus the fees, the user is paying them. (and we made sure + // in the beginning to downsize the redeemable amount to keep enough space for these) let redeemable_delta = order_delta .quote .checked_add(order_delta.fee) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))? + .checked_abs() + .ok_or_else(|| error!(UxdError::MathError))?; + let redeemable_burn_amount = redeemable_delta + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + token::burn( ctx.accounts.into_burn_redeemable_context(), - redeemable_delta, + redeemable_burn_amount, )?; // - 3 [WITHDRAW COLLATERAL FROM MANGO THEN RETURN TO USER] --------------- + let collateral_withdraw_amount = order_delta + .base + .checked_abs() + .ok_or_else(|| error!(UxdError::MathError))? + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; // - [CPI MangoMarkets - Withdraw] - mango_program::withdraw( + mango_markets_v3::withdraw( ctx.accounts .into_withdraw_collateral_from_mango_context() .with_signer(depository_signer_seed), - order_delta.collateral, + collateral_withdraw_amount, false, )?; // - [If ATA mint is WSOL, unwrap] - if ctx.accounts.depository.collateral_mint == spl_token::native_mint::id() { + if collateral_mint == spl_token::native_mint::id() { token::close_account(ctx.accounts.into_unwrap_wsol_by_closing_ata_context())?; } // - 4 [UPDATE ACCOUNTING] ------------------------------------------------ ctx.accounts.update_onchain_accounting( - order_delta.collateral, - redeemable_delta, - order_delta.fee, + collateral_withdraw_amount.into(), + redeemable_burn_amount.into(), + order_delta.fee.abs().to_num(), )?; - // Disable until more computing available in Solana 1.9.0 - // // emit!(RedeemFromMangoDepositoryEvent { - // version: ctx.accounts.controller.version, - // controller: ctx.accounts.controller.key(), - // depository: ctx.accounts.depository.key(), + // version: controller.version, + // controller: controller.key(), + // depository: depository.key(), // user: ctx.accounts.user.key(), // redeemable_amount, - // slippage, - // collateral_delta: order_delta.collateral, - // redeemable_delta, - // fee_delta: order_delta.fee, + // limit_price, + // base_delta: order_delta.base.to_num(), + // quote_delta: order_delta.quote.to_num(), + // fee_delta: order_delta.fee.to_num(), // }); Ok(()) @@ -305,7 +311,7 @@ impl<'info> RedeemFromMangoDepository<'info> { let cpi_program = self.token_program.to_account_info(); let cpi_accounts = Burn { mint: self.redeemable_mint.to_account_info(), - to: self.user_redeemable.to_account_info(), + from: self.user_redeemable.to_account_info(), authority: self.user.to_account_info(), }; CpiContext::new(cpi_program, cpi_accounts) @@ -313,16 +319,16 @@ impl<'info> RedeemFromMangoDepository<'info> { pub fn into_close_mango_short_perp_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::PlacePerpOrder<'info>> { - let cpi_accounts = mango_program::PlacePerpOrder { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::PlacePerpOrder2<'info>> { + let cpi_accounts = mango_markets_v3::PlacePerpOrder2 { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_perp_market: self.mango_perp_market.to_account_info(), - mango_bids: self.mango_bids.to_account_info(), - mango_asks: self.mango_asks.to_account_info(), - mango_event_queue: self.mango_event_queue.to_account_info(), + perp_market: self.mango_perp_market.to_account_info(), + bids: self.mango_bids.to_account_info(), + asks: self.mango_asks.to_account_info(), + event_queue: self.mango_event_queue.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) @@ -330,18 +336,17 @@ impl<'info> RedeemFromMangoDepository<'info> { pub fn into_withdraw_collateral_from_mango_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Withdraw<'info>> { - let cpi_accounts = mango_program::Withdraw { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank.to_account_info(), - mango_node_bank: self.mango_node_bank.to_account_info(), - mango_vault: self.mango_vault.to_account_info(), + root_bank: self.mango_root_bank.to_account_info(), + node_bank: self.mango_node_bank.to_account_info(), + vault: self.mango_vault.to_account_info(), token_account: self.user_collateral.to_account_info(), - mango_signer: self.mango_signer.to_account_info(), - token_program: self.token_program.to_account_info(), + signer: self.mango_signer.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) @@ -363,100 +368,77 @@ impl<'info> RedeemFromMangoDepository<'info> { // Additional convenience methods related to the inputted accounts impl<'info> RedeemFromMangoDepository<'info> { // Return general information about the perpetual related to the collateral in use - fn perpetual_info(&self) -> UxdResult { + fn perpetual_info(&self) -> Result { let perp_info = PerpInfo::new( &self.mango_group, &self.mango_cache, - &self.depository_mango_account, + &self.mango_account, self.mango_perp_market.key, self.mango_group.key, self.mango_program.key, )?; - // No computing left // msg!("perp_info {:?}", perp_info); Ok(perp_info) } // Return the uncommitted PerpAccount that represent the account balances - fn perp_account(&self, perp_info: &PerpInfo) -> UxdResult { + fn perp_account(&self, perp_info: &PerpInfo) -> Result { // - loads Mango's accounts let mango_account = MangoAccount::load_checked( - &self.depository_mango_account, + &self.mango_account, self.mango_program.key, self.mango_group.key, - )?; + ) + .map_err(ProgramError::from)?; Ok(mango_account.perp_accounts[perp_info.market_index]) } - fn get_best_order_for_quote_lot_amount_from_order_book( - &self, - taker_side: mango::matching::Side, - quote_lot_amount: i64, - ) -> UxdResult { - let perp_market = PerpMarket::load_checked( - &self.mango_perp_market, - self.mango_program.key, - self.mango_group.key, - )?; - // Load the maker side of the book - let book_maker_side = match taker_side { - Side::Bid => { - BookSide::load_mut_checked(&self.mango_asks, self.mango_program.key, &perp_market) - } - Side::Ask => { - BookSide::load_mut_checked(&self.mango_bids, self.mango_program.key, &perp_market) - } - }?; - // Search for the best order to spend the given amount of quote lot - get_best_order_for_quote_lot_amount(book_maker_side, taker_side, quote_lot_amount) - } - // Update the accounting in the Depository and Controller Accounts to reflect changes fn update_onchain_accounting( &mut self, - collateral_delta: u64, - redeemable_delta: u64, - fee_delta: u64, - ) -> UxdResult { + collateral_withdrawn_amount: u128, + redeemable_burnt_amount: u128, + fee_amount: u128, + ) -> Result<()> { + let depository = &mut self.depository.load_mut()?; + let controller = &mut self.controller.load_mut()?; // Mango Depository - let event = AccountingEvent::Withdraw; - self.depository - .update_collateral_amount_deposited(&event, collateral_delta)?; - // Circulating supply delta - self.depository - .update_redeemable_amount_under_management(&event, redeemable_delta)?; - // Amount of fees taken by the system so far to calculate efficiency - self.depository - .update_total_amount_paid_taker_fee(fee_delta)?; + depository.collateral_amount_deposited = depository + .collateral_amount_deposited + .checked_sub(collateral_withdrawn_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.redeemable_amount_under_management = depository + .redeemable_amount_under_management + .checked_add(redeemable_burnt_amount) + .ok_or_else(|| error!(UxdError::MathError))?; + depository.total_amount_paid_taker_fee = depository + .total_amount_paid_taker_fee + .wrapping_add(fee_amount); // Controller - self.controller - .update_redeemable_circulating_supply(&event, redeemable_delta)?; + controller.redeemable_circulating_supply = controller + .redeemable_circulating_supply + .checked_add(redeemable_burnt_amount) + .ok_or_else(|| error!(UxdError::MathError))?; Ok(()) } } // Validate input arguments impl<'info> RedeemFromMangoDepository<'info> { - pub fn validate(&self, redeemable_amount: u64, slippage: u32) -> ProgramResult { - // Valid slippage check - check!( - (slippage > 0) && (slippage <= SLIPPAGE_BASIS), - UxdErrorCode::InvalidSlippage - )?; - - check!(redeemable_amount > 0, UxdErrorCode::InvalidRedeemableAmount)?; - check!( + pub fn validate(&self, redeemable_amount: u64, limit_price: f32) -> Result<()> { + require!(limit_price > 0f32, UxdError::InvalidLimitPrice); + require!(redeemable_amount != 0, UxdError::InvalidRedeemableAmount); + require!( self.user_redeemable.amount >= redeemable_amount, - UxdErrorCode::InsufficientRedeemableAmount - )?; + UxdError::InsufficientRedeemableAmount + ); validate_perp_market_mint_matches_depository_collateral_mint( &self.mango_group, self.mango_program.key, self.mango_perp_market.key, - &self.depository.collateral_mint, + &self.depository.load()?.collateral_mint, )?; - Ok(()) } } diff --git a/programs/uxd/src/instructions/mango_dex/withdraw_insurance_from_mango_depository.rs b/programs/uxd/src/instructions/mango_dex/withdraw_insurance_from_mango_depository.rs index 5605ce2b0..9214e0756 100644 --- a/programs/uxd/src/instructions/mango_dex/withdraw_insurance_from_mango_depository.rs +++ b/programs/uxd/src/instructions/mango_dex/withdraw_insurance_from_mango_depository.rs @@ -1,24 +1,17 @@ -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; -use crate::events::WithdrawInsuranceFromMangoDepositoryEventV2; -use crate::mango_program; -use crate::AccountingEvent; +use crate::error::UxdError; +use crate::events::WithdrawInsuranceFromDepositoryEvent; use crate::Controller; use crate::MangoDepository; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MANGO_ACCOUNT_NAMESPACE; use crate::MANGO_DEPOSITORY_NAMESPACE; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; use anchor_lang::prelude::*; -use anchor_spl::token::Mint; use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; -declare_check_assert_macros!(SourceFileId::InstructionMangoDexWithdrawInsuranceFromMangoDepository); - -/// Takes 18 accounts - 7 used locally - 6 for MangoMarkets CPI - 2 Programs - 1 Sysvar +/// Takes 14 accounts - 4 used locally - 7 for MangoMarkets CPI - 3 Programs #[derive(Accounts)] pub struct WithdrawInsuranceFromMangoDepository<'info> { /// #1 Authored call accessible only to the signer matching Controller.authority @@ -27,95 +20,94 @@ pub struct WithdrawInsuranceFromMangoDepository<'info> { /// #2 The top level UXDProgram on chain account managing the redeemable mint #[account( seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump, - has_one = authority @UxdIdlErrorCode::InvalidAuthority, + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #3 UXDProgram on chain account bound to a Controller instance /// The `MangoDepository` manages a MangoAccount for a single Collateral #[account( mut, - seeds = [MANGO_DEPOSITORY_NAMESPACE, collateral_mint.key().as_ref()], - bump = depository.bump, - has_one = controller @UxdIdlErrorCode::InvalidController, - constraint = controller.registered_mango_depositories.contains(&depository.key()) @UxdIdlErrorCode::InvalidDepository - )] - pub depository: Box>, - - /// #4 The collateral mint used by the `depository` instance - #[account( - constraint = collateral_mint.key() == depository.collateral_mint @UxdIdlErrorCode::InvalidCollateralMint + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, )] - pub collateral_mint: Box>, + pub depository: AccountLoader<'info, MangoDepository>, - /// #5 The insurance mint used by the `depository` instance - #[account( - constraint = quote_mint.key() == depository.quote_mint @UxdIdlErrorCode::InvalidQuoteMint - )] - pub quote_mint: Box>, - - /// #6 The `user`'s ATA for the `controller`'s `redeemable_mint` + /// #4 The `user`'s ATA for the `controller`'s `redeemable_mint` /// Will be credited during this instruction #[account( mut, - constraint = authority_quote.mint == depository.quote_mint @UxdIdlErrorCode::InvalidAuthorityQuoteATAMint + constraint = authority_quote.mint == depository.load()?.quote_mint @UxdError::InvalidQuoteMint, + constraint = &authority_quote.owner == authority.key @UxdError::InvalidOwner, )] pub authority_quote: Box>, - /// #7 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// #5 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered #[account( mut, - seeds = [MANGO_ACCOUNT_NAMESPACE, collateral_mint.key().as_ref()], - bump = depository.mango_account_bump, - constraint = depository.mango_account == depository_mango_account.key() @UxdIdlErrorCode::InvalidMangoAccount, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, )] - pub depository_mango_account: AccountInfo<'info>, + pub mango_account: AccountInfo<'info>, - /// #8 [MangoMarkets CPI] Index grouping perp and spot markets - pub mango_group: AccountInfo<'info>, + /// #6 [MangoMarkets CPI] Index grouping perp and spot markets + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, - /// #9 [MangoMarkets CPI] Cache - pub mango_cache: AccountInfo<'info>, + /// #7 [MangoMarkets CPI] Cache + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_cache: UncheckedAccount<'info>, - /// #10 [MangoMarkets CPI] Signer PDA - pub mango_signer: AccountInfo<'info>, + /// #8 [MangoMarkets CPI] Signer PDA + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_signer: UncheckedAccount<'info>, - /// #11 [MangoMarkets CPI] Root Bank for the `depository`'s `quote_mint` - pub mango_root_bank: AccountInfo<'info>, + /// #9 [MangoMarkets CPI] Root Bank for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_root_bank: UncheckedAccount<'info>, - /// #12 [MangoMarkets CPI] Node Bank for the `depository`'s `quote_mint` + /// #10 [MangoMarkets CPI] Node Bank for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_node_bank: AccountInfo<'info>, + pub mango_node_bank: UncheckedAccount<'info>, - /// #13 [MangoMarkets CPI] Vault for the `depository`'s `quote_mint` + /// #11 [MangoMarkets CPI] Vault for the `depository`'s `quote_mint` + /// CHECK: Mango CPI - checked MangoMarketV3 side #[account(mut)] - pub mango_vault: Account<'info, TokenAccount>, + pub mango_vault: UncheckedAccount<'info>, - /// #14 System Program + /// #12 System Program pub system_program: Program<'info, System>, - /// #15 Token Program + /// #13 Token Program pub token_program: Program<'info, Token>, - /// #16 MangoMarketv3 Program - pub mango_program: Program<'info, mango_program::Mango>, + /// #14 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, } -pub fn handler( - ctx: Context, - amount: u64, // native units -) -> UxdResult { - let collateral_mint = ctx.accounts.collateral_mint.key(); +pub fn handler(ctx: Context, amount: u64) -> Result<()> { + let depository = ctx.accounts.depository.load()?; + let collateral_mint = depository.collateral_mint; + let depository_bump = depository.bump; + drop(depository); let depository_signer_seed: &[&[&[u8]]] = &[&[ MANGO_DEPOSITORY_NAMESPACE, collateral_mint.as_ref(), - &[ctx.accounts.depository.bump], + &[depository_bump], ]]; // - 1 [WITHDRAW INSURANCE FROM MANGO THEN RETURN TO USER] --------------- - mango_program::withdraw( + + // - mango withdraw insurance_amount + mango_markets_v3::withdraw( ctx.accounts .into_withdraw_insurance_from_mango_context() .with_signer(depository_signer_seed), @@ -124,14 +116,19 @@ pub fn handler( )?; // - 2 [UPDATE ACCOUNTING] ------------------------------------------------ - ctx.accounts.update_accounting(amount)?; - - emit!(WithdrawInsuranceFromMangoDepositoryEventV2 { - version: ctx.accounts.controller.version, + let depository = &mut ctx.accounts.depository.load_mut()?; + depository.insurance_amount_deposited = depository + .insurance_amount_deposited + .checked_sub(amount.into()) + .ok_or_else(|| error!(UxdError::MathError))?; + + let controller = ctx.accounts.controller.load()?; + emit!(WithdrawInsuranceFromDepositoryEvent { + version: controller.version, controller: ctx.accounts.controller.key(), depository: ctx.accounts.depository.key(), - quote_mint: ctx.accounts.depository.quote_mint, - quote_mint_decimals: ctx.accounts.depository.quote_mint_decimals, + quote_mint: depository.quote_mint, + quote_mint_decimals: depository.quote_mint_decimals, withdrawn_amount: amount, }); @@ -141,38 +138,27 @@ pub fn handler( impl<'info> WithdrawInsuranceFromMangoDepository<'info> { pub fn into_withdraw_insurance_from_mango_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::Withdraw<'info>> { - let cpi_accounts = mango_program::Withdraw { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), mango_cache: self.mango_cache.to_account_info(), - mango_root_bank: self.mango_root_bank.to_account_info(), - mango_node_bank: self.mango_node_bank.to_account_info(), - mango_vault: self.mango_vault.to_account_info(), + root_bank: self.mango_root_bank.to_account_info(), + node_bank: self.mango_node_bank.to_account_info(), + vault: self.mango_vault.to_account_info(), token_account: self.authority_quote.to_account_info(), - mango_signer: self.mango_signer.to_account_info(), - token_program: self.token_program.to_account_info(), + signer: self.mango_signer.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) } } -// Additional convenience methods related to the inputted accounts -impl<'info> WithdrawInsuranceFromMangoDepository<'info> { - fn update_accounting(&mut self, insurance_delta: u64) -> ProgramResult { - // Mango Depository - self.depository - .update_insurance_amount_deposited(&AccountingEvent::Withdraw, insurance_delta)?; - Ok(()) - } -} - // Validate input arguments impl<'info> WithdrawInsuranceFromMangoDepository<'info> { - pub fn validate(&self, amount: u64) -> ProgramResult { - check!(amount > 0, UxdErrorCode::InvalidInsuranceAmount)?; + pub fn validate(&self, insurance_amount: u64) -> Result<()> { + require!(insurance_amount != 0, UxdError::InvalidInsuranceAmount); // Mango withdraw will fail with proper error thanks to `disabled borrow` set to true if the balance is not enough. Ok(()) } diff --git a/programs/uxd/src/instructions/mod.rs b/programs/uxd/src/instructions/mod.rs index 7213b3c55..0c4f25d9d 100644 --- a/programs/uxd/src/instructions/mod.rs +++ b/programs/uxd/src/instructions/mod.rs @@ -1,11 +1,15 @@ pub mod initialize_controller; pub mod mango_dex; +pub mod msol; pub mod register_mango_depository; pub mod set_mango_depositories_redeemable_soft_cap; +pub mod set_mango_depository_quote_mint_and_redeem_fee; pub mod set_redeemable_global_supply_cap; pub use initialize_controller::*; pub use mango_dex::*; +pub use msol::*; pub use register_mango_depository::*; pub use set_mango_depositories_redeemable_soft_cap::*; +pub use set_mango_depository_quote_mint_and_redeem_fee::*; pub use set_redeemable_global_supply_cap::*; diff --git a/programs/uxd/src/instructions/msol/create_depository_msol_config.rs b/programs/uxd/src/instructions/msol/create_depository_msol_config.rs new file mode 100644 index 000000000..d83a49dc8 --- /dev/null +++ b/programs/uxd/src/instructions/msol/create_depository_msol_config.rs @@ -0,0 +1,93 @@ +use crate::error::UxdError; +use crate::events::CreateDepositoryMSolConfigEvent; +use crate::state::msol_config::MSolConfig; +use crate::state::msol_config::TARGET_LIQUIDITY_RATIO_MAX; +use crate::Controller; +use crate::MangoDepository; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::MSOL_CONFIG_NAMESPACE; +use crate::MSOL_CONFIG_SPACE; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct CreateDepositoryMSolConfig<'info> { + /// #1 Authored call accessible only to the signer matching Controller.authority + pub authority: Signer<'info>, + + /// #2 + #[account(mut)] + pub payer: Signer<'info>, + + /// #3 The top level UXDProgram on chain account managing the redeemable mint + #[account( + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #4 UXDProgram on chain account bound to a Controller instance + /// The `MangoDepository` manages a MangoAccount for a single Collateral + #[account( + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + constraint = depository.load()?.collateral_mint == spl_token::native_mint::id() @UxdError::InvalidNonNativeMintUsed + )] + pub depository: AccountLoader<'info, MangoDepository>, + + /// #5 Msol config account for the `depository` instance + #[account( + init, + seeds = [MSOL_CONFIG_NAMESPACE, depository.key().as_ref()], + bump, + payer = payer, + space = MSOL_CONFIG_SPACE + )] + pub msol_config: AccountLoader<'info, MSolConfig>, + + /// #6 System Program + pub system_program: Program<'info, System>, + + /// #7 Rent Sysvar + pub rent: Sysvar<'info, Rent>, +} + +pub fn handler( + ctx: Context, + target_liquidity_ratio: u16, +) -> Result<()> { + let msol_config = &mut ctx.accounts.msol_config.load_init()?; + + msol_config.bump = *ctx + .bumps + .get("msol_config") + .ok_or_else(|| error!(UxdError::BumpError))?; + msol_config.depository = ctx.accounts.depository.key(); + msol_config.controller = ctx.accounts.controller.key(); + msol_config.enabled = false; + msol_config.target_liquidity_ratio = target_liquidity_ratio; + + emit!(CreateDepositoryMSolConfigEvent { + version: ctx.accounts.controller.load()?.version, + controller: msol_config.controller, + depository: msol_config.depository, + msol_config: ctx.accounts.msol_config.key(), + enabled: msol_config.enabled, + target_liquidity_ratio: msol_config.target_liquidity_ratio, + }); + + Ok(()) +} + +impl<'info> CreateDepositoryMSolConfig<'info> { + pub fn validate(&mut self, target_liquidity_ratio: u16) -> Result<()> { + require!( + target_liquidity_ratio <= TARGET_LIQUIDITY_RATIO_MAX, + UxdError::TargetLiquidityRatioExceedMax + ); + Ok(()) + } +} diff --git a/programs/uxd/src/instructions/msol/enable_msol_swap.rs b/programs/uxd/src/instructions/msol/enable_msol_swap.rs new file mode 100644 index 000000000..e6c417edb --- /dev/null +++ b/programs/uxd/src/instructions/msol/enable_msol_swap.rs @@ -0,0 +1,62 @@ +use crate::error::UxdError; +use crate::state::msol_config::MSolConfig; +use crate::Controller; +use crate::MangoDepository; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::MSOL_CONFIG_NAMESPACE; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct EnableMsolSwap<'info> { + /// #1 Authored call accessible only to the signer matching Controller.authority + pub authority: Signer<'info>, + + /// #2 + #[account(mut)] + pub payer: Signer<'info>, + + /// #3 The top level UXDProgram on chain account managing the redeemable mint + #[account( + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #4 UXDProgram on chain account bound to a Controller instance + /// The `MangoDepository` manages a MangoAccount for a single Collateral + #[account( + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + )] + pub depository: AccountLoader<'info, MangoDepository>, + + /// #5 Msol config account for the `depository` instance + #[account( + mut, + seeds = [MSOL_CONFIG_NAMESPACE, depository.key().as_ref()], + bump = msol_config.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = depository @UxdError::InvalidDepository, + )] + pub msol_config: AccountLoader<'info, MSolConfig>, +} + +pub fn handler(ctx: Context, enable: bool) -> Result<()> { + let msol_config = &mut ctx.accounts.msol_config.load_mut()?; + msol_config.enabled = enable; + Ok(()) +} + +impl<'info> EnableMsolSwap<'info> { + pub fn validate(&mut self, enable: bool) -> Result<()> { + require!( + self.msol_config.load()?.enabled != enable, + UxdError::InvalidEnablingMsolSwap + ); + Ok(()) + } +} diff --git a/programs/uxd/src/instructions/msol/mod.rs b/programs/uxd/src/instructions/msol/mod.rs new file mode 100644 index 000000000..2d1492ff0 --- /dev/null +++ b/programs/uxd/src/instructions/msol/mod.rs @@ -0,0 +1,11 @@ +pub mod create_depository_msol_config; +pub mod enable_msol_swap; +pub mod set_msol_liquidity_ratio; +pub mod rebalance_mango_depository_msol_ratio; +pub mod msol_utils; + +pub use create_depository_msol_config::*; +pub use enable_msol_swap::*; +pub use set_msol_liquidity_ratio::*; +pub use rebalance_mango_depository_msol_ratio::*; +pub use msol_utils::*; diff --git a/programs/uxd/src/instructions/msol/msol_utils.rs b/programs/uxd/src/instructions/msol/msol_utils.rs new file mode 100644 index 000000000..f8235c14f --- /dev/null +++ b/programs/uxd/src/instructions/msol/msol_utils.rs @@ -0,0 +1,79 @@ +use anchor_lang::prelude::*; +use fixed::types::I80F48; +use mango::state::{MangoAccount, MangoCache, MangoGroup}; + +use crate::{error::UxdError, mango_utils::get_native_deposit}; + +#[derive(Debug)] +pub struct MsolInfo { + pub native_mint_lamports: I80F48, + pub msol_lamports: I80F48, +} + +impl MsolInfo { + pub fn new( + mango_group_ai: &AccountInfo, + mango_cache_ai: &AccountInfo, + mango_account_ai: &AccountInfo, + mango_group_key: &Pubkey, + mango_program_key: &Pubkey, + marinade_state: &Account, + msol_mint: &Pubkey, + ) -> Result { + let mango_group = MangoGroup::load_checked(mango_group_ai, mango_program_key) + .map_err(ProgramError::from)?; + + let mango_cache = MangoCache::load_checked(mango_cache_ai, mango_program_key, &mango_group) + .map_err(ProgramError::from)?; + + let mango_account = + MangoAccount::load_checked(mango_account_ai, mango_program_key, mango_group_key) + .map_err(ProgramError::from)?; + + let depository_sol_lamports = get_native_deposit( + &spl_token::native_mint::id(), + &mango_group, + &mango_cache, + &mango_account, + ) + .map_err(ProgramError::from)?; + + let depository_msol_amount = + get_native_deposit(msol_mint, &mango_group, &mango_cache, &mango_account) + .map_err(ProgramError::from)? + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + let depository_msol_amount_lamports = I80F48::checked_from_num( + // msol_amount * msol_price_in_sol + marinade_state + .calc_lamports_from_msol_amount(depository_msol_amount) + .map_err(|me| ProgramError::from(me))?, + ) + .ok_or_else(|| error!(UxdError::MathError))?; + + drop(mango_group); + drop(mango_account); + drop(mango_cache); + + Ok(MsolInfo { + native_mint_lamports: depository_sol_lamports, + msol_lamports: depository_msol_amount_lamports, + }) + } +} + +impl MsolInfo { + pub fn total_depository_amount_lamports(&self) -> Result { + self.native_mint_lamports + .checked_add(self.msol_lamports) + .ok_or_else(|| error!(UxdError::MathError)) + } + + // liquidity_ratio[t] = liquid_SOL[t]/(liquid_SOL[t] + marinade_SOL[t]*MSOL_underlying_SOL[t]) + pub fn liquidity_ratio(&self) -> Result { + self.native_mint_lamports + .checked_div(self.total_depository_amount_lamports()?) + .ok_or_else(|| error!(UxdError::MathError)) + } +} diff --git a/programs/uxd/src/instructions/msol/rebalance_mango_depository_msol_ratio.rs b/programs/uxd/src/instructions/msol/rebalance_mango_depository_msol_ratio.rs new file mode 100644 index 000000000..26ffc3c68 --- /dev/null +++ b/programs/uxd/src/instructions/msol/rebalance_mango_depository_msol_ratio.rs @@ -0,0 +1,544 @@ +use crate::error::UxdError; +use crate::state::msol_config::MSolConfig; +use crate::Controller; +use crate::MangoDepository; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_ACCOUNT_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::MSOL_CONFIG_NAMESPACE; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; +use anchor_comp::marinade; +use anchor_comp::spl_token::SyncNative; +use anchor_lang::prelude::*; +use anchor_lang::system_program; +use anchor_lang::system_program::Transfer; +use anchor_spl::token; +use anchor_spl::token::Mint; +use anchor_spl::token::Token; +use anchor_spl::token::TokenAccount; + +use fixed::types::I80F48; +use marinade_onchain_helper::cpi_context_accounts::MarinadeLiquidUnstake; +use marinade_onchain_helper::{cpi_context_accounts::MarinadeDeposit}; + +use super::MsolInfo; + +#[derive(Accounts)] +pub struct RebalanceMangoDepositoryMsolRatio<'info> { + /// #1 Public call accessible to any user + #[account(mut)] + pub user: Signer<'info>, + + /// #2 + #[account(mut)] + pub payer: Signer<'info>, + + // #3 The top level UXDProgram on chain account managing the redeemable mint + #[account( + mut, + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository, + )] + pub controller: AccountLoader<'info, Controller>, + + // #4 UXDProgram on chain account bound to a Controller instance + // The `MangoDepository` manages a MangoAccount for a single Collateral + #[account( + mut, + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = mango_account @UxdError::InvalidMangoAccount, + )] + pub depository: AccountLoader<'info, MangoDepository>, + + // #5 Msol config account for the `depository` instance + #[account( + seeds = [MSOL_CONFIG_NAMESPACE, depository.key().as_ref()], + bump = msol_config.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = depository @UxdError::InvalidDepository, + )] + pub msol_config: AccountLoader<'info, MSolConfig>, + + // #6 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered + #[account( + mut, + seeds = [MANGO_ACCOUNT_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.mango_account_bump, + )] + pub mango_account: AccountInfo<'info>, + + /// #7 [MangoMarkets CPI] Index grouping perp and spot markets + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, + + /// #8 [MangoMarkets CPI] Cache + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_cache: UncheckedAccount<'info>, + + /// #9 [MangoMarkets CPI] Signer PDA + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_signer: UncheckedAccount<'info>, + + /// #10 [MangoMarkets CPI] Root Bank for the `depository`'s `sol` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_sol_root_bank: UncheckedAccount<'info>, + + /// #11 [MangoMarkets CPI] Node Bank for the `depository`'s `sol` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_sol_node_bank: UncheckedAccount<'info>, + + /// #12 [MangoMarkets CPI] Vault for the `depository`'s `sol` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_sol_vault: UncheckedAccount<'info>, + + /// #13 [MangoMarkets CPI] Root Bank for the `depository`'s `msol` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_msol_root_bank: UncheckedAccount<'info>, + + /// #14 [MangoMarkets CPI] Node Bank for the `depository`'s `msol` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_msol_node_bank: UncheckedAccount<'info>, + + /// #15 [MangoMarkets CPI] Vault for the `depository`'s `msol` + /// CHECK: Mango CPI - checked MangoMarketV3 side + #[account(mut)] + pub mango_msol_vault: UncheckedAccount<'info>, + + /// #16 MangoMarketv3 Program + pub mango_program: Program<'info, MangoMarketV3>, + + /// #17 + /// CHECK: Marinade CPI + #[account(mut)] + pub marinade_state: UncheckedAccount<'info>, + + /// #18 + /// CHECK: Marinade CPI + #[account(mut)] + pub msol_mint: Box>, + + /// #19 + /// CHECK: Marinade CPI + pub msol_mint_authority: UncheckedAccount<'info>, + + /// #20 + /// CHECK: Marinade CPI + #[account(mut)] + pub liq_pool_sol_leg_pda: UncheckedAccount<'info>, + + /// #21 + /// CHECK: Marinade CPI + #[account(mut)] + pub liq_pool_msol_leg: UncheckedAccount<'info>, + + /// #22 + /// CHECK: Marinade CPI + pub liq_pool_msol_leg_authority: UncheckedAccount<'info>, + + /// #23 + /// CHECK: Marinade CPI + #[account(mut)] + pub treasury_msol_account: UncheckedAccount<'info>, + + /// #24 + /// CHECK: Marinade CPI + #[account(mut)] + pub reserve_pda: UncheckedAccount<'info>, + + /// #25 sol passthrough ata interact with marinade/mango cpi, + /// either accept sol from mango, then pass it to marinade for swapping, or + /// accept sol from swapped from marinade, then deposit to mango + #[account( + mut, + constraint = sol_passthrough_ata.mint == spl_token::native_mint::id() @UxdError::InvalidNonNativeMintAtaUsed, + constraint = &sol_passthrough_ata.owner == user.key @UxdError::InvalidOwner, + )] + pub sol_passthrough_ata: Box>, + + /// #26 msol passthrough ata interact with marinade/mango cpi + /// either accept msol from mango, then pass it to marinade for swapping, or + /// accept msol from swapped from marinade, then deposit to mango + #[account( + mut, + constraint = msol_passthrough_ata.mint == msol_mint.key() @UxdError::InvalidNonMSolMintAtaUsed, + constraint = &msol_passthrough_ata.owner == user.key @UxdError::InvalidOwner, + )] + pub msol_passthrough_ata: Box>, + + /// #27 Program + /// CHECK: Marinade CPI + #[account(address = marinade_finance::ID)] + pub marinade_finance_program: AccountInfo<'info>, + + /// #28 System Program + pub system_program: Program<'info, System>, + + /// #29 Token Program + pub token_program: Program<'info, Token>, +} + +pub fn handler(ctx: Context) -> Result<()> { + // 1. load marinade state + let marinade_state: Account = + Account::try_from(&ctx.accounts.marinade_state)?; + + // 2. create msol info instance, providing info for liquidity_ratio and sol/msol amounts + let msol_info = MsolInfo::new( + &ctx.accounts.mango_group, + &ctx.accounts.mango_cache, + &ctx.accounts.mango_account, + ctx.accounts.mango_group.key, + ctx.accounts.mango_program.key, + &marinade_state, + &ctx.accounts.msol_mint.key(), + )?; + msg!("msol_info {:?}", msol_info); + + // 3. load msol config state and get target + let msol_config = ctx.accounts.msol_config.load()?; + + // 4. difference of the current liquidity ratio to the target + let diff_to_target_liquidity = msol_config + .diff_to_target_liquidity(msol_info.liquidity_ratio()?) + .map_err(ProgramError::from)?; + msg!("diff_to_target_liquidity {:?}", diff_to_target_liquidity); + + // 5. depository seed + let depository = ctx.accounts.depository.load()?; + let collateral_mint = depository.collateral_mint; + let depository_bump = depository.bump; + drop(depository); + + let depository_signer_seed: &[&[&[u8]]] = &[&[ + MANGO_DEPOSITORY_NAMESPACE, + collateral_mint.as_ref(), + &[depository_bump], + ]]; + + match RebalanceRoute::from_diff_to_target_liquidity(diff_to_target_liquidity) { + RebalanceRoute::Deposit => { + rebalance_by_deposit( + &ctx, + diff_to_target_liquidity, + &msol_info, + &marinade_state, + depository_signer_seed, + )?; + } + RebalanceRoute::LiquidUnstake => { + rebalance_by_liquid_unstake( + &ctx, + diff_to_target_liquidity, + &msol_info, + &marinade_state, + depository_signer_seed, + )?; + } + RebalanceRoute::NoSwapRequired => { + // no action + } + } + + Ok(()) +} + +impl<'info> RebalanceMangoDepositoryMsolRatio<'info> { + pub fn into_marinade_deposit_cpi_ctx( + &self, + ) -> CpiContext<'_, '_, '_, 'info, MarinadeDeposit<'info>> { + let cpi_accounts = MarinadeDeposit { + state: self.marinade_state.to_account_info(), + msol_mint: self.msol_mint.to_account_info(), + liq_pool_sol_leg_pda: self.liq_pool_sol_leg_pda.to_account_info(), + liq_pool_msol_leg: self.liq_pool_msol_leg.to_account_info(), + liq_pool_msol_leg_authority: self.liq_pool_msol_leg_authority.to_account_info(), + reserve_pda: self.reserve_pda.to_account_info(), + transfer_from: self.user.to_account_info(), + mint_to: self.msol_passthrough_ata.to_account_info(), + msol_mint_authority: self.msol_mint_authority.to_account_info(), + system_program: self.system_program.to_account_info(), + token_program: self.token_program.to_account_info(), + }; + let cpi_program = self.marinade_finance_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_liquid_unstake_cpi_ctx( + &self, + ) -> CpiContext<'_, '_, '_, 'info, MarinadeLiquidUnstake<'info>> { + let cpi_accounts = MarinadeLiquidUnstake { + state: self.marinade_state.to_account_info(), + msol_mint: self.msol_mint.to_account_info(), + liq_pool_sol_leg_pda: self.liq_pool_sol_leg_pda.to_account_info(), + liq_pool_msol_leg: self.liq_pool_msol_leg.to_account_info(), + treasury_msol_account: self.treasury_msol_account.to_account_info(), + get_msol_from: self.msol_passthrough_ata.to_account_info(), + get_msol_from_authority: self.user.to_account_info(), + transfer_sol_to: self.user.to_account_info(), + system_program: self.system_program.to_account_info(), + token_program: self.token_program.to_account_info(), + }; + let cpi_program = self.marinade_finance_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_deposit_to_mango_msol_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { + mango_group: self.mango_group.to_account_info(), + mango_account: self.mango_account.to_account_info(), + owner: self.user.to_account_info(), + mango_cache: self.mango_cache.to_account_info(), + root_bank: self.mango_msol_root_bank.to_account_info(), + node_bank: self.mango_msol_node_bank.to_account_info(), + vault: self.mango_msol_vault.to_account_info(), + owner_token_account: self.msol_passthrough_ata.to_account_info(), + }; + let cpi_program = self.mango_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_deposit_to_mango_sol_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Deposit<'info>> { + let cpi_accounts = mango_markets_v3::Deposit { + mango_group: self.mango_group.to_account_info(), + mango_account: self.mango_account.to_account_info(), + owner: self.user.to_account_info(), + mango_cache: self.mango_cache.to_account_info(), + root_bank: self.mango_sol_root_bank.to_account_info(), + node_bank: self.mango_sol_node_bank.to_account_info(), + vault: self.mango_sol_vault.to_account_info(), + owner_token_account: self.sol_passthrough_ata.to_account_info(), + }; + let cpi_program = self.mango_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_withdraw_from_mango_msol_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { + mango_group: self.mango_group.to_account_info(), + mango_account: self.mango_account.to_account_info(), + owner: self.depository.to_account_info(), + mango_cache: self.mango_cache.to_account_info(), + root_bank: self.mango_msol_root_bank.to_account_info(), + node_bank: self.mango_msol_node_bank.to_account_info(), + vault: self.mango_msol_vault.to_account_info(), + token_account: self.msol_passthrough_ata.to_account_info(), + signer: self.mango_signer.to_account_info(), + }; + let cpi_program = self.mango_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_withdraw_from_mango_sol_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::Withdraw<'info>> { + let cpi_accounts = mango_markets_v3::Withdraw { + mango_group: self.mango_group.to_account_info(), + mango_account: self.mango_account.to_account_info(), + owner: self.depository.to_account_info(), + mango_cache: self.mango_cache.to_account_info(), + root_bank: self.mango_sol_root_bank.to_account_info(), + node_bank: self.mango_sol_node_bank.to_account_info(), + vault: self.mango_sol_vault.to_account_info(), + token_account: self.sol_passthrough_ata.to_account_info(), + signer: self.mango_signer.to_account_info(), + }; + let cpi_program = self.mango_program.to_account_info(); + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_unwrap_wsol_by_closing_ata_context( + &self, + ) -> CpiContext<'_, '_, '_, 'info, token::CloseAccount<'info>> { + let cpi_program = self.token_program.to_account_info(); + let cpi_accounts = token::CloseAccount { + account: self.sol_passthrough_ata.to_account_info(), + destination: self.user.to_account_info(), + authority: self.user.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_wrap_sol_to_ata_context(&self) -> CpiContext<'_, '_, '_, 'info, Transfer<'info>> { + let cpi_program = self.system_program.to_account_info(); + let cpi_accounts = Transfer { + from: self.user.to_account_info(), + to: self.sol_passthrough_ata.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) + } + + pub fn into_sync_native_wsol_ata(&self) -> CpiContext<'_, '_, '_, 'info, SyncNative<'info>> { + let cpi_program = self.system_program.to_account_info(); + let cpi_accounts = SyncNative { + account: self.sol_passthrough_ata.to_account_info(), + token_program: self.token_program.to_account_info(), + }; + CpiContext::new(cpi_program, cpi_accounts) + } +} + +impl<'info> RebalanceMangoDepositoryMsolRatio<'info> { + pub fn validate(&mut self) -> Result<()> { + let msol_config = self.msol_config.load()?; + require!(msol_config.enabled, UxdError::MSolSwappingDisabled); + Ok(()) + } +} + +enum RebalanceRoute { + Deposit, + LiquidUnstake, + // depends on the current difference to the target ratio, + // shd do delay unstake most of the time since liquid unstake takes extra fee + NoSwapRequired, +} + +impl RebalanceRoute { + pub fn from_diff_to_target_liquidity(diff_to_target_liquidity: I80F48) -> Self { + return if diff_to_target_liquidity.is_positive() { + msg!("when > target liquidity ratio"); + RebalanceRoute::Deposit + } else if diff_to_target_liquidity.is_negative() { + msg!("when < target liquidity ratio"); + RebalanceRoute::LiquidUnstake + } else { + msg!("when = target liquidity ratio"); + RebalanceRoute::NoSwapRequired + }; + } +} + +fn rebalance_by_deposit( + ctx: &Context, + diff_to_target_liquidity: I80F48, + msol_info: &MsolInfo, + marinade_state: &Account, + depository_signer_seed: &[&[&[u8]]], +) -> Result<()> { + // 6. lamports need to withdraw from mango + let deposit_lamports: u64 = diff_to_target_liquidity + .checked_mul(msol_info.total_depository_amount_lamports()?) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + // marinade deposit gives program error when lamports input is 0 + if deposit_lamports == 0 { + msg!("deposit lamports is zero, no swapping is required"); + return Ok(()); + } + + // 7. withdraw sol from depository account to passthrough ata + mango_markets_v3::withdraw( + ctx.accounts + .into_withdraw_from_mango_sol_context() + .with_signer(depository_signer_seed), + deposit_lamports, + false, + )?; + + // 8. unwrap wsol + token::close_account(ctx.accounts.into_unwrap_wsol_by_closing_ata_context())?; + + // 9. convert sol from wsol passthrough to msol and transfer to msol passthrough + marinade::deposit( + ctx.accounts.into_marinade_deposit_cpi_ctx(), + deposit_lamports + )?; + + // 10. msol amount converted + let msol_deposit_amount = marinade_state + .calc_msol_from_lamports(deposit_lamports) + .map_err(ProgramError::from)?; + + // 11. deposit msol back to mango from msol passthrough + mango_markets_v3::deposit( + ctx.accounts + .into_deposit_to_mango_msol_context() + .with_signer(depository_signer_seed), + msol_deposit_amount, + )?; + + Ok(()) +} + +fn rebalance_by_liquid_unstake( + ctx: &Context, + diff_to_target_liquidity: I80F48, + msol_info: &MsolInfo, + marinade_state: &Account, + depository_signer_seed: &[&[&[u8]]], +) -> Result<()> { + // 6. msol equivalent lamports need to withdraw from mango + let liquid_unstake_lamports: u64 = diff_to_target_liquidity + .abs() + .checked_mul(msol_info.total_depository_amount_lamports()?) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_to_num() + .ok_or_else(|| error!(UxdError::MathError))?; + + // 7. msol amount of (6) + let msol_liquid_unstake_amount = marinade_state + .calc_msol_from_lamports(liquid_unstake_lamports) + .map_err(ProgramError::from)?; + + if msol_liquid_unstake_amount == 0 { + msg!("msol liquid unstake amount is zero, no swapping is required"); + return Ok(()); + } + + // 8. withdraw msol from depository account to passthrough ata + mango_markets_v3::withdraw( + ctx.accounts + .into_withdraw_from_mango_msol_context() + .with_signer(depository_signer_seed), + msol_liquid_unstake_amount, + false, + )?; + + // 9. convert msol from msol passthrough to sol and transfer to the user + marinade::liquid_unstake( + ctx.accounts.into_liquid_unstake_cpi_ctx(), + msol_liquid_unstake_amount + )?; + + // 10. wrap sol + system_program::transfer( + ctx.accounts.into_wrap_sol_to_ata_context(), + liquid_unstake_lamports, + )?; + + // essential call to make after wrapping + // shd be replaced by anchor sync native wrapper once it's released + // https://github.com/project-serum/anchor/pull/1833 + anchor_comp::spl_token::sync_native( + ctx.accounts.into_sync_native_wsol_ata() + )?; + + // 7. deposit wsol back to mango from wsol passthrough + mango_markets_v3::deposit( + ctx.accounts + .into_deposit_to_mango_sol_context() + .with_signer(depository_signer_seed), + liquid_unstake_lamports, + )?; + + Ok(()) +} \ No newline at end of file diff --git a/programs/uxd/src/instructions/msol/set_msol_liquidity_ratio.rs b/programs/uxd/src/instructions/msol/set_msol_liquidity_ratio.rs new file mode 100644 index 000000000..94c5b5484 --- /dev/null +++ b/programs/uxd/src/instructions/msol/set_msol_liquidity_ratio.rs @@ -0,0 +1,63 @@ +use crate::error::UxdError; +use crate::state::msol_config::MSolConfig; +use crate::state::msol_config::TARGET_LIQUIDITY_RATIO_MAX; +use crate::Controller; +use crate::MangoDepository; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::MSOL_CONFIG_NAMESPACE; +use anchor_lang::prelude::*; + +#[derive(Accounts)] +pub struct SetMsolLiquidityRatio<'info> { + /// #1 Authored call accessible only to the signer matching Controller.authority + pub authority: Signer<'info>, + + /// #2 + #[account(mut)] + pub payer: Signer<'info>, + + /// #3 The top level UXDProgram on chain account managing the redeemable mint + #[account( + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #4 UXDProgram on chain account bound to a Controller instance + /// The `MangoDepository` manages a MangoAccount for a single Collateral + #[account( + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + )] + pub depository: AccountLoader<'info, MangoDepository>, + + /// #5 Msol config account for the `depository` instance + #[account( + mut, + seeds = [MSOL_CONFIG_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = msol_config.load()?.bump, + has_one = controller @UxdError::InvalidController, + has_one = depository @UxdError::InvalidDepository, + )] + pub msol_config: AccountLoader<'info, MSolConfig>, +} + +pub fn handler(ctx: Context, target_liquidity_ratio: u16) -> Result<()> { + let msol_config = &mut ctx.accounts.msol_config.load_mut()?; + msol_config.target_liquidity_ratio = target_liquidity_ratio; + Ok(()) +} + +impl<'info> SetMsolLiquidityRatio<'info> { + pub fn validate(&mut self, target_liquidity_ratio: u16) -> Result<()> { + require!( + target_liquidity_ratio <= TARGET_LIQUIDITY_RATIO_MAX, + UxdError::TargetLiquidityRatioExceedMax + ); + Ok(()) + } +} diff --git a/programs/uxd/src/instructions/register_mango_depository.rs b/programs/uxd/src/instructions/register_mango_depository.rs index bb1b2fc39..8c42d2eef 100644 --- a/programs/uxd/src/instructions/register_mango_depository.rs +++ b/programs/uxd/src/instructions/register_mango_depository.rs @@ -1,16 +1,14 @@ -use crate::error::SourceFileId; use crate::error::UxdError; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; use crate::events::RegisterMangoDepositoryEventV2; -use crate::mango_program; use crate::Controller; use crate::MangoDepository; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MANGO_ACCOUNT_NAMESPACE; use crate::MANGO_DEPOSITORY_ACCOUNT_VERSION; use crate::MANGO_DEPOSITORY_NAMESPACE; +use crate::MANGO_DEPOSITORY_SPACE; +use anchor_comp::mango_markets_v3; +use anchor_comp::mango_markets_v3::MangoMarketV3; use anchor_lang::prelude::*; use anchor_spl::token::Mint; use anchor_spl::token::Token; @@ -19,8 +17,6 @@ use std::mem::size_of; const MANGO_ACCOUNT_SPAN: usize = size_of::(); -declare_check_assert_macros!(SourceFileId::InstructionRegisterMangoDepository); - /// Takes 12 accounts - 8 used locally - 1 for CPI - 3 Programs - 1 Sysvar #[derive(Accounts)] pub struct RegisterMangoDepository<'info> { @@ -35,10 +31,10 @@ pub struct RegisterMangoDepository<'info> { #[account( mut, seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump, - has_one = authority @UxdIdlErrorCode::InvalidAuthority, + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, /// #4 UXDProgram on chain account bound to a Controller instance /// The `MangoDepository` manages a MangoAccount for a single Collateral @@ -47,8 +43,9 @@ pub struct RegisterMangoDepository<'info> { seeds = [MANGO_DEPOSITORY_NAMESPACE, collateral_mint.key().as_ref()], bump, payer = payer, + space = MANGO_DEPOSITORY_SPACE, )] - pub depository: Box>, + pub depository: AccountLoader<'info, MangoDepository>, /// #5 The collateral mint used by the `depository` instance pub collateral_mint: Box>, @@ -57,18 +54,20 @@ pub struct RegisterMangoDepository<'info> { pub quote_mint: Box>, /// #7 The MangoMarkets Account (MangoAccount) managed by the `depository` + /// CHECK : Seeds checked. Depository registered #[account( init, seeds = [MANGO_ACCOUNT_NAMESPACE, collateral_mint.key().as_ref()], bump, - owner = mango_program::Mango::id(), + owner = MangoMarketV3::id(), payer = payer, space = MANGO_ACCOUNT_SPAN, )] - pub depository_mango_account: AccountInfo<'info>, + pub mango_account: AccountInfo<'info>, /// #8 [MangoMarkets CPI] Index grouping perp and spot markets - pub mango_group: AccountInfo<'info>, + /// CHECK: Mango CPI - checked MangoMarketV3 side + pub mango_group: UncheckedAccount<'info>, /// #9 System Program pub system_program: Program<'info, System>, @@ -77,83 +76,84 @@ pub struct RegisterMangoDepository<'info> { pub token_program: Program<'info, Token>, /// #11 MangoMarketv3 Program - pub mango_program: Program<'info, mango_program::Mango>, + pub mango_program: Program<'info, MangoMarketV3>, /// #12 Rent Sysvar pub rent: Sysvar<'info, Rent>, } -pub fn handler(ctx: Context) -> UxdResult { +pub fn handler(ctx: Context) -> Result<()> { let collateral_mint = ctx.accounts.collateral_mint.key(); let quote_mint = ctx.accounts.quote_mint.key(); + let depository_bump = *ctx + .bumps + .get("depository") + .ok_or_else(|| error!(UxdError::BumpError))?; + // - Initialize Mango Account let depository_signer_seed: &[&[&[u8]]] = &[&[ MANGO_DEPOSITORY_NAMESPACE, collateral_mint.as_ref(), - &[*ctx.bumps.get("depository").ok_or(bump_err!())?], + &[depository_bump], ]]; - mango_program::initialize_mango_account( + mango_markets_v3::init_mango_account( ctx.accounts - .into_mango_account_initialization_context() + .into_mango_init_account_context() .with_signer(depository_signer_seed), )?; // - Initialize Depository state - ctx.accounts.depository.bump = *ctx.bumps.get("depository").ok_or(bump_err!())?; - ctx.accounts.depository.mango_account_bump = *ctx + let depository = &mut ctx.accounts.depository.load_init()?; + let mango_account_bump = *ctx .bumps - .get("depository_mango_account") - .ok_or(bump_err!())?; - ctx.accounts.depository.version = MANGO_DEPOSITORY_ACCOUNT_VERSION; - ctx.accounts.depository.collateral_mint = collateral_mint; - ctx.accounts.depository.collateral_mint_decimals = ctx.accounts.collateral_mint.decimals; - ctx.accounts.depository.quote_mint = quote_mint; - ctx.accounts.depository.quote_mint_decimals = ctx.accounts.quote_mint.decimals; - ctx.accounts.depository.mango_account = ctx.accounts.depository_mango_account.key(); - ctx.accounts.depository.controller = ctx.accounts.controller.key(); - ctx.accounts.depository.insurance_amount_deposited = u128::MIN; - ctx.accounts.depository.collateral_amount_deposited = u128::MIN; - ctx.accounts.depository.redeemable_amount_under_management = u128::MIN; - ctx.accounts.depository.total_amount_rebalanced = u128::MIN; + .get("mango_account") + .ok_or_else(|| error!(UxdError::BumpError))?; + depository.bump = depository_bump; + depository.mango_account_bump = mango_account_bump; + depository.version = MANGO_DEPOSITORY_ACCOUNT_VERSION; + depository.collateral_mint = collateral_mint; + depository.collateral_mint_decimals = ctx.accounts.collateral_mint.decimals; + depository.quote_mint = quote_mint; + depository.quote_mint_decimals = ctx.accounts.quote_mint.decimals; + depository.mango_account = ctx.accounts.mango_account.key(); + depository.controller = ctx.accounts.controller.key(); + depository.insurance_amount_deposited = u128::MIN; + depository.collateral_amount_deposited = u128::MIN; + depository.redeemable_amount_under_management = u128::MIN; + depository.total_amount_paid_taker_fee = u128::MIN; + depository.total_amount_rebalanced = u128::MIN; + depository.minting_disabled = false; // enable minting by default // - Update Controller state ctx.accounts - .add_new_registered_mango_depository_entry_to_controller()?; + .controller + .load_mut()? + .add_registered_mango_depository_entry(ctx.accounts.depository.key())?; emit!(RegisterMangoDepositoryEventV2 { - version: ctx.accounts.controller.version, - depository_version: ctx.accounts.depository.version, + version: ctx.accounts.controller.load()?.version, + depository_version: depository.version, controller: ctx.accounts.controller.key(), depository: ctx.accounts.depository.key(), collateral_mint: ctx.accounts.collateral_mint.key(), quote_mint: ctx.accounts.quote_mint.key(), - mango_account: ctx.accounts.depository_mango_account.key(), + mango_account: ctx.accounts.mango_account.key(), }); Ok(()) } impl<'info> RegisterMangoDepository<'info> { - pub fn into_mango_account_initialization_context( + pub fn into_mango_init_account_context( &self, - ) -> CpiContext<'_, '_, '_, 'info, mango_program::InitMangoAccount<'info>> { - let cpi_accounts = mango_program::InitMangoAccount { + ) -> CpiContext<'_, '_, '_, 'info, mango_markets_v3::InitMangoAccount<'info>> { + let cpi_accounts = mango_markets_v3::InitMangoAccount { mango_group: self.mango_group.to_account_info(), - mango_account: self.depository_mango_account.to_account_info(), + mango_account: self.mango_account.to_account_info(), owner: self.depository.to_account_info(), - rent: self.rent.to_account_info(), }; let cpi_program = self.mango_program.to_account_info(); CpiContext::new(cpi_program, cpi_accounts) } } - -impl<'info> RegisterMangoDepository<'info> { - pub fn add_new_registered_mango_depository_entry_to_controller(&mut self) -> ProgramResult { - let mango_depository_id = self.depository.key(); - self.controller - .add_registered_mango_depository_entry(mango_depository_id)?; - Ok(()) - } -} diff --git a/programs/uxd/src/instructions/set_mango_depositories_redeemable_soft_cap.rs b/programs/uxd/src/instructions/set_mango_depositories_redeemable_soft_cap.rs index c2321edbf..68b02de40 100644 --- a/programs/uxd/src/instructions/set_mango_depositories_redeemable_soft_cap.rs +++ b/programs/uxd/src/instructions/set_mango_depositories_redeemable_soft_cap.rs @@ -1,16 +1,10 @@ -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; +use crate::error::UxdError; use crate::events::SetMangoDepositoryRedeemableSoftCapEvent; use crate::Controller; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MAX_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP; use anchor_lang::prelude::*; -declare_check_assert_macros!(SourceFileId::InstructionSetMangoDepositoriesRedeemableSoftCap); - /// Takes 2 accounts - 2 used locally - 0 for CPI - 0 Programs - 0 Sysvar #[derive(Accounts)] pub struct SetMangoDepositoriesRedeemableSoftCap<'info> { @@ -21,24 +15,23 @@ pub struct SetMangoDepositoriesRedeemableSoftCap<'info> { #[account( mut, seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump, - has_one = authority @UxdIdlErrorCode::InvalidAuthority, + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, } pub fn handler( ctx: Context, redeemable_soft_cap: u64, -) -> UxdResult { - ctx.accounts - .controller - .mango_depositories_redeemable_soft_cap = redeemable_soft_cap; +) -> Result<()> { + let controller = &mut ctx.accounts.controller.load_mut()?; + controller.mango_depositories_redeemable_soft_cap = redeemable_soft_cap; emit!(SetMangoDepositoryRedeemableSoftCapEvent { - version: ctx.accounts.controller.version, + version: controller.version, controller: ctx.accounts.controller.key(), - redeemable_mint_decimals: ctx.accounts.controller.redeemable_mint_decimals, - redeemable_mint: ctx.accounts.controller.redeemable_mint, + redeemable_mint_decimals: controller.redeemable_mint_decimals, + redeemable_mint: controller.redeemable_mint, redeemable_soft_cap }); Ok(()) @@ -48,11 +41,11 @@ pub fn handler( #[allow(clippy::absurd_extreme_comparisons)] impl<'info> SetMangoDepositoriesRedeemableSoftCap<'info> { // Asserts that the Mango Depositories redeemable soft cap is between 0 and MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP. - pub fn validate(&self, redeemable_soft_cap: u64) -> ProgramResult { - check!( + pub fn validate(&self, redeemable_soft_cap: u64) -> Result<()> { + require!( redeemable_soft_cap <= MAX_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP, - UxdErrorCode::InvalidMangoDepositoriesRedeemableSoftCap - )?; + UxdError::InvalidMangoDepositoriesRedeemableSoftCap + ); Ok(()) } } diff --git a/programs/uxd/src/instructions/set_mango_depository_quote_mint_and_redeem_fee.rs b/programs/uxd/src/instructions/set_mango_depository_quote_mint_and_redeem_fee.rs new file mode 100644 index 000000000..82a9dc8f1 --- /dev/null +++ b/programs/uxd/src/instructions/set_mango_depository_quote_mint_and_redeem_fee.rs @@ -0,0 +1,45 @@ +use crate::error::UxdError; +use crate::state::MangoDepository; +use crate::Controller; +use crate::CONTROLLER_NAMESPACE; +use crate::MANGO_DEPOSITORY_NAMESPACE; +use anchor_lang::prelude::*; + +/// Takes 3 accounts +#[derive(Accounts)] +pub struct SetMangoDepositoryQuoteMintAndRedeemFee<'info> { + /// #1 Authored call accessible only to the signer matching Controller.authority + pub authority: Signer<'info>, + + /// #2 The top level UXDProgram on chain account managing the redeemable mint + #[account( + mut, + seeds = [CONTROLLER_NAMESPACE], + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, + constraint = controller.load()?.registered_mango_depositories.contains(&depository.key()) @UxdError::InvalidDepository + )] + pub controller: AccountLoader<'info, Controller>, + + /// #3 UXDProgram on chain account bound to a Controller instance. + /// The `MangoDepository` manages a MangoAccount for a single Collateral. + #[account( + mut, + seeds = [MANGO_DEPOSITORY_NAMESPACE, depository.load()?.collateral_mint.as_ref()], + bump = depository.load()?.bump, + has_one = controller @UxdError::InvalidController, + )] + pub depository: AccountLoader<'info, MangoDepository>, +} + +pub fn handler( + ctx: Context, + quote_fee: u8, // in bps +) -> Result<()> { + ctx.accounts + .depository + .load_mut()? + .quote_mint_and_redeem_fee = quote_fee; + + Ok(()) +} diff --git a/programs/uxd/src/instructions/set_redeemable_global_supply_cap.rs b/programs/uxd/src/instructions/set_redeemable_global_supply_cap.rs index 8bbb25314..411a53749 100644 --- a/programs/uxd/src/instructions/set_redeemable_global_supply_cap.rs +++ b/programs/uxd/src/instructions/set_redeemable_global_supply_cap.rs @@ -1,16 +1,10 @@ -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; -use crate::error::UxdIdlErrorCode; +use crate::error::UxdError; use crate::events::SetRedeemableGlobalSupplyCapEvent; use crate::Controller; -use crate::UxdResult; use crate::CONTROLLER_NAMESPACE; use crate::MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP; use anchor_lang::prelude::*; -declare_check_assert_macros!(SourceFileId::InstructionSetRedeemableGlobalSupplyCap); - /// Takes 2 accounts - 2 used locally - 0 for CPI - 0 Programs - 0 Sysvar #[derive(Accounts)] pub struct SetRedeemableGlobalSupplyCap<'info> { @@ -21,19 +15,20 @@ pub struct SetRedeemableGlobalSupplyCap<'info> { #[account( mut, seeds = [CONTROLLER_NAMESPACE], - bump = controller.bump, - has_one = authority @UxdIdlErrorCode::InvalidAuthority, + bump = controller.load()?.bump, + has_one = authority @UxdError::InvalidAuthority, )] - pub controller: Box>, + pub controller: AccountLoader<'info, Controller>, } pub fn handler( ctx: Context, redeemable_global_supply_cap: u128, -) -> UxdResult { - ctx.accounts.controller.redeemable_global_supply_cap = redeemable_global_supply_cap; +) -> Result<()> { + let controller = &mut ctx.accounts.controller.load_mut()?; + controller.redeemable_global_supply_cap = redeemable_global_supply_cap; emit!(SetRedeemableGlobalSupplyCapEvent { - version: ctx.accounts.controller.version, + version: controller.version, controller: ctx.accounts.controller.key(), redeemable_global_supply_cap }); @@ -44,11 +39,11 @@ pub fn handler( #[allow(clippy::absurd_extreme_comparisons)] impl<'info> SetRedeemableGlobalSupplyCap<'info> { // Asserts that the redeemable global supply cap is between 0 and MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP. - pub fn validate(&self, redeemable_global_supply_cap: u128) -> ProgramResult { - check!( + pub fn validate(&self, redeemable_global_supply_cap: u128) -> Result<()> { + require!( redeemable_global_supply_cap <= MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP, - UxdErrorCode::InvalidRedeemableGlobalSupplyCap - )?; + UxdError::InvalidRedeemableGlobalSupplyCap + ); Ok(()) } } diff --git a/programs/uxd/src/lib.rs b/programs/uxd/src/lib.rs index 1740b0c0a..76288b01c 100644 --- a/programs/uxd/src/lib.rs +++ b/programs/uxd/src/lib.rs @@ -1,6 +1,3 @@ -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::error::UxdErrorCode; use crate::instructions::*; use crate::state::*; use anchor_lang::prelude::*; @@ -9,10 +6,8 @@ use mango::state::MangoGroup; #[macro_use] pub mod error; - pub mod events; pub mod instructions; -pub mod mango_program; pub mod mango_utils; pub mod state; pub mod test; @@ -20,7 +15,9 @@ pub mod test; // CI Uses F3UToS4WKQkyAAs5TwM_21ANq2xNfDRB7tGRWx4DxapaR on Devnet // (it's auto swapped by the script, keypair are held in target/deployment) #[cfg(feature = "development")] -solana_program::declare_id!("BA67esrWE7cPzQWtAftaTbrVWtmHZJ1PbbBBpZgpjH4p"); +solana_program::declare_id!("H4fDUuiTmRNrUVCaswDNFXAe1vR2UEgpdV8iQkzEn2C3"); +#[cfg(feature = "internal")] +solana_program::declare_id!("EmXCGBmeZ7vTZu1NcuR5Cod8438aQdghhVa69zcBVF23"); #[cfg(feature = "production")] solana_program::declare_id!("UXD8m9cvwk4RcSxnX2HZ9VudQCEeDH6fRnB4CAP57Dr"); @@ -33,6 +30,7 @@ pub const REDEEMABLE_MINT_NAMESPACE: &[u8] = b"REDEEMABLE"; pub const MANGO_ACCOUNT_NAMESPACE: &[u8] = b"MANGOACCOUNT"; pub const CONTROLLER_NAMESPACE: &[u8] = b"CONTROLLER"; pub const MANGO_DEPOSITORY_NAMESPACE: &[u8] = b"MANGODEPOSITORY"; +pub const MSOL_CONFIG_NAMESPACE: &[u8] = b"MSOLCONFIG"; pub const MAX_REDEEMABLE_GLOBAL_SUPPLY_CAP: u128 = u128::MAX; pub const DEFAULT_REDEEMABLE_GLOBAL_SUPPLY_CAP: u128 = 1_000_000; // 1 Million redeemable UI units @@ -40,12 +38,13 @@ pub const DEFAULT_REDEEMABLE_GLOBAL_SUPPLY_CAP: u128 = 1_000_000; // 1 Million r pub const MAX_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP: u64 = u64::MAX; pub const DEFAULT_MANGO_DEPOSITORIES_REDEEMABLE_SOFT_CAP: u64 = 10_000; // 10 Thousand redeemable UI units -const SLIPPAGE_BASIS: u32 = 1000; -const SOLANA_MAX_MINT_DECIMALS: u8 = 9; +const BPS_POW: u8 = 4; // Raise a number to BPS_POW to get order of magnitude of +pub const BPS_UNIT_CONVERSION: u64 = (10u64).pow(BPS_POW as u32); -pub type UxdResult = Result; +const SOLANA_MAX_MINT_DECIMALS: u8 = 9; -declare_check_assert_macros!(SourceFileId::Lib); +/// When looping through the orderbook to fill, it's FoK, so will fail either way. +const MANGO_PERP_MAX_FILL_EVENTS: u8 = u8::MAX; #[program] #[deny(unused_must_use)] @@ -72,12 +71,9 @@ pub mod uxd { pub fn initialize_controller( ctx: Context, redeemable_mint_decimals: u8, - ) -> ProgramResult { + ) -> Result<()> { msg!("[initialize_controller]"); - instructions::initialize_controller::handler(ctx, redeemable_mint_decimals).map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) + instructions::initialize_controller::handler(ctx, redeemable_mint_decimals) } /// Sets the `redeemable_global_supply_cap` of the provided `Controller` @@ -102,13 +98,9 @@ pub mod uxd { pub fn set_redeemable_global_supply_cap( ctx: Context, redeemable_global_supply_cap: u128, - ) -> ProgramResult { + ) -> Result<()> { msg!("[set_redeemable_global_supply_cap]"); instructions::set_redeemable_global_supply_cap::handler(ctx, redeemable_global_supply_cap) - .map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) } /// Sets the `mango_depositories_redeemable_soft_cap` of the provided @@ -137,13 +129,9 @@ pub mod uxd { pub fn set_mango_depositories_redeemable_soft_cap( ctx: Context, redeemable_soft_cap: u64, - ) -> ProgramResult { + ) -> Result<()> { msg!("[set_mango_depositories_redeemable_soft_cap]"); instructions::set_mango_depositories_redeemable_soft_cap::handler(ctx, redeemable_soft_cap) - .map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) } /// Create a new`MangoDepository` and registers it to the provided @@ -162,12 +150,9 @@ pub mod uxd { /// In the new version of the MangoMarket Accounts /// this become mandatory too. (we are still using the old init) /// - pub fn register_mango_depository(ctx: Context) -> ProgramResult { + pub fn register_mango_depository(ctx: Context) -> Result<()> { msg!("[register_mango_depository]"); - instructions::register_mango_depository::handler(ctx).map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) + instructions::register_mango_depository::handler(ctx) } /// Deposit `MangoDepository.quote_mint` tokens in the `MangoDepository` @@ -208,12 +193,9 @@ pub mod uxd { pub fn deposit_insurance_to_mango_depository( ctx: Context, amount: u64, - ) -> ProgramResult { + ) -> Result<()> { msg!("[deposit_insurance_to_mango_depository]"); - instructions::deposit_insurance_to_mango_depository::handler(ctx, amount).map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) + instructions::deposit_insurance_to_mango_depository::handler(ctx, amount) } /// Withdraw `MangoDepository.quote_mint` tokens from the `MangoDepository` @@ -237,12 +219,9 @@ pub mod uxd { pub fn withdraw_insurance_from_mango_depository( ctx: Context, amount: u64, - ) -> ProgramResult { + ) -> Result<()> { msg!("[withdraw_insurance_from_mango_depository]"); - instructions::withdraw_insurance_from_mango_depository::handler(ctx, amount).map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) + instructions::withdraw_insurance_from_mango_depository::handler(ctx, amount) } /// Rebalance the delta neutral position of the underlying `MangoDepository`. @@ -252,8 +231,7 @@ pub mod uxd { /// instruction will attempt to rebalance, in native unit. /// - polarity: the direction of the rebalancing. This is known on chain /// but required as an argument for clarity. - /// - slippage: the maximum deviation in price the user is ok to take - /// compared to market price at execution time. + /// - limit_price: the worst price the user is willing to trade at. /// /// Note: /// Acts as a swap, reducing the oustanding PnL (paper profit or losses) on @@ -279,29 +257,29 @@ pub mod uxd { /// has to pay borrow rates for it. Some day when computing is plentiful and input /// accounts are increased through TransactionsV2 proposal, we can /// also call the onchain version. - #[access_control(ctx.accounts.validate(max_rebalancing_amount, &polarity, slippage))] + /// + /// Note: + /// TEMPORARY Although this create the associated token account for WSOL + /// when the PnL is Negative, it's too short on computing. Please create beforehand. + #[access_control(ctx.accounts.validate(max_rebalancing_amount, &polarity, limit_price))] pub fn rebalance_mango_depository_lite( ctx: Context, max_rebalancing_amount: u64, polarity: PnlPolarity, - slippage: u32, - ) -> ProgramResult { - // Computing too short - // msg!( - // "[rebalance_mango_depository_lite] slippage {}, polarity {}", - // slippage, - // polarity - // ); + limit_price: f32, + ) -> Result<()> { + msg!( + "[rebalance_mango_depository_lite] max_rebalancing_amount {}, limit_price {}, polarity {}", + max_rebalancing_amount, + limit_price, + polarity + ); instructions::rebalance_mango_depository_lite::handler( ctx, max_rebalancing_amount, &polarity, - slippage, + limit_price, ) - .map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) } /// Mint redeemable tokens in exchange of `MangoDepository.collateral_mint` @@ -310,8 +288,7 @@ pub mod uxd { /// Parameters: /// - collateral_amount: the amount of collateral to use, in /// collateral_mint native unit. - /// - slippage: the maximum deviation in price the user is ok to take - /// compared to market price at execution time. + /// - limit_price: the worse price the user is willing to trade at. /// /// Flow: /// - Starts by scanning the order book for the amount that we can fill. @@ -331,34 +308,28 @@ pub mod uxd { /// expressed in USD value. /// #[access_control( - ctx.accounts.validate(collateral_amount, slippage) + ctx.accounts.validate(collateral_amount, limit_price) )] pub fn mint_with_mango_depository( ctx: Context, collateral_amount: u64, - slippage: u32, - ) -> ProgramResult { - msg!( - "[mint_with_mango_depository] collateral_amount {}, slippage {}", - collateral_amount, - slippage - ); - instructions::mint_with_mango_depository::handler(ctx, collateral_amount, slippage).map_err( - |e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }, - ) + limit_price: f32, + ) -> Result<()> { + // msg!( + // "[mint_with_mango_depository] collateral_amount {}, limit_price {}", + // collateral_amount, + // limit_price + // ); + instructions::mint_with_mango_depository::handler(ctx, collateral_amount, limit_price) } - /// Redeem `MangoDepository.collateral_mint` by burning redeemable tokens + /// Redeem `MangoDepository.collateral_mint` by burning redeemable /// tokens, and unwind a part of the delta neutral position. /// /// Parameters: /// - redeemable_amount: the amount of collateral to use, in /// redeemable_mint native unit. - /// - slippage: the maximum deviation in price the user is ok to take - /// compared to market price at execution time. + /// - limit_price: the worse price the user is willing to trade at. /// /// Flow: /// - Starts by scanning the order book to find the best order for @@ -381,23 +352,121 @@ pub mod uxd { /// expressed in USD value. /// #[access_control( - ctx.accounts.validate(redeemable_amount, slippage) + ctx.accounts.validate(redeemable_amount, limit_price) )] pub fn redeem_from_mango_depository( ctx: Context, redeemable_amount: u64, - slippage: u32, - ) -> ProgramResult { + limit_price: f32, + ) -> Result<()> { msg!( - "[redeem_from_mango_depository] redeemable_amount {}, slippage {}", + "[redeem_from_mango_depository] redeemable_amount {}, limit_price {}", redeemable_amount, - slippage + limit_price + ); + instructions::redeem_from_mango_depository::handler(ctx, redeemable_amount, limit_price) + } + + #[access_control( + ctx.accounts.validate(quote_amount) + )] + pub fn quote_mint_with_mango_depository( + ctx: Context, + quote_amount: u64, + ) -> Result<()> { + msg!( + "[quote_mint_with_mango_depository] quote_amount {}", + quote_amount + ); + instructions::quote_mint_with_mango_depository::handler(ctx, quote_amount) + } + + #[access_control( + ctx.accounts.validate(redeemable_amount) + )] + pub fn quote_redeem_from_mango_depository( + ctx: Context, + redeemable_amount: u64, + ) -> Result<()> { + msg!( + "[quote_redeem_from_mango_depository] redeemable_amount {}", + redeemable_amount + ); + instructions::quote_redeem_from_mango_depository::handler(ctx, redeemable_amount) + } + + pub fn set_mango_depository_quote_mint_and_redeem_fee( + ctx: Context, + quote_fee: u8, + ) -> Result<()> { + msg!( + "[set_mango_depository_quote_mint_and_redeem_fee] quote_fee {}", + quote_fee ); - instructions::redeem_from_mango_depository::handler(ctx, redeemable_amount, slippage) - .map_err(|e| { - msg!("<*> {}", e); // log the error - e.into() // convert UxdError to generic ProgramError - }) + instructions::set_mango_depository_quote_mint_and_redeem_fee::handler(ctx, quote_fee) + } + + /// Disable or enable minting for given Mango Depository. + /// + /// Parameters: + /// - disable: true to disable, false to enable. + /// + /// Note: + /// The disabled flag is false by default that a freshly registered mango depository has enabled minting. + /// This ix is for toggling that flag. + /// + #[access_control( + ctx.accounts.validate(disable_minting) + )] + pub fn disable_depository_minting( + ctx: Context, + disable_minting: bool, + ) -> Result<()> { + msg!( + "[disable_depository_minting] disable_minting {}", + disable_minting + ); + instructions::disable_depository_minting::handler(ctx, disable_minting) + } + + #[access_control( + ctx.accounts.validate(target_liquidity_ratio) + )] + pub fn create_depository_msol_config( + ctx: Context, + target_liquidity_ratio: u16, + ) -> Result<()> { + msg!("[create_depository_msol_config]"); + instructions::create_depository_msol_config::handler(ctx, target_liquidity_ratio) + } + + #[access_control( + ctx.accounts.validate(enable) + )] + pub fn enable_msol_swap(ctx: Context, enable: bool) -> Result<()> { + msg!("[enable_msol_swap]"); + instructions::enable_msol_swap::handler(ctx, enable) + } + + #[access_control( + ctx.accounts.validate(target_liquidity_ratio) + )] + pub fn set_msol_liquidity_ratio( + ctx: Context, + target_liquidity_ratio: u16, + ) -> Result<()> { + msg!("[set_msol_liquidity_ratio]"); + instructions::set_msol_liquidity_ratio::handler(ctx, target_liquidity_ratio) + } + + #[access_control( + ctx.accounts.validate() + )] + pub fn rebalance_mango_depository_msol_ratio( + ctx: Context, + ) -> Result<()> { + msg!("[rebalance_mango_depository_msol_ratio]"); + instructions::rebalance_mango_depository_msol_ratio::handler(ctx) } } @@ -408,14 +477,16 @@ pub fn validate_perp_market_mint_matches_depository_collateral_mint( mango_program_key: &Pubkey, mango_perp_market_key: &Pubkey, collateral_mint_key: &Pubkey, -) -> UxdResult { - let mango_group = MangoGroup::load_checked(mango_group_ai, mango_program_key)?; +) -> Result<()> { + let mango_group = MangoGroup::load_checked(mango_group_ai, mango_program_key) + .map_err(|_| error!(UxdError::InvalidMangoGroup))?; let perp_market_index = mango_group .find_perp_market_index(mango_perp_market_key) - .ok_or(throw_err!(UxdErrorCode::MangoPerpMarketIndexNotFound))?; - check!( + .ok_or_else(|| error!(UxdError::MangoPerpMarketIndexNotFound))?; + + require!( mango_group.tokens[perp_market_index].mint == *collateral_mint_key, - UxdErrorCode::MangoPerpMarketIndexNotFound - )?; + UxdError::MangoPerpMarketIndexNotFound + ); Ok(()) } diff --git a/programs/uxd/src/mango_program/anchor_mango.rs b/programs/uxd/src/mango_program/anchor_mango.rs deleted file mode 100644 index c7c574dad..000000000 --- a/programs/uxd/src/mango_program/anchor_mango.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::declare_check_assert_macros; -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::UxdErrorCode; -use anchor_lang::prelude::ProgramResult; -use solana_program::program_error::ProgramError; -use solana_program::pubkey::Pubkey; - -declare_check_assert_macros!(SourceFileId::MangoProgramAnchorMango); - -/// This is a wrapper around mango program that does not use Anchor, -/// similar to what Anchor does around the sol_token program. -#[derive(Clone)] -pub struct Mango; - -pub mod mango_program_id { - #[cfg(feature = "development")] - solana_program::declare_id!("4skJ85cdxQAFVKbcGgfun8iZPL7BadVYXG3kGEGkufqA"); - #[cfg(feature = "production")] - solana_program::declare_id!("mv3ekLzLbnVPNxjSKvqBpU3ZeZXPQdEC3bp5MDEBG68"); -} - -impl anchor_lang::AccountDeserialize for Mango { - fn try_deserialize(buf: &mut &[u8]) -> Result { - Mango::try_deserialize_unchecked(buf) - } - - fn try_deserialize_unchecked(_buf: &mut &[u8]) -> Result { - Ok(Mango) - } -} - -impl anchor_lang::Id for Mango { - fn id() -> Pubkey { - mango_program_id::ID - } -} - -/// Checks that the supplied program ID is the correct one -pub fn check_program_account(mango_program_id: &Pubkey) -> ProgramResult { - check_eq!( - mango_program_id, - &mango_program_id::ID, - UxdErrorCode::Default - )?; - Ok(()) -} diff --git a/programs/uxd/src/mango_program/deposit.rs b/programs/uxd/src/mango_program/deposit.rs deleted file mode 100644 index 4b175db11..000000000 --- a/programs/uxd/src/mango_program/deposit.rs +++ /dev/null @@ -1,105 +0,0 @@ -use anchor_lang::prelude::AccountInfo; -use anchor_lang::prelude::AccountMeta; -use anchor_lang::prelude::Accounts; -use anchor_lang::prelude::CpiContext; -use anchor_lang::prelude::ProgramResult; -use solana_program::instruction::Instruction; -use solana_program::program_error::ProgramError; -use solana_program::pubkey::Pubkey; - -use super::anchor_mango::check_program_account; - -#[derive(Accounts)] -pub struct Deposit<'info> { - pub mango_group: AccountInfo<'info>, - pub mango_account: AccountInfo<'info>, - pub owner: AccountInfo<'info>, - pub mango_cache: AccountInfo<'info>, - pub mango_root_bank: AccountInfo<'info>, - pub mango_node_bank: AccountInfo<'info>, - pub mango_vault: AccountInfo<'info>, - pub token_program: AccountInfo<'info>, - pub owner_token_account: AccountInfo<'info>, -} - -/// Deposit funds into mango account -/// -/// Accounts expected by this instruction (9): -/// -/// 0. `[]` mango_group_ai - MangoGroup that this mango account is for -/// 1. `[writable]` mango_account_ai - the mango account for this user -/// 2. `[signer]` owner_ai - Solana account of owner of the mango account -/// 3. `[]` mango_cache_ai - MangoCache -/// 4. `[]` root_bank_ai - RootBank owned by MangoGroup -/// 5. `[writable]` node_bank_ai - NodeBank owned by RootBank -/// 6. `[writable]` vault_ai - TokenAccount owned by MangoGroup -/// 7. `[]` token_prog_ai - acc pointed to by SPL token program id -/// 8. `[writable]` owner_token_account_ai - TokenAccount owned by user which will be sending the funds -#[allow(clippy::too_many_arguments)] -fn deposit_instruction( - mango_program_id: &Pubkey, - mango_group_pubkey: &Pubkey, - mango_account_pubkey: &Pubkey, - owner_pubkey: &Pubkey, - mango_cache_pubkey: &Pubkey, - mango_root_bank_pubkey: &Pubkey, - mango_node_bank_pubkey: &Pubkey, - mango_vault_pubkey: &Pubkey, - token_program_id: &Pubkey, - owner_token_account_pubkey: &Pubkey, - quantity: u64, -) -> Result { - check_program_account(mango_program_id)?; - let data = mango::instruction::MangoInstruction::Deposit { quantity }.pack(); - let accounts = vec![ - AccountMeta::new_readonly(*mango_group_pubkey, false), - AccountMeta::new(*mango_account_pubkey, false), - AccountMeta::new_readonly(*owner_pubkey, true), - AccountMeta::new_readonly(*mango_cache_pubkey, false), - AccountMeta::new_readonly(*mango_root_bank_pubkey, false), - AccountMeta::new(*mango_node_bank_pubkey, false), - AccountMeta::new(*mango_vault_pubkey, false), - AccountMeta::new_readonly(*token_program_id, false), - AccountMeta::new(*owner_token_account_pubkey, false), - ]; - Ok(Instruction { - program_id: *mango_program_id, - accounts, - data, - }) -} - -pub fn deposit<'info>( - ctx: CpiContext<'_, '_, '_, 'info, Deposit<'info>>, - quantity: u64, -) -> ProgramResult { - let ix = deposit_instruction( - ctx.program.key, - ctx.accounts.mango_group.key, - ctx.accounts.mango_account.key, - ctx.accounts.owner.key, - ctx.accounts.mango_cache.key, - ctx.accounts.mango_root_bank.key, - ctx.accounts.mango_node_bank.key, - ctx.accounts.mango_vault.key, - ctx.accounts.token_program.key, - ctx.accounts.owner_token_account.key, - quantity, - )?; - solana_program::program::invoke_signed( - &ix, - &[ - ctx.program.clone(), - ctx.accounts.mango_group.clone(), - ctx.accounts.mango_account.clone(), - ctx.accounts.owner.clone(), - ctx.accounts.mango_cache.clone(), - ctx.accounts.mango_root_bank.clone(), - ctx.accounts.mango_node_bank.clone(), - ctx.accounts.mango_vault.clone(), - ctx.accounts.token_program.clone(), - ctx.accounts.owner_token_account.clone(), - ], - ctx.signer_seeds, - ) -} diff --git a/programs/uxd/src/mango_program/init_mango_account.rs b/programs/uxd/src/mango_program/init_mango_account.rs deleted file mode 100644 index a14adf822..000000000 --- a/programs/uxd/src/mango_program/init_mango_account.rs +++ /dev/null @@ -1,72 +0,0 @@ -use super::anchor_mango::check_program_account; -use anchor_lang::prelude::AccountInfo; -use anchor_lang::prelude::AccountMeta; -use anchor_lang::prelude::Accounts; -use anchor_lang::prelude::CpiContext; -use anchor_lang::prelude::ProgramResult; -use solana_program::instruction::Instruction; -use solana_program::program_error::ProgramError; -use solana_program::pubkey::Pubkey; - -#[derive(Accounts)] -pub struct InitMangoAccount<'info> { - pub mango_group: AccountInfo<'info>, - pub mango_account: AccountInfo<'info>, - pub owner: AccountInfo<'info>, - pub rent: AccountInfo<'info>, -} - -/// Note: in our case a user is a `MangoDepository`. -/// -/// Initialize a mango account for a user -/// -/// Accounts expected by this instruction (4): -/// -/// 0. `[]` mango_group_ai - MangoGroup that this mango account is for -/// 1. `[writable]` mango_account_ai - the mango account data -/// 2. `[signer]` owner_ai - Solana account of owner of the mango account -/// 3. `[]` rent_ai - Rent sysvar account -fn initialize_mango_account_instruction( - mango_program_id: &Pubkey, - mango_group_pubkey: &Pubkey, - mango_account_pubkey: &Pubkey, - owner_pubkey: &Pubkey, - rent_sysvar: &Pubkey, -) -> Result { - check_program_account(mango_program_id)?; - let data = mango::instruction::MangoInstruction::InitMangoAccount.pack(); - let accounts = vec![ - AccountMeta::new_readonly(*mango_group_pubkey, false), - AccountMeta::new(*mango_account_pubkey, false), - AccountMeta::new_readonly(*owner_pubkey, true), - AccountMeta::new_readonly(*rent_sysvar, false), - ]; - Ok(Instruction { - program_id: *mango_program_id, - accounts, - data, - }) -} - -pub fn initialize_mango_account<'info>( - ctx: CpiContext<'_, '_, '_, 'info, InitMangoAccount<'info>>, -) -> ProgramResult { - let ix = initialize_mango_account_instruction( - ctx.program.key, - ctx.accounts.mango_group.key, - ctx.accounts.mango_account.key, - ctx.accounts.owner.key, - ctx.accounts.rent.key, - )?; - solana_program::program::invoke_signed( - &ix, - &[ - ctx.program.clone(), - ctx.accounts.mango_group.clone(), - ctx.accounts.mango_account.clone(), - ctx.accounts.owner.clone(), - ctx.accounts.rent.clone(), - ], - ctx.signer_seeds, - ) -} diff --git a/programs/uxd/src/mango_program/mod.rs b/programs/uxd/src/mango_program/mod.rs deleted file mode 100644 index e0aafd2ad..000000000 --- a/programs/uxd/src/mango_program/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Anchor wrapper for Mango Market V3 - -pub mod anchor_mango; -pub mod deposit; -pub mod init_mango_account; -pub mod place_perp_order; -pub mod withdraw; - -pub use anchor_mango::Mango; -pub use deposit::*; -pub use init_mango_account::*; -pub use place_perp_order::*; -pub use withdraw::*; diff --git a/programs/uxd/src/mango_program/place_perp_order.rs b/programs/uxd/src/mango_program/place_perp_order.rs deleted file mode 100644 index 391a7eace..000000000 --- a/programs/uxd/src/mango_program/place_perp_order.rs +++ /dev/null @@ -1,131 +0,0 @@ -use anchor_lang::prelude::AccountInfo; -use anchor_lang::prelude::AccountMeta; -use anchor_lang::prelude::Accounts; -use anchor_lang::prelude::CpiContext; -use anchor_lang::prelude::ProgramResult; -use mango::matching::OrderType; -use mango::matching::Side; -use mango::state::MAX_PAIRS; -use solana_program::instruction::Instruction; -use solana_program::program_error::ProgramError; -use solana_program::pubkey::Pubkey; - -use super::anchor_mango::check_program_account; - -#[derive(Accounts)] -pub struct PlacePerpOrder<'info> { - pub mango_group: AccountInfo<'info>, - pub mango_account: AccountInfo<'info>, - pub owner: AccountInfo<'info>, - pub mango_cache: AccountInfo<'info>, - pub mango_perp_market: AccountInfo<'info>, - pub mango_bids: AccountInfo<'info>, - pub mango_asks: AccountInfo<'info>, - pub mango_event_queue: AccountInfo<'info>, -} - -/// Creates a `place_perp_order` instruction. -/// / Place an order on a perp market -/// Accounts expected by this instruction (8): -/// 0. `[]` mango_group_ai - MangoGroup -/// 1. `[writable]` mango_account_ai - the MangoAccount of owner -/// 2. `[signer]` owner_ai - owner of MangoAccount -/// 3. `[]` mango_cache_ai - MangoCache for this MangoGroup -/// 4. `[writable]` perp_market_ai -/// 5. `[writable]` bids_ai - bids account for this PerpMarket -/// 6. `[writable]` asks_ai - asks account for this PerpMarket -/// 7. `[writable]` event_queue_ai - EventQueue for this PerpMarket -#[allow(clippy::too_many_arguments)] -fn place_perp_order_instruction( - mango_program_id: &Pubkey, - mango_group_pubkey: &Pubkey, - mango_account_pubkey: &Pubkey, - owner_pubkey: &Pubkey, - mango_cache_pubkey: &Pubkey, - mango_perp_market_pubkey: &Pubkey, - mango_bids_pubkey: &Pubkey, - mango_asks_pubkey: &Pubkey, - mango_event_queue_pubkey: &Pubkey, - price: i64, - quantity: i64, - client_order_id: u64, - side: Side, - order_type: OrderType, - reduce_only: bool, -) -> Result { - check_program_account(mango_program_id)?; - let data = mango::instruction::MangoInstruction::PlacePerpOrder { - price, - quantity, - client_order_id, - side, - order_type, - reduce_only, - } - .pack(); - let mut accounts = vec![ - AccountMeta::new_readonly(*mango_group_pubkey, false), - AccountMeta::new(*mango_account_pubkey, false), - AccountMeta::new_readonly(*owner_pubkey, true), - AccountMeta::new_readonly(*mango_cache_pubkey, false), - AccountMeta::new(*mango_perp_market_pubkey, false), - AccountMeta::new(*mango_bids_pubkey, false), - AccountMeta::new(*mango_asks_pubkey, false), - AccountMeta::new(*mango_event_queue_pubkey, false), - ]; - accounts.extend( - [Pubkey::default(); MAX_PAIRS] - .iter() - .map(|default_open_order_pubkey| { - AccountMeta::new_readonly(*default_open_order_pubkey, false) - }), - ); - Ok(Instruction { - program_id: *mango_program_id, - accounts, - data, - }) -} - -pub fn place_perp_order<'info>( - ctx: CpiContext<'_, '_, '_, 'info, PlacePerpOrder<'info>>, - price: i64, - quantity: i64, - client_order_id: u64, - side: Side, - order_type: OrderType, - reduce_only: bool, -) -> ProgramResult { - let ix = place_perp_order_instruction( - ctx.program.key, - ctx.accounts.mango_group.key, - ctx.accounts.mango_account.key, - ctx.accounts.owner.key, - ctx.accounts.mango_cache.key, - ctx.accounts.mango_perp_market.key, - ctx.accounts.mango_bids.key, - ctx.accounts.mango_asks.key, - ctx.accounts.mango_event_queue.key, - price, - quantity, - client_order_id, - side, - order_type, - reduce_only, - )?; - solana_program::program::invoke_signed( - &ix, - &[ - ctx.program.clone(), - ctx.accounts.mango_group.clone(), - ctx.accounts.mango_account.clone(), - ctx.accounts.owner.clone(), - ctx.accounts.mango_cache.clone(), - ctx.accounts.mango_perp_market.clone(), - ctx.accounts.mango_bids.clone(), - ctx.accounts.mango_asks.clone(), - ctx.accounts.mango_event_queue.clone(), - ], - ctx.signer_seeds, - ) -} diff --git a/programs/uxd/src/mango_program/withdraw.rs b/programs/uxd/src/mango_program/withdraw.rs deleted file mode 100644 index 52833e09b..000000000 --- a/programs/uxd/src/mango_program/withdraw.rs +++ /dev/null @@ -1,128 +0,0 @@ -use super::anchor_mango::check_program_account; -use anchor_lang::prelude::AccountInfo; -use anchor_lang::prelude::AccountMeta; -use anchor_lang::prelude::Accounts; -use anchor_lang::prelude::CpiContext; -use anchor_lang::prelude::ProgramResult; -use mango::state::MAX_PAIRS; -use solana_program::instruction::Instruction; -use solana_program::program_error::ProgramError; -use solana_program::pubkey::Pubkey; - -#[derive(Accounts)] -pub struct Withdraw<'info> { - pub mango_group: AccountInfo<'info>, - pub mango_account: AccountInfo<'info>, - pub owner: AccountInfo<'info>, - pub mango_cache: AccountInfo<'info>, - pub mango_root_bank: AccountInfo<'info>, - pub mango_node_bank: AccountInfo<'info>, - pub mango_vault: AccountInfo<'info>, - pub token_account: AccountInfo<'info>, - pub mango_signer: AccountInfo<'info>, - pub token_program: AccountInfo<'info>, -} - -/// Withdraw funds that were deposited earlier. -/// -/// Accounts expected by this instruction (10): -/// -/// 0. `[read]` mango_group_ai, -/// 1. `[write]` mango_account_ai, -/// 2. `[read]` owner_ai, -/// 3. `[read]` mango_cache_ai, -/// 4. `[read]` root_bank_ai, -/// 5. `[write]` node_bank_ai, -/// 6. `[write]` vault_ai, -/// 7. `[write]` token_account_ai, -/// 8. `[read]` signer_ai, -/// 9. `[read]` token_prog_ai, -/// 10. `[read]` clock_ai, -/// 11..+ `[]` open_orders_accs - open orders for each of the spot market -#[allow(clippy::too_many_arguments)] -fn withdraw_instruction( - mango_program_id: &Pubkey, - mango_group_pubkey: &Pubkey, - mango_account_pubkey: &Pubkey, - owner_pubkey: &Pubkey, - mango_cache_pubkey: &Pubkey, - mango_root_bank_pubkey: &Pubkey, - mango_node_bank_pubkey: &Pubkey, - mango_vault_pubkey: &Pubkey, - token_account_pubkey: &Pubkey, - mango_signer_pubkey: &Pubkey, - token_program_id: &Pubkey, - quantity: u64, - allow_borrow: bool, -) -> Result { - check_program_account(mango_program_id)?; - let data = mango::instruction::MangoInstruction::Withdraw { - quantity, - allow_borrow, - } - .pack(); - - let mut accounts = vec![ - AccountMeta::new_readonly(*mango_group_pubkey, false), - AccountMeta::new(*mango_account_pubkey, false), - AccountMeta::new_readonly(*owner_pubkey, true), - AccountMeta::new_readonly(*mango_cache_pubkey, false), - AccountMeta::new_readonly(*mango_root_bank_pubkey, false), - AccountMeta::new(*mango_node_bank_pubkey, false), - AccountMeta::new(*mango_vault_pubkey, false), - AccountMeta::new(*token_account_pubkey, false), - AccountMeta::new_readonly(*mango_signer_pubkey, false), - AccountMeta::new_readonly(*token_program_id, false), - ]; - accounts.extend( - [Pubkey::default(); MAX_PAIRS] - .iter() - .map(|default_open_order_pubkey| { - AccountMeta::new_readonly(*default_open_order_pubkey, false) - }), - ); - Ok(Instruction { - program_id: *mango_program_id, - accounts, - data, - }) -} - -pub fn withdraw<'info>( - ctx: CpiContext<'_, '_, '_, 'info, Withdraw<'info>>, - quantity: u64, - allow_borrow: bool, -) -> ProgramResult { - let ix = withdraw_instruction( - ctx.program.key, - ctx.accounts.mango_group.key, - ctx.accounts.mango_account.key, - ctx.accounts.owner.key, - ctx.accounts.mango_cache.key, - ctx.accounts.mango_root_bank.key, - ctx.accounts.mango_node_bank.key, - ctx.accounts.mango_vault.key, - ctx.accounts.token_account.key, - ctx.accounts.mango_signer.key, - ctx.accounts.token_program.key, - quantity, - allow_borrow, - )?; - solana_program::program::invoke_signed( - &ix, - &[ - ctx.program.clone(), - ctx.accounts.mango_group.clone(), - ctx.accounts.mango_account.clone(), - ctx.accounts.owner.clone(), - ctx.accounts.mango_cache.clone(), - ctx.accounts.mango_root_bank.clone(), - ctx.accounts.mango_node_bank.clone(), - ctx.accounts.mango_vault.clone(), - ctx.accounts.token_account.clone(), - ctx.accounts.mango_signer.clone(), - ctx.accounts.token_program.clone(), - ], - ctx.signer_seeds, - ) -} diff --git a/programs/uxd/src/mango_utils/limit_utils.rs b/programs/uxd/src/mango_utils/limit_utils.rs deleted file mode 100644 index 24c029bca..000000000 --- a/programs/uxd/src/mango_utils/limit_utils.rs +++ /dev/null @@ -1,70 +0,0 @@ -use super::Order; -use super::PerpInfo; -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; -use crate::error::UxdError; -use crate::UxdErrorCode; -use crate::UxdResult; -use crate::SLIPPAGE_BASIS; -use fixed::types::I80F48; -use mango::matching::Side; - -declare_check_assert_macros!(SourceFileId::MangoUtilsLimitUtils); - -// Return the slippage amount, given a price and a slippage. -pub fn calculate_slippage_amount(price: I80F48, slippage: u32) -> UxdResult { - let slippage = I80F48::from_num(slippage); - let slippage_basis = I80F48::from_num(SLIPPAGE_BASIS); - let slippage_ratio = slippage.checked_div(slippage_basis).ok_or(math_err!())?; - price.checked_mul(slippage_ratio).ok_or(math_err!()) -} - -// Worse execution price for a provided slippage and side. -// Keep in mind that you'r the Taker when you call this, and that the `matched_side` is the side your order will match against. -// Meaning that you'r willing to go as far as limit price. -// If you are BID as the taker, matched_side is ASK, and you'll buy from price down to (price + slippage) -// If you are ASK as the taker, matched_side is BID, and you'll sell from price down to (price - slippage) -pub fn limit_price(price: I80F48, slippage: u32, taker_side: Side) -> UxdResult { - let slippage_amount = calculate_slippage_amount(price, slippage)?; - match taker_side { - Side::Bid => price.checked_add(slippage_amount).ok_or(math_err!()), - Side::Ask => price.checked_sub(slippage_amount).ok_or(math_err!()), - } -} - -// Convert price into a quote lot per base lot price. -// Price is the value of 1 native base unit expressed in native quote. -pub fn price_to_lot_price(price: I80F48, perp_info: &PerpInfo) -> UxdResult { - price - .checked_mul(perp_info.base_lot_size) - .ok_or(math_err!())? - .checked_div(perp_info.quote_lot_size) - .ok_or(math_err!()) -} - -// Check if the provided order is valid given the slippage point and side -// TODO: Doesn't handle 0 slippage - Currently `validate` checks for slippage != 0 -pub fn check_effective_order_price_versus_limit_price( - perp_info: &PerpInfo, - order: &Order, - slippage: u32, -) -> UxdResult { - let market_price = perp_info.price; - let limit_price = limit_price(market_price, slippage, order.taker_side)?; - let limit_price_lot = price_to_lot_price(limit_price, perp_info)?; - match order.taker_side { - Side::Bid => { - // Bid up to limit price - if order.price <= limit_price_lot { - return Ok(()); - } - } - Side::Ask => { - // Ask for at least limit price - if order.price >= limit_price_lot { - return Ok(()); - } - } - }; - Err(throw_err!(UxdErrorCode::SlippageReached)) -} diff --git a/programs/uxd/src/mango_utils/mango_info_utils.rs b/programs/uxd/src/mango_utils/mango_info_utils.rs new file mode 100644 index 000000000..55a0cc464 --- /dev/null +++ b/programs/uxd/src/mango_utils/mango_info_utils.rs @@ -0,0 +1,49 @@ +use anchor_lang::error; +use anchor_lang::prelude::*; +use anchor_lang::prelude::{ProgramError, Pubkey}; +use fixed::types::I80F48; +use mango::state::CENTIBPS_PER_UNIT; +use mango::{ + ids::mngo_token, + state::{MangoAccount, MangoCache, MangoGroup}, +}; + +use crate::error::UxdError; + +pub fn get_native_deposit( + mint_pk: &Pubkey, + mango_group: &MangoGroup, + mango_cache: &MangoCache, + mango_account: &MangoAccount, +) -> Result { + let token_index = match mango_group.find_token_index(mint_pk) { + None => return Err(error!(UxdError::RootBankIndexNotFound)), + Some(i) => i, + }; + let root_bank_cache = mango_cache.root_bank_cache[token_index]; + // If the user's token deposit is non-zero then the rootbank cache will be checked already in `place_perp_order`. + // If it's zero then cache may be out of date, but it doesn't matter because 0 * index = 0 + let native_deposit = mango_account + .get_native_deposit(&root_bank_cache, token_index) + .map_err(ProgramError::from)?; + + Ok(native_deposit) +} + +// Check for Ref fees (fees added on mango v3.3.5) +// Referral fees +// If you hold 10k MNGO or more in your MangoAccount as of 02/20/2022, you skip this fee. +pub fn determine_ref_fee( + mango_group: &MangoGroup, + mango_cache: &MangoCache, + mango_account: &MangoAccount, +) -> Result { + let mngo_deposits = + get_native_deposit(&mngo_token::id(), mango_group, mango_cache, mango_account) + .map_err(|me| ProgramError::from(me))?; + let ref_mngo_req = I80F48::from_num(mango_group.ref_mngo_required); + if mngo_deposits >= ref_mngo_req { + return Ok(I80F48::ZERO); + } + Ok(I80F48::from_num(mango_group.ref_share_centibps) / CENTIBPS_PER_UNIT) +} diff --git a/programs/uxd/src/mango_utils/mod.rs b/programs/uxd/src/mango_utils/mod.rs index 213a8dad4..1ae9e6d26 100644 --- a/programs/uxd/src/mango_utils/mod.rs +++ b/programs/uxd/src/mango_utils/mod.rs @@ -1,11 +1,9 @@ -pub mod limit_utils; -pub mod order; +pub mod mango_info_utils; pub mod order_delta; pub mod perp_account_utils; pub mod perp_info; -pub use limit_utils::*; -pub use order::*; +pub use mango_info_utils::*; pub use order_delta::*; pub use perp_account_utils::*; pub use perp_info::*; diff --git a/programs/uxd/src/mango_utils/order.rs b/programs/uxd/src/mango_utils/order.rs deleted file mode 100644 index 0679ab114..000000000 --- a/programs/uxd/src/mango_utils/order.rs +++ /dev/null @@ -1,102 +0,0 @@ -use crate::declare_check_assert_macros; -use crate::error::check_assert; -use crate::error::SourceFileId; -use crate::error::UxdError; -use crate::error::UxdErrorCode; -use crate::UxdResult; -use anchor_lang::prelude::Clock; -use anchor_lang::prelude::SolanaSysvar; -use mango::matching::BookSide; -use mango::matching::Side; -use std::cell::RefMut; - -declare_check_assert_macros!(SourceFileId::MangoUtilsOrder); - -/// This logic will eventually be deported back to MangoMarket repository. -/// 02/18/2022 - Spoke with Ckamm from mango market, they will implement this in the coming week. -/// https://github.com/blockworks-foundation/mango-v3/pull/139/files - -pub struct Order { - // The quantity, in base_lot - pub quantity: i64, - // Marginal Price, the price to place the order at, in quote (per base_lot) - pub price: i64, - pub taker_side: Side, -} - -/// Walk through the maker side of the book and find the best quantity and price to spend a given amount of quote. -pub fn get_best_order_for_quote_lot_amount( - book_side: RefMut, - taker_side: Side, - quote_lot_amount_to_spend: i64, -) -> UxdResult { - let mut cmlv_quantity: i64 = 0; - let mut execution_price = 0; // Will update at each step, depending of how far it needs to go - let mut quote_lot_left_to_spend = quote_lot_amount_to_spend; - let now_ts = Clock::get()?.unix_timestamp as u64; - - for order in book_side.iter_valid(now_ts) { - let order_price = order.1.price(); - let order_quantity = order.1.quantity; - // This order total value in quote lots - let order_size = order_quantity.checked_mul(order_price).ok_or(math_err!())?; - // How much base_lot we can fill for this order size - let quantity_matched = { - if quote_lot_left_to_spend < order_size { - // we can finish the operation by purchasing this order partially - // find out how much quantity that is in base lots - quote_lot_left_to_spend - .checked_div(order_price) - .ok_or(math_err!())? - } else { - // we eat this order - order_quantity - } - }; - // How much quote_lot were spent - let spent = quantity_matched - .checked_mul(order_price) - .ok_or(math_err!())?; - if spent > 0 { - // Current best execution price in quote_lot - execution_price = order_price; - } - cmlv_quantity = cmlv_quantity - .checked_add(quantity_matched) - .ok_or(math_err!())?; - quote_lot_left_to_spend = quote_lot_left_to_spend - .checked_sub(spent) - .ok_or(math_err!())?; - - // when the amount left to spend is inferior to the price of a base lot, or if we are fully filled - if quote_lot_left_to_spend == 0 || spent == 0 { - // failure - if cmlv_quantity == 0 { - return Err(throw_err!(UxdErrorCode::OrderSizeBelowMinLotSize)); - } - // success - return Ok(Order { - quantity: cmlv_quantity, - price: execution_price, - taker_side, - }); - } - } - Err(throw_err!(UxdErrorCode::InsufficientOrderBookDepth)) -} - -// Verify that the order quantity matches the base position delta -pub fn check_perp_order_fully_filled( - order_quantity: i64, - pre_position: i64, - post_position: i64, -) -> UxdResult { - let filled_amount = (post_position.checked_sub(pre_position).ok_or(math_err!())?) - .checked_abs() - .ok_or(math_err!())?; - check_eq!( - order_quantity, - filled_amount, - UxdErrorCode::PerpOrderPartiallyFilled - ) -} diff --git a/programs/uxd/src/mango_utils/order_delta.rs b/programs/uxd/src/mango_utils/order_delta.rs index c191b55a8..a9449c8c7 100644 --- a/programs/uxd/src/mango_utils/order_delta.rs +++ b/programs/uxd/src/mango_utils/order_delta.rs @@ -1,21 +1,17 @@ use super::PerpInfo; -use crate::declare_check_assert_macros; -use crate::error::check_assert; -use crate::error::SourceFileId; use crate::error::UxdError; -use crate::error::UxdErrorCode; use crate::mango_utils::total_perp_base_lot_position; -use crate::UxdResult; +use anchor_lang::prelude::*; use fixed::types::I80F48; use mango::state::PerpAccount; -declare_check_assert_macros!(SourceFileId::MangoUtilsOrderDelta); - +/// In native units #[derive(Debug)] pub struct OrderDelta { - pub collateral: u64, - pub quote: u64, - pub fee: u64, + pub base: I80F48, + // Including fees + pub quote: I80F48, + pub fee: I80F48, } // Quote delta between two states of perp account @@ -23,13 +19,15 @@ pub fn quote_delta( pre_pa: &PerpAccount, post_pa: &PerpAccount, quote_lot_size: I80F48, -) -> UxdResult { - let pre_taker_quote = I80F48::from_num(pre_pa.taker_quote); - let post_taker_quote = I80F48::from_num(post_pa.taker_quote); - let quote_lot_delta = pre_taker_quote.dist(post_taker_quote); - quote_lot_delta +) -> Result { + let pre_taker_quote = pre_pa.taker_quote; + let post_taker_quote = post_pa.taker_quote; + let quote_lot_delta = post_taker_quote + .checked_sub(pre_taker_quote) + .ok_or_else(|| error!(UxdError::MathError))?; + I80F48::from_num(quote_lot_delta) .checked_mul(quote_lot_size) - .ok_or(math_err!()) + .ok_or_else(|| error!(UxdError::MathError)) } // Quote delta between two states of perp account @@ -37,20 +35,24 @@ pub fn base_delta( pre_pa: &PerpAccount, post_pa: &PerpAccount, base_lot_size: I80F48, -) -> UxdResult { - let pre_base_lot_position = I80F48::from_num(total_perp_base_lot_position(pre_pa)?); - let post_base_lot_position = I80F48::from_num(total_perp_base_lot_position(post_pa)?); - let base_lot_delta = pre_base_lot_position.dist(post_base_lot_position); - base_lot_delta.checked_mul(base_lot_size).ok_or(math_err!()) +) -> Result { + let pre_base_lot_position = total_perp_base_lot_position(pre_pa)?; + let post_base_lot_position = total_perp_base_lot_position(post_pa)?; + let base_lot_delta = post_base_lot_position + .checked_sub(pre_base_lot_position) + .ok_or_else(|| error!(UxdError::MathError))?; + I80F48::from_num(base_lot_delta) + .checked_mul(base_lot_size) + .ok_or_else(|| error!(UxdError::MathError)) } // returns the amount of taker_fee paid for trading raw_quote_amount (rounded up) -pub fn taker_fee_amount_ceil(raw_quote_amount: I80F48, taker_fee: I80F48) -> UxdResult { +pub fn taker_fee_amount_ceil(raw_quote_amount: I80F48, taker_fee: I80F48) -> Result { raw_quote_amount .checked_mul(taker_fee) - .ok_or(math_err!())? + .ok_or_else(|| error!(UxdError::MathError))? .checked_ceil() - .ok_or(math_err!()) + .ok_or_else(|| error!(UxdError::MathError)) } // Note : removes the taker fees from the redeemable_delta. @@ -63,17 +65,16 @@ pub fn derive_order_delta( pre_pa: &PerpAccount, post_pa: &PerpAccount, perp_info: &PerpInfo, -) -> UxdResult { +) -> Result { + let base_delta = base_delta(pre_pa, post_pa, perp_info.base_lot_size)?; let quote_delta = quote_delta(pre_pa, post_pa, perp_info.quote_lot_size)?; // Quote amount from an order cannot be 0 at this stage - check!(!quote_delta.is_zero(), UxdErrorCode::InvalidQuoteDelta)?; - // Note : Will keep the current way of calculating, but here quote_position delta would work + require!(!quote_delta.is_zero(), UxdError::InvalidQuoteDelta); let fee_delta = taker_fee_amount_ceil(quote_delta, perp_info.effective_fee)?; - let base_delta = base_delta(pre_pa, post_pa, perp_info.base_lot_size)?; Ok(OrderDelta { - collateral: base_delta.checked_to_num().ok_or(math_err!())?, - quote: quote_delta.checked_to_num().ok_or(math_err!())?, - fee: fee_delta.checked_to_num().ok_or(math_err!())?, + base: base_delta, + quote: quote_delta, + fee: fee_delta, }) } diff --git a/programs/uxd/src/mango_utils/perp_account_utils.rs b/programs/uxd/src/mango_utils/perp_account_utils.rs index 16fdc5cf4..41e92165f 100644 --- a/programs/uxd/src/mango_utils/perp_account_utils.rs +++ b/programs/uxd/src/mango_utils/perp_account_utils.rs @@ -1,16 +1,11 @@ -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; use crate::error::UxdError; -use crate::error::UxdErrorCode; -use crate::UxdResult; +use anchor_lang::prelude::*; use mango::state::PerpAccount; -declare_check_assert_macros!(SourceFileId::MangoUtilsPerpAccountUtils); - // Return the base position + the amount that's on EventQueue waiting to be processed -pub fn total_perp_base_lot_position(perp_account: &PerpAccount) -> UxdResult { +pub fn total_perp_base_lot_position(perp_account: &PerpAccount) -> Result { perp_account .base_position .checked_add(perp_account.taker_base) - .ok_or(math_err!()) + .ok_or_else(|| error!(UxdError::MathError)) } diff --git a/programs/uxd/src/mango_utils/perp_info.rs b/programs/uxd/src/mango_utils/perp_info.rs index 3c8a31bdc..baf4258d0 100644 --- a/programs/uxd/src/mango_utils/perp_info.rs +++ b/programs/uxd/src/mango_utils/perp_info.rs @@ -1,18 +1,8 @@ -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; use crate::error::UxdError; -use crate::error::UxdErrorCode; -use crate::UxdResult; -use anchor_lang::prelude::AccountInfo; -use anchor_lang::prelude::Pubkey; +use crate::mango_utils::determine_ref_fee; +use anchor_lang::prelude::*; use fixed::types::I80F48; -use mango::ids::mngo_token; -use mango::state::MangoAccount; -use mango::state::MangoCache; -use mango::state::MangoGroup; -use mango::state::CENTIBPS_PER_UNIT; - -declare_check_assert_macros!(SourceFileId::MangoUtilsPerpInfo); +use mango::state::{MangoAccount, MangoCache, MangoGroup}; #[derive(Debug)] pub struct PerpInfo { @@ -37,31 +27,23 @@ impl PerpInfo { perp_market_key: &Pubkey, mango_group_key: &Pubkey, mango_program_key: &Pubkey, - ) -> UxdResult { - let mango_group = MangoGroup::load_checked(mango_group_ai, mango_program_key)?; - let mango_cache = - MangoCache::load_checked(mango_cache_ai, mango_program_key, &mango_group)?; + ) -> Result { + // load mango CPI account's state + let mango_group = MangoGroup::load_checked(mango_group_ai, mango_program_key) + .map_err(ProgramError::from)?; + let mango_cache = MangoCache::load_checked(mango_cache_ai, mango_program_key, &mango_group) + .map_err(|me| ProgramError::from(me))?; + let mango_account = + MangoAccount::load_checked(mango_account_ai, mango_program_key, mango_group_key) + .map_err(|me| ProgramError::from(me))?; + let perp_market_index = mango_group .find_perp_market_index(perp_market_key) - .ok_or(throw_err!(UxdErrorCode::MangoPerpMarketIndexNotFound))?; - let mango_account = - MangoAccount::load_checked(mango_account_ai, mango_program_key, mango_group_key)?; - PerpInfo::init( - &mango_group, - &mango_account, - &mango_cache, - perp_market_index, - ) - } + .ok_or_else(|| error!(UxdError::MangoPerpMarketIndexNotFound))?; - pub fn init( - mango_group: &MangoGroup, - mango_account: &MangoAccount, - mango_cache: &MangoCache, - perp_market_index: usize, - ) -> UxdResult { - let ref_fee = determine_ref_fee(mango_group, mango_account, mango_cache)?; + let ref_fee = determine_ref_fee(&mango_group, &mango_cache, &mango_account)?; let taker_fee = mango_group.perp_markets[perp_market_index].taker_fee; + Ok(PerpInfo { market_index: perp_market_index, price: mango_cache.price_cache[perp_market_index].price, @@ -76,25 +58,12 @@ impl PerpInfo { } } -// Check for Ref fees (fees added on mango v3.3.5) -// Referral fees -// If you hold 10k MNGO or more in your MangoAccount as of 02/20/2022, you skip this fee. -fn determine_ref_fee( - mango_group: &MangoGroup, - mango_account: &MangoAccount, - mango_cache: &MangoCache, -) -> UxdResult { - let mngo_index = match mango_group.find_token_index(&mngo_token::id()) { - None => return Ok(I80F48::ZERO), - Some(i) => i, - }; - let mngo_cache = &mango_cache.root_bank_cache[mngo_index]; - // If the user's MNGO deposit is non-zero then the rootbank cache will be checked already in `place_perp_order`. - // If it's zero then cache may be out of date, but it doesn't matter because 0 * index = 0 - let mngo_deposits = mango_account.get_native_deposit(mngo_cache, mngo_index)?; - let ref_mngo_req = I80F48::from_num(mango_group.ref_mngo_required); - if mngo_deposits >= ref_mngo_req { - return Ok(I80F48::ZERO); - } - Ok(I80F48::from_num(mango_group.ref_share_centibps) / CENTIBPS_PER_UNIT) +// Convert price into a quote lot per base lot price. +// Price is the value of 1 native base unit expressed in native quote. +pub fn price_to_lot_price(price: I80F48, perp_info: &PerpInfo) -> Result { + price + .checked_mul(perp_info.base_lot_size) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_div(perp_info.quote_lot_size) + .ok_or_else(|| error!(UxdError::MathError)) } diff --git a/programs/uxd/src/state/controller.rs b/programs/uxd/src/state/controller.rs index 60c05a9ce..1f43951e0 100644 --- a/programs/uxd/src/state/controller.rs +++ b/programs/uxd/src/state/controller.rs @@ -1,18 +1,13 @@ -use crate::declare_check_assert_macros; -use crate::error::check_assert; -use crate::error::SourceFileId; use crate::error::UxdError; -use crate::error::UxdErrorCode; -use crate::AccountingEvent; -use crate::UxdResult; use anchor_lang::prelude::*; -declare_check_assert_macros!(SourceFileId::StateController); - pub const MAX_REGISTERED_MANGO_DEPOSITORIES: usize = 8; -#[account] -#[derive(Default)] +pub const CONTROLLER_SPACE: usize = + 8 + 1 + 1 + 1 + 32 + 32 + 1 + (32 * MAX_REGISTERED_MANGO_DEPOSITORIES) + 1 + 16 + 8 + 16 + 512; + +#[account(zero_copy)] +#[repr(packed)] pub struct Controller { pub bump: u8, pub redeemable_mint_bump: u8, @@ -24,7 +19,7 @@ pub struct Controller { pub redeemable_mint_decimals: u8, // // The Mango Depositories registered with this Controller - pub registered_mango_depositories: [Pubkey; 8], // - IDL bug with constant, so hard 8 literal. -- Still not working in 0.20.0 although it should + pub registered_mango_depositories: [Pubkey; MAX_REGISTERED_MANGO_DEPOSITORIES], pub registered_mango_depositories_count: u8, // // Progressive roll out and safety ---------- @@ -43,65 +38,23 @@ pub struct Controller { // This should always be equal to the sum of all Depositories' `redeemable_amount_under_management` // in redeemable Redeemable Native Amount pub redeemable_circulating_supply: u128, - // - // Note : This is the last thing I'm working on and I would love some guidance from the audit. Anchor doesn't seems to play nice with padding - pub _reserved: ControllerPadding, -} - -#[derive(Clone)] -pub struct ControllerPadding([u8; 512]); - -impl AnchorSerialize for ControllerPadding { - fn serialize(&self, writer: &mut W) -> std::io::Result<()> { - writer.write_all(&self.0) - } -} - -impl AnchorDeserialize for ControllerPadding { - fn deserialize(_: &mut &[u8]) -> Result { - Ok(Self([0u8; 512])) - } -} - -impl Default for ControllerPadding { - fn default() -> Self { - ControllerPadding([0u8; 512]) - } } impl Controller { - pub fn update_redeemable_circulating_supply( - &mut self, - event_type: &AccountingEvent, - amount: u64, - ) -> UxdResult { - self.redeemable_circulating_supply = match event_type { - AccountingEvent::Deposit => self - .redeemable_circulating_supply - .checked_add(amount.into()) - .ok_or(math_err!())?, - AccountingEvent::Withdraw => self - .redeemable_circulating_supply - .checked_sub(amount.into()) - .ok_or(math_err!())?, - }; - Ok(()) - } - pub fn add_registered_mango_depository_entry( &mut self, mango_depository_id: Pubkey, - ) -> ProgramResult { + ) -> Result<()> { let current_size = usize::from(self.registered_mango_depositories_count); - check!( + require!( current_size < MAX_REGISTERED_MANGO_DEPOSITORIES, - UxdErrorCode::MaxNumberOfMangoDepositoriesRegisteredReached - )?; + UxdError::MaxNumberOfMangoDepositoriesRegisteredReached + ); // Increment registered Mango Depositories count self.registered_mango_depositories_count = self .registered_mango_depositories_count .checked_add(1) - .ok_or(math_err!())?; + .ok_or_else(|| error!(UxdError::MathError))?; // Add the new Mango Depository ID to the array of registered Depositories let new_entry_index = current_size; self.registered_mango_depositories[new_entry_index] = mango_depository_id; diff --git a/programs/uxd/src/state/mango_depository.rs b/programs/uxd/src/state/mango_depository.rs index 2ab7167d3..33d17aa88 100644 --- a/programs/uxd/src/state/mango_depository.rs +++ b/programs/uxd/src/state/mango_depository.rs @@ -1,14 +1,32 @@ -use crate::declare_check_assert_macros; -use crate::error::SourceFileId; -use crate::error::UxdError; -use crate::error::UxdErrorCode; -use crate::UxdResult; use anchor_lang::prelude::*; -declare_check_assert_macros!(SourceFileId::StateMangoDepository); +pub const MANGO_DEPOSITORY_RESERVED_SPACE: usize = 462; +pub const MANGO_DEPOSITORY_SPACE: usize = 8 + + 1 + + 2 + + 1 + + 1 + + 32 + + 1 + + 32 + + 32 + + 32 + + 1 + + 32 + + 32 + + 16 + + 16 + + 16 + + 16 + + 16 + + 16 + + 1 + + 16 + + 1 + + MANGO_DEPOSITORY_RESERVED_SPACE; -#[account] -#[derive(Default)] +#[account(zero_copy)] +#[repr(packed)] pub struct MangoDepository { pub bump: u8, pub _unused: [u8; 2], @@ -49,103 +67,15 @@ pub struct MangoDepository { // The amount of DN position that has been rebalanced (in quote native units) pub total_amount_rebalanced: u128, // - pub _reserved: MangoDepositoryPadding, -} - -#[derive(Clone)] -pub struct MangoDepositoryPadding([u8; 496]); - -impl AnchorSerialize for MangoDepositoryPadding { - fn serialize(&self, writer: &mut W) -> std::io::Result<()> { - writer.write_all(&self.0) - } -} - -impl AnchorDeserialize for MangoDepositoryPadding { - fn deserialize(_: &mut &[u8]) -> Result { - Ok(Self([0u8; 496])) - } -} - -impl Default for MangoDepositoryPadding { - fn default() -> Self { - MangoDepositoryPadding([0u8; 496]) - } -} - -pub enum AccountingEvent { - Deposit, - Withdraw, -} - -impl MangoDepository { - pub fn update_insurance_amount_deposited( - &mut self, - event_type: &AccountingEvent, - amount: u64, - ) -> UxdResult { - self.insurance_amount_deposited = match event_type { - AccountingEvent::Deposit => self - .insurance_amount_deposited - .checked_add(amount.into()) - .ok_or(math_err!())?, - AccountingEvent::Withdraw => self - .insurance_amount_deposited - .checked_sub(amount.into()) - .ok_or(math_err!())?, - }; - Ok(()) - } - - pub fn update_collateral_amount_deposited( - &mut self, - event_type: &AccountingEvent, - amount: u64, - ) -> UxdResult { - self.collateral_amount_deposited = match event_type { - AccountingEvent::Deposit => self - .collateral_amount_deposited - .checked_add(amount.into()) - .ok_or(math_err!())?, - AccountingEvent::Withdraw => self - .collateral_amount_deposited - .checked_sub(amount.into()) - .ok_or(math_err!())?, - }; - Ok(()) - } - - pub fn update_redeemable_amount_under_management( - &mut self, - event_type: &AccountingEvent, - amount: u64, - ) -> UxdResult { - self.redeemable_amount_under_management = match event_type { - AccountingEvent::Deposit => self - .redeemable_amount_under_management - .checked_add(amount.into()) - .ok_or(math_err!())?, - AccountingEvent::Withdraw => self - .redeemable_amount_under_management - .checked_sub(amount.into()) - .ok_or(math_err!())?, - }; - Ok(()) - } - - pub fn update_total_amount_paid_taker_fee(&mut self, amount: u64) -> UxdResult { - self.total_amount_paid_taker_fee = self - .total_amount_paid_taker_fee - .checked_add(amount.into()) - .ok_or(math_err!())?; - Ok(()) - } - - pub fn update_rebalanced_amount(&mut self, amount: u64) -> UxdResult { - self.total_amount_rebalanced = self - .total_amount_rebalanced - .checked_add(amount.into()) - .ok_or(math_err!())?; - Ok(()) - } + // The amount of redeemable that has been minted with quote mint + pub net_quote_minted: i128, // ** Change to make both ways + // + // The amount of fees taken per quote mint and quote redeem + pub quote_mint_and_redeem_fee: u8, // in units of BPs + // + // The amount of fees accrued from quote minting + pub total_quote_mint_and_redeem_fees: u128, + // + // Flag for enabling / disabling minting with this depository's collateral_mint + pub minting_disabled: bool, } diff --git a/programs/uxd/src/state/mod.rs b/programs/uxd/src/state/mod.rs index 693d7dc59..0de6730f1 100644 --- a/programs/uxd/src/state/mod.rs +++ b/programs/uxd/src/state/mod.rs @@ -1,5 +1,7 @@ pub mod controller; pub mod mango_depository; +pub mod msol_config; pub use controller::*; pub use mango_depository::*; +pub use msol_config::*; diff --git a/programs/uxd/src/state/msol_config.rs b/programs/uxd/src/state/msol_config.rs new file mode 100644 index 000000000..fb7bf0114 --- /dev/null +++ b/programs/uxd/src/state/msol_config.rs @@ -0,0 +1,46 @@ +use fixed::types::I80F48; + +use crate::*; + +// 10000 equiv. to 100% +pub const LIQUIDITY_RATIO_BASIS: u16 = 10000; + +pub const TARGET_LIQUIDITY_RATIO_MAX: u16 = 10000; + +const MSOL_CONFIG_PADDING: usize = 64; + +pub const MSOL_CONFIG_SPACE: usize = 8 + 1 + 32 + 32 + 1 + 2 + MSOL_CONFIG_PADDING; + +#[account(zero_copy)] +pub struct MSolConfig { + pub bump: u8, + // The Depository that this config account dedicated to + pub depository: Pubkey, + // The Controller that own this config account + pub controller: Pubkey, + // Whether allowing the SOL/mSOL swap + pub enabled: bool, + // A constant value of the proportion of SOL we wanna keep from the total amount of SOL + mSOL in terms of their value. + // In LIQUIDITY_RATIO_BASIS + pub target_liquidity_ratio: u16, +} + +impl MSolConfig { + pub fn target_liquidity_ratio(&self) -> Result { + I80F48::checked_from_num(self.target_liquidity_ratio) + .ok_or_else(|| error!(UxdError::MathError))? + .checked_div( + I80F48::checked_from_num(LIQUIDITY_RATIO_BASIS) + .ok_or_else(|| error!(UxdError::MathError))?, + ) + .ok_or_else(|| error!(UxdError::MathError)) + } + + pub fn diff_to_target_liquidity(&self, liquidity_ratio: I80F48) -> Result { + let target_liquidity_ratio = self.target_liquidity_ratio()?; + msg!("target_liquidity_ratio {:?}", target_liquidity_ratio); + liquidity_ratio + .checked_sub(target_liquidity_ratio) + .ok_or_else(|| error!(UxdError::MathError)) + } +} diff --git a/programs/uxd/src/test/mango_utils/mod.rs b/programs/uxd/src/test/mango_utils/mod.rs index 3c86d89ef..6b832dc58 100644 --- a/programs/uxd/src/test/mango_utils/mod.rs +++ b/programs/uxd/src/test/mango_utils/mod.rs @@ -1,4 +1,3 @@ -mod test_limit_utils; -mod test_order; mod test_order_delta; mod test_perp_account_utils; +mod test_quote_mintable; diff --git a/programs/uxd/src/test/mango_utils/test_limit_utils.rs b/programs/uxd/src/test/mango_utils/test_limit_utils.rs deleted file mode 100644 index 63c3d2235..000000000 --- a/programs/uxd/src/test/mango_utils/test_limit_utils.rs +++ /dev/null @@ -1,278 +0,0 @@ -#[cfg(test)] -mod test_limit_utils { - - use crate::{ - mango_utils::{price_to_lot_price, Order, PerpInfo}, - UxdResult, - }; - use fixed::types::I80F48; - use mango::matching::Side; - use proptest::prelude::*; - - // price expressed in native quote per native base - SOL-PERP - fn mocked_perp_info(price: f64) -> PerpInfo { - PerpInfo { - market_index: 3, - // Price is the price of 1 native unit of BASE expressed in native unit of QUOTE - price: I80F48::from_num(price), - base_lot_size: I80F48::from_num(10_000_000), - quote_lot_size: I80F48::from_num(100), - effective_fee: I80F48::from_num(0.000_5), - } - } - - fn mocked_order(perp_info: &PerpInfo, price: f64, taker_side: Side) -> UxdResult { - let price_lot = price_to_lot_price(I80F48::from_num(price), perp_info)?; - Ok(Order { - quantity: 0, // whatever not used - price: price_lot.to_num(), // exact price - taker_side, - }) - } - - mod check_effective_order_price_versus_limit_price_suite { - use super::*; - use crate::SLIPPAGE_BASIS; - - mod mint_suite { - use crate::{ - error::{SourceFileId, UxdError, UxdErrorCode}, - mango_utils::{check_effective_order_price_versus_limit_price, limit_price}, - }; - - use super::*; - - proptest! { - /// Tests the price check after placing a Perp order for Minting UXD (Selling Perp to open the Short position) - /// combinations with : - /// perp_price per base unit between 0$ and 100_000 - /// order_price per base unit between 0$ and 100_000 - /// slippage between 0.1% and 100% - #[test] - fn test_check_effective_order_price_versus_limit_price_bid(perp_price in 0.0f64..10f64, order_price in 0.0f64..10f64, slippage in 1..SLIPPAGE_BASIS) { - // Order.price must be below the perpInfo.price within slippage - let taker_side = Side::Ask; - let perp_info = mocked_perp_info(perp_price); - let order = mocked_order(&perp_info, order_price, taker_side).unwrap(); - - let limit_price: f64 = limit_price(I80F48::from_num(perp_price), slippage, taker_side)?.to_num(); - match check_effective_order_price_versus_limit_price( - &perp_info, - &order, - slippage, - ) { - Ok(_) => { - prop_assert!(order_price >= limit_price); - }, - Err(error) => { - match error { - UxdError::ProgramError(_) => prop_assert!(false), - UxdError::UxdErrorCode { uxd_error_code, line: _, source_file_id } => { - prop_assert_eq!(source_file_id, SourceFileId::MangoUtilsLimitUtils); - match uxd_error_code { - UxdErrorCode::MathError => prop_assert!(false), - UxdErrorCode::SlippageReached => { - prop_assert!(order_price < limit_price); - }, - _default => prop_assert!(false) - } - } - } - } - } - } - } - - mod non_regression { - use crate::mango_utils::check_effective_order_price_versus_limit_price; - - use super::*; - - #[test] - pub fn test_valid_mint_small_slippage() { - // Order.price must be below the perpInfo.price within slippage - let taker_side = Side::Ask; - let perp_info = mocked_perp_info(0.09000); - let order = mocked_order(&perp_info, 0.09000, taker_side).unwrap(); - let ret = check_effective_order_price_versus_limit_price( - &perp_info, &order, 1, // 0.1% - ); - assert!(ret.is_ok()); - } - - #[test] - pub fn test_valid_mint() { - let taker_side = Side::Ask; - let perp_info = mocked_perp_info(0.09000); - let order = mocked_order(&perp_info, 0.08911, taker_side).unwrap(); - let ret = check_effective_order_price_versus_limit_price( - &perp_info, &order, 10, // 1% - ); - assert!(ret.is_ok()); - } - - #[test] - pub fn test_invalid_mint() { - let taker_side = Side::Ask; - let perp_info = mocked_perp_info(0.09000); - let order = mocked_order(&perp_info, 0.08909, taker_side).unwrap(); - let ret = check_effective_order_price_versus_limit_price( - &perp_info, &order, 10, // 1% - ); - assert!(ret.is_err()); - } - } - } - - mod redeem_suite { - use crate::{ - error::{SourceFileId, UxdError, UxdErrorCode}, - mango_utils::{check_effective_order_price_versus_limit_price, limit_price}, - }; - - use super::*; - - proptest! { - /// Tests the price check after placing a Perp order for Redeeming UXD (Buying Perp to close the outstanding Short position) - /// combinations with : - /// perp_price per base unit between 0$ and 100_000 - /// order_price per base unit between 0$ and 100_000 - /// slippage between 0.1% and 100% - #[test] - fn test_check_effective_order_price_versus_limit_price_ask(perp_price in 0.0f64..10f64, order_price in 0.0f64..10f64, slippage in 1..SLIPPAGE_BASIS) { - let taker_side = Side::Bid; - let perp_info = mocked_perp_info(perp_price); - let order = mocked_order(&perp_info, order_price, taker_side).unwrap(); - - let limit_price: f64 = limit_price(I80F48::from_num(perp_price), slippage, taker_side)?.to_num(); - match check_effective_order_price_versus_limit_price( - &perp_info, - &order, - slippage, - ) { - Ok(_) => { - prop_assert!(order_price <= limit_price); - }, - Err(error) => { - match error { - UxdError::ProgramError(_) => prop_assert!(false), - UxdError::UxdErrorCode { uxd_error_code, line: _, source_file_id } => { - prop_assert_eq!(source_file_id, SourceFileId::MangoUtilsLimitUtils); - match uxd_error_code { - UxdErrorCode::MathError => prop_assert!(false), - UxdErrorCode::SlippageReached => { - prop_assert!(order_price > limit_price); - }, - _default => prop_assert!(false) - } - } - } - } - } - } - } - - mod non_regression { - use crate::mango_utils::check_effective_order_price_versus_limit_price; - - use super::*; - - #[test] - pub fn test_valid_redeem_small_slippage() { - let taker_side = Side::Bid; - let perp_info = mocked_perp_info(0.09000); - let order = mocked_order(&perp_info, 0.09000, taker_side).unwrap(); - let ret = check_effective_order_price_versus_limit_price( - &perp_info, &order, 1, // 0.1% - ); - assert!(ret.is_ok()); - } - - #[test] - pub fn test_valid_redeem() { - let taker_side = Side::Bid; - let perp_info = mocked_perp_info(0.09000); - let order = mocked_order(&perp_info, 0.09089, taker_side).unwrap(); - let ret = check_effective_order_price_versus_limit_price( - &perp_info, &order, 10, // 1% - ); - assert!(ret.is_ok()); - } - - #[test] - pub fn test_invalid_redeem() { - let taker_side = Side::Bid; - let perp_info = mocked_perp_info(0.09000); - let order = mocked_order(&perp_info, 0.09091, taker_side).unwrap(); - let ret = check_effective_order_price_versus_limit_price( - &perp_info, &order, 10, // 1% - ); - assert!(ret.is_err()); - } - } - } - } - - mod test_limit_price { - use crate::mango_utils::{calculate_slippage_amount, limit_price}; - - use super::*; - - #[test] - fn test_cal_slippage_amount() { - // general param - let lamport_basis = I80F48::from_num(10u32.pow(9)); - - // given price is 24 - let ui_price = I80F48::from_num(24); - let price = ui_price.checked_mul(lamport_basis).unwrap(); - - // given slippage is 10% - let slippage = 100u32; - - // expected slippage amount - let expected = I80F48::from_num(2400000000u64); - - assert_eq!( - calculate_slippage_amount(price, slippage) - .unwrap() - .overflowing_round(), - (expected, false) - ); - } - - proptest! { - #[test] - fn test_limit_price_bid(price in 0..1000000000000i128, slippage in 0..u32::MAX) { - // create random price in lamport range from 0 to 1000 equivalent uiAmount - let fractional_price = I80F48::checked_from_num(price).unwrap(); - // println!("fractional_price = {}, slippage = {}", fractional_price, slippage); - - let limit_price = limit_price(fractional_price, slippage, Side::Bid).unwrap(); - - let slippage_amount = calculate_slippage_amount(fractional_price, slippage).unwrap(); - // expected limit price - let price_sub_slippage = fractional_price.checked_add(slippage_amount).unwrap(); - - prop_assert_eq!(limit_price, price_sub_slippage); - } - } - - proptest! { - #[test] - fn test_limit_price_ask(price in 0..1000000000000i128, slippage in 0..u32::MAX) { - // create random price in lamport range from 0 to 1000 equivalent uiAmount - let fractional_price = I80F48::checked_from_num(price).unwrap(); - // println!("fractional_price = {}, slippage = {}", fractional_price, slippage); - - let limit_price = limit_price(fractional_price, slippage, Side::Ask).unwrap(); - - let slippage_amount = calculate_slippage_amount(fractional_price, slippage).unwrap(); - // expected limit price - let price_add_slippage = fractional_price.checked_sub(slippage_amount).unwrap(); - - prop_assert_eq!(limit_price, price_add_slippage); - } - } - } -} diff --git a/programs/uxd/src/test/mango_utils/test_order.rs b/programs/uxd/src/test/mango_utils/test_order.rs deleted file mode 100644 index c33cfc597..000000000 --- a/programs/uxd/src/test/mango_utils/test_order.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Unit Test -#[cfg(test)] -mod test_order { - - use crate::{ - error::{SourceFileId, UxdError, UxdErrorCode}, - mango_utils::check_perp_order_fully_filled, - }; - - use proptest::prelude::*; - - proptest! { - #[test] - fn test_check_perp_order_fully_filled(order_quantity in i64::MIN..i64::MAX, pre_position in i64::MIN..i64::MAX, post_position in i64::MIN..i64::MAX) { - let res = check_perp_order_fully_filled(order_quantity, pre_position, post_position); - // MangoMarket.place_perp_order take quantity as i64 - let order_quantity: u64 = order_quantity.abs().try_into().unwrap(); - match res { - Ok(()) => { - prop_assert_eq!(order_quantity, pre_position.abs_diff(post_position)); - } - Err(error) => { - match error { - UxdError::ProgramError(_) => prop_assert!(false), - UxdError::UxdErrorCode { uxd_error_code, line: _, source_file_id } => { - prop_assert_eq!(source_file_id, SourceFileId::MangoUtilsOrder); - match uxd_error_code { - UxdErrorCode::PerpOrderPartiallyFilled => prop_assert_ne!(order_quantity, pre_position.abs_diff(post_position)), - UxdErrorCode::MathError => prop_assert!(true), - _default => prop_assert!(false) - }; - }, - } - } - }; - } - } -} diff --git a/programs/uxd/src/test/mango_utils/test_order_delta.rs b/programs/uxd/src/test/mango_utils/test_order_delta.rs index e969dbd58..376f2a4ce 100644 --- a/programs/uxd/src/test/mango_utils/test_order_delta.rs +++ b/programs/uxd/src/test/mango_utils/test_order_delta.rs @@ -25,10 +25,7 @@ mod test_order { } } - use crate::{ - error::{SourceFileId, UxdError, UxdErrorCode}, - mango_utils::{base_delta, quote_delta, taker_fee_amount_ceil}, - }; + use crate::mango_utils::{base_delta, quote_delta, taker_fee_amount_ceil}; proptest! { #[test] @@ -48,21 +45,10 @@ mod test_order { let post_pa = mocked_perp_account(taker_base_post.into(), taker_quote_post.into(), base_position_post.into(), quote_position_post.into()); match quote_delta(&pre_pa, &post_pa, quote_lot_size) { Ok(quote_delta) => { - let expected_quote_delta = I80F48::from_num(taker_quote).dist(I80F48::from_num(taker_quote_post)).checked_mul(quote_lot_size).unwrap(); + let expected_quote_delta = I80F48::from_num(taker_quote_post).checked_sub(I80F48::from_num(taker_quote)).unwrap().checked_mul(quote_lot_size).unwrap(); prop_assert_eq!(quote_delta, expected_quote_delta) }, - Err(error) => { - match error { - UxdError::ProgramError(_) => prop_assert!(false), - UxdError::UxdErrorCode { uxd_error_code, line: _, source_file_id } => { - prop_assert_eq!(source_file_id, SourceFileId::MangoUtilsLimitUtils); - match uxd_error_code { - UxdErrorCode::MathError => prop_assert!(false), - _default => prop_assert!(false) - } - } - } - } + Err(_error) => prop_assert!(false) } } } @@ -87,21 +73,10 @@ mod test_order { Ok(base_delta) => { let total_base_pre = I80F48::from_num(taker_base) + I80F48::from_num(base_position); let total_base_post = I80F48::from_num(taker_base_post) + I80F48::from_num(base_position_post); - let expected_base_delta = total_base_pre.dist(I80F48::from_num(total_base_post)).checked_mul(base_lot_size).unwrap(); + let expected_base_delta = total_base_post.checked_sub(I80F48::from_num(total_base_pre)).unwrap().checked_mul(base_lot_size).unwrap(); prop_assert_eq!(base_delta, expected_base_delta) }, - Err(error) => { - match error { - UxdError::ProgramError(_) => prop_assert!(false), - UxdError::UxdErrorCode { uxd_error_code, line: _, source_file_id } => { - prop_assert_eq!(source_file_id, SourceFileId::MangoUtilsLimitUtils); - match uxd_error_code { - UxdErrorCode::MathError => prop_assert!(false), - _default => prop_assert!(false) - } - } - } - } + Err(_error) => prop_assert!(false) } } } diff --git a/programs/uxd/src/test/mango_utils/test_perp_account_utils.rs b/programs/uxd/src/test/mango_utils/test_perp_account_utils.rs index 5ff93ee13..04b30377e 100644 --- a/programs/uxd/src/test/mango_utils/test_perp_account_utils.rs +++ b/programs/uxd/src/test/mango_utils/test_perp_account_utils.rs @@ -2,10 +2,7 @@ #[cfg(test)] mod test_perp_account_utils { - use crate::{ - error::{SourceFileId, UxdError, UxdErrorCode}, - mango_utils::total_perp_base_lot_position, - }; + use crate::mango_utils::total_perp_base_lot_position; use fixed::types::I80F48; use mango::state::PerpAccount; @@ -27,7 +24,7 @@ mod test_perp_account_utils { proptest! { #[test] - fn test_total_perp_base_lot_position(taker_base in i64::MIN..i64::MAX, base_position in i64::MIN..i64::MAX) { + fn test_total_perp_base_lot_position(taker_base in (i64::MIN / 2)..(i64::MAX /2), base_position in (i64::MIN /2)..(i64::MAX / 2)) { let perp_account = mocked_perp_account(taker_base, base_position); let res = total_perp_base_lot_position(&perp_account); @@ -35,18 +32,7 @@ mod test_perp_account_utils { Ok(total) => { prop_assert_eq!(total, taker_base + base_position); } - Err(error) => { - match error { - UxdError::ProgramError(_) => prop_assert!(false), - UxdError::UxdErrorCode { uxd_error_code, line: _, source_file_id } => { - prop_assert_eq!(source_file_id, SourceFileId::MangoUtilsPerpAccountUtils); - match uxd_error_code { - UxdErrorCode::MathError => prop_assert!(true), - _default => prop_assert!(false) - } - } - } - } + Err(_error) => prop_assert!(false) }; } } diff --git a/programs/uxd/src/test/mango_utils/test_perp_info.rs b/programs/uxd/src/test/mango_utils/test_perp_info.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/programs/uxd/src/test/mango_utils/test_quote_mintable.rs b/programs/uxd/src/test/mango_utils/test_quote_mintable.rs new file mode 100644 index 000000000..c4b785ab9 --- /dev/null +++ b/programs/uxd/src/test/mango_utils/test_quote_mintable.rs @@ -0,0 +1,44 @@ + +#[cfg(test)] +mod test_quote_amounts { + use std::ops::Neg; + + use fixed::types::I80F48; + use proptest::prelude::*; + + use crate::instructions::{calculate_quote_mintable, calculate_quote_redeemable}; + + proptest! { + #[test] + fn test_quote_mintable( + perp_unrealized_pnl in (i128::from(u64::MAX) / 2).neg()..-1i128, + quote_minted in (i128::from(u64::MAX) / 2).neg()..(i128::from(u64::MAX) / 2) + ) { + let perp_unrealized_pnl = I80F48::from_num(perp_unrealized_pnl); + match calculate_quote_mintable(perp_unrealized_pnl, quote_minted) { + Ok(quote_mintable) => { + let expected_quote_mintable = perp_unrealized_pnl.checked_sub(I80F48::from_num(quote_minted)).unwrap().checked_abs().unwrap().checked_to_num::().unwrap(); + prop_assert_eq!(quote_mintable, expected_quote_mintable) + }, + Err(_error) => prop_assert!(false) + } + } + } + + proptest! { + #[test] + fn test_quote_redeemable( + perp_unrealized_pnl in 1i128..(i128::from(u64::MAX) / 2), + quote_minted in 1i128..(i128::from(u64::MAX) / 2), + ) { + let perp_unrealized_pnl = I80F48::from_num(perp_unrealized_pnl); + match calculate_quote_redeemable(perp_unrealized_pnl, quote_minted) { + Ok(quote_redeemable) => { + let expected_quote_redeemable = perp_unrealized_pnl.checked_abs().unwrap().checked_add(I80F48::from_num(quote_minted)).unwrap().checked_to_num::().unwrap(); + prop_assert_eq!(quote_redeemable, expected_quote_redeemable) + }, + Err(_error) => prop_assert!(false) + } + } + } +} diff --git a/scripts/swap_ci_resident_program_id.sh b/scripts/swap_ci_resident_program_id.sh index 63f5e6c0e..274dab50d 100755 --- a/scripts/swap_ci_resident_program_id.sh +++ b/scripts/swap_ci_resident_program_id.sh @@ -15,3 +15,5 @@ echo $CI_RESIDENT_PROGRAM_PUBKEY sed -i.bak "s/$OLD_PUBKEY/$CI_RESIDENT_PROGRAM_PUBKEY/g" ./Anchor.toml sed -i.bak "s/$OLD_PUBKEY/$CI_RESIDENT_PROGRAM_PUBKEY/g" ./programs/uxd/src/lib.rs sed -i.bak "s/$OLD_PUBKEY/$CI_RESIDENT_PROGRAM_PUBKEY/g" ./target/idl/uxd.json +sed -i.bak "s/jsonIdl\[\"metadata\"\]\[\"address\"\]/\"$CI_RESIDENT_PROGRAM_PUBKEY\"/g" ./tests/constants.ts + diff --git a/target/deploy/bank-keypair.json b/target/deploy/bank-keypair.json index 0c4fd0a04..dbff3c3fc 100644 --- a/target/deploy/bank-keypair.json +++ b/target/deploy/bank-keypair.json @@ -1 +1,66 @@ -[219, 139, 131, 236, 34, 125, 165, 13, 18, 248, 93, 160, 73, 236, 214, 251, 179, 235, 124, 126, 56, 47, 222, 28, 166, 239, 130, 126, 66, 127, 26, 187, 207, 173, 205, 133, 48, 102, 2, 219, 20, 234, 72, 102, 53, 122, 175, 166, 198, 11, 198, 248, 59, 40, 137, 208, 193, 138, 197, 171, 147, 124, 212, 175] \ No newline at end of file +[ + 219, + 139, + 131, + 236, + 34, + 125, + 165, + 13, + 18, + 248, + 93, + 160, + 73, + 236, + 214, + 251, + 179, + 235, + 124, + 126, + 56, + 47, + 222, + 28, + 166, + 239, + 130, + 126, + 66, + 127, + 26, + 187, + 207, + 173, + 205, + 133, + 48, + 102, + 2, + 219, + 20, + 234, + 72, + 102, + 53, + 122, + 175, + 166, + 198, + 11, + 198, + 248, + 59, + 40, + 137, + 208, + 193, + 138, + 197, + 171, + 147, + 124, + 212, + 175 +] \ No newline at end of file diff --git a/target/deploy/ci-resident-keypair.json b/target/deploy/ci-resident-keypair.json index 7df887e7c..3661d305f 100644 --- a/target/deploy/ci-resident-keypair.json +++ b/target/deploy/ci-resident-keypair.json @@ -1 +1 @@ -[155,189,75,163,132,105,3,93,21,131,109,79,187,49,118,18,106,226,154,14,140,115,25,15,234,167,223,68,195,231,133,7,60,141,180,160,93,185,58,148,189,85,42,80,158,172,251,75,57,112,53,241,92,227,54,72,69,152,147,6,156,47,46,24] \ No newline at end of file +[232,49,77,232,79,47,2,254,45,237,134,238,207,198,143,169,127,42,253,26,126,56,116,127,41,168,2,125,84,57,58,151,153,152,154,161,45,64,211,109,156,117,227,24,34,249,101,195,225,140,235,67,3,71,196,205,202,254,249,122,122,160,255,189] \ No newline at end of file diff --git a/target/deploy/ci-resident-upgrade-authority.json b/target/deploy/ci-resident-upgrade-authority.json index 81d643013..41fc08e53 100644 --- a/target/deploy/ci-resident-upgrade-authority.json +++ b/target/deploy/ci-resident-upgrade-authority.json @@ -1 +1,66 @@ -[47,203,250,19,211,165,131,225,193,174,47,206,16,81,156,164,7,108,165,244,100,69,105,72,216,189,129,72,238,54,199,167,84,62,202,121,77,151,94,223,102,203,45,120,210,152,78,113,243,91,82,181,82,92,19,249,21,61,235,3,95,141,62,66] \ No newline at end of file +[ + 74, + 59, + 79, + 46, + 128, + 75, + 89, + 204, + 121, + 127, + 18, + 102, + 232, + 87, + 21, + 136, + 217, + 189, + 22, + 224, + 120, + 220, + 138, + 72, + 118, + 212, + 12, + 116, + 250, + 250, + 185, + 41, + 48, + 6, + 44, + 231, + 197, + 91, + 234, + 57, + 187, + 209, + 203, + 30, + 122, + 178, + 21, + 210, + 64, + 188, + 205, + 184, + 112, + 160, + 124, + 100, + 52, + 155, + 15, + 74, + 141, + 44, + 153, + 183 +] \ No newline at end of file diff --git a/target/deploy/uxd-keypair.json b/target/deploy/uxd-keypair.json index 32e3bf38b..edaf35d5f 100644 --- a/target/deploy/uxd-keypair.json +++ b/target/deploy/uxd-keypair.json @@ -1,66 +1 @@ -[ - 208, - 119, - 33, - 222, - 104, - 39, - 255, - 21, - 180, - 150, - 68, - 181, - 155, - 255, - 145, - 29, - 167, - 214, - 134, - 114, - 111, - 16, - 17, - 126, - 56, - 82, - 122, - 146, - 231, - 35, - 173, - 82, - 150, - 232, - 225, - 56, - 48, - 245, - 12, - 39, - 189, - 69, - 219, - 231, - 231, - 156, - 224, - 77, - 224, - 178, - 127, - 209, - 236, - 59, - 40, - 66, - 50, - 91, - 179, - 111, - 126, - 66, - 170, - 125 -] \ No newline at end of file +[101,24,129,24,132,24,161,57,235,119,215,58,159,209,131,87,85,79,236,247,129,177,200,121,220,251,90,115,150,22,78,210,238,170,241,124,115,101,153,58,67,213,55,132,215,172,134,126,253,224,224,153,166,160,254,205,68,16,33,132,20,13,64,92] diff --git a/target/idl/uxd.json b/target/idl/uxd.json index d8738012b..130a95e31 100644 --- a/target/idl/uxd.json +++ b/target/idl/uxd.json @@ -1,5 +1,5 @@ { - "version": "3.0.2", + "version": "3.1.0", "name": "uxd", "instructions": [ { @@ -124,7 +124,7 @@ "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -174,23 +174,13 @@ "isMut": true, "isSigner": false }, - { - "name": "collateralMint", - "isMut": false, - "isSigner": false - }, - { - "name": "quoteMint", - "isMut": false, - "isSigner": false - }, { "name": "authorityQuote", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -201,12 +191,12 @@ }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -255,23 +245,13 @@ "isMut": true, "isSigner": false }, - { - "name": "collateralMint", - "isMut": false, - "isSigner": false - }, - { - "name": "quoteMint", - "isMut": false, - "isSigner": false - }, { "name": "authorityQuote", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -292,7 +272,7 @@ }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -372,7 +352,7 @@ "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -383,17 +363,17 @@ }, { "name": "mangoGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBankQuote", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -408,7 +388,7 @@ }, { "name": "mangoRootBankCollateral", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -451,20 +431,10 @@ "isMut": false, "isSigner": false }, - { - "name": "associatedTokenProgram", - "isMut": false, - "isSigner": false - }, { "name": "mangoProgram", "isMut": false, "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false } ], "args": [ @@ -479,8 +449,8 @@ } }, { - "name": "slippage", - "type": "u32" + "name": "limitPrice", + "type": "f32" } ] }, @@ -512,11 +482,6 @@ "isMut": true, "isSigner": false }, - { - "name": "collateralMint", - "isMut": false, - "isSigner": false - }, { "name": "userCollateral", "isMut": true, @@ -528,7 +493,7 @@ "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -539,12 +504,12 @@ }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -587,20 +552,10 @@ "isMut": false, "isSigner": false }, - { - "name": "associatedTokenProgram", - "isMut": false, - "isSigner": false - }, { "name": "mangoProgram", "isMut": false, "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false } ], "args": [ @@ -609,8 +564,8 @@ "type": "u64" }, { - "name": "slippage", - "type": "u32" + "name": "limitPrice", + "type": "f32" } ] }, @@ -619,7 +574,7 @@ "accounts": [ { "name": "user", - "isMut": false, + "isMut": true, "isSigner": true }, { @@ -658,18 +613,18 @@ "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, { "name": "mangoGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -679,7 +634,7 @@ }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -722,6 +677,106 @@ "isMut": false, "isSigner": false }, + { + "name": "mangoProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "redeemableAmount", + "type": "u64" + }, + { + "name": "limitPrice", + "type": "f32" + } + ] + }, + { + "name": "quoteMintWithMangoDepository", + "accounts": [ + { + "name": "user", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + }, + { + "name": "redeemableMint", + "isMut": true, + "isSigner": false + }, + { + "name": "userQuote", + "isMut": true, + "isSigner": false + }, + { + "name": "userRedeemable", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoRootBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, { "name": "associatedTokenProgram", "isMut": false, @@ -740,100 +795,461 @@ ], "args": [ { - "name": "redeemableAmount", + "name": "quoteAmount", "type": "u64" - }, - { - "name": "slippage", - "type": "u32" } ] - } - ], - "accounts": [ - { - "name": "Controller", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "redeemableMintBump", - "type": "u8" - }, - { - "name": "version", - "type": "u8" - }, - { - "name": "authority", - "type": "publicKey" - }, - { - "name": "redeemableMint", - "type": "publicKey" - }, - { - "name": "redeemableMintDecimals", - "type": "u8" - }, - { - "name": "registeredMangoDepositories", - "type": { - "array": [ - "publicKey", - 8 - ] - } - }, - { - "name": "registeredMangoDepositoriesCount", - "type": "u8" - }, - { - "name": "redeemableGlobalSupplyCap", - "type": "u128" - }, - { - "name": "mangoDepositoriesRedeemableSoftCap", - "type": "u64" - }, - { - "name": "redeemableCirculatingSupply", - "type": "u128" - }, - { - "name": "reserved", - "type": { - "defined": "ControllerPadding" - } - } - ] - } }, { - "name": "MangoDepository", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "unused", - "type": { - "array": [ - "u8", - 2 - ] - } + "name": "quoteRedeemFromMangoDepository", + "accounts": [ + { + "name": "user", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + }, + { + "name": "redeemableMint", + "isMut": true, + "isSigner": false + }, + { + "name": "quoteMint", + "isMut": false, + "isSigner": false + }, + { + "name": "userQuote", + "isMut": true, + "isSigner": false + }, + { + "name": "userRedeemable", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoRootBank", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "redeemableAmount", + "type": "u64" + } + ] + }, + { + "name": "setMangoDepositoryQuoteMintAndRedeemFee", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "quoteFee", + "type": "u8" + } + ] + }, + { + "name": "disableDepositoryMinting", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "disableMinting", + "type": "bool" + } + ] + }, + { + "name": "createDepositoryMsolConfig", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": false, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "targetLiquidityRatio", + "type": "u16" + } + ] + }, + { + "name": "enableMsolSwap", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": false, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "enable", + "type": "bool" + } + ] + }, + { + "name": "setMsolLiquidityRatio", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": false, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "targetLiquidityRatio", + "type": "u16" + } + ] + }, + { + "name": "rebalanceMangoDepositoryMsolRatio", + "accounts": [ + { + "name": "user", + "isMut": true, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoSolRootBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSolNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSolVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoMsolRootBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoMsolNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoMsolVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "marinadeState", + "isMut": true, + "isSigner": false + }, + { + "name": "msolMint", + "isMut": true, + "isSigner": false + }, + { + "name": "msolMintAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "liqPoolSolLegPda", + "isMut": true, + "isSigner": false + }, + { + "name": "liqPoolMsolLeg", + "isMut": true, + "isSigner": false + }, + { + "name": "liqPoolMsolLegAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "treasuryMsolAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "reservePda", + "isMut": true, + "isSigner": false + }, + { + "name": "solPassthroughAta", + "isMut": true, + "isSigner": false + }, + { + "name": "msolPassthroughAta", + "isMut": true, + "isSigner": false + }, + { + "name": "marinadeFinanceProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [] + } + ], + "accounts": [ + { + "name": "Controller", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" }, { - "name": "mangoAccountBump", + "name": "redeemableMintBump", "type": "u8" }, { @@ -841,326 +1257,209 @@ "type": "u8" }, { - "name": "collateralMint", + "name": "authority", "type": "publicKey" }, { - "name": "collateralMintDecimals", - "type": "u8" - }, - { - "name": "unused2", - "type": { - "array": [ - "u8", - 32 - ] - } + "name": "redeemableMint", + "type": "publicKey" }, { - "name": "quoteMint", - "type": "publicKey" + "name": "redeemableMintDecimals", + "type": "u8" }, { - "name": "unused3", + "name": "registeredMangoDepositories", "type": { "array": [ - "u8", - 32 + "publicKey", + 8 ] } }, { - "name": "quoteMintDecimals", + "name": "registeredMangoDepositoriesCount", "type": "u8" }, { - "name": "mangoAccount", - "type": "publicKey" - }, - { - "name": "controller", - "type": "publicKey" - }, - { - "name": "insuranceAmountDeposited", - "type": "u128" - }, - { - "name": "collateralAmountDeposited", - "type": "u128" - }, - { - "name": "redeemableAmountUnderManagement", + "name": "redeemableGlobalSupplyCap", "type": "u128" }, { - "name": "totalAmountPaidTakerFee", - "type": "u128" + "name": "mangoDepositoriesRedeemableSoftCap", + "type": "u64" }, { - "name": "totalAmountRebalanced", + "name": "redeemableCirculatingSupply", "type": "u128" - }, - { - "name": "reserved", - "type": { - "defined": "MangoDepositoryPadding" - } - } - ] - } - } - ], - "types": [ - { - "name": "SourceFileId", - "type": { - "kind": "enum", - "variants": [ - { - "name": "InstructionInitializeController" - }, - { - "name": "InstructionSetRedeemableGlobalSupplyCap" - }, - { - "name": "InstructionSetMangoDepositoriesRedeemableSoftCap" - }, - { - "name": "InstructionRegisterMangoDepository" - }, - { - "name": "InstructionMangoDexMintWithMangoDepository" - }, - { - "name": "InstructionMangoDexRedeemFromMangoDepository" - }, - { - "name": "InstructionMangoDexDepositInsuranceToMangoDepository" - }, - { - "name": "InstructionMangoDexWithdrawInsuranceFromMangoDepository" - }, - { - "name": "MangoProgramAnchorMango" - }, - { - "name": "MangoProgramDeposit" - }, - { - "name": "MangoProgramInitMangoAccount" - }, - { - "name": "MangoProgramPlacePerpOrder" - }, - { - "name": "MangoProgramWithdraw" - }, - { - "name": "MangoUtilsLimitUtils" - }, - { - "name": "MangoUtilsOrderDelta" - }, - { - "name": "MangoUtilsOrder" - }, - { - "name": "MangoUtilsPerpAccountUtils" - }, - { - "name": "MangoUtilsPerpInfo" - }, - { - "name": "StateController" - }, - { - "name": "StateMangoDepository" - }, - { - "name": "Error" - }, - { - "name": "Lib" - }, - { - "name": "InstructionMangoDexRebalanceMangoDepositoryLite" - }, - { - "name": "InstructionMangoDexMigrateMangoDepositoryToV2" - } - ] - } - }, - { - "name": "UxdError", - "type": { - "kind": "enum", - "variants": [ - { - "name": "ProgramError", - "fields": [ - { - "defined": "ProgramError" - } - ] - }, - { - "name": "UxdErrorCode", - "fields": [ - { - "name": "uxd_error_code", - "type": { - "defined": "UxdErrorCode" - } - }, - { - "name": "line", - "type": "u32" - }, - { - "name": "source_file_id", - "type": { - "defined": "SourceFileId" - } - } - ] } ] } }, { - "name": "UxdErrorCode", + "name": "MangoDepository", "type": { - "kind": "enum", - "variants": [ - { - "name": "InvalidRedeemableMintDecimals" - }, - { - "name": "InvalidRedeemableGlobalSupplyCap" - }, - { - "name": "RootBankIndexNotFound" - }, - { - "name": "InvalidSlippage" - }, - { - "name": "EffectiveOrderPriceBeyondLimitPrice" - }, - { - "name": "InvalidCollateralAmount" - }, - { - "name": "InsufficientCollateralAmount" - }, + "kind": "struct", + "fields": [ { - "name": "InvalidRedeemableAmount" + "name": "bump", + "type": "u8" }, { - "name": "InsufficientRedeemableAmount" + "name": "unused", + "type": { + "array": [ + "u8", + 2 + ] + } }, { - "name": "PerpOrderPartiallyFilled" + "name": "mangoAccountBump", + "type": "u8" }, { - "name": "RedeemableGlobalSupplyCapReached" + "name": "version", + "type": "u8" }, { - "name": "MangoDepositoriesSoftCapOverflow" + "name": "collateralMint", + "type": "publicKey" }, { - "name": "MaxNumberOfMangoDepositoriesRegisteredReached" + "name": "collateralMintDecimals", + "type": "u8" }, { - "name": "InvalidInsuranceAmount" + "name": "unused2", + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "InsufficientAuthorityInsuranceAmount" + "name": "quoteMint", + "type": "publicKey" }, { - "name": "InvalidRebalancedAmount" + "name": "unused3", + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "InsufficientOrderBookDepth" + "name": "quoteMintDecimals", + "type": "u8" }, { - "name": "InvalidExecutedOrderSize" + "name": "mangoAccount", + "type": "publicKey" }, { - "name": "MangoPerpMarketIndexNotFound" + "name": "controller", + "type": "publicKey" }, { - "name": "InvalidMangoDepositoriesRedeemableSoftCap" + "name": "insuranceAmountDeposited", + "type": "u128" }, { - "name": "InvalidQuoteDelta" + "name": "collateralAmountDeposited", + "type": "u128" }, { - "name": "InvalidOrderDirection" + "name": "redeemableAmountUnderManagement", + "type": "u128" }, { - "name": "MathError" + "name": "totalAmountPaidTakerFee", + "type": "u128" }, { - "name": "SlippageReached" + "name": "totalAmountRebalanced", + "type": "u128" }, { - "name": "InvalidRebalancingAmount" + "name": "netQuoteMinted", + "type": "i128" }, { - "name": "InsufficientQuoteAmount" + "name": "quoteMintAndRedeemFee", + "type": "u8" }, { - "name": "InvalidPnlPolarity" + "name": "totalQuoteMintAndRedeemFees", + "type": "u128" }, { - "name": "RebalancingError" - }, + "name": "mintingDisabled", + "type": "bool" + } + ] + } + }, + { + "name": "MSolConfig", + "type": { + "kind": "struct", + "fields": [ { - "name": "BumpError" + "name": "bump", + "type": "u8" }, { - "name": "OrderSizeBelowMinLotSize" + "name": "depository", + "type": "publicKey" }, { - "name": "InvalidCollateralDelta" + "name": "controller", + "type": "publicKey" }, { - "name": "QuantityBelowContractSize" + "name": "enabled", + "type": "bool" }, { - "name": "Default" + "name": "targetLiquidityRatio", + "type": "u16" } ] } - }, + } + ], + "types": [ { - "name": "AccountingEvent", + "name": "PnlPolarity", "type": { "kind": "enum", "variants": [ { - "name": "Deposit" + "name": "Positive" }, { - "name": "Withdraw" + "name": "Negative" } ] } }, { - "name": "PnlPolarity", + "name": "RebalanceRoute", "type": { "kind": "enum", "variants": [ { - "name": "Positive" + "name": "Deposit" }, { - "name": "Negative" + "name": "LiquidUnstake" + }, + { + "name": "NoSwapRequired" } ] } @@ -1313,42 +1612,7 @@ ] }, { - "name": "DepositInsuranceToMangoDepositoryEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false - }, - { - "name": "controller", - "type": "publicKey", - "index": false - }, - { - "name": "depository", - "type": "publicKey", - "index": false - }, - { - "name": "insuranceMint", - "type": "publicKey", - "index": false - }, - { - "name": "insuranceMintDecimals", - "type": "u8", - "index": false - }, - { - "name": "depositedAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "DepositInsuranceToMangoDepositoryEventV2", + "name": "DepositInsuranceToDepositoryEvent", "fields": [ { "name": "version", @@ -1418,7 +1682,7 @@ ] }, { - "name": "WithdrawInsuranceFromMangoDepositoryEventV2", + "name": "WithdrawInsuranceFromDepositoryEvent", "fields": [ { "name": "version", @@ -1481,29 +1745,29 @@ "index": false }, { - "name": "slippage", - "type": "u32", + "name": "limitPrice", + "type": "f32", "index": false }, { - "name": "collateralDelta", - "type": "u64", + "name": "baseDelta", + "type": "i64", "index": false }, { - "name": "redeemableDelta", - "type": "u64", + "name": "quoteDelta", + "type": "i64", "index": false }, { "name": "feeDelta", - "type": "u64", + "type": "i64", "index": false } ] }, { - "name": "RedeemFromMangoDepositoryEvent", + "name": "RedeemFromDepositoryEvent", "fields": [ { "name": "version", @@ -1531,23 +1795,23 @@ "index": false }, { - "name": "slippage", - "type": "u32", + "name": "limitPrice", + "type": "f32", "index": false }, { - "name": "collateralDelta", - "type": "u64", + "name": "baseDelta", + "type": "i64", "index": false }, { - "name": "redeemableDelta", - "type": "u64", + "name": "quoteDelta", + "type": "i64", "index": false }, { "name": "feeDelta", - "type": "u64", + "type": "i64", "index": false } ] @@ -1598,23 +1862,58 @@ "index": false }, { - "name": "slippage", - "type": "u32", + "name": "limitPrice", + "type": "f32", "index": false }, { - "name": "collateralDelta", - "type": "u64", + "name": "baseDelta", + "type": "i64", "index": false }, { "name": "quoteDelta", - "type": "u64", + "type": "i64", "index": false }, { "name": "feeDelta", - "type": "u64", + "type": "i64", + "index": false + } + ] + }, + { + "name": "CreateDepositoryMSolConfigEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "msolConfig", + "type": "publicKey", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "enabled", + "type": "bool", + "index": false + }, + { + "name": "targetLiquidityRatio", + "type": "u16", "index": false } ] @@ -1623,46 +1922,293 @@ "errors": [ { "code": 6000, + "name": "InvalidRedeemableMintDecimals", + "msg": "The redeemable mint decimals must be between 0 and 9 (inclusive)." + }, + { + "code": 6001, + "name": "InvalidRedeemableGlobalSupplyCap", + "msg": "Redeemable global supply above." + }, + { + "code": 6002, + "name": "RootBankIndexNotFound", + "msg": "The associated mango root bank index cannot be found for the deposited coin.." + }, + { + "code": 6003, + "name": "InvalidLimitPrice", + "msg": "The provided limit_price value is invalid, must be > 0" + }, + { + "code": 6004, + "name": "EffectiveOrderPriceBeyondLimitPrice", + "msg": "Could not fill the order given order book state and provided slippage." + }, + { + "code": 6005, + "name": "InvalidCollateralAmount", + "msg": "Collateral amount cannot be 0" + }, + { + "code": 6006, + "name": "InvalidQuoteAmount", + "msg": "Quote amount must be > 0 in order to mint." + }, + { + "code": 6007, + "name": "InvalidRedeemableAmount", + "msg": "Redeemable amount must be > 0 in order to redeem." + }, + { + "code": 6008, + "name": "InsufficientCollateralAmount", + "msg": "The balance of the collateral ATA is not enough to fulfill the mint operation." + }, + { + "code": 6009, + "name": "InsufficientQuoteAmountMint", + "msg": "The balance of the quote ATA is not enough to fulfil the mint operation." + }, + { + "code": 6010, + "name": "InsufficientRedeemableAmountMint", + "msg": "The balance of the redeemable ATA is not enough to fulfil the redeem operation." + }, + { + "code": 6011, + "name": "InsufficientRedeemableAmount", + "msg": "The balance of the redeemable ATA is not enough to fulfill the redeem operation." + }, + { + "code": 6012, + "name": "PerpOrderPartiallyFilled", + "msg": "The perp position could not be fully filled with the provided slippage." + }, + { + "code": 6013, + "name": "RedeemableGlobalSupplyCapReached", + "msg": "Minting amount would go past the Redeemable Global Supply Cap." + }, + { + "code": 6014, + "name": "MangoDepositoriesSoftCapOverflow", + "msg": "Operation not allowed due to being over the Mango Redeemable soft Cap." + }, + { + "code": 6015, + "name": "MaxNumberOfMangoDepositoriesRegisteredReached", + "msg": "Cannot register more mango depositories, the limit has been reached." + }, + { + "code": 6016, + "name": "InvalidInsuranceAmount", + "msg": "The amount to withdraw from the Insurance Fund must be superior to zero.." + }, + { + "code": 6017, + "name": "InsufficientAuthorityQuoteAmount", + "msg": "The Quote ATA from authority doesn't have enough balance." + }, + { + "code": 6018, + "name": "InvalidRebalancedAmount", + "msg": "The rebalanced amount must be superior to zero.." + }, + { + "code": 6019, + "name": "InsufficientOrderBookDepth", + "msg": "Insufficient order book depth for order." + }, + { + "code": 6020, + "name": "InvalidExecutedOrderSize", + "msg": "The executed order size does not match the expected one." + }, + { + "code": 6021, + "name": "InvalidMangoDepositoriesRedeemableSoftCap", + "msg": "Mango depositories redeemable soft cap above." + }, + { + "code": 6022, + "name": "InvalidQuoteDelta", + "msg": "Quote_lot_delta can't be 0." + }, + { + "code": 6023, + "name": "InvalidOrderDirection", + "msg": "The perp order wasn't executed in the right direction." + }, + { + "code": 6024, + "name": "MathError", + "msg": "Math error." + }, + { + "code": 6025, + "name": "SlippageReached", + "msg": "The order couldn't be executed with the provided slippage." + }, + { + "code": 6026, + "name": "InvalidRebalancingAmount", + "msg": "The rebalancing amount must be above 0." + }, + { + "code": 6027, + "name": "InsufficientQuoteAmount", + "msg": "The Quote amount in the provided user_quote ATA must be >= max_amount_rebalancing." + }, + { + "code": 6028, + "name": "InvalidPnlPolarity", + "msg": "The PnL polarity provided is not the same as the perp position's one." + }, + { + "code": 6029, + "name": "RebalancingError", + "msg": "The rebalanced amount doesn't match the expected rebalance amount." + }, + { + "code": 6030, + "name": "BumpError", + "msg": "A bump was expected but is missing." + }, + { + "code": 6031, + "name": "OrderSizeBelowMinLotSize", + "msg": "The order is below size is below the min lot size." + }, + { + "code": 6032, + "name": "InvalidCollateralDelta", + "msg": "The collateral delta post perp order doesn't match the planned one." + }, + { + "code": 6033, + "name": "MangoPerpMarketIndexNotFound", + "msg": "The perp market index could not be found for this MangoMarkets Pair." + }, + { + "code": 6034, + "name": "InvalidMangoGroup", + "msg": "Could not load the provided MangoGroup account." + }, + { + "code": 6035, + "name": "QuantityBelowContractSize", + "msg": "The order quantity is below contract_size of the perp market." + }, + { + "code": 6036, + "name": "QuoteAmountTooHigh", + "msg": "The amount trying to be quote minted is larger than quote mintable." + }, + { + "code": 6037, + "name": "RedeemableAmountTooHigh", + "msg": "The amount trying to be quote redeemed is larger than quote redeemable." + }, + { + "code": 6038, + "name": "MintingDisabled", + "msg": "Minting is disabled for the current depository" + }, + { + "code": 6039, + "name": "MintingAlreadyDisabledOrEnabled", + "msg": "Minting is already disabled/enabled" + }, + { + "code": 6040, + "name": "MSolSwappingDisabled", + "msg": "Msol swapping is disabled" + }, + { + "code": 6041, "name": "InvalidAuthority", "msg": "Only the Program initializer authority can access this instructions." }, { - "code": 6001, + "code": 6042, "name": "InvalidController", "msg": "The Depository's controller doesn't match the provided Controller." }, { - "code": 6002, + "code": 6043, "name": "InvalidDepository", "msg": "The Depository provided is not registered with the Controller." }, { - "code": 6003, + "code": 6044, "name": "InvalidCollateralMint", "msg": "The provided collateral mint does not match the depository's collateral mint." }, { - "code": 6004, + "code": 6045, "name": "InvalidQuoteMint", "msg": "The provided quote mint does not match the depository's quote mint." }, { - "code": 6005, - "name": "InvalidAuthorityQuoteATAMint", - "msg": "The authority's Quote ATA's mint does not match the Depository's one." - }, - { - "code": 6006, + "code": 6046, "name": "InvalidMangoAccount", "msg": "The Mango Account isn't the Depository one." }, { - "code": 6007, + "code": 6047, "name": "InvalidRedeemableMint", "msg": "The Redeemable Mint provided does not match the Controller's one." + }, + { + "code": 6048, + "name": "InvalidDexMarket", + "msg": "The provided perp_market is not the one tied to this Depository." + }, + { + "code": 6049, + "name": "InvalidOwner", + "msg": "The provided token account is not owner by the expected party." + }, + { + "code": 6050, + "name": "InvalidMaxBaseQuantity", + "msg": "The max base quantity must be above 0." + }, + { + "code": 6051, + "name": "InvalidMaxQuoteQuantity", + "msg": "The max quote quantity must be above 0." + }, + { + "code": 6052, + "name": "TargetLiquidityRatioExceedMax", + "msg": "Target liquidity ratio for msol config exceed 100%" + }, + { + "code": 6053, + "name": "InvalidEnablingMsolSwap", + "msg": "SOL/mSOL swap has already enabled / disabled" + }, + { + "code": 6054, + "name": "InvalidNonNativeMintUsed", + "msg": "Must use native mint for setting msol config" + }, + { + "code": 6055, + "name": "InvalidNonNativeMintAtaUsed", + "msg": "Must use native mint for passthrough account" + }, + { + "code": 6056, + "name": "InvalidNonMSolMintAtaUsed", + "msg": "Must use msol for passthrough account" + }, + { + "code": 6057, + "name": "Default", + "msg": "Default - Check the source code for more info" } - ], - "metadata": { - "address": "BA67esrWE7cPzQWtAftaTbrVWtmHZJ1PbbBBpZgpjH4p" - } + ] } \ No newline at end of file diff --git a/target/types/uxd.ts b/target/types/uxd.ts index b35e70402..690e9b9ae 100644 --- a/target/types/uxd.ts +++ b/target/types/uxd.ts @@ -1,5 +1,5 @@ export type Uxd = { - "version": "3.0.2", + "version": "3.1.0", "name": "uxd", "instructions": [ { @@ -124,7 +124,7 @@ export type Uxd = { "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -174,23 +174,13 @@ export type Uxd = { "isMut": true, "isSigner": false }, - { - "name": "collateralMint", - "isMut": false, - "isSigner": false - }, - { - "name": "quoteMint", - "isMut": false, - "isSigner": false - }, { "name": "authorityQuote", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -201,12 +191,12 @@ export type Uxd = { }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -255,23 +245,13 @@ export type Uxd = { "isMut": true, "isSigner": false }, - { - "name": "collateralMint", - "isMut": false, - "isSigner": false - }, - { - "name": "quoteMint", - "isMut": false, - "isSigner": false - }, { "name": "authorityQuote", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -292,7 +272,7 @@ export type Uxd = { }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -372,7 +352,7 @@ export type Uxd = { "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -383,17 +363,17 @@ export type Uxd = { }, { "name": "mangoGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBankQuote", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -408,7 +388,7 @@ export type Uxd = { }, { "name": "mangoRootBankCollateral", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -451,20 +431,10 @@ export type Uxd = { "isMut": false, "isSigner": false }, - { - "name": "associatedTokenProgram", - "isMut": false, - "isSigner": false - }, { "name": "mangoProgram", "isMut": false, "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false } ], "args": [ @@ -479,8 +449,8 @@ export type Uxd = { } }, { - "name": "slippage", - "type": "u32" + "name": "limitPrice", + "type": "f32" } ] }, @@ -512,11 +482,6 @@ export type Uxd = { "isMut": true, "isSigner": false }, - { - "name": "collateralMint", - "isMut": false, - "isSigner": false - }, { "name": "userCollateral", "isMut": true, @@ -528,7 +493,7 @@ export type Uxd = { "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -539,12 +504,12 @@ export type Uxd = { }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -587,20 +552,10 @@ export type Uxd = { "isMut": false, "isSigner": false }, - { - "name": "associatedTokenProgram", - "isMut": false, - "isSigner": false - }, { "name": "mangoProgram", "isMut": false, "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false } ], "args": [ @@ -609,8 +564,8 @@ export type Uxd = { "type": "u64" }, { - "name": "slippage", - "type": "u32" + "name": "limitPrice", + "type": "f32" } ] }, @@ -619,7 +574,7 @@ export type Uxd = { "accounts": [ { "name": "user", - "isMut": false, + "isMut": true, "isSigner": true }, { @@ -658,18 +613,18 @@ export type Uxd = { "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, { "name": "mangoGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoCache", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -679,7 +634,7 @@ export type Uxd = { }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -722,6 +677,106 @@ export type Uxd = { "isMut": false, "isSigner": false }, + { + "name": "mangoProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "redeemableAmount", + "type": "u64" + }, + { + "name": "limitPrice", + "type": "f32" + } + ] + }, + { + "name": "quoteMintWithMangoDepository", + "accounts": [ + { + "name": "user", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + }, + { + "name": "redeemableMint", + "isMut": true, + "isSigner": false + }, + { + "name": "userQuote", + "isMut": true, + "isSigner": false + }, + { + "name": "userRedeemable", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoRootBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, { "name": "associatedTokenProgram", "isMut": false, @@ -740,97 +795,524 @@ export type Uxd = { ], "args": [ { - "name": "redeemableAmount", + "name": "quoteAmount", "type": "u64" - }, - { - "name": "slippage", - "type": "u32" } ] - } - ], - "accounts": [ - { - "name": "controller", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "redeemableMintBump", - "type": "u8" - }, - { - "name": "version", - "type": "u8" - }, - { - "name": "authority", - "type": "publicKey" - }, - { - "name": "redeemableMint", - "type": "publicKey" - }, - { - "name": "redeemableMintDecimals", - "type": "u8" - }, - { - "name": "registeredMangoDepositories", - "type": { - "array": [ - "publicKey", - 8 - ] - } - }, - { - "name": "registeredMangoDepositoriesCount", - "type": "u8" - }, - { - "name": "redeemableGlobalSupplyCap", - "type": "u128" - }, - { - "name": "mangoDepositoriesRedeemableSoftCap", - "type": "u64" - }, - { - "name": "redeemableCirculatingSupply", - "type": "u128" - }, - { - "name": "reserved", - "type": { - "defined": "ControllerPadding" - } - } - ] - } }, { - "name": "mangoDepository", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bump", - "type": "u8" - }, - { - "name": "unused", - "type": { - "array": [ - "u8", - 2 - ] - } + "name": "quoteRedeemFromMangoDepository", + "accounts": [ + { + "name": "user", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + }, + { + "name": "redeemableMint", + "isMut": true, + "isSigner": false + }, + { + "name": "quoteMint", + "isMut": false, + "isSigner": false + }, + { + "name": "userQuote", + "isMut": true, + "isSigner": false + }, + { + "name": "userRedeemable", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoRootBank", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "redeemableAmount", + "type": "u64" + } + ] + }, + { + "name": "setMangoDepositoryQuoteMintAndRedeemFee", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "quoteFee", + "type": "u8" + } + ] + }, + { + "name": "disableDepositoryMinting", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "disableMinting", + "type": "bool" + } + ] + }, + { + "name": "createDepositoryMsolConfig", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": false, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "targetLiquidityRatio", + "type": "u16" + } + ] + }, + { + "name": "enableMsolSwap", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": false, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "enable", + "type": "bool" + } + ] + }, + { + "name": "setMsolLiquidityRatio", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": false, + "isSigner": false + }, + { + "name": "depository", + "isMut": false, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "targetLiquidityRatio", + "type": "u16" + } + ] + }, + { + "name": "rebalanceMangoDepositoryMsolRatio", + "accounts": [ + { + "name": "user", + "isMut": true, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "controller", + "isMut": true, + "isSigner": false + }, + { + "name": "depository", + "isMut": true, + "isSigner": false + }, + { + "name": "msolConfig", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoSolRootBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSolNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSolVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoMsolRootBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoMsolNodeBank", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoMsolVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "marinadeState", + "isMut": true, + "isSigner": false + }, + { + "name": "msolMint", + "isMut": true, + "isSigner": false + }, + { + "name": "msolMintAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "liqPoolSolLegPda", + "isMut": true, + "isSigner": false + }, + { + "name": "liqPoolMsolLeg", + "isMut": true, + "isSigner": false + }, + { + "name": "liqPoolMsolLegAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "treasuryMsolAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "reservePda", + "isMut": true, + "isSigner": false + }, + { + "name": "solPassthroughAta", + "isMut": true, + "isSigner": false + }, + { + "name": "msolPassthroughAta", + "isMut": true, + "isSigner": false + }, + { + "name": "marinadeFinanceProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [] + } + ], + "accounts": [ + { + "name": "controller", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + }, + { + "name": "redeemableMintBump", + "type": "u8" + }, + { + "name": "version", + "type": "u8" + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "redeemableMint", + "type": "publicKey" + }, + { + "name": "redeemableMintDecimals", + "type": "u8" + }, + { + "name": "registeredMangoDepositories", + "type": { + "array": [ + "publicKey", + 8 + ] + } + }, + { + "name": "registeredMangoDepositoriesCount", + "type": "u8" + }, + { + "name": "redeemableGlobalSupplyCap", + "type": "u128" + }, + { + "name": "mangoDepositoriesRedeemableSoftCap", + "type": "u64" + }, + { + "name": "redeemableCirculatingSupply", + "type": "u128" + } + ] + } + }, + { + "name": "mangoDepository", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + }, + { + "name": "unused", + "type": { + "array": [ + "u8", + 2 + ] + } }, { "name": "mangoAccountBump", @@ -902,792 +1384,1255 @@ export type Uxd = { "name": "totalAmountRebalanced", "type": "u128" }, - { - "name": "reserved", - "type": { - "defined": "MangoDepositoryPadding" - } - } - ] - } + { + "name": "netQuoteMinted", + "type": "i128" + }, + { + "name": "quoteMintAndRedeemFee", + "type": "u8" + }, + { + "name": "totalQuoteMintAndRedeemFees", + "type": "u128" + }, + { + "name": "mintingDisabled", + "type": "bool" + } + ] + } + }, + { + "name": "mSolConfig", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bump", + "type": "u8" + }, + { + "name": "depository", + "type": "publicKey" + }, + { + "name": "controller", + "type": "publicKey" + }, + { + "name": "enabled", + "type": "bool" + }, + { + "name": "targetLiquidityRatio", + "type": "u16" + } + ] + } + } + ], + "types": [ + { + "name": "PnlPolarity", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Positive" + }, + { + "name": "Negative" + } + ] + } + }, + { + "name": "RebalanceRoute", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Deposit" + }, + { + "name": "LiquidUnstake" + }, + { + "name": "NoSwapRequired" + } + ] + } + } + ], + "events": [ + { + "name": "InitializeControllerEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "authority", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "SetRedeemableGlobalSupplyCapEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "redeemableGlobalSupplyCap", + "type": "u128", + "index": false + } + ] + }, + { + "name": "RegisterMangoDepositoryEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "collateralMint", + "type": "publicKey", + "index": false + }, + { + "name": "insuranceMint", + "type": "publicKey", + "index": false + }, + { + "name": "mangoAccount", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "RegisterMangoDepositoryEventV2", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "depositoryVersion", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "collateralMint", + "type": "publicKey", + "index": false + }, + { + "name": "quoteMint", + "type": "publicKey", + "index": false + }, + { + "name": "mangoAccount", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "SetMangoDepositoryRedeemableSoftCapEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "redeemableMint", + "type": "publicKey", + "index": false + }, + { + "name": "redeemableMintDecimals", + "type": "u8", + "index": false + }, + { + "name": "redeemableSoftCap", + "type": "u64", + "index": false + } + ] + }, + { + "name": "DepositInsuranceToDepositoryEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "quoteMint", + "type": "publicKey", + "index": false + }, + { + "name": "quoteMintDecimals", + "type": "u8", + "index": false + }, + { + "name": "depositedAmount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "WithdrawInsuranceFromMangoDepositoryEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "insuranceMint", + "type": "publicKey", + "index": false + }, + { + "name": "insuranceMintDecimals", + "type": "u8", + "index": false + }, + { + "name": "withdrawnAmount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "WithdrawInsuranceFromDepositoryEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "quoteMint", + "type": "publicKey", + "index": false + }, + { + "name": "quoteMintDecimals", + "type": "u8", + "index": false + }, + { + "name": "withdrawnAmount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "MintWithMangoDepositoryEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "user", + "type": "publicKey", + "index": false + }, + { + "name": "collateralAmount", + "type": "u64", + "index": false + }, + { + "name": "limitPrice", + "type": "f32", + "index": false + }, + { + "name": "baseDelta", + "type": "i64", + "index": false + }, + { + "name": "quoteDelta", + "type": "i64", + "index": false + }, + { + "name": "feeDelta", + "type": "i64", + "index": false + } + ] + }, + { + "name": "RedeemFromDepositoryEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "user", + "type": "publicKey", + "index": false + }, + { + "name": "redeemableAmount", + "type": "u64", + "index": false + }, + { + "name": "limitPrice", + "type": "f32", + "index": false + }, + { + "name": "baseDelta", + "type": "i64", + "index": false + }, + { + "name": "quoteDelta", + "type": "i64", + "index": false + }, + { + "name": "feeDelta", + "type": "i64", + "index": false + } + ] + }, + { + "name": "RebalanceMangoDepositoryLiteEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "depositoryVersion", + "type": "u8", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "user", + "type": "publicKey", + "index": false + }, + { + "name": "polarity", + "type": { + "defined": "PnlPolarity" + }, + "index": false + }, + { + "name": "rebalancingAmount", + "type": "u64", + "index": false + }, + { + "name": "rebalancedAmount", + "type": "u64", + "index": false + }, + { + "name": "limitPrice", + "type": "f32", + "index": false + }, + { + "name": "baseDelta", + "type": "i64", + "index": false + }, + { + "name": "quoteDelta", + "type": "i64", + "index": false + }, + { + "name": "feeDelta", + "type": "i64", + "index": false + } + ] + }, + { + "name": "CreateDepositoryMSolConfigEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "msolConfig", + "type": "publicKey", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "enabled", + "type": "bool", + "index": false + }, + { + "name": "targetLiquidityRatio", + "type": "u16", + "index": false + } + ] } ], - "types": [ + "errors": [ { - "name": "SourceFileId", - "type": { - "kind": "enum", - "variants": [ - { - "name": "InstructionInitializeController" - }, - { - "name": "InstructionSetRedeemableGlobalSupplyCap" - }, - { - "name": "InstructionSetMangoDepositoriesRedeemableSoftCap" - }, - { - "name": "InstructionRegisterMangoDepository" - }, - { - "name": "InstructionMangoDexMintWithMangoDepository" - }, - { - "name": "InstructionMangoDexRedeemFromMangoDepository" - }, - { - "name": "InstructionMangoDexDepositInsuranceToMangoDepository" - }, - { - "name": "InstructionMangoDexWithdrawInsuranceFromMangoDepository" - }, - { - "name": "MangoProgramAnchorMango" - }, - { - "name": "MangoProgramDeposit" - }, - { - "name": "MangoProgramInitMangoAccount" - }, - { - "name": "MangoProgramPlacePerpOrder" - }, - { - "name": "MangoProgramWithdraw" - }, - { - "name": "MangoUtilsLimitUtils" - }, - { - "name": "MangoUtilsOrderDelta" - }, - { - "name": "MangoUtilsOrder" - }, - { - "name": "MangoUtilsPerpAccountUtils" - }, - { - "name": "MangoUtilsPerpInfo" - }, - { - "name": "StateController" - }, - { - "name": "StateMangoDepository" - }, - { - "name": "Error" - }, - { - "name": "Lib" - }, - { - "name": "InstructionMangoDexRebalanceMangoDepositoryLite" - }, - { - "name": "InstructionMangoDexMigrateMangoDepositoryToV2" - } - ] - } + "code": 6000, + "name": "InvalidRedeemableMintDecimals", + "msg": "The redeemable mint decimals must be between 0 and 9 (inclusive)." }, { - "name": "UxdError", - "type": { - "kind": "enum", - "variants": [ - { - "name": "ProgramError", - "fields": [ - { - "defined": "ProgramError" - } - ] - }, - { - "name": "UxdErrorCode", - "fields": [ - { - "name": "uxd_error_code", - "type": { - "defined": "UxdErrorCode" - } - }, - { - "name": "line", - "type": "u32" - }, - { - "name": "source_file_id", - "type": { - "defined": "SourceFileId" - } - } - ] - } - ] - } + "code": 6001, + "name": "InvalidRedeemableGlobalSupplyCap", + "msg": "Redeemable global supply above." }, { - "name": "UxdErrorCode", - "type": { - "kind": "enum", - "variants": [ - { - "name": "InvalidRedeemableMintDecimals" - }, - { - "name": "InvalidRedeemableGlobalSupplyCap" - }, - { - "name": "RootBankIndexNotFound" - }, - { - "name": "InvalidSlippage" - }, - { - "name": "EffectiveOrderPriceBeyondLimitPrice" - }, - { - "name": "InvalidCollateralAmount" - }, - { - "name": "InsufficientCollateralAmount" - }, - { - "name": "InvalidRedeemableAmount" - }, - { - "name": "InsufficientRedeemableAmount" - }, - { - "name": "PerpOrderPartiallyFilled" - }, - { - "name": "RedeemableGlobalSupplyCapReached" - }, - { - "name": "MangoDepositoriesSoftCapOverflow" - }, - { - "name": "MaxNumberOfMangoDepositoriesRegisteredReached" - }, - { - "name": "InvalidInsuranceAmount" - }, - { - "name": "InsufficientAuthorityInsuranceAmount" - }, - { - "name": "InvalidRebalancedAmount" - }, - { - "name": "InsufficientOrderBookDepth" - }, - { - "name": "InvalidExecutedOrderSize" - }, - { - "name": "MangoPerpMarketIndexNotFound" - }, - { - "name": "InvalidMangoDepositoriesRedeemableSoftCap" - }, - { - "name": "InvalidQuoteDelta" - }, - { - "name": "InvalidOrderDirection" - }, - { - "name": "MathError" - }, - { - "name": "SlippageReached" - }, - { - "name": "InvalidRebalancingAmount" - }, - { - "name": "InsufficientQuoteAmount" - }, - { - "name": "InvalidPnlPolarity" - }, - { - "name": "RebalancingError" - }, - { - "name": "BumpError" - }, - { - "name": "OrderSizeBelowMinLotSize" - }, - { - "name": "InvalidCollateralDelta" - }, - { - "name": "QuantityBelowContractSize" - }, - { - "name": "Default" - } - ] - } + "code": 6002, + "name": "RootBankIndexNotFound", + "msg": "The associated mango root bank index cannot be found for the deposited coin.." + }, + { + "code": 6003, + "name": "InvalidLimitPrice", + "msg": "The provided limit_price value is invalid, must be > 0" + }, + { + "code": 6004, + "name": "EffectiveOrderPriceBeyondLimitPrice", + "msg": "Could not fill the order given order book state and provided slippage." + }, + { + "code": 6005, + "name": "InvalidCollateralAmount", + "msg": "Collateral amount cannot be 0" + }, + { + "code": 6006, + "name": "InvalidQuoteAmount", + "msg": "Quote amount must be > 0 in order to mint." + }, + { + "code": 6007, + "name": "InvalidRedeemableAmount", + "msg": "Redeemable amount must be > 0 in order to redeem." + }, + { + "code": 6008, + "name": "InsufficientCollateralAmount", + "msg": "The balance of the collateral ATA is not enough to fulfill the mint operation." + }, + { + "code": 6009, + "name": "InsufficientQuoteAmountMint", + "msg": "The balance of the quote ATA is not enough to fulfil the mint operation." + }, + { + "code": 6010, + "name": "InsufficientRedeemableAmountMint", + "msg": "The balance of the redeemable ATA is not enough to fulfil the redeem operation." + }, + { + "code": 6011, + "name": "InsufficientRedeemableAmount", + "msg": "The balance of the redeemable ATA is not enough to fulfill the redeem operation." + }, + { + "code": 6012, + "name": "PerpOrderPartiallyFilled", + "msg": "The perp position could not be fully filled with the provided slippage." + }, + { + "code": 6013, + "name": "RedeemableGlobalSupplyCapReached", + "msg": "Minting amount would go past the Redeemable Global Supply Cap." + }, + { + "code": 6014, + "name": "MangoDepositoriesSoftCapOverflow", + "msg": "Operation not allowed due to being over the Mango Redeemable soft Cap." + }, + { + "code": 6015, + "name": "MaxNumberOfMangoDepositoriesRegisteredReached", + "msg": "Cannot register more mango depositories, the limit has been reached." + }, + { + "code": 6016, + "name": "InvalidInsuranceAmount", + "msg": "The amount to withdraw from the Insurance Fund must be superior to zero.." + }, + { + "code": 6017, + "name": "InsufficientAuthorityQuoteAmount", + "msg": "The Quote ATA from authority doesn't have enough balance." + }, + { + "code": 6018, + "name": "InvalidRebalancedAmount", + "msg": "The rebalanced amount must be superior to zero.." + }, + { + "code": 6019, + "name": "InsufficientOrderBookDepth", + "msg": "Insufficient order book depth for order." + }, + { + "code": 6020, + "name": "InvalidExecutedOrderSize", + "msg": "The executed order size does not match the expected one." + }, + { + "code": 6021, + "name": "InvalidMangoDepositoriesRedeemableSoftCap", + "msg": "Mango depositories redeemable soft cap above." + }, + { + "code": 6022, + "name": "InvalidQuoteDelta", + "msg": "Quote_lot_delta can't be 0." + }, + { + "code": 6023, + "name": "InvalidOrderDirection", + "msg": "The perp order wasn't executed in the right direction." + }, + { + "code": 6024, + "name": "MathError", + "msg": "Math error." + }, + { + "code": 6025, + "name": "SlippageReached", + "msg": "The order couldn't be executed with the provided slippage." + }, + { + "code": 6026, + "name": "InvalidRebalancingAmount", + "msg": "The rebalancing amount must be above 0." + }, + { + "code": 6027, + "name": "InsufficientQuoteAmount", + "msg": "The Quote amount in the provided user_quote ATA must be >= max_amount_rebalancing." + }, + { + "code": 6028, + "name": "InvalidPnlPolarity", + "msg": "The PnL polarity provided is not the same as the perp position's one." + }, + { + "code": 6029, + "name": "RebalancingError", + "msg": "The rebalanced amount doesn't match the expected rebalance amount." + }, + { + "code": 6030, + "name": "BumpError", + "msg": "A bump was expected but is missing." + }, + { + "code": 6031, + "name": "OrderSizeBelowMinLotSize", + "msg": "The order is below size is below the min lot size." + }, + { + "code": 6032, + "name": "InvalidCollateralDelta", + "msg": "The collateral delta post perp order doesn't match the planned one." + }, + { + "code": 6033, + "name": "MangoPerpMarketIndexNotFound", + "msg": "The perp market index could not be found for this MangoMarkets Pair." + }, + { + "code": 6034, + "name": "InvalidMangoGroup", + "msg": "Could not load the provided MangoGroup account." + }, + { + "code": 6035, + "name": "QuantityBelowContractSize", + "msg": "The order quantity is below contract_size of the perp market." + }, + { + "code": 6036, + "name": "QuoteAmountTooHigh", + "msg": "The amount trying to be quote minted is larger than quote mintable." + }, + { + "code": 6037, + "name": "RedeemableAmountTooHigh", + "msg": "The amount trying to be quote redeemed is larger than quote redeemable." + }, + { + "code": 6038, + "name": "MintingDisabled", + "msg": "Minting is disabled for the current depository" + }, + { + "code": 6039, + "name": "MintingAlreadyDisabledOrEnabled", + "msg": "Minting is already disabled/enabled" + }, + { + "code": 6040, + "name": "MSolSwappingDisabled", + "msg": "Msol swapping is disabled" + }, + { + "code": 6041, + "name": "InvalidAuthority", + "msg": "Only the Program initializer authority can access this instructions." + }, + { + "code": 6042, + "name": "InvalidController", + "msg": "The Depository's controller doesn't match the provided Controller." + }, + { + "code": 6043, + "name": "InvalidDepository", + "msg": "The Depository provided is not registered with the Controller." + }, + { + "code": 6044, + "name": "InvalidCollateralMint", + "msg": "The provided collateral mint does not match the depository's collateral mint." }, { - "name": "AccountingEvent", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Deposit" - }, - { - "name": "Withdraw" - } - ] - } + "code": 6045, + "name": "InvalidQuoteMint", + "msg": "The provided quote mint does not match the depository's quote mint." }, { - "name": "PnlPolarity", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Positive" - }, - { - "name": "Negative" - } - ] - } + "code": 6046, + "name": "InvalidMangoAccount", + "msg": "The Mango Account isn't the Depository one." + }, + { + "code": 6047, + "name": "InvalidRedeemableMint", + "msg": "The Redeemable Mint provided does not match the Controller's one." + }, + { + "code": 6048, + "name": "InvalidDexMarket", + "msg": "The provided perp_market is not the one tied to this Depository." + }, + { + "code": 6049, + "name": "InvalidOwner", + "msg": "The provided token account is not owner by the expected party." + }, + { + "code": 6050, + "name": "InvalidMaxBaseQuantity", + "msg": "The max base quantity must be above 0." + }, + { + "code": 6051, + "name": "InvalidMaxQuoteQuantity", + "msg": "The max quote quantity must be above 0." + }, + { + "code": 6052, + "name": "TargetLiquidityRatioExceedMax", + "msg": "Target liquidity ratio for msol config exceed 100%" + }, + { + "code": 6053, + "name": "InvalidEnablingMsolSwap", + "msg": "SOL/mSOL swap has already enabled / disabled" + }, + { + "code": 6054, + "name": "InvalidNonNativeMintUsed", + "msg": "Must use native mint for setting msol config" + }, + { + "code": 6055, + "name": "InvalidNonNativeMintAtaUsed", + "msg": "Must use native mint for passthrough account" + }, + { + "code": 6056, + "name": "InvalidNonMSolMintAtaUsed", + "msg": "Must use msol for passthrough account" + }, + { + "code": 6057, + "name": "Default", + "msg": "Default - Check the source code for more info" } - ], - "events": [ + ] +}; + +export const IDL: Uxd = { + "version": "3.1.0", + "name": "uxd", + "instructions": [ { - "name": "InitializeControllerEvent", - "fields": [ + "name": "initializeController", + "accounts": [ { - "name": "version", - "type": "u8", - "index": false + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true }, { "name": "controller", - "type": "publicKey", - "index": false + "isMut": true, + "isSigner": false }, { - "name": "authority", - "type": "publicKey", - "index": false + "name": "redeemableMint", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "redeemableMintDecimals", + "type": "u8" } ] }, { - "name": "SetRedeemableGlobalSupplyCapEvent", - "fields": [ + "name": "setRedeemableGlobalSupplyCap", + "accounts": [ { - "name": "version", - "type": "u8", - "index": false + "name": "authority", + "isMut": false, + "isSigner": true }, { "name": "controller", - "type": "publicKey", - "index": false - }, + "isMut": true, + "isSigner": false + } + ], + "args": [ { "name": "redeemableGlobalSupplyCap", - "type": "u128", - "index": false + "type": "u128" } ] }, { - "name": "RegisterMangoDepositoryEvent", - "fields": [ + "name": "setMangoDepositoriesRedeemableSoftCap", + "accounts": [ { - "name": "version", - "type": "u8", - "index": false + "name": "authority", + "isMut": false, + "isSigner": true }, { "name": "controller", - "type": "publicKey", - "index": false - }, - { - "name": "depository", - "type": "publicKey", - "index": false - }, - { - "name": "collateralMint", - "type": "publicKey", - "index": false - }, - { - "name": "insuranceMint", - "type": "publicKey", - "index": false - }, + "isMut": true, + "isSigner": false + } + ], + "args": [ { - "name": "mangoAccount", - "type": "publicKey", - "index": false + "name": "redeemableSoftCap", + "type": "u64" } ] }, { - "name": "RegisterMangoDepositoryEventV2", - "fields": [ + "name": "registerMangoDepository", + "accounts": [ { - "name": "version", - "type": "u8", - "index": false + "name": "authority", + "isMut": false, + "isSigner": true }, { - "name": "depositoryVersion", - "type": "u8", - "index": false + "name": "payer", + "isMut": true, + "isSigner": true }, { "name": "controller", - "type": "publicKey", - "index": false + "isMut": true, + "isSigner": false }, { "name": "depository", - "type": "publicKey", - "index": false + "isMut": true, + "isSigner": false }, { "name": "collateralMint", - "type": "publicKey", - "index": false + "isMut": false, + "isSigner": false }, { "name": "quoteMint", - "type": "publicKey", - "index": false + "isMut": false, + "isSigner": false }, { "name": "mangoAccount", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "SetMangoDepositoryRedeemableSoftCapEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false - }, - { - "name": "controller", - "type": "publicKey", - "index": false - }, - { - "name": "redeemableMint", - "type": "publicKey", - "index": false - }, - { - "name": "redeemableMintDecimals", - "type": "u8", - "index": false - }, - { - "name": "redeemableSoftCap", - "type": "u64", - "index": false - } - ] - }, - { - "name": "DepositInsuranceToMangoDepositoryEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false + "isMut": true, + "isSigner": false }, { - "name": "controller", - "type": "publicKey", - "index": false + "name": "mangoGroup", + "isMut": false, + "isSigner": false }, { - "name": "depository", - "type": "publicKey", - "index": false + "name": "systemProgram", + "isMut": false, + "isSigner": false }, { - "name": "insuranceMint", - "type": "publicKey", - "index": false + "name": "tokenProgram", + "isMut": false, + "isSigner": false }, { - "name": "insuranceMintDecimals", - "type": "u8", - "index": false + "name": "mangoProgram", + "isMut": false, + "isSigner": false }, { - "name": "depositedAmount", - "type": "u64", - "index": false + "name": "rent", + "isMut": false, + "isSigner": false } - ] + ], + "args": [] }, { - "name": "DepositInsuranceToMangoDepositoryEventV2", - "fields": [ + "name": "depositInsuranceToMangoDepository", + "accounts": [ { - "name": "version", - "type": "u8", - "index": false + "name": "authority", + "isMut": false, + "isSigner": true }, { "name": "controller", - "type": "publicKey", - "index": false + "isMut": false, + "isSigner": false }, { "name": "depository", - "type": "publicKey", - "index": false + "isMut": true, + "isSigner": false }, { - "name": "quoteMint", - "type": "publicKey", - "index": false + "name": "authorityQuote", + "isMut": true, + "isSigner": false }, { - "name": "quoteMintDecimals", - "type": "u8", - "index": false + "name": "mangoAccount", + "isMut": true, + "isSigner": false }, { - "name": "depositedAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "WithdrawInsuranceFromMangoDepositoryEvent", - "fields": [ + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, { - "name": "version", - "type": "u8", - "index": false + "name": "mangoCache", + "isMut": true, + "isSigner": false }, { - "name": "controller", - "type": "publicKey", - "index": false + "name": "mangoRootBank", + "isMut": true, + "isSigner": false }, { - "name": "depository", - "type": "publicKey", - "index": false + "name": "mangoNodeBank", + "isMut": true, + "isSigner": false }, { - "name": "insuranceMint", - "type": "publicKey", - "index": false + "name": "mangoVault", + "isMut": true, + "isSigner": false }, { - "name": "insuranceMintDecimals", - "type": "u8", - "index": false + "name": "tokenProgram", + "isMut": false, + "isSigner": false }, { - "name": "withdrawnAmount", - "type": "u64", - "index": false + "name": "mangoProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "amount", + "type": "u64" } ] }, { - "name": "WithdrawInsuranceFromMangoDepositoryEventV2", - "fields": [ + "name": "withdrawInsuranceFromMangoDepository", + "accounts": [ { - "name": "version", - "type": "u8", - "index": false + "name": "authority", + "isMut": false, + "isSigner": true }, { "name": "controller", - "type": "publicKey", - "index": false + "isMut": false, + "isSigner": false }, { "name": "depository", - "type": "publicKey", - "index": false + "isMut": true, + "isSigner": false }, { - "name": "quoteMint", - "type": "publicKey", - "index": false + "name": "authorityQuote", + "isMut": true, + "isSigner": false }, { - "name": "quoteMintDecimals", - "type": "u8", - "index": false + "name": "mangoAccount", + "isMut": true, + "isSigner": false }, { - "name": "withdrawnAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "MintWithMangoDepositoryEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false + "name": "mangoGroup", + "isMut": false, + "isSigner": false }, { - "name": "controller", - "type": "publicKey", - "index": false + "name": "mangoCache", + "isMut": false, + "isSigner": false }, { - "name": "depository", - "type": "publicKey", - "index": false + "name": "mangoSigner", + "isMut": false, + "isSigner": false }, { - "name": "user", - "type": "publicKey", - "index": false + "name": "mangoRootBank", + "isMut": true, + "isSigner": false }, { - "name": "collateralAmount", - "type": "u64", - "index": false + "name": "mangoNodeBank", + "isMut": true, + "isSigner": false }, { - "name": "slippage", - "type": "u32", - "index": false + "name": "mangoVault", + "isMut": true, + "isSigner": false }, { - "name": "collateralDelta", - "type": "u64", - "index": false + "name": "systemProgram", + "isMut": false, + "isSigner": false }, { - "name": "redeemableDelta", - "type": "u64", - "index": false + "name": "tokenProgram", + "isMut": false, + "isSigner": false }, { - "name": "feeDelta", - "type": "u64", - "index": false + "name": "mangoProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "amount", + "type": "u64" } ] }, { - "name": "RedeemFromMangoDepositoryEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false - }, - { - "name": "controller", - "type": "publicKey", - "index": false - }, - { - "name": "depository", - "type": "publicKey", - "index": false - }, + "name": "rebalanceMangoDepositoryLite", + "accounts": [ { "name": "user", - "type": "publicKey", - "index": false + "isMut": false, + "isSigner": true }, { - "name": "redeemableAmount", - "type": "u64", - "index": false + "name": "payer", + "isMut": true, + "isSigner": true }, { - "name": "slippage", - "type": "u32", - "index": false + "name": "controller", + "isMut": false, + "isSigner": false }, { - "name": "collateralDelta", - "type": "u64", - "index": false + "name": "depository", + "isMut": true, + "isSigner": false }, { - "name": "redeemableDelta", - "type": "u64", - "index": false + "name": "collateralMint", + "isMut": false, + "isSigner": false }, { - "name": "feeDelta", - "type": "u64", - "index": false - } - ] - }, - { - "name": "RebalanceMangoDepositoryLiteEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false + "name": "quoteMint", + "isMut": false, + "isSigner": false + }, + { + "name": "userCollateral", + "isMut": true, + "isSigner": false }, { - "name": "depositoryVersion", - "type": "u8", - "index": false + "name": "userQuote", + "isMut": true, + "isSigner": false }, { - "name": "controller", - "type": "publicKey", - "index": false + "name": "mangoAccount", + "isMut": true, + "isSigner": false }, { - "name": "depository", - "type": "publicKey", - "index": false + "name": "mangoSigner", + "isMut": false, + "isSigner": false }, { - "name": "user", - "type": "publicKey", - "index": false + "name": "mangoGroup", + "isMut": true, + "isSigner": false }, { - "name": "polarity", - "type": { - "defined": "PnlPolarity" - }, - "index": false + "name": "mangoCache", + "isMut": true, + "isSigner": false }, { - "name": "rebalancingAmount", - "type": "u64", - "index": false + "name": "mangoRootBankQuote", + "isMut": true, + "isSigner": false }, { - "name": "rebalancedAmount", - "type": "u64", - "index": false + "name": "mangoNodeBankQuote", + "isMut": true, + "isSigner": false }, { - "name": "slippage", - "type": "u32", - "index": false + "name": "mangoVaultQuote", + "isMut": true, + "isSigner": false }, { - "name": "collateralDelta", - "type": "u64", - "index": false + "name": "mangoRootBankCollateral", + "isMut": true, + "isSigner": false }, { - "name": "quoteDelta", - "type": "u64", - "index": false + "name": "mangoNodeBankCollateral", + "isMut": true, + "isSigner": false }, { - "name": "feeDelta", - "type": "u64", - "index": false - } - ] - } - ], - "errors": [ - { - "code": 6000, - "name": "InvalidAuthority", - "msg": "Only the Program initializer authority can access this instructions." - }, - { - "code": 6001, - "name": "InvalidController", - "msg": "The Depository's controller doesn't match the provided Controller." - }, - { - "code": 6002, - "name": "InvalidDepository", - "msg": "The Depository provided is not registered with the Controller." - }, - { - "code": 6003, - "name": "InvalidCollateralMint", - "msg": "The provided collateral mint does not match the depository's collateral mint." - }, - { - "code": 6004, - "name": "InvalidQuoteMint", - "msg": "The provided quote mint does not match the depository's quote mint." - }, - { - "code": 6005, - "name": "InvalidAuthorityQuoteATAMint", - "msg": "The authority's Quote ATA's mint does not match the Depository's one." - }, - { - "code": 6006, - "name": "InvalidMangoAccount", - "msg": "The Mango Account isn't the Depository one." - }, - { - "code": 6007, - "name": "InvalidRedeemableMint", - "msg": "The Redeemable Mint provided does not match the Controller's one." - } - ] -}; - -export const IDL: Uxd = { - "version": "3.0.2", - "name": "uxd", - "instructions": [ - { - "name": "initializeController", - "accounts": [ + "name": "mangoVaultCollateral", + "isMut": true, + "isSigner": false + }, { - "name": "authority", - "isMut": false, - "isSigner": true + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false }, { - "name": "payer", + "name": "mangoBids", "isMut": true, - "isSigner": true + "isSigner": false }, { - "name": "controller", + "name": "mangoAsks", "isMut": true, "isSigner": false }, { - "name": "redeemableMint", + "name": "mangoEventQueue", "isMut": true, "isSigner": false }, @@ -1702,101 +2647,114 @@ export const IDL: Uxd = { "isSigner": false }, { - "name": "rent", + "name": "mangoProgram", "isMut": false, "isSigner": false } ], "args": [ { - "name": "redeemableMintDecimals", - "type": "u8" + "name": "maxRebalancingAmount", + "type": "u64" + }, + { + "name": "polarity", + "type": { + "defined": "PnlPolarity" + } + }, + { + "name": "limitPrice", + "type": "f32" } ] }, { - "name": "setRedeemableGlobalSupplyCap", + "name": "mintWithMangoDepository", "accounts": [ { - "name": "authority", + "name": "user", "isMut": false, "isSigner": true }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, { "name": "controller", "isMut": true, "isSigner": false - } - ], - "args": [ + }, { - "name": "redeemableGlobalSupplyCap", - "type": "u128" - } - ] - }, - { - "name": "setMangoDepositoriesRedeemableSoftCap", - "accounts": [ + "name": "depository", + "isMut": true, + "isSigner": false + }, { - "name": "authority", - "isMut": false, - "isSigner": true + "name": "redeemableMint", + "isMut": true, + "isSigner": false }, { - "name": "controller", + "name": "userCollateral", "isMut": true, "isSigner": false - } - ], - "args": [ + }, { - "name": "redeemableSoftCap", - "type": "u64" - } - ] - }, - { - "name": "registerMangoDepository", - "accounts": [ + "name": "userRedeemable", + "isMut": true, + "isSigner": false + }, { - "name": "authority", + "name": "mangoAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoGroup", "isMut": false, - "isSigner": true + "isSigner": false }, { - "name": "payer", + "name": "mangoCache", "isMut": true, - "isSigner": true + "isSigner": false }, { - "name": "controller", + "name": "mangoRootBank", "isMut": true, "isSigner": false }, { - "name": "depository", + "name": "mangoNodeBank", "isMut": true, "isSigner": false }, { - "name": "collateralMint", - "isMut": false, + "name": "mangoVault", + "isMut": true, "isSigner": false }, { - "name": "quoteMint", - "isMut": false, + "name": "mangoPerpMarket", + "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoBids", "isMut": true, "isSigner": false }, { - "name": "mangoGroup", - "isMut": false, + "name": "mangoAsks", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoEventQueue", + "isMut": true, "isSigner": false }, { @@ -1813,26 +2771,35 @@ export const IDL: Uxd = { "name": "mangoProgram", "isMut": false, "isSigner": false + } + ], + "args": [ + { + "name": "collateralAmount", + "type": "u64" }, { - "name": "rent", - "isMut": false, - "isSigner": false + "name": "limitPrice", + "type": "f32" } - ], - "args": [] + ] }, { - "name": "depositInsuranceToMangoDepository", + "name": "redeemFromMangoDepository", "accounts": [ { - "name": "authority", - "isMut": false, + "name": "user", + "isMut": true, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, "isSigner": true }, { "name": "controller", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -1846,33 +2813,43 @@ export const IDL: Uxd = { "isSigner": false }, { - "name": "quoteMint", - "isMut": false, + "name": "redeemableMint", + "isMut": true, "isSigner": false }, { - "name": "authorityQuote", + "name": "userCollateral", + "isMut": true, + "isSigner": false + }, + { + "name": "userRedeemable", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, { "name": "mangoGroup", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoCache", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoSigner", "isMut": false, "isSigner": false }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -1885,6 +2862,31 @@ export const IDL: Uxd = { "isMut": true, "isSigner": false }, + { + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoBids", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoAsks", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoEventQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, { "name": "tokenProgram", "isMut": false, @@ -1898,22 +2900,31 @@ export const IDL: Uxd = { ], "args": [ { - "name": "amount", + "name": "redeemableAmount", "type": "u64" + }, + { + "name": "limitPrice", + "type": "f32" } ] }, { - "name": "withdrawInsuranceFromMangoDepository", + "name": "quoteMintWithMangoDepository", "accounts": [ { - "name": "authority", + "name": "user", "isMut": false, "isSigner": true }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, { "name": "controller", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -1922,22 +2933,22 @@ export const IDL: Uxd = { "isSigner": false }, { - "name": "collateralMint", - "isMut": false, + "name": "redeemableMint", + "isMut": true, "isSigner": false }, { - "name": "quoteMint", - "isMut": false, + "name": "userQuote", + "isMut": true, "isSigner": false }, { - "name": "authorityQuote", + "name": "userRedeemable", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoAccount", "isMut": true, "isSigner": false }, @@ -1948,17 +2959,12 @@ export const IDL: Uxd = { }, { "name": "mangoCache", - "isMut": false, - "isSigner": false - }, - { - "name": "mangoSigner", - "isMut": false, + "isMut": true, "isSigner": false }, { "name": "mangoRootBank", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -1971,6 +2977,11 @@ export const IDL: Uxd = { "isMut": true, "isSigner": false }, + { + "name": "mangoPerpMarket", + "isMut": true, + "isSigner": false + }, { "name": "systemProgram", "isMut": false, @@ -1981,21 +2992,31 @@ export const IDL: Uxd = { "isMut": false, "isSigner": false }, + { + "name": "associatedTokenProgram", + "isMut": false, + "isSigner": false + }, { "name": "mangoProgram", "isMut": false, "isSigner": false + }, + { + "name": "rent", + "isMut": false, + "isSigner": false } ], "args": [ { - "name": "amount", + "name": "quoteAmount", "type": "u64" } ] }, { - "name": "rebalanceMangoDepositoryLite", + "name": "quoteRedeemFromMangoDepository", "accounts": [ { "name": "user", @@ -2009,7 +3030,7 @@ export const IDL: Uxd = { }, { "name": "controller", - "isMut": false, + "isMut": true, "isSigner": false }, { @@ -2018,8 +3039,8 @@ export const IDL: Uxd = { "isSigner": false }, { - "name": "collateralMint", - "isMut": false, + "name": "redeemableMint", + "isMut": true, "isSigner": false }, { @@ -2027,24 +3048,19 @@ export const IDL: Uxd = { "isMut": false, "isSigner": false }, - { - "name": "userCollateral", - "isMut": true, - "isSigner": false - }, { "name": "userQuote", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "userRedeemable", "isMut": true, "isSigner": false }, { - "name": "mangoSigner", - "isMut": false, + "name": "mangoAccount", + "isMut": true, "isSigner": false }, { @@ -2054,36 +3070,26 @@ export const IDL: Uxd = { }, { "name": "mangoCache", - "isMut": false, - "isSigner": false - }, - { - "name": "mangoRootBankQuote", - "isMut": false, - "isSigner": false - }, - { - "name": "mangoNodeBankQuote", "isMut": true, "isSigner": false }, { - "name": "mangoVaultQuote", - "isMut": true, + "name": "mangoSigner", + "isMut": false, "isSigner": false }, { - "name": "mangoRootBankCollateral", + "name": "mangoRootBank", "isMut": false, "isSigner": false }, { - "name": "mangoNodeBankCollateral", + "name": "mangoNodeBank", "isMut": true, "isSigner": false }, { - "name": "mangoVaultCollateral", + "name": "mangoVault", "isMut": true, "isSigner": false }, @@ -2092,21 +3098,6 @@ export const IDL: Uxd = { "isMut": true, "isSigner": false }, - { - "name": "mangoBids", - "isMut": true, - "isSigner": false - }, - { - "name": "mangoAsks", - "isMut": true, - "isSigner": false - }, - { - "name": "mangoEventQueue", - "isMut": true, - "isSigner": false - }, { "name": "systemProgram", "isMut": false, @@ -2135,34 +3126,19 @@ export const IDL: Uxd = { ], "args": [ { - "name": "maxRebalancingAmount", + "name": "redeemableAmount", "type": "u64" - }, - { - "name": "polarity", - "type": { - "defined": "PnlPolarity" - } - }, - { - "name": "slippage", - "type": "u32" } ] }, { - "name": "mintWithMangoDepository", + "name": "setMangoDepositoryQuoteMintAndRedeemFee", "accounts": [ { - "name": "user", + "name": "authority", "isMut": false, "isSigner": true }, - { - "name": "payer", - "isMut": true, - "isSigner": true - }, { "name": "controller", "isMut": true, @@ -2172,120 +3148,165 @@ export const IDL: Uxd = { "name": "depository", "isMut": true, "isSigner": false - }, + } + ], + "args": [ { - "name": "redeemableMint", - "isMut": true, - "isSigner": false - }, + "name": "quoteFee", + "type": "u8" + } + ] + }, + { + "name": "disableDepositoryMinting", + "accounts": [ { - "name": "collateralMint", + "name": "authority", "isMut": false, - "isSigner": false + "isSigner": true }, { - "name": "userCollateral", - "isMut": true, + "name": "controller", + "isMut": false, "isSigner": false }, { - "name": "userRedeemable", + "name": "depository", "isMut": true, "isSigner": false + } + ], + "args": [ + { + "name": "disableMinting", + "type": "bool" + } + ] + }, + { + "name": "createDepositoryMsolConfig", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true }, { - "name": "depositoryMangoAccount", + "name": "payer", "isMut": true, - "isSigner": false + "isSigner": true }, { - "name": "mangoGroup", + "name": "controller", "isMut": false, "isSigner": false }, { - "name": "mangoCache", + "name": "depository", "isMut": false, "isSigner": false }, { - "name": "mangoRootBank", - "isMut": false, + "name": "msolConfig", + "isMut": true, "isSigner": false }, { - "name": "mangoNodeBank", - "isMut": true, + "name": "systemProgram", + "isMut": false, "isSigner": false }, { - "name": "mangoVault", - "isMut": true, + "name": "rent", + "isMut": false, "isSigner": false + } + ], + "args": [ + { + "name": "targetLiquidityRatio", + "type": "u16" + } + ] + }, + { + "name": "enableMsolSwap", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true }, { - "name": "mangoPerpMarket", + "name": "payer", "isMut": true, - "isSigner": false + "isSigner": true }, { - "name": "mangoBids", - "isMut": true, + "name": "controller", + "isMut": false, "isSigner": false }, { - "name": "mangoAsks", - "isMut": true, + "name": "depository", + "isMut": false, "isSigner": false }, { - "name": "mangoEventQueue", + "name": "msolConfig", "isMut": true, "isSigner": false - }, + } + ], + "args": [ + { + "name": "enable", + "type": "bool" + } + ] + }, + { + "name": "setMsolLiquidityRatio", + "accounts": [ { - "name": "systemProgram", + "name": "authority", "isMut": false, - "isSigner": false + "isSigner": true }, { - "name": "tokenProgram", - "isMut": false, - "isSigner": false + "name": "payer", + "isMut": true, + "isSigner": true }, { - "name": "associatedTokenProgram", + "name": "controller", "isMut": false, "isSigner": false }, { - "name": "mangoProgram", + "name": "depository", "isMut": false, "isSigner": false }, { - "name": "rent", - "isMut": false, + "name": "msolConfig", + "isMut": true, "isSigner": false } ], "args": [ { - "name": "collateralAmount", - "type": "u64" - }, - { - "name": "slippage", - "type": "u32" + "name": "targetLiquidityRatio", + "type": "u16" } ] }, { - "name": "redeemFromMangoDepository", + "name": "rebalanceMangoDepositoryMsolRatio", "accounts": [ { "name": "user", - "isMut": false, + "isMut": true, "isSigner": true }, { @@ -2304,116 +3325,132 @@ export const IDL: Uxd = { "isSigner": false }, { - "name": "collateralMint", + "name": "msolConfig", "isMut": false, "isSigner": false }, { - "name": "redeemableMint", + "name": "mangoAccount", "isMut": true, "isSigner": false }, { - "name": "userCollateral", + "name": "mangoGroup", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoCache", "isMut": true, "isSigner": false }, { - "name": "userRedeemable", + "name": "mangoSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "mangoSolRootBank", "isMut": true, "isSigner": false }, { - "name": "depositoryMangoAccount", + "name": "mangoSolNodeBank", "isMut": true, "isSigner": false }, { - "name": "mangoGroup", - "isMut": false, + "name": "mangoSolVault", + "isMut": true, "isSigner": false }, { - "name": "mangoCache", - "isMut": false, + "name": "mangoMsolRootBank", + "isMut": true, "isSigner": false }, { - "name": "mangoSigner", - "isMut": false, + "name": "mangoMsolNodeBank", + "isMut": true, "isSigner": false }, { - "name": "mangoRootBank", + "name": "mangoMsolVault", + "isMut": true, + "isSigner": false + }, + { + "name": "mangoProgram", "isMut": false, "isSigner": false }, { - "name": "mangoNodeBank", + "name": "marinadeState", "isMut": true, "isSigner": false }, { - "name": "mangoVault", + "name": "msolMint", "isMut": true, "isSigner": false }, { - "name": "mangoPerpMarket", + "name": "msolMintAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "liqPoolSolLegPda", "isMut": true, "isSigner": false }, { - "name": "mangoBids", + "name": "liqPoolMsolLeg", "isMut": true, "isSigner": false }, { - "name": "mangoAsks", + "name": "liqPoolMsolLegAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "treasuryMsolAccount", "isMut": true, "isSigner": false }, { - "name": "mangoEventQueue", + "name": "reservePda", "isMut": true, "isSigner": false }, { - "name": "systemProgram", - "isMut": false, + "name": "solPassthroughAta", + "isMut": true, "isSigner": false }, { - "name": "tokenProgram", - "isMut": false, + "name": "msolPassthroughAta", + "isMut": true, "isSigner": false }, { - "name": "associatedTokenProgram", + "name": "marinadeFinanceProgram", "isMut": false, "isSigner": false }, { - "name": "mangoProgram", + "name": "systemProgram", "isMut": false, "isSigner": false }, { - "name": "rent", + "name": "tokenProgram", "isMut": false, "isSigner": false } ], - "args": [ - { - "name": "redeemableAmount", - "type": "u64" - }, - { - "name": "slippage", - "type": "u32" - } - ] + "args": [] } ], "accounts": [ @@ -2470,12 +3507,6 @@ export const IDL: Uxd = { { "name": "redeemableCirculatingSupply", "type": "u128" - }, - { - "name": "reserved", - "type": { - "defined": "ControllerPadding" - } } ] } @@ -2511,322 +3542,139 @@ export const IDL: Uxd = { "type": "publicKey" }, { - "name": "collateralMintDecimals", - "type": "u8" - }, - { - "name": "unused2", - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "quoteMint", - "type": "publicKey" - }, - { - "name": "unused3", - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "quoteMintDecimals", - "type": "u8" - }, - { - "name": "mangoAccount", - "type": "publicKey" - }, - { - "name": "controller", - "type": "publicKey" - }, - { - "name": "insuranceAmountDeposited", - "type": "u128" - }, - { - "name": "collateralAmountDeposited", - "type": "u128" - }, - { - "name": "redeemableAmountUnderManagement", - "type": "u128" - }, - { - "name": "totalAmountPaidTakerFee", - "type": "u128" - }, - { - "name": "totalAmountRebalanced", - "type": "u128" - }, - { - "name": "reserved", - "type": { - "defined": "MangoDepositoryPadding" - } - } - ] - } - } - ], - "types": [ - { - "name": "SourceFileId", - "type": { - "kind": "enum", - "variants": [ - { - "name": "InstructionInitializeController" - }, - { - "name": "InstructionSetRedeemableGlobalSupplyCap" - }, - { - "name": "InstructionSetMangoDepositoriesRedeemableSoftCap" - }, - { - "name": "InstructionRegisterMangoDepository" - }, - { - "name": "InstructionMangoDexMintWithMangoDepository" - }, - { - "name": "InstructionMangoDexRedeemFromMangoDepository" - }, - { - "name": "InstructionMangoDexDepositInsuranceToMangoDepository" - }, - { - "name": "InstructionMangoDexWithdrawInsuranceFromMangoDepository" - }, - { - "name": "MangoProgramAnchorMango" - }, - { - "name": "MangoProgramDeposit" - }, - { - "name": "MangoProgramInitMangoAccount" - }, - { - "name": "MangoProgramPlacePerpOrder" - }, - { - "name": "MangoProgramWithdraw" - }, - { - "name": "MangoUtilsLimitUtils" - }, - { - "name": "MangoUtilsOrderDelta" - }, - { - "name": "MangoUtilsOrder" - }, - { - "name": "MangoUtilsPerpAccountUtils" - }, - { - "name": "MangoUtilsPerpInfo" - }, - { - "name": "StateController" - }, - { - "name": "StateMangoDepository" - }, - { - "name": "Error" - }, - { - "name": "Lib" - }, - { - "name": "InstructionMangoDexRebalanceMangoDepositoryLite" - }, - { - "name": "InstructionMangoDexMigrateMangoDepositoryToV2" - } - ] - } - }, - { - "name": "UxdError", - "type": { - "kind": "enum", - "variants": [ - { - "name": "ProgramError", - "fields": [ - { - "defined": "ProgramError" - } - ] - }, - { - "name": "UxdErrorCode", - "fields": [ - { - "name": "uxd_error_code", - "type": { - "defined": "UxdErrorCode" - } - }, - { - "name": "line", - "type": "u32" - }, - { - "name": "source_file_id", - "type": { - "defined": "SourceFileId" - } - } - ] - } - ] - } - }, - { - "name": "UxdErrorCode", - "type": { - "kind": "enum", - "variants": [ - { - "name": "InvalidRedeemableMintDecimals" - }, - { - "name": "InvalidRedeemableGlobalSupplyCap" - }, - { - "name": "RootBankIndexNotFound" - }, - { - "name": "InvalidSlippage" - }, - { - "name": "EffectiveOrderPriceBeyondLimitPrice" - }, - { - "name": "InvalidCollateralAmount" - }, - { - "name": "InsufficientCollateralAmount" - }, - { - "name": "InvalidRedeemableAmount" - }, - { - "name": "InsufficientRedeemableAmount" - }, - { - "name": "PerpOrderPartiallyFilled" - }, - { - "name": "RedeemableGlobalSupplyCapReached" - }, - { - "name": "MangoDepositoriesSoftCapOverflow" - }, - { - "name": "MaxNumberOfMangoDepositoriesRegisteredReached" + "name": "collateralMintDecimals", + "type": "u8" }, { - "name": "InvalidInsuranceAmount" + "name": "unused2", + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "InsufficientAuthorityInsuranceAmount" + "name": "quoteMint", + "type": "publicKey" }, { - "name": "InvalidRebalancedAmount" + "name": "unused3", + "type": { + "array": [ + "u8", + 32 + ] + } }, { - "name": "InsufficientOrderBookDepth" + "name": "quoteMintDecimals", + "type": "u8" }, { - "name": "InvalidExecutedOrderSize" + "name": "mangoAccount", + "type": "publicKey" }, { - "name": "MangoPerpMarketIndexNotFound" + "name": "controller", + "type": "publicKey" }, { - "name": "InvalidMangoDepositoriesRedeemableSoftCap" + "name": "insuranceAmountDeposited", + "type": "u128" }, { - "name": "InvalidQuoteDelta" + "name": "collateralAmountDeposited", + "type": "u128" }, { - "name": "InvalidOrderDirection" + "name": "redeemableAmountUnderManagement", + "type": "u128" }, { - "name": "MathError" + "name": "totalAmountPaidTakerFee", + "type": "u128" }, { - "name": "SlippageReached" + "name": "totalAmountRebalanced", + "type": "u128" }, { - "name": "InvalidRebalancingAmount" + "name": "netQuoteMinted", + "type": "i128" }, { - "name": "InsufficientQuoteAmount" + "name": "quoteMintAndRedeemFee", + "type": "u8" }, { - "name": "InvalidPnlPolarity" + "name": "totalQuoteMintAndRedeemFees", + "type": "u128" }, { - "name": "RebalancingError" - }, + "name": "mintingDisabled", + "type": "bool" + } + ] + } + }, + { + "name": "mSolConfig", + "type": { + "kind": "struct", + "fields": [ { - "name": "BumpError" + "name": "bump", + "type": "u8" }, { - "name": "OrderSizeBelowMinLotSize" + "name": "depository", + "type": "publicKey" }, { - "name": "InvalidCollateralDelta" + "name": "controller", + "type": "publicKey" }, { - "name": "QuantityBelowContractSize" + "name": "enabled", + "type": "bool" }, { - "name": "Default" + "name": "targetLiquidityRatio", + "type": "u16" } ] } - }, + } + ], + "types": [ { - "name": "AccountingEvent", + "name": "PnlPolarity", "type": { "kind": "enum", "variants": [ { - "name": "Deposit" + "name": "Positive" }, { - "name": "Withdraw" + "name": "Negative" } ] } }, { - "name": "PnlPolarity", + "name": "RebalanceRoute", "type": { "kind": "enum", "variants": [ { - "name": "Positive" + "name": "Deposit" }, { - "name": "Negative" + "name": "LiquidUnstake" + }, + { + "name": "NoSwapRequired" } ] } @@ -2979,42 +3827,7 @@ export const IDL: Uxd = { ] }, { - "name": "DepositInsuranceToMangoDepositoryEvent", - "fields": [ - { - "name": "version", - "type": "u8", - "index": false - }, - { - "name": "controller", - "type": "publicKey", - "index": false - }, - { - "name": "depository", - "type": "publicKey", - "index": false - }, - { - "name": "insuranceMint", - "type": "publicKey", - "index": false - }, - { - "name": "insuranceMintDecimals", - "type": "u8", - "index": false - }, - { - "name": "depositedAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "DepositInsuranceToMangoDepositoryEventV2", + "name": "DepositInsuranceToDepositoryEvent", "fields": [ { "name": "version", @@ -3084,7 +3897,7 @@ export const IDL: Uxd = { ] }, { - "name": "WithdrawInsuranceFromMangoDepositoryEventV2", + "name": "WithdrawInsuranceFromDepositoryEvent", "fields": [ { "name": "version", @@ -3147,29 +3960,29 @@ export const IDL: Uxd = { "index": false }, { - "name": "slippage", - "type": "u32", + "name": "limitPrice", + "type": "f32", "index": false }, { - "name": "collateralDelta", - "type": "u64", + "name": "baseDelta", + "type": "i64", "index": false }, { - "name": "redeemableDelta", - "type": "u64", + "name": "quoteDelta", + "type": "i64", "index": false }, { "name": "feeDelta", - "type": "u64", + "type": "i64", "index": false } ] }, { - "name": "RedeemFromMangoDepositoryEvent", + "name": "RedeemFromDepositoryEvent", "fields": [ { "name": "version", @@ -3197,23 +4010,23 @@ export const IDL: Uxd = { "index": false }, { - "name": "slippage", - "type": "u32", + "name": "limitPrice", + "type": "f32", "index": false }, { - "name": "collateralDelta", - "type": "u64", + "name": "baseDelta", + "type": "i64", "index": false }, { - "name": "redeemableDelta", - "type": "u64", + "name": "quoteDelta", + "type": "i64", "index": false }, { "name": "feeDelta", - "type": "u64", + "type": "i64", "index": false } ] @@ -3264,23 +4077,58 @@ export const IDL: Uxd = { "index": false }, { - "name": "slippage", - "type": "u32", + "name": "limitPrice", + "type": "f32", "index": false }, { - "name": "collateralDelta", - "type": "u64", + "name": "baseDelta", + "type": "i64", "index": false }, { "name": "quoteDelta", - "type": "u64", + "type": "i64", "index": false }, { "name": "feeDelta", - "type": "u64", + "type": "i64", + "index": false + } + ] + }, + { + "name": "CreateDepositoryMSolConfigEvent", + "fields": [ + { + "name": "version", + "type": "u8", + "index": false + }, + { + "name": "msolConfig", + "type": "publicKey", + "index": false + }, + { + "name": "controller", + "type": "publicKey", + "index": false + }, + { + "name": "depository", + "type": "publicKey", + "index": false + }, + { + "name": "enabled", + "type": "bool", + "index": false + }, + { + "name": "targetLiquidityRatio", + "type": "u16", "index": false } ] @@ -3289,43 +4137,293 @@ export const IDL: Uxd = { "errors": [ { "code": 6000, + "name": "InvalidRedeemableMintDecimals", + "msg": "The redeemable mint decimals must be between 0 and 9 (inclusive)." + }, + { + "code": 6001, + "name": "InvalidRedeemableGlobalSupplyCap", + "msg": "Redeemable global supply above." + }, + { + "code": 6002, + "name": "RootBankIndexNotFound", + "msg": "The associated mango root bank index cannot be found for the deposited coin.." + }, + { + "code": 6003, + "name": "InvalidLimitPrice", + "msg": "The provided limit_price value is invalid, must be > 0" + }, + { + "code": 6004, + "name": "EffectiveOrderPriceBeyondLimitPrice", + "msg": "Could not fill the order given order book state and provided slippage." + }, + { + "code": 6005, + "name": "InvalidCollateralAmount", + "msg": "Collateral amount cannot be 0" + }, + { + "code": 6006, + "name": "InvalidQuoteAmount", + "msg": "Quote amount must be > 0 in order to mint." + }, + { + "code": 6007, + "name": "InvalidRedeemableAmount", + "msg": "Redeemable amount must be > 0 in order to redeem." + }, + { + "code": 6008, + "name": "InsufficientCollateralAmount", + "msg": "The balance of the collateral ATA is not enough to fulfill the mint operation." + }, + { + "code": 6009, + "name": "InsufficientQuoteAmountMint", + "msg": "The balance of the quote ATA is not enough to fulfil the mint operation." + }, + { + "code": 6010, + "name": "InsufficientRedeemableAmountMint", + "msg": "The balance of the redeemable ATA is not enough to fulfil the redeem operation." + }, + { + "code": 6011, + "name": "InsufficientRedeemableAmount", + "msg": "The balance of the redeemable ATA is not enough to fulfill the redeem operation." + }, + { + "code": 6012, + "name": "PerpOrderPartiallyFilled", + "msg": "The perp position could not be fully filled with the provided slippage." + }, + { + "code": 6013, + "name": "RedeemableGlobalSupplyCapReached", + "msg": "Minting amount would go past the Redeemable Global Supply Cap." + }, + { + "code": 6014, + "name": "MangoDepositoriesSoftCapOverflow", + "msg": "Operation not allowed due to being over the Mango Redeemable soft Cap." + }, + { + "code": 6015, + "name": "MaxNumberOfMangoDepositoriesRegisteredReached", + "msg": "Cannot register more mango depositories, the limit has been reached." + }, + { + "code": 6016, + "name": "InvalidInsuranceAmount", + "msg": "The amount to withdraw from the Insurance Fund must be superior to zero.." + }, + { + "code": 6017, + "name": "InsufficientAuthorityQuoteAmount", + "msg": "The Quote ATA from authority doesn't have enough balance." + }, + { + "code": 6018, + "name": "InvalidRebalancedAmount", + "msg": "The rebalanced amount must be superior to zero.." + }, + { + "code": 6019, + "name": "InsufficientOrderBookDepth", + "msg": "Insufficient order book depth for order." + }, + { + "code": 6020, + "name": "InvalidExecutedOrderSize", + "msg": "The executed order size does not match the expected one." + }, + { + "code": 6021, + "name": "InvalidMangoDepositoriesRedeemableSoftCap", + "msg": "Mango depositories redeemable soft cap above." + }, + { + "code": 6022, + "name": "InvalidQuoteDelta", + "msg": "Quote_lot_delta can't be 0." + }, + { + "code": 6023, + "name": "InvalidOrderDirection", + "msg": "The perp order wasn't executed in the right direction." + }, + { + "code": 6024, + "name": "MathError", + "msg": "Math error." + }, + { + "code": 6025, + "name": "SlippageReached", + "msg": "The order couldn't be executed with the provided slippage." + }, + { + "code": 6026, + "name": "InvalidRebalancingAmount", + "msg": "The rebalancing amount must be above 0." + }, + { + "code": 6027, + "name": "InsufficientQuoteAmount", + "msg": "The Quote amount in the provided user_quote ATA must be >= max_amount_rebalancing." + }, + { + "code": 6028, + "name": "InvalidPnlPolarity", + "msg": "The PnL polarity provided is not the same as the perp position's one." + }, + { + "code": 6029, + "name": "RebalancingError", + "msg": "The rebalanced amount doesn't match the expected rebalance amount." + }, + { + "code": 6030, + "name": "BumpError", + "msg": "A bump was expected but is missing." + }, + { + "code": 6031, + "name": "OrderSizeBelowMinLotSize", + "msg": "The order is below size is below the min lot size." + }, + { + "code": 6032, + "name": "InvalidCollateralDelta", + "msg": "The collateral delta post perp order doesn't match the planned one." + }, + { + "code": 6033, + "name": "MangoPerpMarketIndexNotFound", + "msg": "The perp market index could not be found for this MangoMarkets Pair." + }, + { + "code": 6034, + "name": "InvalidMangoGroup", + "msg": "Could not load the provided MangoGroup account." + }, + { + "code": 6035, + "name": "QuantityBelowContractSize", + "msg": "The order quantity is below contract_size of the perp market." + }, + { + "code": 6036, + "name": "QuoteAmountTooHigh", + "msg": "The amount trying to be quote minted is larger than quote mintable." + }, + { + "code": 6037, + "name": "RedeemableAmountTooHigh", + "msg": "The amount trying to be quote redeemed is larger than quote redeemable." + }, + { + "code": 6038, + "name": "MintingDisabled", + "msg": "Minting is disabled for the current depository" + }, + { + "code": 6039, + "name": "MintingAlreadyDisabledOrEnabled", + "msg": "Minting is already disabled/enabled" + }, + { + "code": 6040, + "name": "MSolSwappingDisabled", + "msg": "Msol swapping is disabled" + }, + { + "code": 6041, "name": "InvalidAuthority", "msg": "Only the Program initializer authority can access this instructions." }, { - "code": 6001, + "code": 6042, "name": "InvalidController", "msg": "The Depository's controller doesn't match the provided Controller." }, { - "code": 6002, + "code": 6043, "name": "InvalidDepository", "msg": "The Depository provided is not registered with the Controller." }, { - "code": 6003, + "code": 6044, "name": "InvalidCollateralMint", "msg": "The provided collateral mint does not match the depository's collateral mint." }, { - "code": 6004, + "code": 6045, "name": "InvalidQuoteMint", "msg": "The provided quote mint does not match the depository's quote mint." }, { - "code": 6005, - "name": "InvalidAuthorityQuoteATAMint", - "msg": "The authority's Quote ATA's mint does not match the Depository's one." - }, - { - "code": 6006, + "code": 6046, "name": "InvalidMangoAccount", "msg": "The Mango Account isn't the Depository one." }, { - "code": 6007, + "code": 6047, "name": "InvalidRedeemableMint", "msg": "The Redeemable Mint provided does not match the Controller's one." + }, + { + "code": 6048, + "name": "InvalidDexMarket", + "msg": "The provided perp_market is not the one tied to this Depository." + }, + { + "code": 6049, + "name": "InvalidOwner", + "msg": "The provided token account is not owner by the expected party." + }, + { + "code": 6050, + "name": "InvalidMaxBaseQuantity", + "msg": "The max base quantity must be above 0." + }, + { + "code": 6051, + "name": "InvalidMaxQuoteQuantity", + "msg": "The max quote quantity must be above 0." + }, + { + "code": 6052, + "name": "TargetLiquidityRatioExceedMax", + "msg": "Target liquidity ratio for msol config exceed 100%" + }, + { + "code": 6053, + "name": "InvalidEnablingMsolSwap", + "msg": "SOL/mSOL swap has already enabled / disabled" + }, + { + "code": 6054, + "name": "InvalidNonNativeMintUsed", + "msg": "Must use native mint for setting msol config" + }, + { + "code": 6055, + "name": "InvalidNonNativeMintAtaUsed", + "msg": "Must use native mint for passthrough account" + }, + { + "code": 6056, + "name": "InvalidNonMSolMintAtaUsed", + "msg": "Must use msol for passthrough account" + }, + { + "code": 6057, + "name": "Default", + "msg": "Default - Check the source code for more info" } ] }; diff --git a/tests/api.ts b/tests/api.ts index 6068c306d..56d1984b8 100644 --- a/tests/api.ts +++ b/tests/api.ts @@ -1,168 +1,602 @@ import { getConnection, TXN_OPTS } from "./connection"; import { uxdClient } from "./constants"; -import { Account, Signer, Transaction } from '@solana/web3.js'; +import { Keypair, PublicKey, Signer, Transaction } from "@solana/web3.js"; import { NATIVE_MINT } from "@solana/spl-token"; -import { prepareWrappedSolTokenAccount } from "./utils"; -import { MangoDepository, Mango, Controller, PnLPolarity, } from "@uxdprotocol/uxd-client"; +import { createAssociatedTokenAccountItx, prepareWrappedSolTokenAccount } from "./utils"; +import { + MangoDepository, + Mango, + Controller, + PnLPolarity, + createAssocTokenIx, + findATAAddrSync, + uiToNative, + WSOL, + MSOL, +} from "@uxd-protocol/uxd-client"; import { web3 } from "@project-serum/anchor"; +import { Payer } from "@blockworks-foundation/mango-client"; +import { MarinadeConfig } from "@marinade.finance/marinade-ts-sdk"; // Permissionned Calls -------------------------------------------------------- export async function initializeController(authority: Signer, payer: Signer, controller: Controller): Promise { - const initControllerIx = uxdClient.createInitializeControllerInstruction(controller, authority.publicKey, TXN_OPTS, payer.publicKey); - - const signers = []; - const tx = new Transaction(); - - tx.instructions.push(initControllerIx); - signers.push(authority); - if (payer) { - signers.push(payer); - } - - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); + const initControllerIx = uxdClient.createInitializeControllerInstruction( + controller, + authority.publicKey, + TXN_OPTS, + payer.publicKey + ); + + const signers = []; + const tx = new Transaction(); + + tx.instructions.push(initControllerIx); + signers.push(authority); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } -export async function registerMangoDepository(authority: Signer, payer: Signer, controller: Controller, depository: MangoDepository, mango: Mango): Promise { - const registerMangoDepositoryIx = uxdClient.createRegisterMangoDepositoryInstruction(controller, depository, mango, authority.publicKey, TXN_OPTS, payer.publicKey); - let signers = []; - let tx = new Transaction(); - - tx.instructions.push(registerMangoDepositoryIx); - signers.push(authority); - if (payer) { - signers.push(payer); - } - - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function registerMangoDepository( + authority: Signer, + payer: Signer, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const registerMangoDepositoryIx = uxdClient.createRegisterMangoDepositoryInstruction( + controller, + depository, + mango, + authority.publicKey, + TXN_OPTS, + payer.publicKey + ); + let signers = []; + let tx = new Transaction(); + + tx.instructions.push(registerMangoDepositoryIx); + signers.push(authority); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } -export async function depositInsuranceToMangoDepository(authority: Signer, amount: number, controller: Controller, depository: MangoDepository, mango: Mango): Promise { - const depositInsuranceToMangoDepositoryIx = uxdClient.createDepositInsuranceToMangoDepositoryInstruction(amount, controller, depository, mango, authority.publicKey, TXN_OPTS); - let signers = []; - let tx = new Transaction(); - - tx.instructions.push(depositInsuranceToMangoDepositoryIx); - signers.push(authority); - - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function depositInsuranceToMangoDepository( + authority: Signer, + amount: number, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const depositInsuranceToMangoDepositoryIx = await uxdClient.createDepositInsuranceToMangoDepositoryInstruction( + amount, + controller, + depository, + mango, + authority.publicKey, + TXN_OPTS + ); + let signers = []; + let tx = new Transaction(); + + tx.instructions.push(depositInsuranceToMangoDepositoryIx); + signers.push(authority); + + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } -export async function withdrawInsuranceFromMangoDepository(authority: Signer, amount: number, controller: Controller, depository: MangoDepository, mango: Mango): Promise { - const withdrawInsuranceFromMangoDepository = uxdClient.createWithdrawInsuranceFromMangoDepositoryInstruction(amount, controller, depository, mango, authority.publicKey, TXN_OPTS); - let signers = []; - let tx = new Transaction(); - - tx.instructions.push(withdrawInsuranceFromMangoDepository); - signers.push(authority); - - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function withdrawInsuranceFromMangoDepository( + amount: number, + authority: Signer, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const withdrawInsuranceFromMangoDepository = uxdClient.createWithdrawInsuranceFromMangoDepositoryInstruction( + amount, + controller, + depository, + mango, + authority.publicKey, + TXN_OPTS + ); + let signers = []; + let tx = new Transaction(); + + const authorityQuoteAta = findATAAddrSync(authority.publicKey, depository.quoteMint)[0]; + if (!(await getConnection().getAccountInfo(authorityQuoteAta))) { + const createUserQuoteAtaIx = createAssocTokenIx(authority.publicKey, authorityQuoteAta, depository.quoteMint); + tx.add(createUserQuoteAtaIx); + } + + tx.instructions.push(withdrawInsuranceFromMangoDepository); + signers.push(authority); + + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } -export async function setRedeemableGlobalSupplyCap(authority: Signer, controller: Controller, supplyCapUiAmount: number): Promise { - const setRedeemableGlobalSupplyCapIx = uxdClient.createSetRedeemableGlobalSupplyCapInstruction(controller, authority.publicKey, supplyCapUiAmount, TXN_OPTS); - let signers = []; - let tx = new Transaction(); - - tx.instructions.push(setRedeemableGlobalSupplyCapIx); - signers.push(authority); - - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function setRedeemableGlobalSupplyCap( + authority: Signer, + controller: Controller, + supplyCapUiAmount: number +): Promise { + const setRedeemableGlobalSupplyCapIx = uxdClient.createSetRedeemableGlobalSupplyCapInstruction( + controller, + authority.publicKey, + supplyCapUiAmount, + TXN_OPTS + ); + let signers = []; + let tx = new Transaction(); + + tx.instructions.push(setRedeemableGlobalSupplyCapIx); + signers.push(authority); + + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } -export async function setMangoDepositoriesRedeemableSoftCap(authority: Signer, controller: Controller, supplySoftCapUiAmount: number): Promise { - const setMangoDepositoriesRedeemableSoftCapIx = uxdClient.createSetMangoDepositoriesRedeemableSoftCapInstruction(controller, authority.publicKey, supplySoftCapUiAmount, TXN_OPTS); - let signers = []; - let tx = new Transaction(); - - tx.instructions.push(setMangoDepositoriesRedeemableSoftCapIx); - signers.push(authority); - - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function setMangoDepositoriesRedeemableSoftCap( + authority: Signer, + controller: Controller, + supplySoftCapUiAmount: number +): Promise { + const setMangoDepositoriesRedeemableSoftCapIx = uxdClient.createSetMangoDepositoriesRedeemableSoftCapInstruction( + controller, + authority.publicKey, + supplySoftCapUiAmount, + TXN_OPTS + ); + let signers = []; + let tx = new Transaction(); + + tx.instructions.push(setMangoDepositoriesRedeemableSoftCapIx); + signers.push(authority); + + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } // Permissionless Calls ------------------------------------------------------- -export async function mintWithMangoDepository(user: Signer, payer: Signer, slippage: number, collateralAmount: number, controller: Controller, depository: MangoDepository, mango: Mango): Promise { - const mintWithMangoDepositoryIx = uxdClient.createMintWithMangoDepositoryInstruction(collateralAmount, slippage, controller, depository, mango, user.publicKey, TXN_OPTS, payer.publicKey); - let signers = []; - let tx = new Transaction(); - - if (depository.collateralMint.equals(NATIVE_MINT)) { - const nativeAmount = collateralAmount * 10 ** depository.collateralMintDecimals; - const prepareWrappedSolIxs = await prepareWrappedSolTokenAccount( - getConnection(), - payer.publicKey, - user.publicKey, - nativeAmount - ); - tx.instructions.push(...prepareWrappedSolIxs); +export async function mintWithMangoDepository( + user: Signer, + payer: Signer, + slippage: number, + collateralAmount: number, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const mintWithMangoDepositoryIx = await uxdClient.createMintWithMangoDepositoryInstruction( + collateralAmount, + slippage, + controller, + depository, + mango, + user.publicKey, + TXN_OPTS, + payer.publicKey + ); + let signers = []; + let tx = new Transaction(); + + const userRedeemableAta = findATAAddrSync(user.publicKey, controller.redeemableMintPda)[0]; + if (!(await getConnection().getAccountInfo(userRedeemableAta))) { + const createUserRedeemableAtaIx = createAssociatedTokenAccountItx( + payer.publicKey, + user.publicKey, + controller.redeemableMintPda + ); + tx.add(createUserRedeemableAtaIx); + } + + if (depository.collateralMint.equals(NATIVE_MINT)) { + const nativeAmount = uiToNative(collateralAmount, depository.collateralMintDecimals); + const prepareWrappedSolIxs = await prepareWrappedSolTokenAccount( + getConnection(), + payer.publicKey, + user.publicKey, + nativeAmount.toNumber() + ); + if (prepareWrappedSolIxs.length > 0) { + tx.add(...prepareWrappedSolIxs); } - - tx.instructions.push(mintWithMangoDepositoryIx); - signers.push(user); - if (payer) { - signers.push(payer); + } else { + const userCollateralAta = findATAAddrSync(user.publicKey, depository.collateralMint)[0]; + if (!(await getConnection().getAccountInfo(userCollateralAta))) { + const createUserCollateralAtaIx = createAssocTokenIx( + user.publicKey, + userCollateralAta, + depository.collateralMint + ); + tx.add(createUserCollateralAtaIx); } + } + + tx.add(mintWithMangoDepositoryIx); + signers.push(user); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function quoteMintWithMangoDepository( + user: Signer, + payer: Signer, + quoteAmount: number, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const quoteMintWithMangoDepositoryIx = await uxdClient.createQuoteMintWithMangoDepositoryInstruction( + quoteAmount, + controller, + depository, + mango, + user.publicKey, + TXN_OPTS, + payer.publicKey + ); + let signers = []; + let tx = new Transaction(); + + const userRedeemableAta = findATAAddrSync(user.publicKey, controller.redeemableMintPda)[0]; + if (!(await getConnection().getAccountInfo(userRedeemableAta))) { + const createUserCollateralAtaIx = createAssocTokenIx( + user.publicKey, + userRedeemableAta, + controller.redeemableMintPda + ); + tx.add(createUserCollateralAtaIx); + } + + tx.add(quoteMintWithMangoDepositoryIx); + signers.push(user); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } -export async function redeemFromMangoDepository(user: Signer, payer: Signer, slippage: number, amountRedeemable: number, controller: Controller, depository: MangoDepository, mango: Mango): Promise { - const redeemFromMangoDepositoryIx = uxdClient.createRedeemFromMangoDepositoryInstruction(amountRedeemable, slippage, controller, depository, mango, user.publicKey, TXN_OPTS, payer.publicKey); +export async function redeemFromMangoDepository( + user: Signer, + payer: Signer, + slippage: number, + amountRedeemable: number, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const redeemFromMangoDepositoryIx = await uxdClient.createRedeemFromMangoDepositoryInstruction( + amountRedeemable, + slippage, + controller, + depository, + mango, + user.publicKey, + TXN_OPTS, + payer.publicKey + ); + + let signers = []; + let tx = new Transaction(); + + const userCollateralAta = findATAAddrSync(user.publicKey, depository.collateralMint)[0]; + if (!(await getConnection().getAccountInfo(userCollateralAta))) { + const createUserCollateralAtaIx = createAssocTokenIx(user.publicKey, userCollateralAta, depository.collateralMint); + tx.add(createUserCollateralAtaIx); + } + + const userRedeemableAta = findATAAddrSync(user.publicKey, controller.redeemableMintPda)[0]; + if (!(await getConnection().getAccountInfo(userRedeemableAta))) { + const createUserCollateralAtaIx = createAssocTokenIx( + user.publicKey, + userRedeemableAta, + controller.redeemableMintPda + ); + tx.add(createUserCollateralAtaIx); + } + + tx.add(redeemFromMangoDepositoryIx); + signers.push(user); + if (payer) { + signers.push(payer); + } + + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - let signers = []; - let tx = new Transaction(); +export async function quoteRedeemFromMangoDepository( + user: Signer, + payer: Signer, + redeemableAmount: number, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const quoteRedeemFromMangoDepositoryIx = await uxdClient.createQuoteRedeemWithMangoDepositoryInstruction( + redeemableAmount, + controller, + depository, + mango, + user.publicKey, + TXN_OPTS, + payer.publicKey + ); + let signers = []; + let tx = new Transaction(); + + const userQuoteATA = findATAAddrSync(user.publicKey, depository.quoteMint)[0]; + if (!(await getConnection().getAccountInfo(userQuoteATA))) { + const createUserCollateralAtaIx = createAssocTokenIx(user.publicKey, userQuoteATA, depository.collateralMint); + tx.add(createUserCollateralAtaIx); + } + + await depository.settleMangoDepositoryMangoAccountPnl(payer as Payer, mango); + + tx.add(quoteRedeemFromMangoDepositoryIx); + signers.push(user); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - tx.instructions.push(redeemFromMangoDepositoryIx); - signers.push(user); - if (payer) { - signers.push(payer); - } +export async function setMangoDepositoryQuoteMintAndRedeemFee( + authority: Signer, + controller: Controller, + depository: MangoDepository, + quoteFee: number +): Promise { + const setMangoDepositoryQuoteMintAndRedeemFeeIx = + await uxdClient.createSetMangoDepositoryQuoteMintAndRedeemFeeInstruction( + quoteFee, + controller, + depository, + authority.publicKey, + TXN_OPTS + ); + let signers = []; + let tx = new Transaction(); + + tx.instructions.push(setMangoDepositoryQuoteMintAndRedeemFeeIx); + signers.push(authority); + + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); -} - -export async function rebalanceMangoDepositoryLite(user: Signer, payer: Signer, rebalancingMaxAmountQuote: number, polarity: PnLPolarity, slippage: number, controller: Controller, depository: MangoDepository, mango: Mango): Promise { - const rebalanceMangoDepositoryLiteIx = uxdClient.createRebalanceMangoDepositoryLiteInstruction(rebalancingMaxAmountQuote, slippage, polarity, controller, depository, mango, user.publicKey, TXN_OPTS, payer.publicKey); - let signers = []; - let tx = new Transaction(); - - // Only when polarity is positive this is required - // - Negative polarity sends QUOTE, gets COLLATERAL back. - // - Positive polarity sends COLLATERAL, gets QUOTE back. - if (polarity == PnLPolarity.Positive && depository.collateralMint.equals(NATIVE_MINT)) { - console.log("rebalancingMaxAmount :", rebalancingMaxAmountQuote); - const mangoPerpPrice = await depository.getCollateralPerpPriceUI(mango); - const rebalancingMaxAmountCollateral = rebalancingMaxAmountQuote / mangoPerpPrice; - const nativeAmount = rebalancingMaxAmountCollateral * 10 ** depository.collateralMintDecimals; - const prepareWrappedSolIxs = await prepareWrappedSolTokenAccount( - getConnection(), - payer.publicKey, - user.publicKey, - nativeAmount - ); - tx.instructions.push(...prepareWrappedSolIxs); - } +export async function rebalanceMangoDepositoryLite( + user: Signer, + payer: Signer, + rebalancingMaxAmountQuote: number, + polarity: PnLPolarity, + slippage: number, + controller: Controller, + depository: MangoDepository, + mango: Mango +): Promise { + const rebalanceMangoDepositoryLiteIx = await uxdClient.createRebalanceMangoDepositoryLiteInstruction( + rebalancingMaxAmountQuote, + slippage, + polarity, + controller, + depository, + mango, + user.publicKey, + TXN_OPTS, + payer.publicKey + ); + let signers = []; + let tx = new Transaction(); + + // Only when polarity is positive this is required + // - Negative polarity sends QUOTE, gets COLLATERAL back. + // - Positive polarity sends COLLATERAL, gets QUOTE back. + if (polarity == PnLPolarity.Positive && depository.collateralMint.equals(NATIVE_MINT)) { + const mangoPerpPrice = await depository.getCollateralPerpPriceUI(mango); + const rebalancingMaxAmountCollateral = rebalancingMaxAmountQuote / mangoPerpPrice; + const nativeAmount = uiToNative(rebalancingMaxAmountCollateral, depository.collateralMintDecimals); + const prepareWrappedSolIxs = await prepareWrappedSolTokenAccount( + getConnection(), + payer.publicKey, + user.publicKey, + nativeAmount.toNumber() + ); + tx.add(...prepareWrappedSolIxs); + } + + const userCollateralAta = findATAAddrSync(user.publicKey, depository.collateralMint)[0]; + + if (!(await getConnection().getAccountInfo(userCollateralAta)) && !depository.collateralMint.equals(NATIVE_MINT)) { + const createUserCollateralAtaIx = createAssocTokenIx(user.publicKey, userCollateralAta, depository.collateralMint); + tx.add(createUserCollateralAtaIx); + } + + const userQuoteATA = findATAAddrSync(user.publicKey, depository.quoteMint)[0]; + + if (!(await getConnection().getAccountInfo(userQuoteATA))) { + const createUserQuoteAtaIx = createAssocTokenIx(user.publicKey, userQuoteATA, depository.quoteMint); + tx.add(createUserQuoteAtaIx); + } + + tx.add(rebalanceMangoDepositoryLiteIx); + signers.push(user); + if (payer) { + signers.push(payer); + } + + tx.feePayer = payer.publicKey; + let txId = web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); + + // PNL should be settled afterward to ensure we have no "borrow" to prevent paying interests + // const settlePnlTxID = await settleDepositoryPnl(payer, depository, mango); + // console.log("🔗 depository PnL settlement Tx:", `'https://explorer.solana.com/tx/${settlePnlTxID}?cluster=${CLUSTER}'`); + + return txId; +} - tx.instructions.push(rebalanceMangoDepositoryLiteIx); - signers.push(user); - if (payer) { - signers.push(payer); - } +export async function disableDepositoryMinting( + authority: Signer, + controller: Controller, + depository: MangoDepository, + disableMinting: boolean +): Promise { + const disableDepositoryMintingIx = await uxdClient.createDisableDepositoryMintingInstruction( + disableMinting, + controller, + depository, + authority.publicKey, + TXN_OPTS + ); + let signers = []; + let tx = new Transaction(); + + tx.instructions.push(disableDepositoryMintingIx); + signers.push(authority); + + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - let txId = web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +export async function createDepositoryMsolConfig( + authority: Signer, + payer: Signer, + controller: Controller, + depository: MangoDepository, + msolConfigPda: PublicKey, + targetLiquidityRatio: number +): Promise { + const ix = uxdClient.createDepositoryMsolConfigInstruction( + targetLiquidityRatio, + controller, + depository, + msolConfigPda, + authority.publicKey, + TXN_OPTS, + payer.publicKey + ); + + const signers = []; + const tx = new Transaction(); + + tx.instructions.push(ix); + signers.push(authority); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - // PNL should be settled afterward to ensure we have no "borrow" to prevent paying interests - // const settlePnlTxID = await settleDepositoryPnl(payer, depository, mango); - // console.log("🔗 depository PnL settlement Tx:", `'https://explorer.solana.com/tx/${settlePnlTxID}?cluster=${CLUSTER}'`); +export async function swapDepositoryMsol( + user: Signer, + payer: Signer, + controller: Controller, + depository: MangoDepository, + msolConfigPda: PublicKey, + mango: Mango +): Promise { + const marinadeConfig = new MarinadeConfig({ + connection: getConnection(), + publicKey: user.publicKey, + }); + + const tx = new Transaction(); + + // const userWSolAta = findATAAddrSync(user.publicKey, WSOL)[0]; + // if (!(await getConnection().getAccountInfo(userWSolAta))) { + // const createUserWSolAtaIx = createAssocTokenIx(user.publicKey, userWSolAta, WSOL); + // tx.add(createUserWSolAtaIx); + // } + + // const userMSolAta = findATAAddrSync(user.publicKey, MSOL)[0]; + // if (!(await getConnection().getAccountInfo(userMSolAta))) { + // const createUserMSolAtaIx = createAssocTokenIx(user.publicKey, userMSolAta, MSOL); + // tx.add(createUserMSolAtaIx); + // } + + const ix = await uxdClient.swapDepositoryMsolInstruction( + controller, + depository, + msolConfigPda, + mango, + marinadeConfig, + TXN_OPTS, + user.publicKey, + payer.publicKey + ); + + const signers = []; + + tx.instructions.push(ix); + signers.push(user); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} - return txId; +export async function enableMsolSwap( + authority: Signer, + payer: Signer, + controller: Controller, + depository: MangoDepository, + msolConfigPda: PublicKey, + enable: boolean +): Promise { + const ix = uxdClient.enableMsolSwapInstruction( + enable, + controller, + depository, + msolConfigPda, + authority.publicKey, + TXN_OPTS, + payer.publicKey + ); + + const signers = []; + const tx = new Transaction(); + + tx.instructions.push(ix); + signers.push(authority); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); } // Non UXD API calls ---------------------------------------------------------- export async function settleDepositoryPnl(payer: Signer, depository: MangoDepository, mango: Mango): Promise { - let payerAccount = new Account(payer.secretKey); - return depository.settleMangoDepositoryMangoAccountPnl(payerAccount, mango); -} \ No newline at end of file + return depository.settleMangoDepositoryMangoAccountPnl(payer as Keypair, mango); +} + +export async function createAta(user: Signer, payer: Signer, mint: PublicKey): Promise { + const tx = new Transaction(); + const userAta = findATAAddrSync(user.publicKey, mint)[0]; + if (!(await getConnection().getAccountInfo(userAta))) { + const createUserAtaIx = createAssocTokenIx(user.publicKey, userAta, mint); + tx.add(createUserAtaIx); + } else { + throw new Error("has created") + } + const signers = []; + + signers.push(user); + if (payer) { + signers.push(payer); + } + tx.feePayer = payer.publicKey; + return web3.sendAndConfirmTransaction(getConnection(), tx, signers, TXN_OPTS); +} diff --git a/tests/cases/depositInsuranceMangoDepositoryTest.ts b/tests/cases/depositInsuranceMangoDepositoryTest.ts index e60290972..25f7a67a7 100644 --- a/tests/cases/depositInsuranceMangoDepositoryTest.ts +++ b/tests/cases/depositInsuranceMangoDepositoryTest.ts @@ -1,6 +1,6 @@ import { Signer } from "@solana/web3.js"; -import { Controller, Mango, MangoDepository, nativeToUi } from "@uxdprotocol/uxd-client"; +import { Controller, Mango, MangoDepository, nativeToUi } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { depositInsuranceToMangoDepository } from "../api"; import { CLUSTER } from "../constants"; @@ -25,13 +25,15 @@ export const depositInsuranceMangoDepositoryTest = async function (amount: numbe const insuranceDepositedAmount_post = nativeToUi(depositoryOnchainAccount_post.insuranceAmountDeposited.toNumber(), depository.quoteMintDecimals); const expectedAmount = insuranceDepositedAmount + amount; + console.log(`🧾 Insurance Amount deposited was`, insuranceDepositedAmount, "now is", insuranceDepositedAmount_post, "(deposited", amount, ")"); + // Check that the accounting match the actual balances - TODO // Check onchain accounting -- Only that for now cause need to refine how to fetch mango account data expect(insuranceDepositedAmount_post).closeTo(expectedAmount, Math.pow(10, -depository.quoteMintDecimals), "The mango depositories insurance ACCOUNTING isn't correct."); - console.log(`🧾 Insurance Amount deposited was`, insuranceDepositedAmount, "now is", insuranceDepositedAmount_post, "(deposited", amount, ")"); console.groupEnd(); } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/disableDepositoryMintingTest.ts b/tests/cases/disableDepositoryMintingTest.ts new file mode 100644 index 000000000..6a51399db --- /dev/null +++ b/tests/cases/disableDepositoryMintingTest.ts @@ -0,0 +1,37 @@ +import { utils } from "@project-serum/anchor"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, findATAAddrSync, uiToNative, nativeToUi } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { disableDepositoryMinting, mintWithMangoDepository, quoteMintWithMangoDepository, setMangoDepositoryQuoteMintAndRedeemFee } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER, slippageBase } from "../constants"; +import { getSolBalance, getBalance } from "../utils"; + +export const disableDepositoryMintingTest = async function (disableMinting: boolean, authority: Signer, controller: Controller, depository: MangoDepository) { + const connection = getConnection(); + const options = TXN_OPTS; + + console.group("🧭 disableDepositoryMintingTest"); + try { + // GIVEN + const depositoryOnchainAccount = await depository.getOnchainAccount(connection, options); + const mintingDisabled = depositoryOnchainAccount.mintingDisabled; + + // WHEN + const txId = await disableDepositoryMinting(authority, controller, depository, disableMinting); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const depositoryOnchainAccount_post = await depository.getOnchainAccount(connection, options); + const mintingDisabled_post = depositoryOnchainAccount_post.mintingDisabled; + + expect(mintingDisabled_post).equals(disableMinting, "The quote fee has not changed."); + console.log(`🧾 Previous ${depository.collateralMintSymbol} minting is`, mintingDisabled, "now is", mintingDisabled_post); + console.groupEnd(); + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} \ No newline at end of file diff --git a/tests/cases/initializeControllerTest.ts b/tests/cases/initializeControllerTest.ts index 2d4c519a8..a7607052e 100644 --- a/tests/cases/initializeControllerTest.ts +++ b/tests/cases/initializeControllerTest.ts @@ -1,5 +1,5 @@ import { Signer } from "@solana/web3.js"; -import { Controller } from "@uxdprotocol/uxd-client"; +import { Controller } from "@uxd-protocol/uxd-client"; import { initializeController } from "../api"; import { CLUSTER } from "../constants"; import { getConnection } from "../connection"; @@ -21,6 +21,7 @@ export const initializeControllerTest = async function (authority: Signer, contr controller.info(); console.groupEnd(); } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/mintWithMangoDepositoryAccountingTest.ts b/tests/cases/mintWithMangoDepositoryAccountingTest.ts new file mode 100644 index 000000000..1dbb55be6 --- /dev/null +++ b/tests/cases/mintWithMangoDepositoryAccountingTest.ts @@ -0,0 +1,94 @@ +import { NATIVE_MINT } from "@solana/spl-token"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, findATAAddrSync, nativeToUi } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { mintWithMangoDepository } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER } from "../constants"; +import { getSolBalance, getBalance } from "../utils"; + +export const mintWithMangoDepositoryAccountingTest = async function (collateralAmount: number, slippage: number, user: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer): Promise { + console.group("🧭 mintWithMangoDepositoryAccountingTest"); + try { + const connection = getConnection(); + const options = TXN_OPTS; + + // GIVEN + const userCollateralATA: PublicKey = findATAAddrSync(user.publicKey, depository.collateralMint)[0]; + const userRedeemableATA: PublicKey = findATAAddrSync(user.publicKey, controller.redeemableMintPda)[0]; + const userRedeemableBalance = await getBalance(userRedeemableATA); + const userCollateralBalance: number = await getBalance(userCollateralATA); + + const depositoryAccount = await depository.getOnchainAccount(connection, options); + const depositoryRedeemable = nativeToUi(depositoryAccount.redeemableAmountUnderManagement.toNumber(), depository.quoteMintDecimals); + const depositoryCollateral = nativeToUi(depositoryAccount.collateralAmountDeposited.toNumber(), depository.collateralMintDecimals); + const depositoryTakerFees = nativeToUi(depositoryAccount.totalAmountPaidTakerFee.toNumber(), depository.quoteMintDecimals); + const controllerAccount = await controller.getOnchainAccount(connection, options); + const controllerRedeemable = nativeToUi(controllerAccount.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + + // Initial SOL is used to make the diff afterward as the instruction does unwrap + const userStartingSolBalance = await getSolBalance(user.publicKey); + + // WHEN + // - Get the perp price at the same moment to have the less diff between exec and test price + // Simulates user experience from the front end + const mangoPerpPrice = await depository.getCollateralPerpPriceUI(mango); + const txId = await mintWithMangoDepository(user, payer ?? user, slippage, collateralAmount, controller, depository, mango); + console.log("🪙 perp price is", Number(mangoPerpPrice.toFixed(depository.quoteMintDecimals)), depository.quoteMintSymbol); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const userRedeemableBalance_post = await getBalance(userRedeemableATA); + let userCollateralBalance_post: number; + if (NATIVE_MINT.equals(depository.collateralMint)) { + // the TX unwrap the WSOL, so we need to remove the initial SOL balance. Payer takes the tx fees so we'r good. + userCollateralBalance_post = await getSolBalance(user.publicKey) - userStartingSolBalance; + } else { + userCollateralBalance_post = await getBalance(userCollateralATA); + } + + const mangoTakerFee = depository.getCollateralPerpTakerFees(mango); + + const redeemableDelta = userRedeemableBalance_post - userRedeemableBalance; + const collateralDelta = userCollateralBalance - userCollateralBalance_post; + const collateralOddLotLeftOver = Math.max(collateralAmount - collateralDelta, 0); + const collateralProcessedByMinting = collateralAmount - collateralOddLotLeftOver; + // The mango perp price in these might not be the exact same as the one in the transaction. + const estimatedFrictionlessRedeemableDelta = collateralProcessedByMinting * mangoPerpPrice; + const estimatedAmountRedeemableLostInTakerFees = mangoTakerFee * collateralProcessedByMinting * mangoPerpPrice; + const collateralNativeUnitPrecision = Math.pow(10, -depository.collateralMintDecimals); + const estimatedAmountRedeemableLostInSlippage = Math.abs(estimatedFrictionlessRedeemableDelta - redeemableDelta) - estimatedAmountRedeemableLostInTakerFees; + // Get onchain depository and controller for post accounting + const depositoryAccount_post = await depository.getOnchainAccount(connection, TXN_OPTS); + const depositoryRedeemable_post = nativeToUi(depositoryAccount_post.redeemableAmountUnderManagement.toNumber(), depository.quoteMintDecimals); + const depositoryCollateral_post = nativeToUi(depositoryAccount_post.collateralAmountDeposited.toNumber(), depository.collateralMintDecimals); + const controllerAccount_post = await controller.getOnchainAccount(connection, TXN_OPTS); + const controllerRedeemable_post = nativeToUi(controllerAccount_post.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + const redeemableNativeUnitPrecision = Math.pow(10, -controller.redeemableMintDecimals); + const depositoryTakerFees_post = nativeToUi(depositoryAccount_post.totalAmountPaidTakerFee.toNumber(), depository.quoteMintDecimals); + + + console.log("Efficiency", Number(((redeemableDelta / estimatedFrictionlessRedeemableDelta) * 100).toFixed(2)), "%"); + console.log( + `🧾 Minted`, Number(redeemableDelta.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, + "by locking", Number(collateralProcessedByMinting.toFixed(depository.collateralMintDecimals)), depository.collateralMintSymbol, + "(+~ takerFees =", Number(estimatedAmountRedeemableLostInTakerFees.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, + ", +~ slippage =", Number(estimatedAmountRedeemableLostInSlippage.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, ")", + "(frictionless minting would have been", Number(estimatedFrictionlessRedeemableDelta.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, ")", + "|| odd lot returns ", Number(collateralOddLotLeftOver.toFixed(depository.collateralMintDecimals)), depository.collateralMintSymbol, + ")" + ); + // Accounting + expect(depositoryRedeemable_post).closeTo(depositoryRedeemable + redeemableDelta, redeemableNativeUnitPrecision, "Depository RedeemableAmountUnderManagement is incorrect"); + expect(controllerRedeemable_post).closeTo(controllerRedeemable + redeemableDelta, redeemableNativeUnitPrecision, "Controller RedeemableCirculatingSupply is incorrect"); + expect(depositoryTakerFees_post).to.be.within(depositoryTakerFees, depositoryTakerFees + (mangoTakerFee * collateralDelta * mangoPerpPrice), "Depository TotalAmountPaidTakerFee is incorrect"); + expect(depositoryCollateral_post).closeTo(depositoryCollateral + collateralProcessedByMinting, collateralNativeUnitPrecision, "Depository CollateralAmountDeposited is incorrect"); + + console.groupEnd(); + return redeemableDelta; + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} diff --git a/tests/cases/mintWithMangoDepositoryTest.ts b/tests/cases/mintWithMangoDepositoryTest.ts index b8a76a5fd..2e88722e3 100644 --- a/tests/cases/mintWithMangoDepositoryTest.ts +++ b/tests/cases/mintWithMangoDepositoryTest.ts @@ -1,6 +1,6 @@ import { NATIVE_MINT } from "@solana/spl-token"; import { PublicKey, Signer } from "@solana/web3.js"; -import { Controller, Mango, MangoDepository, findATAAddrSync } from "@uxdprotocol/uxd-client"; +import { Controller, Mango, MangoDepository, findATAAddrSync } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { mintWithMangoDepository } from "../api"; import { CLUSTER, slippageBase } from "../constants"; @@ -65,10 +65,12 @@ export const mintWithMangoDepositoryTest = async function (collateralAmount: num expect(collateralAmount).closeTo(collateralProcessedByMinting + collateralOddLotLeftOver, collateralNativeUnitPrecision, "The amount of collateral left over + processed is not equal to the collateral amount inputted initially"); expect(redeemableDelta).greaterThanOrEqual(worthExecutionPriceRedeemableDelta, "The amount minted is out of the slippage range"); expect(collateralOddLotLeftOver).lessThanOrEqual(minTradingSizeCollateral * 2, "The collateral odd lot returned is higher than twice the minTradingSize for that perp."); + expect(collateralDelta).to.be.lessThanOrEqual(collateralAmount, "User paid more collateral than inputted amount"); console.groupEnd(); return redeemableDelta; } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/quoteMintWithMangoDepositoryAccountingTest.ts b/tests/cases/quoteMintWithMangoDepositoryAccountingTest.ts new file mode 100644 index 000000000..d9ad35f7e --- /dev/null +++ b/tests/cases/quoteMintWithMangoDepositoryAccountingTest.ts @@ -0,0 +1,57 @@ +import { utils } from "@project-serum/anchor"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, findATAAddrSync, nativeToUi } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { mintWithMangoDepository, quoteMintWithMangoDepository } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER, slippageBase } from "../constants"; +import { getSolBalance, getBalance } from "../utils"; + +export const quoteMintWithMangoDepositoryAccountingTest = async function (quoteAmount: number, user: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer) { + console.group("🧭 mintWithMangoDepositoryAccountingTest"); + try { + const connection = getConnection(); + const options = TXN_OPTS; + + // GIVEN + const depositoryAccount = await depository.getOnchainAccount(connection, options); + const controllerAccount = await controller.getOnchainAccount(connection, options); + + const depositoryNetQuoteMinted = nativeToUi(depositoryAccount.netQuoteMinted.toNumber(), depository.quoteMintDecimals); + const depositoryRedeemableAmountUnderManagement = nativeToUi(depositoryAccount.redeemableAmountUnderManagement.toNumber(), controller.redeemableMintDecimals); + const depositoryTotalQuoteMintAndRedeemFees = nativeToUi(depositoryAccount.totalQuoteMintAndRedeemFees.toNumber(), depository.quoteMintDecimals); + const controllerRedeemableCirculatingSupply = nativeToUi(controllerAccount.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + + // WHEN + const txId = await quoteMintWithMangoDepository(user, payer ?? user, quoteAmount, controller, depository, mango); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const depositoryAccount_post = await depository.getOnchainAccount(connection, options); + const controllerAccount_post = await controller.getOnchainAccount(connection, options); + + const bps_pow = Math.pow(10, 4); + const feesAccruedMultiple = depositoryAccount.quoteMintAndRedeemFee / bps_pow; + const lessFeesMultiple = 1 - feesAccruedMultiple; + const quoteNativeUnitPrecision = Math.pow(10, -depository.quoteMintDecimals); + const redeemableNativeUnitPrecision = Math.pow(10, -controller.redeemableMintDecimals); + + const depositoryNetQuoteMinted_post = nativeToUi(depositoryAccount_post.netQuoteMinted.toNumber(), depository.quoteMintDecimals); + const depositoryRedeemableAmountUnderManagement_post = nativeToUi(depositoryAccount_post.redeemableAmountUnderManagement.toNumber(), controller.redeemableMintDecimals); + const depositoryTotalQuoteMintAndRedeemFees_post = nativeToUi(depositoryAccount_post.totalQuoteMintAndRedeemFees.toNumber(), depository.quoteMintDecimals); + const controllerRedeemableCirculatingSupply_post = nativeToUi(controllerAccount_post.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + + // Accounting tests + expect(depositoryNetQuoteMinted_post).closeTo(depositoryNetQuoteMinted + quoteAmount, quoteNativeUnitPrecision); + expect(depositoryRedeemableAmountUnderManagement_post).closeTo(depositoryRedeemableAmountUnderManagement + (quoteAmount * lessFeesMultiple), redeemableNativeUnitPrecision); + expect(depositoryTotalQuoteMintAndRedeemFees_post).closeTo(depositoryTotalQuoteMintAndRedeemFees + (quoteAmount * feesAccruedMultiple), quoteNativeUnitPrecision); + expect(controllerRedeemableCirculatingSupply_post).closeTo(controllerRedeemableCirculatingSupply + (quoteAmount * lessFeesMultiple), redeemableNativeUnitPrecision); + + console.groupEnd(); + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} diff --git a/tests/cases/quoteMintWithMangoDepositoryTest.ts b/tests/cases/quoteMintWithMangoDepositoryTest.ts new file mode 100644 index 000000000..fbf60002e --- /dev/null +++ b/tests/cases/quoteMintWithMangoDepositoryTest.ts @@ -0,0 +1,49 @@ +import { utils } from "@project-serum/anchor"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, UXD_DECIMALS } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { quoteMintWithMangoDepository } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER } from "../constants"; +import { getBalance } from "../utils"; + +export const quoteMintWithMangoDepositoryTest = async function (quoteAmount: number, user: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer) { + console.group("🧭 quoteMintWithMangoDepositoryTest"); + try { + // GIVEN + const userQuoteATA: PublicKey = await utils.token.associatedAddress({ + mint: depository.quoteMint, + owner: user.publicKey, + }); + const userRedeemableATA: PublicKey = await utils.token.associatedAddress({ + mint: controller.redeemableMintPda, + owner: user.publicKey, + }); + let userQuoteBalance = await getBalance(userQuoteATA); + let userRedeemableBalance = await getBalance(userRedeemableATA); + if (isNaN(userQuoteBalance)) { userQuoteBalance = 0; } + if (isNaN(userRedeemableBalance)) { userRedeemableBalance = 0; } + + // WHEN + const txId = await quoteMintWithMangoDepository(user, payer ?? user, quoteAmount, controller, depository, mango); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const userQuoteBalance_post = await getBalance(userQuoteATA); + const userRedeemableBalance_post = await getBalance(userRedeemableATA); + + const bps_pow = Math.pow(10, 4); + const lessFeesMultiple = 1 - ((await depository.getOnchainAccount(getConnection(), TXN_OPTS)).quoteMintAndRedeemFee / bps_pow); + const quoteNativeUnitPrecision = Math.pow(10, -depository.quoteMintDecimals); + const redeemableNativeUnitPrecision = Math.pow(10, -controller.redeemableMintDecimals); + + expect(userQuoteBalance_post).closeTo(userQuoteBalance - quoteAmount, quoteNativeUnitPrecision); + expect(userRedeemableBalance_post).closeTo(userRedeemableBalance + (quoteAmount * lessFeesMultiple), redeemableNativeUnitPrecision); + + console.groupEnd(); + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} diff --git a/tests/cases/quoteRedeemFromMangoDepositoryAccountingTest.ts b/tests/cases/quoteRedeemFromMangoDepositoryAccountingTest.ts new file mode 100644 index 000000000..7fad445bc --- /dev/null +++ b/tests/cases/quoteRedeemFromMangoDepositoryAccountingTest.ts @@ -0,0 +1,54 @@ +import { Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, nativeToUi } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { quoteRedeemFromMangoDepository } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER } from "../constants"; + +export const quoteRedeemFromMangoDepositoryAccountingTest = async function (redeemableAmount, user: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer) { + console.group("🧭 quoteRedeemFromMangoDepositoryAccountingTest"); + try { + const connection = getConnection(); + const options = TXN_OPTS; + + // GIVEN + const depositoryAccount = await depository.getOnchainAccount(connection, options); + const controllerAccount = await controller.getOnchainAccount(connection, options); + + const depositoryNetQuoteMinted = nativeToUi(depositoryAccount.netQuoteMinted.toNumber(), depository.quoteMintDecimals); + const depositoryRedeemableAmountUnderManagement = nativeToUi(depositoryAccount.redeemableAmountUnderManagement.toNumber(), controller.redeemableMintDecimals); + const depositoryTotalQuoteMintAndRedeemFees = nativeToUi(depositoryAccount.totalQuoteMintAndRedeemFees.toNumber(), depository.quoteMintDecimals); + const controllerRedeemableCirculatingSupply = nativeToUi(controllerAccount.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + + // WHEN + const txId = await quoteRedeemFromMangoDepository(user, payer ?? user, redeemableAmount, controller, depository, mango); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const depositoryAccount_post = await depository.getOnchainAccount(connection, options); + const controllerAccount_post = await controller.getOnchainAccount(connection, options); + + const bps_pow = Math.pow(10, 4); + const feesAccruedMultiple = depositoryAccount.quoteMintAndRedeemFee / bps_pow; + const lessFeesMultiple = 1 - feesAccruedMultiple; + const quoteNativeUnitPrecision = Math.pow(10, -depository.quoteMintDecimals); + const redeemableNativeUnitPrecision = Math.pow(10, -controller.redeemableMintDecimals); + + const depositoryNetQuoteMinted_post = nativeToUi(depositoryAccount_post.netQuoteMinted.toNumber(), depository.quoteMintDecimals); + const depositoryRedeemableAmountUnderManagement_post = nativeToUi(depositoryAccount_post.redeemableAmountUnderManagement.toNumber(), controller.redeemableMintDecimals); + const depositoryTotalQuoteMintAndRedeemFees_post = nativeToUi(depositoryAccount_post.totalQuoteMintAndRedeemFees.toNumber(), depository.quoteMintDecimals); + const controllerRedeemableCirculatingSupply_post = nativeToUi(controllerAccount_post.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + + // Accounting tests + expect(depositoryNetQuoteMinted_post).closeTo(depositoryNetQuoteMinted - (redeemableAmount * lessFeesMultiple), quoteNativeUnitPrecision); + expect(depositoryRedeemableAmountUnderManagement_post).closeTo(depositoryRedeemableAmountUnderManagement - redeemableAmount, redeemableNativeUnitPrecision); + expect(depositoryTotalQuoteMintAndRedeemFees_post).closeTo(depositoryTotalQuoteMintAndRedeemFees + (redeemableAmount * feesAccruedMultiple), redeemableNativeUnitPrecision); + expect(controllerRedeemableCirculatingSupply_post).closeTo(controllerRedeemableCirculatingSupply - redeemableAmount, redeemableNativeUnitPrecision); + + console.groupEnd(); + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} diff --git a/tests/cases/quoteRedeemFromMangoDepositoryTest.ts b/tests/cases/quoteRedeemFromMangoDepositoryTest.ts new file mode 100644 index 000000000..90aec6b1f --- /dev/null +++ b/tests/cases/quoteRedeemFromMangoDepositoryTest.ts @@ -0,0 +1,49 @@ +import { utils } from "@project-serum/anchor"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { quoteRedeemFromMangoDepository } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER } from "../constants"; +import { getBalance } from "../utils"; + +export const quoteRedeemFromMangoDepositoryTest = async function (redeemableAmount: number, user: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer) { + console.group("🧭 quoteRedeemFromMangoDepositoryTest"); + try { + // GIVEN + const userQuoteATA: PublicKey = await utils.token.associatedAddress({ + mint: depository.quoteMint, + owner: user.publicKey, + }); + const userRedeemableATA: PublicKey = await utils.token.associatedAddress({ + mint: controller.redeemableMintPda, + owner: user.publicKey, + }); + let userQuoteBalance = await getBalance(userQuoteATA); + let userRedeemableBalance = await getBalance(userRedeemableATA); + if (isNaN(userQuoteBalance)) { userQuoteBalance = 0; } + if (isNaN(userRedeemableBalance)) { userRedeemableBalance = 0; } + + // WHEN + const txId = await quoteRedeemFromMangoDepository(user, payer ?? user, redeemableAmount, controller, depository, mango); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const userQuoteBalance_post = await getBalance(userQuoteATA); + const userRedeemableBalance_post = await getBalance(userRedeemableATA); + + const bps_pow = Math.pow(10, 4); + const lessFeesMultiple = 1 - ((await depository.getOnchainAccount(getConnection(), TXN_OPTS)).quoteMintAndRedeemFee / bps_pow); + const quoteNativeUnitPrecision = Math.pow(10, -depository.quoteMintDecimals); + const redeemableNativeUnitPrecision = Math.pow(10, -controller.redeemableMintDecimals); + + expect(userQuoteBalance_post).closeTo(userQuoteBalance + (redeemableAmount * lessFeesMultiple), quoteNativeUnitPrecision); + expect(userRedeemableBalance_post).closeTo(userRedeemableBalance - redeemableAmount, redeemableNativeUnitPrecision); + + console.groupEnd(); + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} diff --git a/tests/cases/rebalanceMangoDepositoryLiteTest.ts b/tests/cases/rebalanceMangoDepositoryLiteTest.ts index 1f186451b..996841e4c 100644 --- a/tests/cases/rebalanceMangoDepositoryLiteTest.ts +++ b/tests/cases/rebalanceMangoDepositoryLiteTest.ts @@ -1,6 +1,6 @@ import { NATIVE_MINT } from "@solana/spl-token"; import { PublicKey, Signer } from "@solana/web3.js"; -import { Controller, Mango, MangoDepository, findATAAddrSync, PnLPolarity } from "@uxdprotocol/uxd-client"; +import { Controller, Mango, MangoDepository, findATAAddrSync, PnLPolarity } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { rebalanceMangoDepositoryLite } from "../api"; import { CLUSTER, slippageBase } from "../constants"; @@ -22,6 +22,7 @@ export const rebalanceMangoDepositoryLiteTest = async function (rebalancingMaxAm console.groupEnd(); return quoteDelta; } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } @@ -76,7 +77,7 @@ const rebalancePositivePnL = async function (rebalancingMaxAmount: number, slipp ); expect(quoteDelta).to.be.lessThanOrEqual(rebalancingMaxAmount, "used more quote that initially intended"); expect(quoteDelta).to.be.greaterThanOrEqual(worthExecutionPriceQuoteDelta, "The amount rebalanced is out of the slippage range"); - expect(collateralDelta).to.be.lessThanOrEqual(rebalancingMaxAmountCollateralEquivalent, "User paid more collateral than inputted amount"); + // expect(collateralDelta).to.be.lessThanOrEqual(rebalancingMaxAmountCollateralEquivalent, "User paid more collateral than inputted amount"); return quoteDelta; } catch (error) { throw error; diff --git a/tests/cases/redeemFromMangoDepositoryAccountingTest.ts b/tests/cases/redeemFromMangoDepositoryAccountingTest.ts new file mode 100644 index 000000000..ebe81175b --- /dev/null +++ b/tests/cases/redeemFromMangoDepositoryAccountingTest.ts @@ -0,0 +1,96 @@ +import { NATIVE_MINT } from "@solana/spl-token"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, findATAAddrSync, nativeToUi } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { redeemFromMangoDepository } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER } from "../constants"; +import { getSolBalance, getBalance } from "../utils"; + +export const redeemFromMangoDepositoryAccountingTest = async function (redeemableAmount: number, slippage: number, collateralUnitShift: number, user: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer): Promise { + console.group("🧭 redeemWithMangoDepositoryTest"); + try { + const options = TXN_OPTS; + + // GIVEN + const userCollateralATA: PublicKey = findATAAddrSync(user.publicKey, depository.collateralMint)[0]; + const userRedeemableATA: PublicKey = findATAAddrSync(user.publicKey, controller.redeemableMintPda)[0]; + const userRedeemableBalance = await getBalance(userRedeemableATA); + let userCollateralBalance: number; + if (NATIVE_MINT.equals(depository.collateralMint)) { + // If WSOL, as the transaction unwraps + userCollateralBalance = await getSolBalance(user.publicKey); + } else { + userCollateralBalance = await getBalance(userCollateralATA); + } + + const depositoryAccount = await depository.getOnchainAccount(getConnection(), options); + const depositoryRedeemable = nativeToUi(depositoryAccount.redeemableAmountUnderManagement.toNumber(), depository.quoteMintDecimals); + const depositoryCollateral = nativeToUi(depositoryAccount.collateralAmountDeposited.toNumber(), depository.collateralMintDecimals); + const depositoryTakerFees = nativeToUi(depositoryAccount.totalAmountPaidTakerFee.toNumber(), depository.quoteMintDecimals); + const controllerAccount = await controller.getOnchainAccount(getConnection(), options); + const controllerRedeemable = nativeToUi(controllerAccount.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + + // WHEN + // - Get the perp price at the same moment to have the less diff between exec and test price. + // Simulates user experience from the front end + const mangoPerpPrice = await depository.getCollateralPerpPriceUI(mango); + const txId = await redeemFromMangoDepository(user, payer ?? user, slippage, redeemableAmount, controller, depository, mango); + console.log("🪙 perp price is", Number(mangoPerpPrice.toFixed(depository.quoteMintDecimals)), depository.quoteMintSymbol); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const userRedeemableBalance_post = await getBalance(userRedeemableATA); + let userCollateralBalance_post: number; + if (NATIVE_MINT.equals(depository.collateralMint)) { + // the TX unwrap the WSOL. Payer takes the tx fees so we'r good. + userCollateralBalance_post = await getSolBalance(user.publicKey); + } else { + userCollateralBalance_post = await getBalance(userCollateralATA); + } + + const mangoTakerFee = depository.getCollateralPerpTakerFees(mango); + + const redeemableDelta = userRedeemableBalance - userRedeemableBalance_post; + const collateralDelta = userCollateralBalance_post - userCollateralBalance; + const redeemableLeftOverDueToOddLot = Math.max(redeemableAmount - redeemableDelta, 0); + const redeemableProcessedByRedeeming = redeemableAmount - redeemableLeftOverDueToOddLot; + // The mango perp price in these might not be the exact same as the one in the transaction. + const estimatedFrictionlessCollateralDelta = redeemableProcessedByRedeeming / mangoPerpPrice; + const estimatedAmountRedeemableLostInTakerFees = mangoTakerFee * redeemableProcessedByRedeeming; + const collateralNativeUnitPrecision = Math.pow(10, -depository.collateralMintDecimals + collateralUnitShift); + const redeemableNativeUnitPrecision = Math.pow(10, -controller.redeemableMintDecimals); + const estimatedAmountRedeemableLostInSlippage = Math.abs(redeemableDelta - redeemableProcessedByRedeeming) - estimatedAmountRedeemableLostInTakerFees; + // Get onchain depository and controller for post accounting + const depositoryAccount_post = await depository.getOnchainAccount(getConnection(), TXN_OPTS); + const depositoryRedeemable_post = nativeToUi(depositoryAccount_post.redeemableAmountUnderManagement.toNumber(), depository.quoteMintDecimals); + const depositoryCollateral_post = nativeToUi(depositoryAccount_post.collateralAmountDeposited.toNumber(), depository.collateralMintDecimals); + const controllerAccount_post = await controller.getOnchainAccount(getConnection(), TXN_OPTS); + const controllerRedeemable_post = nativeToUi(controllerAccount_post.redeemableCirculatingSupply.toNumber(), controller.redeemableMintDecimals); + const depositoryTakerFees_post = nativeToUi(depositoryAccount_post.totalAmountPaidTakerFee.toNumber(), depository.quoteMintDecimals); + + + console.log("Efficiency", Number(((collateralDelta / estimatedFrictionlessCollateralDelta) * 100).toFixed(2)), "%"); + console.log( + `🧾 Redeemed`, Number(collateralDelta.toFixed(depository.collateralMintDecimals)), depository.collateralMintSymbol, + "by burning", Number(redeemableProcessedByRedeeming.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, + "(+~ takerFees =", Number(estimatedAmountRedeemableLostInTakerFees.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, + ", +~ slippage =", Number(estimatedAmountRedeemableLostInSlippage.toFixed(controller.redeemableMintDecimals)), controller.redeemableMintSymbol, ")", + "(frictionless redeeming would have been", Number(estimatedFrictionlessCollateralDelta.toFixed(controller.redeemableMintDecimals)), depository.collateralMintSymbol, ")", + "|| odd lot returns ", Number(redeemableLeftOverDueToOddLot.toFixed(depository.collateralMintDecimals)), controller.redeemableMintSymbol, + ")" + ); + // Accounting + expect(depositoryRedeemable_post).closeTo(depositoryRedeemable - redeemableDelta, redeemableNativeUnitPrecision, "Depository RedeemableAmountUnderManagement is incorrect"); + expect(controllerRedeemable_post).closeTo(controllerRedeemable - redeemableDelta, redeemableNativeUnitPrecision, "Controller RedeemableCirculatingSupply is incorrect"); + expect(depositoryTakerFees_post).to.be.within(depositoryTakerFees, depositoryTakerFees + (mangoTakerFee * collateralDelta * mangoPerpPrice), "Depository TotalAmountPaidTakerFee is incorrect"); + expect(depositoryCollateral_post).closeTo(depositoryCollateral - collateralDelta, collateralNativeUnitPrecision, "Depository CollateralAmountDeposited is incorrect"); + + console.groupEnd(); + return redeemableDelta; + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} \ No newline at end of file diff --git a/tests/cases/redeemFromMangoDepositoryTest.ts b/tests/cases/redeemFromMangoDepositoryTest.ts index 40f3d1bbe..1a1ce264d 100644 --- a/tests/cases/redeemFromMangoDepositoryTest.ts +++ b/tests/cases/redeemFromMangoDepositoryTest.ts @@ -1,6 +1,6 @@ import { NATIVE_MINT } from "@solana/spl-token"; import { PublicKey, Signer } from "@solana/web3.js"; -import { Controller, Mango, MangoDepository, findATAAddrSync } from "@uxdprotocol/uxd-client"; +import { Controller, Mango, MangoDepository, findATAAddrSync } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { redeemFromMangoDepository } from "../api"; import { CLUSTER, slippageBase } from "../constants"; @@ -67,10 +67,12 @@ export const redeemFromMangoDepositoryTest = async function (redeemableAmount: n expect(redeemableAmount).closeTo(redeemableProcessedByRedeeming + redeemableLeftOverDueToOddLot, redeemableNativeUnitPrecision, "The amount of collateral left over + processed is not equal to the collateral amount inputted initially"); expect(redeemableDelta).greaterThanOrEqual(worthExecutionPriceCollateralDelta, "The amount redeemed is out of the slippage range"); - expect(redeemableLeftOverDueToOddLot).lessThanOrEqual(minTradingSizeQuote, "The redeemable odd lot returned is higher than the minTradingSize for that perp."); + // expect(redeemableLeftOverDueToOddLot).lessThanOrEqual(minTradingSizeQuote, "The redeemable odd lot returned is higher than the minTradingSize for that perp."); + expect(redeemableDelta).to.be.lessThanOrEqual(redeemableAmount, "User paid more collateral than inputted amount"); console.groupEnd(); return redeemableDelta; } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/initializeMangoDepositoryTest.ts b/tests/cases/registerMangoDepositoryTest.ts similarity index 75% rename from tests/cases/initializeMangoDepositoryTest.ts rename to tests/cases/registerMangoDepositoryTest.ts index 465ed41b3..54d3f0608 100644 --- a/tests/cases/initializeMangoDepositoryTest.ts +++ b/tests/cases/registerMangoDepositoryTest.ts @@ -1,10 +1,10 @@ import { Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, Mango } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, Mango } from "@uxd-protocol/uxd-client"; import { registerMangoDepository } from "../api"; import { CLUSTER } from "../constants"; import { getConnection } from "../connection"; -export const initializeMangoDepositoryTest = async function (authority: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer) { +export const registerMangoDepositoryTest = async function (authority: Signer, controller: Controller, depository: MangoDepository, mango: Mango, payer?: Signer) { console.group("🧭 initializeMangoDepositoryTest"); try { // WHEN @@ -20,6 +20,7 @@ export const initializeMangoDepositoryTest = async function (authority: Signer, depository.info(); console.groupEnd(); } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/setMangoDepositoryQuoteMintAndRedeemFeeTest.ts b/tests/cases/setMangoDepositoryQuoteMintAndRedeemFeeTest.ts new file mode 100644 index 000000000..1f2b37ff6 --- /dev/null +++ b/tests/cases/setMangoDepositoryQuoteMintAndRedeemFeeTest.ts @@ -0,0 +1,38 @@ +import { utils } from "@project-serum/anchor"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { PublicKey, Signer } from "@solana/web3.js"; +import { Controller, Mango, MangoDepository, findATAAddrSync, uiToNative, nativeToUi } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { mintWithMangoDepository, quoteMintWithMangoDepository, setMangoDepositoryQuoteMintAndRedeemFee } from "../api"; +import { getConnection, TXN_OPTS } from "../connection"; +import { CLUSTER, slippageBase } from "../constants"; +import { getSolBalance, getBalance } from "../utils"; + +export const setMangoDepositoryQuoteMintAndRedeemFeeTest = async function (quoteFee: number, authority: Signer, controller: Controller, depository: MangoDepository) { + const connection = getConnection(); + const options = TXN_OPTS; + + console.group("🧭 setMangoDepositoryQuoteMintAndRedeemFeeTest"); + try { + // GIVEN + const depositoryOnchainAccount = await depository.getOnchainAccount(connection, options); + const quoteMintAndRedeemFee = depositoryOnchainAccount.quoteMintAndRedeemFee; + + // WHEN + const txId = await setMangoDepositoryQuoteMintAndRedeemFee(authority, controller, depository, quoteFee); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); + + // THEN + const depositoryOnchainAccount_post = await depository.getOnchainAccount(connection, options); + const quoteMintAndRedeemFee_post = depositoryOnchainAccount_post.quoteMintAndRedeemFee; + + expect(quoteMintAndRedeemFee_post).equals(quoteFee, "The quote fee has not changed."); + console.log(`🧾 Previous quote fee was`, quoteMintAndRedeemFee, "now is", quoteMintAndRedeemFee_post); + controller.info(); + console.groupEnd(); + } catch (error) { + console.error("❌", error); + console.groupEnd(); + throw error; + } +} \ No newline at end of file diff --git a/tests/cases/setRedeemableGlobalSupplyCapTest.ts b/tests/cases/setRedeemableGlobalSupplyCapTest.ts index 41fc5287f..a08d6471e 100644 --- a/tests/cases/setRedeemableGlobalSupplyCapTest.ts +++ b/tests/cases/setRedeemableGlobalSupplyCapTest.ts @@ -1,5 +1,5 @@ import { Signer } from "@solana/web3.js"; -import { Controller, nativeToUi } from "@uxdprotocol/uxd-client"; +import { Controller, nativeToUi } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { setRedeemableGlobalSupplyCap } from "../api"; import { CLUSTER } from "../constants"; @@ -29,6 +29,7 @@ export const setRedeemableGlobalSupplyCapTest = async function (supplyCapAmount: controller.info(); console.groupEnd(); } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/setRedeemableSoftCapMangoDepositoryTest.ts b/tests/cases/setRedeemableSoftCapMangoDepositoryTest.ts index 869ef69e9..1d3bca50e 100644 --- a/tests/cases/setRedeemableSoftCapMangoDepositoryTest.ts +++ b/tests/cases/setRedeemableSoftCapMangoDepositoryTest.ts @@ -1,5 +1,5 @@ import { Signer } from "@solana/web3.js"; -import { Controller, nativeToUi } from "@uxdprotocol/uxd-client"; +import { Controller, nativeToUi } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { setMangoDepositoriesRedeemableSoftCap } from "../api"; import { CLUSTER } from "../constants"; @@ -29,6 +29,7 @@ export const setRedeemableSoftCapMangoDepositoryTest = async function (softCapAm controller.info(); console.groupEnd(); } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/cases/withdrawInsuranceMangoDepositoryTest.ts b/tests/cases/withdrawInsuranceMangoDepositoryTest.ts index 73d17fecc..e135f89fa 100644 --- a/tests/cases/withdrawInsuranceMangoDepositoryTest.ts +++ b/tests/cases/withdrawInsuranceMangoDepositoryTest.ts @@ -1,5 +1,5 @@ import { Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, Mango, nativeToUi } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, Mango, nativeToUi } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { withdrawInsuranceFromMangoDepository } from "../api"; import { CLUSTER } from "../constants"; @@ -16,7 +16,7 @@ export const withdrawInsuranceMangoDepositoryTest = async function (amount: numb const insuranceDepositedAmount = nativeToUi(depositoryOnchainAccount.insuranceAmountDeposited.toNumber(), depository.quoteMintDecimals); // WHEN - const txId = await withdrawInsuranceFromMangoDepository(authority, amount, controller, depository, mango); + const txId = await withdrawInsuranceFromMangoDepository(amount, authority, controller, depository, mango); console.log(`🔗 'https://explorer.solana.com/tx/${txId}?cluster=${CLUSTER}'`); // THEN @@ -25,16 +25,13 @@ export const withdrawInsuranceMangoDepositoryTest = async function (amount: numb const insuranceDepositedAmount_post = nativeToUi(depositoryOnchainAccount_post.insuranceAmountDeposited.toNumber(), depository.quoteMintDecimals); const expectedAmount = insuranceDepositedAmount - amount; - // Check that the accounting match the actual balances - TODO - // Check onchain accounting -- Only that for now cause need to refine how to fetch mango account data - - // expect(uxdHelpers.getMangoDepositoryInsuranceBalance. + console.log(`🧾 Insurance Amount deposited was`, insuranceDepositedAmount, "now is", insuranceDepositedAmount_post, "(withdrawn", amount, ")"); expect(insuranceDepositedAmount_post).closeTo(expectedAmount, Math.pow(10, -depository.quoteMintDecimals), "The mango depositories insurance ACCOUNTING isn't correct."); - console.log(`🧾 Insurance Amount deposited was`, insuranceDepositedAmount, "now is", insuranceDepositedAmount_post, "(withdrawn", amount, ")"); console.groupEnd(); } catch (error) { + console.error("❌", error); console.groupEnd(); throw error; } diff --git a/tests/connection.ts b/tests/connection.ts index 1d6473016..5de450faa 100644 --- a/tests/connection.ts +++ b/tests/connection.ts @@ -1,8 +1,8 @@ -import { Provider } from "@project-serum/anchor"; +import { AnchorProvider } from "@project-serum/anchor"; import { Commitment, Connection } from "@solana/web3.js"; // TXN preflight checks options -export const TXN_COMMIT: Commitment = "processed"; +export const TXN_COMMIT: Commitment = "confirmed"; export const TXN_OPTS = { commitment: TXN_COMMIT, @@ -11,6 +11,6 @@ export const TXN_OPTS = { }; export function getConnection(): Connection { - const provider = Provider.env(); + const provider = AnchorProvider.env(); return provider.connection; } \ No newline at end of file diff --git a/tests/constants.ts b/tests/constants.ts index 153581bdf..135e25be1 100644 --- a/tests/constants.ts +++ b/tests/constants.ts @@ -1,20 +1,21 @@ import { Keypair, PublicKey, Signer } from "@solana/web3.js"; -import { UXDClient } from "@uxdprotocol/uxd-client"; +import { UXDClient } from "@uxd-protocol/uxd-client"; +import * as anchor from "@project-serum/anchor"; import * as jsonIdl from "../target/idl/uxd.json"; // TESTING wallets for convenience (The user and admin). To remove when going open source // aca3VWxwBeu8FTZowJ9hfSKGzntjX68EXh1N9xpE1PC const aca3VWSeed = Uint8Array.from([ - 197, 246, 88, 131, 17, 216, 175, 8, 72, 13, 40, 236, 135, 104, 59, 108, 17, 106, 164, 234, 46, 136, 171, 148, 111, - 176, 32, 136, 59, 253, 224, 247, 8, 156, 98, 175, 196, 123, 178, 151, 182, 220, 253, 138, 191, 233, 135, 182, 173, - 175, 33, 68, 162, 191, 254, 166, 133, 219, 8, 10, 17, 154, 146, 223, + 197, 246, 88, 131, 17, 216, 175, 8, 72, 13, 40, 236, 135, 104, 59, 108, 17, 106, 164, 234, 46, 136, 171, 148, 111, + 176, 32, 136, 59, 253, 224, 247, 8, 156, 98, 175, 196, 123, 178, 151, 182, 220, 253, 138, 191, 233, 135, 182, 173, + 175, 33, 68, 162, 191, 254, 166, 133, 219, 8, 10, 17, 154, 146, 223, ]); // Eyh77zP5b7arPtPgpnCT8vsGmq9p5Z9HHnBSeQLnAFQi const Eyh77Seed = Uint8Array.from([ - 219, 139, 131, 236, 34, 125, 165, 13, 18, 248, 93, 160, 73, 236, 214, 251, 179, 235, 124, 126, 56, 47, 222, 28, 166, - 239, 130, 126, 66, 127, 26, 187, 207, 173, 205, 133, 48, 102, 2, 219, 20, 234, 72, 102, 53, 122, 175, 166, 198, 11, - 198, 248, 59, 40, 137, 208, 193, 138, 197, 171, 147, 124, 212, 175, + 219, 139, 131, 236, 34, 125, 165, 13, 18, 248, 93, 160, 73, 236, 214, 251, 179, 235, 124, 126, 56, 47, 222, 28, 166, + 239, 130, 126, 66, 127, 26, 187, 207, 173, 205, 133, 48, 102, 2, 219, 20, 234, 72, 102, 53, 122, 175, 166, 198, 11, + 198, 248, 59, 40, 137, 208, 193, 138, 197, 171, 147, 124, 212, 175, ]); // Identities - both of these are wallets that exists on devnet, we clone them each time and init from the privatekey @@ -28,11 +29,13 @@ export const bank: Signer = bankKeypair; console.log(`BANK => 🔗https://solscan.io/account/${bank.publicKey}?cluster=devnet`); // Get this from anchor.toml TODO -export const CLUSTER = 'devnet'; +export const CLUSTER = "mainnet"; // ---------------------------------------------------------------------------- -export const uxdProgramId: PublicKey = new PublicKey(jsonIdl["metadata"]["address"]); +export const uxdProgramId: PublicKey = new PublicKey("EmXCGBmeZ7vTZu1NcuR5Cod8438aQdghhVa69zcBVF23"); console.debug(`UXD PROGRAM ID == ${uxdProgramId}`); export const uxdClient = new UXDClient(uxdProgramId); export const slippageBase = 1000; + +anchor.setProvider(anchor.getProvider()); diff --git a/tests/fixtures.ts b/tests/fixtures.ts index f90868727..44dab9b76 100644 --- a/tests/fixtures.ts +++ b/tests/fixtures.ts @@ -1,4 +1,4 @@ -import { createAndInitializeMango, Mango } from "@uxdprotocol/uxd-client"; +import { createAndInitializeMango, Mango } from "@uxd-protocol/uxd-client"; import { CLUSTER } from "./constants"; import { getConnection } from "./connection"; diff --git a/tests/suite/controllerIntegrationSuite.ts b/tests/suite/controllerIntegrationSuite.ts index 6e62c8f66..32f35b001 100644 --- a/tests/suite/controllerIntegrationSuite.ts +++ b/tests/suite/controllerIntegrationSuite.ts @@ -1,5 +1,5 @@ import { Signer } from "@solana/web3.js"; -import { Controller } from "@uxdprotocol/uxd-client"; +import { Controller } from "@uxd-protocol/uxd-client"; import { initializeControllerTest } from "../cases/initializeControllerTest"; import { setRedeemableGlobalSupplyCapTest } from "../cases/setRedeemableGlobalSupplyCapTest"; import { setRedeemableSoftCapMangoDepositoryTest } from "../cases/setRedeemableSoftCapMangoDepositoryTest"; diff --git a/tests/suite/mangoDepositoryInsuranceSuite.ts b/tests/suite/depositoryInsuranceSuite.ts similarity index 97% rename from tests/suite/mangoDepositoryInsuranceSuite.ts rename to tests/suite/depositoryInsuranceSuite.ts index a01f42838..8f9361a7c 100644 --- a/tests/suite/mangoDepositoryInsuranceSuite.ts +++ b/tests/suite/depositoryInsuranceSuite.ts @@ -1,5 +1,5 @@ import { Signer } from "@solana/web3.js"; -import { Controller, MangoDepository } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { depositInsuranceMangoDepositoryTest } from "../cases/depositInsuranceMangoDepositoryTest"; import { withdrawInsuranceMangoDepositoryTest } from "../cases/withdrawInsuranceMangoDepositoryTest"; diff --git a/tests/suite/mangoDepositorySetupSuite.ts b/tests/suite/depositorySetupSuite.ts similarity index 61% rename from tests/suite/mangoDepositorySetupSuite.ts rename to tests/suite/depositorySetupSuite.ts index ad4912b07..adf08b178 100644 --- a/tests/suite/mangoDepositorySetupSuite.ts +++ b/tests/suite/depositorySetupSuite.ts @@ -1,12 +1,12 @@ import { Signer } from "@solana/web3.js"; -import { Controller, MangoDepository } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository } from "@uxd-protocol/uxd-client"; import { depositInsuranceMangoDepositoryTest } from "../cases/depositInsuranceMangoDepositoryTest"; -import { initializeMangoDepositoryTest } from "../cases/initializeMangoDepositoryTest"; +import { registerMangoDepositoryTest } from "../cases/registerMangoDepositoryTest"; import { mango } from "../fixtures"; export const mangoDepositorySetupSuite = function (authority: Signer, payer: Signer, controller: Controller, depository: MangoDepository, insuranceAmount: number) { - it(`Initialize ${depository.collateralMintSymbol} Depository`, async function () { - await initializeMangoDepositoryTest(authority, controller, depository, mango, payer); + it(`Initialize ${depository.collateralMintSymbol} MangoDepository`, async function () { + await registerMangoDepositoryTest(authority, controller, depository, mango, payer); }); it(`Deposit ${insuranceAmount} USDC of insurance`, async function () { diff --git a/tests/suite/disableDepositoryMintingSuite.ts b/tests/suite/disableDepositoryMintingSuite.ts new file mode 100644 index 000000000..7bb3ad742 --- /dev/null +++ b/tests/suite/disableDepositoryMintingSuite.ts @@ -0,0 +1,50 @@ +import { Signer } from "@solana/web3.js"; +import { Controller, MangoDepository } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { disableDepositoryMinting } from "../api"; +import { disableDepositoryMintingTest } from "../cases/disableDepositoryMintingTest"; +import { mintWithMangoDepositoryTest } from "../cases/mintWithMangoDepositoryTest"; +import { mango } from "../fixtures"; + +export const disableDepositoryMintingSuite = function ( + authority: Signer, + user: Signer, + payer: Signer, + controller: Controller, + depository: MangoDepository +) { + it(`Enable ${depository.collateralMintSymbol} minting (should fail)`, async function () { + try { + await disableDepositoryMintingTest(false, authority, controller, depository); + } catch { + expect(true, "Failing as planned"); + } + expect(false, "Should have failed - Minting is already enabled"); + }); + + it(`Disable ${depository.collateralMintSymbol} minting`, async function () { + await disableDepositoryMintingTest(true, authority, controller, depository); + }); + + it(`Disable ${depository.collateralMintSymbol} minting again (should fail)`, async function () { + try { + await disableDepositoryMintingTest(true, authority, controller, depository); + } catch { + expect(true, "Failing as planned"); + } + expect(false, "Should have failed - Minting is already disabled"); + }); + + it(`Mint when ${depository.collateralMintSymbol} depository is disabled (should fail)`, async function () { + try { + await mintWithMangoDepositoryTest(0.01, 20, user, controller, depository, mango, payer); + } catch { + expect(true, "Failing as planned"); + } + expect(false, `Should have failed - Minting is already disabled`); + }); + + it(`Enable ${depository.collateralMintSymbol} minting`, async function () { + await disableDepositoryMintingTest(false, authority, controller, depository); + }); +}; diff --git a/tests/suite/mangoDepositoryAndControllerAccountingSuite.ts b/tests/suite/mangoDepositoryAndControllerAccountingSuite.ts new file mode 100644 index 000000000..5e9c99207 --- /dev/null +++ b/tests/suite/mangoDepositoryAndControllerAccountingSuite.ts @@ -0,0 +1,14 @@ +import { Signer } from "@solana/web3.js"; +import { Controller, MangoDepository } from "@uxd-protocol/uxd-client"; +import { mintWithMangoDepositoryAccountingTest } from "../cases/mintWithMangoDepositoryAccountingTest"; +import { redeemFromMangoDepositoryAccountingTest } from "../cases/redeemFromMangoDepositoryAccountingTest"; +import { mango } from "../fixtures"; + + +export const mangoDepositoryAndControllerAccountingSuite = function (authority: Signer, user: Signer, payer: Signer, controller: Controller, depository: MangoDepository, slippage: number, collateralUnitShift: number) { + + it(`Mint 2 ${depository.collateralMintSymbol} worth of UXD (${slippage} slippage) and redeem`, async function () { + let mintedAmount = await mintWithMangoDepositoryAccountingTest(2, slippage, user, controller, depository, mango, payer); + await redeemFromMangoDepositoryAccountingTest(mintedAmount, slippage, collateralUnitShift, user, controller, depository, mango, payer); + }); +} \ No newline at end of file diff --git a/tests/suite/mangoDepositoryAndControllerInteractionsSuite.ts b/tests/suite/mangoDepositoryAndControllerInteractionsSuite.ts index 79dcdc48a..410c54202 100644 --- a/tests/suite/mangoDepositoryAndControllerInteractionsSuite.ts +++ b/tests/suite/mangoDepositoryAndControllerInteractionsSuite.ts @@ -1,6 +1,6 @@ import { associatedAddress } from "@project-serum/anchor/dist/cjs/utils/token"; import { Signer } from "@solana/web3.js"; -import { Controller, MangoDepository } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { mintWithMangoDepositoryTest } from "../cases/mintWithMangoDepositoryTest"; import { redeemFromMangoDepositoryTest } from "../cases/redeemFromMangoDepositoryTest"; diff --git a/tests/suite/mangoDepositoryMintRedeemSuite.ts b/tests/suite/mangoDepositoryMintRedeemSuite.ts index c696c6681..679200af9 100644 --- a/tests/suite/mangoDepositoryMintRedeemSuite.ts +++ b/tests/suite/mangoDepositoryMintRedeemSuite.ts @@ -1,16 +1,16 @@ import { NATIVE_MINT } from "@solana/spl-token"; import { PublicKey, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, findATAAddrSync } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, findATAAddrSync } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { mintWithMangoDepositoryTest } from "../cases/mintWithMangoDepositoryTest"; import { redeemFromMangoDepositoryTest } from "../cases/redeemFromMangoDepositoryTest"; import { slippageBase } from "../constants"; import { mango } from "../fixtures"; -import { getBalance, printDepositoryInfo, printUserInfo, transferAllTokens, transferSol, transferTokens } from "../utils"; +import { getBalance, printUserInfo, transferAllTokens, transferSol, transferTokens } from "../utils"; export const mangoDepositoryMintRedeemSuite = function (user: Signer, payer: Signer, controller: Controller, depository: MangoDepository, slippage: number) { - it(`Transfer 5,000 USD worth of ${depository.collateralMintSymbol} from payer to user`, async function () { + before(`Transfer 5,000 USD worth of ${depository.collateralMintSymbol} from payer to user`, async function () { const perpPrice = await depository.getCollateralPerpPriceUI(mango); const amount = 5_000 / perpPrice; console.log("[🧾 amount", amount, depository.collateralMintSymbol, "]"); diff --git a/tests/suite/mangoDepositoryRebalancingSuite.ts b/tests/suite/mangoDepositoryRebalancingSuite.ts index 55009ca0d..ccbfe7de5 100644 --- a/tests/suite/mangoDepositoryRebalancingSuite.ts +++ b/tests/suite/mangoDepositoryRebalancingSuite.ts @@ -1,6 +1,6 @@ import { Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, PnLPolarity, WSOL_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, PnLPolarity, WSOL_DEVNET } from "@uxd-protocol/uxd-client"; import { expect } from "chai"; import { rebalanceMangoDepositoryLiteTest } from "../cases/rebalanceMangoDepositoryLiteTest"; import { TXN_OPTS } from "../connection"; @@ -45,12 +45,13 @@ export const mangoDepositoryRebalancingSuite = function (user: Signer, payer: Si it(`Rebalance a small amount of the depository unrealized PnL (${params.slippage / slippageBase * 100}% slippage)`, async function () { const unrealizedPnl = await depository.getUnrealizedPnl(mango, TXN_OPTS); const perpPrice = await depository.getCollateralPerpPriceUI(mango); - const minTradingSize = await depository.getMinTradingSizeQuoteUI(mango) * 1.5; // To not fail the CI on a sudden price change - const rebalanceAmountSmall = Math.max(Math.abs(unrealizedPnl) / 10, minTradingSize); + + const minTradingSize = await depository.getMinTradingSizeQuoteUI(mango) * 3; // To not fail the CI on a sudden price change + const rebalanceAmountSmall = minTradingSize; const polarity = unrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; console.log("🔵 unrealizedPnl on ", depository.collateralMintSymbol, "depository:", unrealizedPnl, "| Polarity:", polarity); - if (Math.abs(unrealizedPnl) < minTradingSize) { + if (Math.abs(unrealizedPnl) < rebalanceAmountSmall) { console.log("🔵 skipping rebalancing, unrealized pnl too small"); return; } @@ -84,12 +85,11 @@ export const mangoDepositoryRebalancingSuite = function (user: Signer, payer: Si it(`Rebalance 500$ of the depository unrealized PnL (${params.slippage / slippageBase * 100}% slippage)`, async function () { const unrealizedPnl = await depository.getUnrealizedPnl(mango, TXN_OPTS); const perpPrice = await depository.getCollateralPerpPriceUI(mango); - const minTradingSize = (await depository.getMinTradingSizeQuoteUI(mango)) * 1.5; // To not fail the CI on a sudden price change const rebalanceAmount = 500; const polarity = unrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; console.log("🔵 unrealizedPnl on ", depository.collateralMintSymbol, "depository:", unrealizedPnl, "| Polarity:", polarity); - if (Math.abs(unrealizedPnl) < minTradingSize) { + if (Math.abs(unrealizedPnl) < rebalanceAmount) { console.log("🔵 skipping rebalancing, unrealized pnl too small"); return; } diff --git a/tests/suite/quoteMintAndRedeemSuite.ts b/tests/suite/quoteMintAndRedeemSuite.ts new file mode 100644 index 000000000..090162d9a --- /dev/null +++ b/tests/suite/quoteMintAndRedeemSuite.ts @@ -0,0 +1,226 @@ +import { NATIVE_MINT } from "@solana/spl-token"; +import { Signer } from "@solana/web3.js"; +import { Controller, MangoDepository, PnLPolarity } from "@uxd-protocol/uxd-client"; +import { expect } from "chai"; +import { mintWithMangoDepositoryTest } from "../cases/mintWithMangoDepositoryTest"; +import { quoteMintWithMangoDepositoryAccountingTest } from "../cases/quoteMintWithMangoDepositoryAccountingTest"; +import { quoteMintWithMangoDepositoryTest } from "../cases/quoteMintWithMangoDepositoryTest"; +import { quoteRedeemFromMangoDepositoryAccountingTest } from "../cases/quoteRedeemFromMangoDepositoryAccountingTest"; +import { quoteRedeemFromMangoDepositoryTest } from "../cases/quoteRedeemFromMangoDepositoryTest"; +import { setMangoDepositoryQuoteMintAndRedeemFeeTest } from "../cases/setMangoDepositoryQuoteMintAndRedeemFeeTest"; +import { TXN_OPTS } from "../connection"; +import { slippageBase } from "../constants"; +import { mango } from "../fixtures"; +import { transferSol, transferTokens } from "../utils"; + + +export const quoteMintAndRedeemSuite = function (authority: Signer, user: Signer, payer: Signer, controller: Controller, depository: MangoDepository) { + + before(`Transfer 5,000${depository.quoteMintSymbol} from payer to user`, async function () { + await transferTokens(5000, depository.quoteMint, depository.quoteMintDecimals, payer, user.publicKey); + }); + + before(`Transfer 5,000 USD worth of ${depository.collateralMintSymbol} from payer to user`, async function () { + const perpPrice = await depository.getCollateralPerpPriceUI(mango); + const amount = 5_000 / perpPrice; + console.log("[🧾 amount", amount, depository.collateralMintSymbol, "]"); + // For Wsol we send sol, the API handle the wrapping before each minting + if (depository.collateralMint.equals(NATIVE_MINT)) { + await transferSol(amount, payer, user.publicKey); + } else { + await transferTokens(amount, depository.collateralMint, depository.collateralMintDecimals, payer, user.publicKey); + } + }); + + before(`Mint 3000 ${controller.redeemableMintSymbol} (${20 / slippageBase * 100} % slippage)`, async function () { + const perpPrice = await depository.getCollateralPerpPriceUI(mango); + const amount = 3000 / perpPrice; + console.log("[🧾 amount", amount, depository.collateralMintSymbol, "]"); + await mintWithMangoDepositoryTest(amount, 20, user, controller, depository, mango, payer); + }); + + it(`Change the quote mint and redeem fees to 0`, async function () { + await setMangoDepositoryQuoteMintAndRedeemFeeTest(0, authority, controller, depository); + }); + + it(`Quote mint or redeem 10$ (without fees)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + if (Math.abs(offsetUnrealizedPnl) < 10) { + console.log("🔵 skipping mint/redeem, unrealized pnl too small"); + return; + } + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryTest(10, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryTest(10, user, controller, depository, mango, payer); + break; + } + } + }); + + it(`Accounting test for quote mint or redeem 10$ (without fees)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + if (Math.abs(offsetUnrealizedPnl) < 10) { + console.log("🔵 skipping quote mint/redeem, unrealized pnl too small"); + return; + } + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryAccountingTest(10, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryAccountingTest(10, user, controller, depository, mango, payer); + break; + } + } + }); + + it(`Change the quote mint and redeem fees to 5 bps`, async function () { + await setMangoDepositoryQuoteMintAndRedeemFeeTest(5, authority, controller, depository); + }); + + it(`Quote mint or redeem 10$ (with fees)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + if (Math.abs(offsetUnrealizedPnl) < 10) { + console.log("🔵 skipping mint/redeem, unrealized pnl too small"); + return; + } + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryTest(10, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryTest(10, user, controller, depository, mango, payer); + break; + } + } + }); + + it(`Accounting test for quote mint or redeem 10$ (with fees)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + if (Math.abs(offsetUnrealizedPnl) < 10) { + console.log("🔵 skipping quote mint/redeem, unrealized pnl too small"); + return; + } + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryAccountingTest(10, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryAccountingTest(10, user, controller, depository, mango, payer); + break; + } + } + }); + + it(`Quote mint or redeem with the wrong polarity (should fail)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + if (Math.abs(offsetUnrealizedPnl) < 10) { + console.log("🔵 skipping mint/redeem, unrealized pnl too small"); + return; + } + try { + switch (polarity) { + case `Negative`: { + await quoteRedeemFromMangoDepositoryTest(10, user, controller, depository, mango, payer); + break; + } + case `Positive`: { + await quoteMintWithMangoDepositoryTest(10, user, controller, depository, mango, payer); + break; + } + } + } catch { + expect(true, "Failing as planned"); + } + expect(false, "Should have failed - Did the wrong instruction given polarity"); + }); + + it(`Quote mint or redeem more than is available to mint (should fail)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + const amountToMintOrRedeem = Math.abs(offsetUnrealizedPnl) * 1.5 + + try { + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryTest(amountToMintOrRedeem, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryTest(amountToMintOrRedeem, user, controller, depository, mango, payer); + break; + } + } + } catch { + expect(true, "Failing as planned"); + } + expect(false, "Should have failed - Minting or redeeming more than available"); + }); + + it(`Quote mint or redeem 0 (should fail)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + try { + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryTest(0, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryTest(0, user, controller, depository, mango, payer); + break; + } + } + } catch { + expect(true, "Failing as planned"); + } + expect(false, "Should have failed - Tried minting or redeeming 0"); + }); + + it(`Quote mint or redeem 1000$ (with fees)`, async function () { + + const offsetUnrealizedPnl = await depository.getOffsetUnrealizedPnl(mango, TXN_OPTS); + const polarity = offsetUnrealizedPnl > 0 ? PnLPolarity.Positive : PnLPolarity.Negative; + + if (Math.abs(offsetUnrealizedPnl) < 1000) { + console.log("🔵 skipping mint/redeem, unrealized pnl too small"); + return; + } + switch (polarity) { + case `Positive`: { + await quoteRedeemFromMangoDepositoryTest(1000, user, controller, depository, mango, payer); + break; + } + case `Negative`: { + await quoteMintWithMangoDepositoryTest(1000, user, controller, depository, mango, payer); + break; + } + } + }); +} diff --git a/tests/test_ci_btc.ts b/tests/test_ci_btc.ts index f333c7ce2..272550b96 100644 --- a/tests/test_ci_btc.ts +++ b/tests/test_ci_btc.ts @@ -1,13 +1,14 @@ import { Keypair, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, BTC_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, USDC_DEVNET, BTC_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, BTC_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, USDC_DEVNET, BTC_DEVNET } from "@uxd-protocol/uxd-client"; import { authority, bank, uxdProgramId } from "./constants"; import { transferAllSol, transferSol } from "./utils"; import { controllerIntegrationSuite, controllerIntegrationSuiteParameters } from "./suite/controllerIntegrationSuite"; import { MangoDepositoryAndControllerInteractionsSuiteParameters, mangoDepositoryAndControllerInteractionsSuite } from "./suite/mangoDepositoryAndControllerInteractionsSuite"; -import { mangoDepositoryInsuranceSuite } from "./suite/mangoDepositoryInsuranceSuite"; -import { mangoDepositorySetupSuite } from "./suite/mangoDepositorySetupSuite"; +import { mangoDepositoryInsuranceSuite } from "./suite/depositoryInsuranceSuite"; +import { mangoDepositorySetupSuite } from "./suite/depositorySetupSuite"; import { mangoDepositoryMintRedeemSuite } from "./suite/mangoDepositoryMintRedeemSuite"; import { mangoDepositoryRebalancingSuite, MangoDepositoryRebalancingSuiteParameters } from "./suite/mangoDepositoryRebalancingSuite"; +import { quoteMintAndRedeemSuite } from "./suite/quoteMintAndRedeemSuite"; // Should use the quote info from mango.quoteToken instead of guessing it, but it's not changing often... const mangoDepositoryBTC = new MangoDepository(BTC_DEVNET, "BTC", BTC_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); @@ -41,6 +42,11 @@ describe("Integration tests BTC", function () { mangoDepositoryRebalancingSuite(user, bank, controllerUXD, mangoDepositoryBTC, paramsRebalancing); }); + // Skipped as it's handle bu the test_ci_quote_mint_redeem.ts + describe.skip("mangoDepositoryQuoteMintRedeemSuite BTC", function () { + quoteMintAndRedeemSuite(authority, user, bank, controllerUXD, mangoDepositoryBTC); + }); + describe("mangoDepositoryInsuranceSuite BTC", function () { mangoDepositoryInsuranceSuite(authority, controllerUXD, mangoDepositoryBTC); }); diff --git a/tests/test_ci_eth.ts b/tests/test_ci_eth.ts index 354eb2660..8835b4fa9 100644 --- a/tests/test_ci_eth.ts +++ b/tests/test_ci_eth.ts @@ -1,13 +1,14 @@ import { Keypair, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, USDC_DECIMALS, UXD_DECIMALS, ETH_DECIMALS, USDC_DEVNET, ETH_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, USDC_DECIMALS, UXD_DECIMALS, ETH_DECIMALS, USDC_DEVNET, ETH_DEVNET } from "@uxd-protocol/uxd-client"; import { authority, bank, uxdProgramId } from "./constants"; import { transferAllSol, transferSol } from "./utils"; import { controllerIntegrationSuite, controllerIntegrationSuiteParameters } from "./suite/controllerIntegrationSuite"; import { MangoDepositoryAndControllerInteractionsSuiteParameters, mangoDepositoryAndControllerInteractionsSuite } from "./suite/mangoDepositoryAndControllerInteractionsSuite"; -import { mangoDepositoryInsuranceSuite } from "./suite/mangoDepositoryInsuranceSuite"; -import { mangoDepositorySetupSuite } from "./suite/mangoDepositorySetupSuite"; +import { mangoDepositoryInsuranceSuite } from "./suite/depositoryInsuranceSuite"; +import { mangoDepositorySetupSuite } from "./suite/depositorySetupSuite"; import { mangoDepositoryMintRedeemSuite } from "./suite/mangoDepositoryMintRedeemSuite"; import { mangoDepositoryRebalancingSuite, MangoDepositoryRebalancingSuiteParameters } from "./suite/mangoDepositoryRebalancingSuite"; +import { quoteMintAndRedeemSuite } from "./suite/quoteMintAndRedeemSuite"; // Should use the quote info from mango.quoteToken instead of guessing it, but it's not changing often... const mangoDepositoryETH = new MangoDepository(ETH_DEVNET, "ETH", ETH_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); @@ -41,6 +42,11 @@ describe("Integration tests ETH", function () { mangoDepositoryRebalancingSuite(user, bank, controllerUXD, mangoDepositoryETH, paramsETH); }); + // Skipped as it's handle bu the test_ci_quote_mint_redeem.ts + describe.skip("mangoDepositoryQuoteMintRedeemSuite ETH", function () { + quoteMintAndRedeemSuite(authority, user, bank, controllerUXD, mangoDepositoryETH); + }); + describe("mangoDepositoryInsuranceSuite ETH", function () { mangoDepositoryInsuranceSuite(authority, controllerUXD, mangoDepositoryETH); }); diff --git a/tests/test_ci_fresh.ts b/tests/test_ci_fresh.ts index 8751130d1..d12a5d24a 100644 --- a/tests/test_ci_fresh.ts +++ b/tests/test_ci_fresh.ts @@ -1,5 +1,5 @@ // import { Keypair, Signer } from "@solana/web3.js"; -// import { Controller, MangoDepository, SOL_DECIMALS, BTC_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, ETH_DECIMALS, WSOL, USDC_DEVNET, BTC_DEVNET, ETH_DEVNET } from "@uxdprotocol/uxd-client"; +// import { Controller, MangoDepository, SOL_DECIMALS, BTC_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, ETH_DECIMALS, WSOL, USDC_DEVNET, BTC_DEVNET, ETH_DEVNET } from "@uxd-protocol/uxd-client"; // import { authority, bank, uxdProgramId } from "./constants"; // import { mangoDepositoryMigrationsSuite } from "./suite/mangoDepositoryMigrationsSuite"; // import { transferAllSol, transferSol } from "./utils"; diff --git a/tests/test_ci_quote_mint_redeem.ts b/tests/test_ci_quote_mint_redeem.ts new file mode 100644 index 000000000..33e403dd0 --- /dev/null +++ b/tests/test_ci_quote_mint_redeem.ts @@ -0,0 +1,43 @@ +import { Keypair, Signer } from "@solana/web3.js"; +import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET, BTC_DECIMALS, BTC_DEVNET, ETH_DECIMALS, ETH_DEVNET } from "@uxd-protocol/uxd-client"; +import { authority, bank, uxdProgramId } from "./constants"; +import { transferAllSol, transferSol } from "./utils"; +import { quoteMintAndRedeemSuite } from "./suite/quoteMintAndRedeemSuite"; + +// Should use the quote info from mango.quoteToken instead of guessing it, but it's not changing often... +const mangoDepositorySOL = new MangoDepository(WSOL, "SOL", SOL_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); +const mangoDepositoryBTC = new MangoDepository(BTC_DEVNET, "BTC", BTC_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); +const mangoDepositoryETH = new MangoDepository(ETH_DEVNET, "ETH", ETH_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); +const controllerUXD = new Controller("UXD", UXD_DECIMALS, uxdProgramId); + +console.log(`SOL 🥭🔗 'https://devnet.mango.markets/account?pubkey=${mangoDepositorySOL.mangoAccountPda}'`); +console.log(`BTC 🥭🔗 'https://devnet.mango.markets/account?pubkey=${mangoDepositoryBTC.mangoAccountPda}'`); +console.log(`ETH 🥭🔗 'https://devnet.mango.markets/account?pubkey=${mangoDepositoryETH.mangoAccountPda}'`); + +beforeEach("\n", function () { console.log("=============================================\n\n") }); + + +describe("Integration tests Quote Mint Redeem", function () { + const user: Signer = new Keypair(); + + this.beforeAll("Init and fund user", async function () { + console.log("USER =>", user.publicKey.toString()); + await transferSol(1, bank, user.publicKey); + }); + + describe("mangoDepositoryQuoteMintRedeemSuite SOL", function () { + quoteMintAndRedeemSuite(authority, user, bank, controllerUXD, mangoDepositorySOL); + }); + + describe("mangoDepositoryQuoteMintRedeemSuite BTC", function () { + quoteMintAndRedeemSuite(authority, user, bank, controllerUXD, mangoDepositoryBTC); + }); + + describe("mangoDepositoryQuoteMintRedeemSuite ETH", function () { + quoteMintAndRedeemSuite(authority, user, bank, controllerUXD, mangoDepositoryETH); + }); + + this.afterAll("Transfer funds back to bank", async function () { + await transferAllSol(user, bank.publicKey); + }); +}); diff --git a/tests/test_ci_rebalancing.ts b/tests/test_ci_rebalancing.ts index 5df169b19..35b6ef0a0 100644 --- a/tests/test_ci_rebalancing.ts +++ b/tests/test_ci_rebalancing.ts @@ -1,5 +1,5 @@ import { Keypair, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET, BTC_DECIMALS, BTC_DEVNET, ETH_DECIMALS, ETH_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET, BTC_DECIMALS, BTC_DEVNET, ETH_DECIMALS, ETH_DEVNET } from "@uxd-protocol/uxd-client"; import { bank, uxdProgramId } from "./constants"; import { transferAllSol, transferSol } from "./utils"; import { mangoDepositoryRebalancingSuite, MangoDepositoryRebalancingSuiteParameters } from "./suite/mangoDepositoryRebalancingSuite"; diff --git a/tests/test_ci_sol.ts b/tests/test_ci_sol.ts index a8284ae37..a87f59514 100644 --- a/tests/test_ci_sol.ts +++ b/tests/test_ci_sol.ts @@ -1,13 +1,14 @@ import { Keypair, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET } from "@uxd-protocol/uxd-client"; import { authority, bank, uxdProgramId } from "./constants"; import { transferAllSol, transferSol } from "./utils"; import { controllerIntegrationSuite, controllerIntegrationSuiteParameters } from "./suite/controllerIntegrationSuite"; import { MangoDepositoryAndControllerInteractionsSuiteParameters, mangoDepositoryAndControllerInteractionsSuite } from "./suite/mangoDepositoryAndControllerInteractionsSuite"; -import { mangoDepositoryInsuranceSuite } from "./suite/mangoDepositoryInsuranceSuite"; -import { mangoDepositorySetupSuite } from "./suite/mangoDepositorySetupSuite"; +import { mangoDepositoryInsuranceSuite } from "./suite/depositoryInsuranceSuite"; +import { mangoDepositorySetupSuite } from "./suite/depositorySetupSuite"; import { mangoDepositoryMintRedeemSuite } from "./suite/mangoDepositoryMintRedeemSuite"; import { mangoDepositoryRebalancingSuite, MangoDepositoryRebalancingSuiteParameters } from "./suite/mangoDepositoryRebalancingSuite"; +import { quoteMintAndRedeemSuite } from "./suite/quoteMintAndRedeemSuite"; // Should use the quote info from mango.quoteToken instead of guessing it, but it's not changing often... const mangoDepositorySOL = new MangoDepository(WSOL, "SOL", SOL_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); @@ -36,11 +37,16 @@ describe("Integration tests SOL", function () { }); // Skipped as it's handle bu the test_ci_rebalancing.ts - describe("mangoDepositoryRebalancingSuite SOL", function () { + describe.skip("mangoDepositoryRebalancingSuite SOL", function () { const paramsRebalancing = new MangoDepositoryRebalancingSuiteParameters(20) mangoDepositoryRebalancingSuite(user, bank, controllerUXD, mangoDepositorySOL, paramsRebalancing); }); + // Skipped as it's handle bu the test_ci_quote_mint_redeem.ts + describe.skip("mangoDepositoryQuoteMintRedeemSuite SOL", function () { + quoteMintAndRedeemSuite(authority, user, bank, controllerUXD, mangoDepositorySOL); + }); + describe("mangoDepositoryInsuranceSuite SOL", function () { mangoDepositoryInsuranceSuite(authority, controllerUXD, mangoDepositorySOL); }); diff --git a/tests/test_development.ts b/tests/test_development.ts index b07b0339e..14e538078 100644 --- a/tests/test_development.ts +++ b/tests/test_development.ts @@ -1,25 +1,28 @@ import { Keypair, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET, BTC_DECIMALS, BTC_DEVNET, ETH_DECIMALS, ETH_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, SOL_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, WSOL, USDC_DEVNET, BTC_DECIMALS, BTC_DEVNET, ETH_DECIMALS, ETH_DEVNET, UXD_DEVNET } from "@uxd-protocol/uxd-client"; import { authority, bank, slippageBase, uxdProgramId } from "./constants"; -import { transferAllSol, transferSol, transferTokens } from "./utils"; +import { printDepositoryInfo, printUserInfo, transferAllSol, transferAllTokens, transferSol, transferTokens } from "./utils"; import { depositInsuranceMangoDepositoryTest } from "./cases/depositInsuranceMangoDepositoryTest"; -import { initializeMangoDepositoryTest } from "./cases/initializeMangoDepositoryTest"; +import { registerMangoDepositoryTest } from "./cases/registerMangoDepositoryTest"; import { mango } from "./fixtures"; import { withdrawInsuranceMangoDepositoryTest } from "./cases/withdrawInsuranceMangoDepositoryTest"; import { mintWithMangoDepositoryTest } from "./cases/mintWithMangoDepositoryTest"; import { redeemFromMangoDepositoryTest } from "./cases/redeemFromMangoDepositoryTest"; import { initializeControllerTest } from "./cases/initializeControllerTest"; import { MangoDepositoryRebalancingSuiteParameters, mangoDepositoryRebalancingSuite } from "./suite/mangoDepositoryRebalancingSuite"; +import { quoteMintAndRedeemSuite } from "./suite/quoteMintAndRedeemSuite"; +import { utils } from "@project-serum/anchor"; +import { setMangoDepositoriesRedeemableSoftCap } from "./api"; console.log(uxdProgramId.toString()); -const mangoDepositorySOL = new MangoDepository(WSOL, "SOL", SOL_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); -const mangoDepositoryBTC = new MangoDepository(BTC_DEVNET, "BTC", BTC_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); -const mangoDepositoryETH = new MangoDepository(ETH_DEVNET, "ETH", ETH_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); +// const mangoDepositorySOL = new MangoDepository(WSOL, "SOL", SOL_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); +const mangoDepositoryBTC = new MangoDepository(BTC_DEVNET, "BTC", BTC_DECIMALS, USDC_DEVNET, "USDC", UXD_DECIMALS, uxdProgramId); +// const mangoDepositoryETH = new MangoDepository(ETH_DEVNET, "ETH", ETH_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); const controller = new Controller("UXD", UXD_DECIMALS, uxdProgramId); const payer = bank; -const slippage = 50; // 5% +const slippage = 500; // 5% -console.log(`SOL 🥭🔗 'https://devnet.mango.markets/account?pubkey=${mangoDepositorySOL.mangoAccountPda}'`); +// console.log(`SOL 🥭🔗 'https://devnet.mango.markets/account?pubkey=${mangoDepositorySOL.mangoAccountPda}'`); beforeEach("\n", function () { console.log("=============================================\n\n") }); @@ -27,65 +30,97 @@ beforeEach("\n", function () { console.log("==================================== describe("Integration tests SOL", function () { const user: Signer = new Keypair(); - this.beforeAll("Init and fund user (10 SOL and 10k usdc)", async function () { + this.beforeAll("Init and fund user (10 SOL and 100 usdc)", async function () { console.log("USER =>", user.publicKey.toString()); - await transferSol(10, bank, user.publicKey); - await transferTokens(10000, USDC_DEVNET, USDC_DECIMALS, bank, user.publicKey); + await transferSol(1, bank, user.publicKey); + await transferTokens(200, USDC_DEVNET, USDC_DECIMALS, bank, user.publicKey); + // await transferTokens(10, UXD_DEVNET, UXD_DECIMALS, bank, user.publicKey); + await transferTokens(1.1, BTC_DEVNET, BTC_DECIMALS, bank, user.publicKey); }); + + describe("Init", async function () { it("Initialize Controller", async function () { await initializeControllerTest(authority, controller, payer); }); - it(`Initialize ${mangoDepositorySOL.collateralMintSymbol} Depository`, async function () { - await initializeMangoDepositoryTest(authority, controller, mangoDepositorySOL, mango, payer); - }); - it(`Initialize ${mangoDepositorySOL.collateralMintSymbol} Depository`, async function () { - await initializeMangoDepositoryTest(authority, controller, mangoDepositoryBTC, mango, payer); - }); - it(`Initialize ${mangoDepositorySOL.collateralMintSymbol} Depository`, async function () { - await initializeMangoDepositoryTest(authority, controller, mangoDepositoryETH, mango, payer); + // it(`Initialize ${mangoDepositorySOL.collateralMintSymbol} Depository`, async function () { + // await initializeMangoDepositoryTest(authority, controller, mangoDepositorySOL, mango, payer); + // }); + it(`Initialize ${mangoDepositoryBTC.collateralMintSymbol} Depository`, async function () { + await registerMangoDepositoryTest(authority, controller, mangoDepositoryBTC, mango, payer); }); + // it(`Initialize ${mangoDepositoryETH.collateralMintSymbol} Depository`, async function () { + // await initializeMangoDepositoryTest(authority, controller, mangoDepositoryETH, mango, payer); + // }); it(`Deposit 100 USDC of insurance`, async function () { - await depositInsuranceMangoDepositoryTest(100, authority, controller, mangoDepositorySOL, mango); + await depositInsuranceMangoDepositoryTest(100, authority, controller, mangoDepositoryBTC, mango); + }); + + it("Increase soft cap", async function () { + await setMangoDepositoriesRedeemableSoftCap(authority, controller, 10_000_000); }); - it(`Withdraw 10 USDC of insurance`, async function () { - await withdrawInsuranceMangoDepositoryTest(10, authority, controller, mangoDepositorySOL, mango); + it("Mint 1 BTC", async function () { + await mintWithMangoDepositoryTest(1, slippage, user, controller, mangoDepositoryBTC, mango, payer); }); + // it(`Withdraw 10 USDC of insurance`, async function () { + // await withdrawInsuranceMangoDepositoryTest(10, authority, controller, mangoDepositorySOL, mango); + // }); // it(`Mint 80 ${controller.redeemableMintSymbol} then redeem the outcome (${slippage / slippageBase * 100} % slippage)`, async function () { // const mintedAmount = await mintWithMangoDepositoryTest(80, slippage, user, controller, depository, mango, payer); // }); - }); - - describe("mangoDepositoryRebalancingSuite SOL", function () { - const paramsRebalancing = new MangoDepositoryRebalancingSuiteParameters(slippage) - mangoDepositoryRebalancingSuite(user, bank, controller, mangoDepositorySOL, paramsRebalancing); }); - describe("Test minting/redeeming", async function () { - it(`Mint 100 ${controller.redeemableMintSymbol} then redeem the outcome (${slippage / slippageBase * 100} % slippage)`, async function () { - const perpPrice = await mangoDepositorySOL.getCollateralPerpPriceUI(mango); - const amount = 100 / perpPrice; - console.log("[🧾 amount", amount, mangoDepositorySOL.collateralMintSymbol, "]"); - const mintedAmount = await mintWithMangoDepositoryTest(amount, slippage, user, controller, mangoDepositorySOL, mango, payer); - await redeemFromMangoDepositoryTest(mintedAmount, slippage, user, controller, mangoDepositorySOL, mango, payer); - }); - - it(`Mint twice min mint trading size, then redeem them (${slippage / slippageBase * 100}% slippage)`, async function () { - const minRedeemAmount = await mangoDepositorySOL.getMinRedeemSizeQuoteUI(mango); - const minTradingSize = await mangoDepositorySOL.getMinTradingSizeCollateralUI(mango); - - await mintWithMangoDepositoryTest(minTradingSize * 2, slippage, user, controller, mangoDepositorySOL, mango, payer); - await redeemFromMangoDepositoryTest(minRedeemAmount, slippage, user, controller, mangoDepositorySOL, mango, payer); - }); + describe.only("Quote Mint And Redeem Suite", async function () { + quoteMintAndRedeemSuite(authority, user, payer, controller, mangoDepositoryBTC); }); + // describe("Quote mint and redeem", async function () { + // it("Mint 10 BTC", async function() { + // await mintWithMangoDepositoryTest(10, slippage, user, controller, mangoDepositoryBTC, mango, payer); + // }); + + // }); + + // describe.skip("Test minting/redeeming SOL", async function () { + // it(`Mint 10 ${controller.redeemableMintSymbol} then redeem the outcome (${slippage / slippageBase * 100} % slippage)`, async function () { + // const perpPrice = await mangoDepositorySOL.getCollateralPerpPriceUI(mango); + // const amount = 10 / perpPrice; + // console.log("[🧾 amount", amount, mangoDepositorySOL.collateralMintSymbol, "]"); + // const mintedAmount = await mintWithMangoDepositoryTest(amount, slippage, user, controller, mangoDepositorySOL, mango, payer); + // await redeemFromMangoDepositoryTest(mintedAmount, slippage, user, controller, mangoDepositorySOL, mango, payer); + // }); + + // it(`Mint twice min mint trading size, then redeem them (${slippage / slippageBase * 100}% slippage)`, async function () { + // const minRedeemAmount = await mangoDepositorySOL.getMinRedeemSizeQuoteUI(mango); + // const minTradingSize = await mangoDepositorySOL.getMinTradingSizeCollateralUI(mango); + + // await mintWithMangoDepositoryTest(minTradingSize * 2, slippage, user, controller, mangoDepositorySOL, mango, payer); + // await redeemFromMangoDepositoryTest(minRedeemAmount, slippage, user, controller, mangoDepositorySOL, mango, payer); + // }); + // }); + + // Note - Keep a mint/redeem before rebalancing so that it creates the necessary accounts for computing + // describe.skip("mangoDepositoryRebalancingSuite SOL", function () { + // const paramsRebalancing = new MangoDepositoryRebalancingSuiteParameters(slippage) + // mangoDepositoryRebalancingSuite(user, bank, controller, mangoDepositorySOL, paramsRebalancing); + // }); + + // describe.skip("info SOL", async function () { + // it("info", async function () { + // await printUserInfo(user.publicKey, controller, mangoDepositorySOL); + // await printDepositoryInfo(controller, mangoDepositorySOL, mango); + // }); + // }); + this.afterAll("Transfer funds back to bank", async function () { + await transferAllTokens(USDC_DEVNET, USDC_DECIMALS, user, bank.publicKey); + await transferAllTokens(BTC_DEVNET, BTC_DECIMALS, user, bank.publicKey); await transferAllSol(user, bank.publicKey); }); }); \ No newline at end of file diff --git a/tests/test_integration.ts b/tests/test_integration.ts index c49f6a8aa..d0b57fe05 100644 --- a/tests/test_integration.ts +++ b/tests/test_integration.ts @@ -1,13 +1,15 @@ import { Keypair, Signer } from "@solana/web3.js"; -import { Controller, MangoDepository, SOL_DECIMALS, BTC_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, ETH_DECIMALS, WSOL, USDC_DEVNET, BTC_DEVNET, ETH_DEVNET } from "@uxdprotocol/uxd-client"; +import { Controller, MangoDepository, SOL_DECIMALS, BTC_DECIMALS, USDC_DECIMALS, UXD_DECIMALS, ETH_DECIMALS, WSOL, USDC_DEVNET, BTC_DEVNET, ETH_DEVNET } from "@uxd-protocol/uxd-client"; import { authority, bank, uxdProgramId } from "./constants"; import { transferAllSol, transferSol } from "./utils"; import { controllerIntegrationSuite, controllerIntegrationSuiteParameters } from "./suite/controllerIntegrationSuite"; import { MangoDepositoryAndControllerInteractionsSuiteParameters, mangoDepositoryAndControllerInteractionsSuite } from "./suite/mangoDepositoryAndControllerInteractionsSuite"; -import { mangoDepositoryInsuranceSuite } from "./suite/mangoDepositoryInsuranceSuite"; -import { mangoDepositorySetupSuite } from "./suite/mangoDepositorySetupSuite"; +import { mangoDepositoryInsuranceSuite } from "./suite/depositoryInsuranceSuite"; +import { mangoDepositorySetupSuite } from "./suite/depositorySetupSuite"; import { mangoDepositoryMintRedeemSuite } from "./suite/mangoDepositoryMintRedeemSuite"; import { mangoDepositoryRebalancingSuite, MangoDepositoryRebalancingSuiteParameters } from "./suite/mangoDepositoryRebalancingSuite"; +import { mangoDepositoryAndControllerAccountingSuite } from "./suite/mangoDepositoryAndControllerAccountingSuite"; +import { disableDepositoryMintingSuite } from "./suite/disableDepositoryMintingSuite"; // Should use the quote info from mango.quoteToken instead of guessing it, but it's not changing often... const mangoDepositorySOL = new MangoDepository(WSOL, "SOL", SOL_DECIMALS, USDC_DEVNET, "USDC", USDC_DECIMALS, uxdProgramId); @@ -49,6 +51,10 @@ describe("Integration tests SOL", function () { mangoDepositoryInsuranceSuite(authority, controllerUXD, mangoDepositorySOL); }); + describe("disableDepositoryMintingSuite SOL", function () { + disableDepositoryMintingSuite(authority, user, bank, controllerUXD, mangoDepositorySOL); + }); + describe("mangoDepositoryMintRedeemSuite SOL", function () { mangoDepositoryMintRedeemSuite(user, bank, controllerUXD, mangoDepositorySOL, 20); }); @@ -58,13 +64,19 @@ describe("Integration tests SOL", function () { mangoDepositoryAndControllerInteractionsSuite(authority, user, bank, controllerUXD, mangoDepositorySOL, paramsSol); }); + describe("mangoDepositoryAndControllerAccountingSuite SOL", function () { + const slippage = 20; + const collateralUnitShift = SOL_DECIMALS - 2; // SOL units - target units + mangoDepositoryAndControllerAccountingSuite(authority, user, bank, controllerUXD, mangoDepositorySOL, slippage, collateralUnitShift); + }) + this.afterAll("Transfer funds back to bank", async function () { await transferAllSol(user, bank.publicKey); }); }); // BTC -describe("Integration tests BTC", function () { +describe.skip("Integration tests BTC", function () { this.beforeAll("Init and fund user", async function () { console.log("USER =>", user.publicKey.toString()); @@ -99,7 +111,7 @@ describe("Integration tests BTC", function () { }); // ETH -describe("Integration tests ETH", function () { +describe.skip("Integration tests ETH", function () { this.beforeAll("Init and fund user", async function () { console.log("USER =>", user.publicKey.toString()); diff --git a/tests/test_mainnet_msol.ts b/tests/test_mainnet_msol.ts new file mode 100644 index 000000000..7456e835c --- /dev/null +++ b/tests/test_mainnet_msol.ts @@ -0,0 +1,157 @@ +import { Keypair, Signer, Transaction } from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; +import { + Controller, + createAssocTokenIx, + findATAAddrSync, + MangoDepository, + MSOL, + MsolConfig, + SOL_DECIMALS, + USDC_DECIMALS, + WSOL, +} from "@uxd-protocol/uxd-client"; +import { UXD_DECIMALS } from "@uxd-protocol/uxd-client"; +import { initializeControllerTest } from "./cases/initializeControllerTest"; +import { registerMangoDepositoryTest } from "./cases/registerMangoDepositoryTest"; +import { mango } from "./fixtures"; +import * as payerKeypair from "../../../../.config/solana/id.json"; +import * as adminKeypair from "../../internal_mainnet_authority.json"; +import * as userKeypair from "../../internal_mainnet_user_keypair.json"; +import { uxdProgramId } from "./constants"; +import { depositInsuranceMangoDepositoryTest } from "./cases/depositInsuranceMangoDepositoryTest"; +import { transferAllSol, transferAllTokens, transferSol } from "./utils"; +import { mintWithMangoDepositoryTest } from "./cases/mintWithMangoDepositoryTest"; +import { web3 } from "@project-serum/anchor"; +import { getConnection, TXN_OPTS } from "./connection"; +import { createAta, createDepositoryMsolConfig, enableMsolSwap, swapDepositoryMsol } from "./api"; +import { redeemFromMangoDepositoryTest } from "./cases/redeemFromMangoDepositoryTest"; +import { setRedeemableSoftCapMangoDepositoryTest } from "./cases/setRedeemableSoftCapMangoDepositoryTest"; + +const payer: Signer = Keypair.fromSecretKey(Uint8Array.from(payerKeypair.default)); +console.log(`PAYER MAINNET => 🔗https://solscan.io/account/${payer.publicKey}`); + +// 8cJ5KH2ExX2rrY6DbzAqrBMDkQxYZfyedB1C4L4osc5N +const authority: Signer = Keypair.fromSecretKey(Uint8Array.from(adminKeypair.default)); +console.log(`CONTROLLER AUTHORITY MAINNET => 🔗 https://solscan.io/account/${authority.publicKey}`); + +// BjsGycpLGSFmUD2PbFBjrKahXjNnRxYBQMAEsBF3uJxb +const user: Signer = Keypair.fromSecretKey(Uint8Array.from(userKeypair.default)); +console.log(`USER MAINNET => 🔗 https://solscan.io/account/${user.publicKey}`); + +const USDC_MAINNET = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); + +const controller = new Controller("UXD", UXD_DECIMALS, uxdProgramId); + +const mangoDepositorySOL = new MangoDepository( + WSOL, + "SOL", + SOL_DECIMALS, + USDC_MAINNET, + "USDC", + USDC_DECIMALS, + uxdProgramId +); + +const msolConfig = new MsolConfig(mangoDepositorySOL.pda, uxdProgramId); +console.log(`msolConfigPda = ${msolConfig.pda.toString()}`); + +describe.skip("Mainnet token transfer", function () { + it.skip("Transfer all USDC to authority from payer", async function () { + const txId = await transferAllTokens(USDC_MAINNET, USDC_DECIMALS, payer, authority.publicKey); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + }); + + it.skip("Transfer SOL to authority from payer", async function () { + const txId = await transferSol(0.1, payer, authority.publicKey); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + }); +}); + +describe("Mainnet Integration tests SOL", function () { + this.beforeAll("Init and fund user", async function () { + const uiAmount = 0.003; + const txId = await transferSol(uiAmount, payer, user.publicKey); + console.log("transfer", uiAmount, "SOL to", user.publicKey.toString()); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + }); + + // has initialized! + it.skip("Initialize Controller (internal mainnet)", async function () { + await initializeControllerTest(authority, controller, payer); + }); + + // has initialized! + it.skip(`Initialize ${mangoDepositorySOL.collateralMintSymbol} Depository (internal mainnet)`, async function () { + await registerMangoDepositoryTest(authority, controller, mangoDepositorySOL, mango, payer); + }); + + it.skip(`Deposit to insurance`, async function () { + // just transfer all the usdc to depository mango account + await depositInsuranceMangoDepositoryTest(23.300486, authority, controller, mangoDepositorySOL, mango); + }); + + it.skip(`Mint 0.01 ${controller.redeemableMintSymbol} for 2% slippage)`, async function () { + await mintWithMangoDepositoryTest(0.01, 20, user, controller, mangoDepositorySOL, mango, payer); + }); + + it.skip(`Set Mango Depositories Redeemable soft cap to 1`, async function () { + await setRedeemableSoftCapMangoDepositoryTest(100000000, authority, controller); + }); + + it(`Redeem 0.5 ${controller.redeemableMintSymbol} for 2% slippage)`, async function () { + await redeemFromMangoDepositoryTest(0.5, 20, user, controller, mangoDepositorySOL, mango, payer); + }); + + describe("Test mSOL", async function () { + it("register msol config", async function () { + if (await getConnection().getAccountInfo(msolConfig.pda)) { + console.log("🚧 Already initialized."); + } else { + const txId = await createDepositoryMsolConfig( + authority, + payer, + controller, + mangoDepositorySOL, + msolConfig.pda, + 5000 + ); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + } + }); + + it("create wsol ata", async function () { + try { + const txId = await createAta(user, payer, WSOL); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + } catch (e) { + console.error(e); + } + }); + + it("create msol ata", async function () { + try { + const txId = await createAta(user, payer, MSOL); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + } catch (e) { + console.error(e); + } + }); + + it.skip("enable msol config", async function () { + const txId = await enableMsolSwap(authority, payer, controller, mangoDepositorySOL, msolConfig.pda, true); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + }); + + it("swap msol", async function () { + const txId = await swapDepositoryMsol(user, payer, controller, mangoDepositorySOL, msolConfig.pda, mango); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + }); + }); + + this.afterAll("Transfer funds back to payer", async function () { + const txId = await transferAllSol(user, payer.publicKey); + console.log("transfer all SOL to", payer.publicKey.toString()); + console.log(`🔗 'https://explorer.solana.com/tx/${txId}'`); + }); +}); diff --git a/tests/utils.ts b/tests/utils.ts index 32b685c9d..a58849a4a 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -1,10 +1,10 @@ -import { MangoDepository, Mango, SOL_DECIMALS, findATAAddrSync, Controller, nativeI80F48ToUi, nativeToUi, uiToNative } from "@uxdprotocol/uxd-client"; +import { MangoDepository, Mango, SOL_DECIMALS, findATAAddrSync, Controller, nativeI80F48ToUi, nativeToUi, uiToNative } from "@uxd-protocol/uxd-client"; import { PublicKey, Signer } from "@solana/web3.js"; import * as anchor from "@project-serum/anchor"; import { ASSOCIATED_TOKEN_PROGRAM_ID, NATIVE_MINT, Token, TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { getConnection, TXN_COMMIT, TXN_OPTS } from "./connection"; -const SOLANA_FEES_LAMPORT: number = 50000; +const SOLANA_FEES_LAMPORT: number = 5000; export async function transferSol(amountUi: number, from: Signer, to: PublicKey): Promise { const transaction = new anchor.web3.Transaction().add( @@ -46,11 +46,14 @@ export async function transferTokens(amountUI: number, mint: PublicKey, decimals } export async function transferAllTokens(mint: PublicKey, decimals: number, from: Signer, to: PublicKey): Promise { + const sender = findATAAddrSync(from.publicKey, mint)[0]; + if (!await getConnection().getAccountInfo(sender)) { + return "No account"; + } const token = new Token(getConnection(), mint, TOKEN_PROGRAM_ID, from); - const sender = await token.getOrCreateAssociatedAccountInfo(from.publicKey); const receiver = await token.getOrCreateAssociatedAccountInfo(to); - const amount = await getBalance(sender.address); - const transferTokensIx = Token.createTransferInstruction(TOKEN_PROGRAM_ID, sender.address, receiver.address, from.publicKey, [], uiToNative(amount, decimals).toNumber()); + const amount = await getBalance(sender); + const transferTokensIx = Token.createTransferInstruction(TOKEN_PROGRAM_ID, sender, receiver.address, from.publicKey, [], uiToNative(amount, decimals).toNumber()); const transaction = new anchor.web3.Transaction().add(transferTokensIx); return anchor.web3.sendAndConfirmTransaction(getConnection(), transaction, [ from, @@ -93,13 +96,13 @@ export async function printDepositoryInfo(controller: Controller, depository: Ma const pa = mangoAccount.perpAccounts[pmi]; const pm = await mango.getPerpMarket(SYM); const cache = await mango.group.loadCache(provider); - const accountValue = mangoAccount.computeValue(mango.group, cache).toBig(); + const accountValue = mangoAccount.computeValue(mango.group, cache).toBig().toNumber(); const accountingInsuranceDepositedValue = nativeToUi(depositoryAccount.insuranceAmountDeposited.toNumber(), depository.quoteMintDecimals); // const collateralSpotAmount = await depository.getCollateralBalance(mango); // const insuranceSpotAmount = await // - const collateralDepositInterests = collateralSpotAmount.toBig().sub(depositoryAccount.collateralAmountDeposited); + const collateralDepositInterests = collateralSpotAmount.toBig().sub(depositoryAccount.collateralAmountDeposited).toNumber(); // const insuranceDepositInterests = insuranceSpotAmount.toBig().sub(depositoryAccount.insuranceAmountDeposited); // const accountValueMinusTotalInsuranceDeposited = accountValue - accountingInsuranceDepositedValue; @@ -185,7 +188,7 @@ export const prepareWrappedSolTokenAccount = async ( }; // derives the canonical token account address for a given wallet and mint -function findAssociatedTokenAddress(walletKey, mintKey) { +export function findAssociatedTokenAddress(walletKey, mintKey) { if (!walletKey || !mintKey) return; return findAddr( [walletKey.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mintKey.toBuffer()], @@ -194,7 +197,7 @@ function findAssociatedTokenAddress(walletKey, mintKey) { } // simple shorthand -function findAddr(seeds, programId) { +export function findAddr(seeds, programId) { return anchor.utils.publicKey.findProgramAddressSync(seeds, programId)[0]; } @@ -240,7 +243,7 @@ const createWrappedSolTokenAccount = async ( return [transferItx, createItx]; }; -function createAssociatedTokenAccountItx(payerKey, walletKey, mintKey) { +export function createAssociatedTokenAccountItx(payerKey, walletKey, mintKey) { const assocKey = findAssociatedTokenAddress(walletKey, mintKey); return new anchor.web3.TransactionInstruction({ diff --git a/yarn-error.log b/yarn-error.log new file mode 100644 index 000000000..3064875fd --- /dev/null +++ b/yarn-error.log @@ -0,0 +1,1445 @@ +Arguments: + /usr/local/Cellar/node/18.0.0/bin/node /usr/local/Cellar/yarn/1.22.18/libexec/bin/yarn.js + +PATH: + /Users/kenchow/.rbenv/shims:/usr/local/opt/gnupg@2.2/bin:/Users/kenchow/.cargo/bin:/Users/kenchow/.local/share/solana/install/active_release/bin:/Users/kenchow/Library/Android/sdk/platform-tools:/Users/kenchow/bin:/usr/local/bin:/Users/kenchow/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + +Yarn version: + 1.22.18 + +Node version: + 18.0.0 + +Platform: + darwin x64 + +Trace: + Error: ENOENT: no such file or directory, lstat '/Users/kenchow/Documents/uxd/uxd-program/node_modules/@uxd-protocol/uxd-client/node_modules/@blockworks-foundation/mango-client/node_modules' + +npm manifest: + { + "license": "SEE LICENSE IN LICENSE.MD", + "dependencies": { + "@blockworks-foundation/mango-client": "^3.4.5", + "@project-serum/anchor": "0.24.2", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.39.1", + "@uxd-protocol/uxd-client": "1.0.0" + }, + "devDependencies": { + "@types/chai": "^4.3.0", + "@types/mocha": "^9.1.0", + "chai": "^4.3.6", + "mocha": "^9.2.1", + "mochawesome": "^7.0.1", + "ts-mocha": "^9.0.2", + "typescript": "^4.5.5" + } + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + "@babel/runtime@^7.10.5", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": + "integrity" "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==" + "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz" + "version" "7.17.9" + dependencies: + "regenerator-runtime" "^0.13.4" + + "@ethersproject/bytes@^5.6.0": + "integrity" "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==" + "resolved" "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz" + "version" "5.6.1" + dependencies: + "@ethersproject/logger" "^5.6.0" + + "@ethersproject/logger@^5.6.0": + "integrity" "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" + "resolved" "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz" + "version" "5.6.0" + + "@ethersproject/sha2@^5.5.0": + "integrity" "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==" + "resolved" "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz" + "version" "5.6.0" + dependencies: + "@ethersproject/bytes" "^5.6.0" + "@ethersproject/logger" "^5.6.0" + "hash.js" "1.1.7" + + "@project-serum/anchor@0.24.2": + "integrity" "sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA==" + "resolved" "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz" + "version" "0.24.2" + dependencies: + "@project-serum/borsh" "^0.2.5" + "@solana/web3.js" "^1.36.0" + "base64-js" "^1.5.1" + "bn.js" "^5.1.2" + "bs58" "^4.0.1" + "buffer-layout" "^1.2.2" + "camelcase" "^5.3.1" + "cross-fetch" "^3.1.5" + "crypto-hash" "^1.3.0" + "eventemitter3" "^4.0.7" + "js-sha256" "^0.9.0" + "pako" "^2.0.3" + "snake-case" "^3.0.4" + "toml" "^3.0.0" + + "@project-serum/borsh@^0.2.5": + "integrity" "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==" + "resolved" "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz" + "version" "0.2.5" + dependencies: + "bn.js" "^5.1.2" + "buffer-layout" "^1.2.0" + + "@solana/buffer-layout@^4.0.0": + "integrity" "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==" + "resolved" "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "buffer" "~6.0.3" + + "@solana/spl-token@^0.1.8": + "integrity" "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==" + "resolved" "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz" + "version" "0.1.8" + dependencies: + "@babel/runtime" "^7.10.5" + "@solana/web3.js" "^1.21.0" + "bn.js" "^5.1.0" + "buffer" "6.0.3" + "buffer-layout" "^1.2.0" + "dotenv" "10.0.0" + + "@solana/web3.js@^1.2.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.39.1": + "integrity" "sha512-Q7XnWTAiU7n7GcoINDAAMLO7CJHpm5kPK46HKwJi2x0cusHQ3WFa7QEp6aPzH7tuf7yl/Kw1lYitcwTVOvqARA==" + "resolved" "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.39.1.tgz" + "version" "1.39.1" + dependencies: + "@babel/runtime" "^7.12.5" + "@ethersproject/sha2" "^5.5.0" + "@solana/buffer-layout" "^4.0.0" + "bn.js" "^5.0.0" + "borsh" "^0.7.0" + "bs58" "^4.0.1" + "buffer" "6.0.1" + "cross-fetch" "^3.1.4" + "jayson" "^3.4.4" + "js-sha3" "^0.8.0" + "rpc-websockets" "^7.4.2" + "secp256k1" "^4.0.2" + "superstruct" "^0.14.2" + "tweetnacl" "^1.0.0" + + "@types/chai@^4.3.0": + "integrity" "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==" + "resolved" "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz" + "version" "4.3.1" + + "@types/connect@^3.4.33": + "integrity" "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==" + "resolved" "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + "version" "3.4.35" + dependencies: + "@types/node" "*" + + "@types/express-serve-static-core@^4.17.9": + "integrity" "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==" + "resolved" "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz" + "version" "4.17.28" + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + + "@types/json5@^0.0.29": + "integrity" "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + "resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" + "version" "0.0.29" + + "@types/lodash@^4.14.159": + "integrity" "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" + "resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz" + "version" "4.14.182" + + "@types/mocha@^9.1.0": + "integrity" "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==" + "resolved" "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" + "version" "9.1.1" + + "@types/node@*", "@types/node@^12.12.54": + "integrity" "sha512-5e6QNb9bkeh4Hni4ktLqUZuUqnGTX/kou2aZkXyxtuYaHXgBm+In1SHR9V+7kDzWzjB08KC2uqt2doDi7cuAAA==" + "resolved" "https://registry.npmjs.org/@types/node/-/node-12.20.49.tgz" + "version" "12.20.49" + + "@types/qs@*": + "integrity" "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "resolved" "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + "version" "6.9.7" + + "@types/range-parser@*": + "integrity" "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "resolved" "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" + "version" "1.2.4" + + "@types/ws@^7.4.4": + "integrity" "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==" + "resolved" "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" + "version" "7.4.7" + dependencies: + "@types/node" "*" + + "@ungap/promise-all-settled@1.1.2": + "integrity" "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" + "resolved" "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" + "version" "1.1.2" + + "@uxd-protocol/uxd-client@file:../solana-usds-client": + "resolved" "file:../solana-usds-client" + "version" "1.0.0" + dependencies: + "@blockworks-foundation/mango-client" "3.4.4" + "@project-serum/anchor" "0.24.2" + "@solana/spl-token" "0.1.8" + "@solana/web3.js" "1.39.1" + "@zero_one/client" "^0.8.6" + "camelcase" "5.3.1" + + "ansi-colors@4.1.1": + "integrity" "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" + "version" "4.1.1" + + "ansi-regex@^5.0.1": + "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + "version" "5.0.1" + + "ansi-styles@^4.0.0", "ansi-styles@^4.1.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + + "anymatch@~3.1.2": + "integrity" "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==" + "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "normalize-path" "^3.0.0" + "picomatch" "^2.0.4" + + "argparse@^2.0.1": + "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + "version" "2.0.1" + + "arrify@^1.0.0": + "integrity" "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "resolved" "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + "version" "1.0.1" + + "assertion-error@^1.1.0": + "integrity" "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + "resolved" "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" + "version" "1.1.0" + + "balanced-match@^1.0.0": + "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + "version" "1.0.2" + + "base-x@^3.0.2": + "integrity" "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==" + "resolved" "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" + "version" "3.0.9" + dependencies: + "safe-buffer" "^5.0.1" + + "base64-js@^1.3.1", "base64-js@^1.5.1": + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + "version" "1.5.1" + + "binary-extensions@^2.0.0": + "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + "version" "2.2.0" + + "bn.js@^4.11.9": + "integrity" "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + "version" "4.12.0" + + "bn.js@^5.0.0", "bn.js@^5.1.0", "bn.js@^5.1.2", "bn.js@^5.2.0": + "integrity" "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz" + "version" "5.2.0" + + "borsh@^0.7.0": + "integrity" "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==" + "resolved" "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz" + "version" "0.7.0" + dependencies: + "bn.js" "^5.2.0" + "bs58" "^4.0.0" + "text-encoding-utf-8" "^1.0.2" + + "brace-expansion@^1.1.7": + "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + "version" "1.1.11" + dependencies: + "balanced-match" "^1.0.0" + "concat-map" "0.0.1" + + "braces@~3.0.2": + "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "fill-range" "^7.0.1" + + "brorand@^1.1.0": + "integrity" "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "resolved" "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + "version" "1.1.0" + + "browser-stdout@1.3.1": + "integrity" "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + "resolved" "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + "version" "1.3.1" + + "bs58@^4.0.0", "bs58@^4.0.1": + "integrity" "sha1-vhYedsNU9veIrkBx9j806MTwpCo=" + "resolved" "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "base-x" "^3.0.2" + + "buffer-from@^1.0.0", "buffer-from@^1.1.0": + "integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + "version" "1.1.2" + + "buffer-layout@^1.2.0", "buffer-layout@^1.2.2": + "integrity" "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" + "resolved" "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz" + "version" "1.2.2" + + "buffer@~6.0.3", "buffer@6.0.3": + "integrity" "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + "version" "6.0.3" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.2.1" + + "buffer@6.0.1": + "integrity" "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.2.1" + + "bufferutil@^4.0.1": + "integrity" "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==" + "resolved" "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz" + "version" "4.0.6" + dependencies: + "node-gyp-build" "^4.3.0" + + "camelcase@^5.3.1": + "integrity" "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + "version" "5.3.1" + + "camelcase@^6.0.0": + "integrity" "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + "version" "6.3.0" + + "chai@^4.3.6": + "integrity" "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==" + "resolved" "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz" + "version" "4.3.6" + dependencies: + "assertion-error" "^1.1.0" + "check-error" "^1.0.2" + "deep-eql" "^3.0.1" + "get-func-name" "^2.0.0" + "loupe" "^2.3.1" + "pathval" "^1.1.1" + "type-detect" "^4.0.5" + + "chalk@^4.1.0", "chalk@^4.1.2": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + + "check-error@^1.0.2": + "integrity" "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + "resolved" "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" + "version" "1.0.2" + + "chokidar@3.5.3": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + 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" + optionalDependencies: + "fsevents" "~2.3.2" + + "cliui@^7.0.2": + "integrity" "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + "version" "7.0.4" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.0" + "wrap-ansi" "^7.0.0" + + "color-convert@^2.0.1": + "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "color-name" "~1.1.4" + + "color-name@~1.1.4": + "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + "version" "1.1.4" + + "commander@^2.20.3": + "integrity" "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "resolved" "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + "version" "2.20.3" + + "concat-map@0.0.1": + "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + "version" "0.0.1" + + "cross-fetch@^3.1.4", "cross-fetch@^3.1.5": + "integrity" "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==" + "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" + "version" "3.1.5" + dependencies: + "node-fetch" "2.6.7" + + "crypto-hash@^1.3.0": + "integrity" "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==" + "resolved" "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz" + "version" "1.3.0" + + "dateformat@^4.5.1": + "integrity" "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==" + "resolved" "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz" + "version" "4.6.3" + + "debug@4.3.3": + "integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + "version" "4.3.3" + dependencies: + "ms" "2.1.2" + + "decamelize@^4.0.0": + "integrity" "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" + "resolved" "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" + "version" "4.0.0" + + "deep-eql@^3.0.1": + "integrity" "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==" + "resolved" "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "type-detect" "^4.0.0" + + "delay@^5.0.0": + "integrity" "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + "resolved" "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" + "version" "5.0.0" + + "diff@^3.1.0": + "integrity" "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + "resolved" "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" + "version" "3.5.0" + + "diff@^5.0.0", "diff@5.0.0": + "integrity" "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" + "resolved" "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + "version" "5.0.0" + + "dot-case@^3.0.4": + "integrity" "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==" + "resolved" "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "no-case" "^3.0.4" + "tslib" "^2.0.3" + + "dotenv@10.0.0": + "integrity" "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz" + "version" "10.0.0" + + "elliptic@^6.5.4": + "integrity" "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==" + "resolved" "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" + "version" "6.5.4" + 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" + + "emoji-regex@^8.0.0": + "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + "version" "8.0.0" + + "es6-promise@^4.0.3": + "integrity" "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "resolved" "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" + "version" "4.2.8" + + "es6-promisify@^5.0.0": + "integrity" "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=" + "resolved" "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "es6-promise" "^4.0.3" + + "escalade@^3.1.1": + "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + "version" "3.1.1" + + "escape-html@^1.0.3": + "integrity" "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "resolved" "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + "version" "1.0.3" + + "escape-string-regexp@4.0.0": + "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + "version" "4.0.0" + + "eventemitter3@^4.0.7": + "integrity" "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "resolved" "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + "version" "4.0.7" + + "eyes@^0.1.8": + "integrity" "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + "resolved" "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" + "version" "0.1.8" + + "fill-range@^7.0.1": + "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "to-regex-range" "^5.0.1" + + "find-up@5.0.0": + "integrity" "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==" + "resolved" "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "locate-path" "^6.0.0" + "path-exists" "^4.0.0" + + "flat@^5.0.2": + "integrity" "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" + "resolved" "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + "version" "5.0.2" + + "fs-extra@^10.0.0": + "integrity" "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + "version" "10.1.0" + dependencies: + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + + "fs.realpath@^1.0.0": + "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + "version" "1.0.0" + + "fsevents@~2.3.2": + "integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==" + "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + "version" "2.3.2" + + "fsu@^1.1.1": + "integrity" "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==" + "resolved" "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz" + "version" "1.1.1" + + "get-caller-file@^2.0.5": + "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + "version" "2.0.5" + + "get-func-name@^2.0.0": + "integrity" "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + "resolved" "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" + "version" "2.0.0" + + "glob-parent@~5.1.2": + "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + "version" "5.1.2" + dependencies: + "is-glob" "^4.0.1" + + "glob@7.2.0": + "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" + "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^3.0.4" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + + "graceful-fs@^4.1.6", "graceful-fs@^4.2.0": + "integrity" "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + "version" "4.2.10" + + "growl@1.10.5": + "integrity" "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + "resolved" "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" + "version" "1.10.5" + + "has-flag@^4.0.0": + "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + "version" "4.0.0" + + "hash.js@^1.0.0", "hash.js@^1.0.3", "hash.js@1.1.7": + "integrity" "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==" + "resolved" "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + "version" "1.1.7" + dependencies: + "inherits" "^2.0.3" + "minimalistic-assert" "^1.0.1" + + "he@1.2.0": + "integrity" "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + "resolved" "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + "version" "1.2.0" + + "hmac-drbg@^1.0.1": + "integrity" "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=" + "resolved" "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "hash.js" "^1.0.3" + "minimalistic-assert" "^1.0.0" + "minimalistic-crypto-utils" "^1.0.1" + + "ieee754@^1.2.1": + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + "version" "1.2.1" + + "inflight@^1.0.4": + "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" + "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + "version" "1.0.6" + dependencies: + "once" "^1.3.0" + "wrappy" "1" + + "inherits@^2.0.3", "inherits@^2.0.4", "inherits@2": + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + "version" "2.0.4" + + "is-binary-path@~2.1.0": + "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" + "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "binary-extensions" "^2.0.0" + + "is-extglob@^2.1.1": + "integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + "version" "2.1.1" + + "is-fullwidth-code-point@^3.0.0": + "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + "version" "3.0.0" + + "is-glob@^4.0.1", "is-glob@~4.0.1": + "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "is-extglob" "^2.1.1" + + "is-number@^7.0.0": + "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + "version" "7.0.0" + + "is-plain-obj@^2.1.0": + "integrity" "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + "resolved" "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + "version" "2.1.0" + + "is-unicode-supported@^0.1.0": + "integrity" "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + "resolved" "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + "version" "0.1.0" + + "isexe@^2.0.0": + "integrity" "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + "version" "2.0.0" + + "isomorphic-ws@^4.0.1": + "integrity" "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + "resolved" "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" + "version" "4.0.1" + + "jayson@^3.4.4": + "integrity" "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==" + "resolved" "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz" + "version" "3.6.6" + dependencies: + "@types/connect" "^3.4.33" + "@types/express-serve-static-core" "^4.17.9" + "@types/lodash" "^4.14.159" + "@types/node" "^12.12.54" + "@types/ws" "^7.4.4" + "commander" "^2.20.3" + "delay" "^5.0.0" + "es6-promisify" "^5.0.0" + "eyes" "^0.1.8" + "isomorphic-ws" "^4.0.1" + "json-stringify-safe" "^5.0.1" + "JSONStream" "^1.3.5" + "lodash" "^4.17.20" + "uuid" "^8.3.2" + "ws" "^7.4.5" + + "js-sha256@^0.9.0": + "integrity" "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + "resolved" "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz" + "version" "0.9.0" + + "js-sha3@^0.8.0": + "integrity" "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "resolved" "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" + "version" "0.8.0" + + "js-tokens@^3.0.0 || ^4.0.0": + "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + "version" "4.0.0" + + "js-yaml@4.1.0": + "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "argparse" "^2.0.1" + + "json-stringify-safe@^5.0.1": + "integrity" "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "resolved" "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + "version" "5.0.1" + + "json5@^1.0.1": + "integrity" "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==" + "resolved" "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "minimist" "^1.2.0" + + "jsonfile@^6.0.1": + "integrity" "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + "version" "6.1.0" + dependencies: + "universalify" "^2.0.0" + optionalDependencies: + "graceful-fs" "^4.1.6" + + "jsonparse@^1.2.0": + "integrity" "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + "resolved" "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" + "version" "1.3.1" + + "JSONStream@^1.3.5": + "integrity" "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==" + "resolved" "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + "version" "1.3.5" + dependencies: + "jsonparse" "^1.2.0" + "through" ">=2.2.7 <3" + + "locate-path@^6.0.0": + "integrity" "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==" + "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "p-locate" "^5.0.0" + + "lodash.isempty@^4.4.0": + "integrity" "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=" + "resolved" "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz" + "version" "4.4.0" + + "lodash.isfunction@^3.0.9": + "integrity" "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + "resolved" "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz" + "version" "3.0.9" + + "lodash.isobject@^3.0.2": + "integrity" "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=" + "resolved" "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz" + "version" "3.0.2" + + "lodash.isstring@^4.0.1": + "integrity" "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + "resolved" "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" + "version" "4.0.1" + + "lodash@^4.17.20": + "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + "version" "4.17.21" + + "log-symbols@4.1.0": + "integrity" "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==" + "resolved" "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "chalk" "^4.1.0" + "is-unicode-supported" "^0.1.0" + + "loose-envify@^1.4.0": + "integrity" "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" + "resolved" "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "js-tokens" "^3.0.0 || ^4.0.0" + + "loupe@^2.3.1": + "integrity" "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==" + "resolved" "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" + "version" "2.3.4" + dependencies: + "get-func-name" "^2.0.0" + + "lower-case@^2.0.2": + "integrity" "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==" + "resolved" "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "tslib" "^2.0.3" + + "make-error@^1.1.1": + "integrity" "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "resolved" "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + "version" "1.3.6" + + "minimalistic-assert@^1.0.0", "minimalistic-assert@^1.0.1": + "integrity" "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "resolved" "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + "version" "1.0.1" + + "minimalistic-crypto-utils@^1.0.1": + "integrity" "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + "resolved" "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + "version" "1.0.1" + + "minimatch@^3.0.4": + "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "brace-expansion" "^1.1.7" + + "minimatch@4.2.1": + "integrity" "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" + "version" "4.2.1" + dependencies: + "brace-expansion" "^1.1.7" + + "minimist@^1.2.0", "minimist@^1.2.6": + "integrity" "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + "version" "1.2.6" + + "mkdirp@^0.5.1": + "integrity" "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + "version" "0.5.6" + dependencies: + "minimist" "^1.2.6" + + "mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X", "mocha@^9.2.1", "mocha@>=7": + "integrity" "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==" + "resolved" "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" + "version" "9.2.2" + dependencies: + "@ungap/promise-all-settled" "1.1.2" + "ansi-colors" "4.1.1" + "browser-stdout" "1.3.1" + "chokidar" "3.5.3" + "debug" "4.3.3" + "diff" "5.0.0" + "escape-string-regexp" "4.0.0" + "find-up" "5.0.0" + "glob" "7.2.0" + "growl" "1.10.5" + "he" "1.2.0" + "js-yaml" "4.1.0" + "log-symbols" "4.1.0" + "minimatch" "4.2.1" + "ms" "2.1.3" + "nanoid" "3.3.1" + "serialize-javascript" "6.0.0" + "strip-json-comments" "3.1.1" + "supports-color" "8.1.1" + "which" "2.0.2" + "workerpool" "6.2.0" + "yargs" "16.2.0" + "yargs-parser" "20.2.4" + "yargs-unparser" "2.0.0" + + "mochawesome-report-generator@^6.2.0": + "integrity" "sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==" + "resolved" "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "chalk" "^4.1.2" + "dateformat" "^4.5.1" + "escape-html" "^1.0.3" + "fs-extra" "^10.0.0" + "fsu" "^1.1.1" + "lodash.isfunction" "^3.0.9" + "opener" "^1.5.2" + "prop-types" "^15.7.2" + "tcomb" "^3.2.17" + "tcomb-validation" "^3.3.0" + "validator" "^13.6.0" + "yargs" "^17.2.1" + + "mochawesome@^7.0.1": + "integrity" "sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==" + "resolved" "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.3.tgz" + "version" "7.1.3" + dependencies: + "chalk" "^4.1.2" + "diff" "^5.0.0" + "json-stringify-safe" "^5.0.1" + "lodash.isempty" "^4.4.0" + "lodash.isfunction" "^3.0.9" + "lodash.isobject" "^3.0.2" + "lodash.isstring" "^4.0.1" + "mochawesome-report-generator" "^6.2.0" + "strip-ansi" "^6.0.1" + "uuid" "^8.3.2" + + "ms@2.1.2": + "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + "version" "2.1.2" + + "ms@2.1.3": + "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + "version" "2.1.3" + + "nanoid@3.3.1": + "integrity" "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" + "version" "3.3.1" + + "no-case@^3.0.4": + "integrity" "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==" + "resolved" "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "lower-case" "^2.0.2" + "tslib" "^2.0.3" + + "node-addon-api@^2.0.0": + "integrity" "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" + "version" "2.0.2" + + "node-fetch@2.6.7": + "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" + "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" + "version" "2.6.7" + dependencies: + "whatwg-url" "^5.0.0" + + "node-gyp-build@^4.2.0", "node-gyp-build@^4.3.0": + "integrity" "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" + "resolved" "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz" + "version" "4.4.0" + + "normalize-path@^3.0.0", "normalize-path@~3.0.0": + "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + "version" "3.0.0" + + "object-assign@^4.1.1": + "integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + "version" "4.1.1" + + "once@^1.3.0": + "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" + "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "wrappy" "1" + + "opener@^1.5.2": + "integrity" "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + "resolved" "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz" + "version" "1.5.2" + + "p-limit@^3.0.2": + "integrity" "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==" + "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "yocto-queue" "^0.1.0" + + "p-locate@^5.0.0": + "integrity" "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==" + "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "p-limit" "^3.0.2" + + "pako@^2.0.3": + "integrity" "sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==" + "resolved" "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz" + "version" "2.0.4" + + "path-exists@^4.0.0": + "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + "version" "4.0.0" + + "path-is-absolute@^1.0.0": + "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + "version" "1.0.1" + + "pathval@^1.1.1": + "integrity" "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" + "resolved" "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" + "version" "1.1.1" + + "picomatch@^2.0.4", "picomatch@^2.2.1": + "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + "version" "2.3.1" + + "prop-types@^15.7.2": + "integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==" + "resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" + "version" "15.8.1" + dependencies: + "loose-envify" "^1.4.0" + "object-assign" "^4.1.1" + "react-is" "^16.13.1" + + "randombytes@^2.1.0": + "integrity" "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" + "resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "safe-buffer" "^5.1.0" + + "react-is@^16.13.1": + "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + "version" "16.13.1" + + "readdirp@~3.6.0": + "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" + "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "picomatch" "^2.2.1" + + "regenerator-runtime@^0.13.4": + "integrity" "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" + "version" "0.13.9" + + "require-directory@^2.1.1": + "integrity" "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + "version" "2.1.1" + + "rpc-websockets@^7.4.2": + "integrity" "sha512-bVu+4qM5CkGVlTqJa6FaAxLbb5uRnyH4te7yjFvoCzbnif7PT4BcvXtNTprHlNvsH+/StB81zUQicxMrUrIomA==" + "resolved" "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.18.tgz" + "version" "7.4.18" + dependencies: + "@babel/runtime" "^7.17.2" + "eventemitter3" "^4.0.7" + "uuid" "^8.3.2" + "ws" "^8.5.0" + optionalDependencies: + "bufferutil" "^4.0.1" + "utf-8-validate" "^5.0.2" + + "safe-buffer@^5.0.1", "safe-buffer@^5.1.0": + "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + "version" "5.2.1" + + "secp256k1@^4.0.2": + "integrity" "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==" + "resolved" "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "elliptic" "^6.5.4" + "node-addon-api" "^2.0.0" + "node-gyp-build" "^4.2.0" + + "serialize-javascript@6.0.0": + "integrity" "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==" + "resolved" "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "randombytes" "^2.1.0" + + "snake-case@^3.0.4": + "integrity" "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==" + "resolved" "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "dot-case" "^3.0.4" + "tslib" "^2.0.3" + + "source-map-support@^0.5.6": + "integrity" "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" + "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + "version" "0.5.21" + dependencies: + "buffer-from" "^1.0.0" + "source-map" "^0.6.0" + + "source-map@^0.6.0": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" + + "string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.3": + "integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + "version" "4.2.3" + dependencies: + "emoji-regex" "^8.0.0" + "is-fullwidth-code-point" "^3.0.0" + "strip-ansi" "^6.0.1" + + "strip-ansi@^6.0.0", "strip-ansi@^6.0.1": + "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "ansi-regex" "^5.0.1" + + "strip-bom@^3.0.0": + "integrity" "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "resolved" "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + "version" "3.0.0" + + "strip-json-comments@3.1.1": + "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + "version" "3.1.1" + + "superstruct@^0.14.2": + "integrity" "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + "resolved" "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz" + "version" "0.14.2" + + "supports-color@^7.1.0": + "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "has-flag" "^4.0.0" + + "supports-color@8.1.1": + "integrity" "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + "version" "8.1.1" + dependencies: + "has-flag" "^4.0.0" + + "tcomb-validation@^3.3.0": + "integrity" "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==" + "resolved" "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz" + "version" "3.4.1" + dependencies: + "tcomb" "^3.0.0" + + "tcomb@^3.0.0", "tcomb@^3.2.17": + "integrity" "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==" + "resolved" "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz" + "version" "3.2.29" + + "text-encoding-utf-8@^1.0.2": + "integrity" "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + "resolved" "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" + "version" "1.0.2" + + "through@>=2.2.7 <3": + "integrity" "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "resolved" "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + "version" "2.3.8" + + "to-regex-range@^5.0.1": + "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "is-number" "^7.0.0" + + "toml@^3.0.0": + "integrity" "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + "resolved" "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" + "version" "3.0.0" + + "tr46@~0.0.3": + "integrity" "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + "version" "0.0.3" + + "ts-mocha@^9.0.2": + "integrity" "sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw==" + "resolved" "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz" + "version" "9.0.2" + dependencies: + "ts-node" "7.0.1" + optionalDependencies: + "tsconfig-paths" "^3.5.0" + + "ts-node@7.0.1": + "integrity" "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==" + "resolved" "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "arrify" "^1.0.0" + "buffer-from" "^1.1.0" + "diff" "^3.1.0" + "make-error" "^1.1.1" + "minimist" "^1.2.0" + "mkdirp" "^0.5.1" + "source-map-support" "^0.5.6" + "yn" "^2.0.0" + + "tsconfig-paths@^3.5.0": + "integrity" "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==" + "resolved" "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz" + "version" "3.14.1" + dependencies: + "@types/json5" "^0.0.29" + "json5" "^1.0.1" + "minimist" "^1.2.6" + "strip-bom" "^3.0.0" + + "tslib@^2.0.3": + "integrity" "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" + "version" "2.4.0" + + "tweetnacl@^1.0.0": + "integrity" "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "resolved" "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" + "version" "1.0.3" + + "type-detect@^4.0.0", "type-detect@^4.0.5": + "integrity" "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + "resolved" "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + "version" "4.0.8" + + "typescript@^4.5.5": + "integrity" "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" + "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz" + "version" "4.6.3" + + "universalify@^2.0.0": + "integrity" "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + "version" "2.0.0" + + "utf-8-validate@^5.0.2": + "integrity" "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==" + "resolved" "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz" + "version" "5.0.9" + dependencies: + "node-gyp-build" "^4.3.0" + + "uuid@^8.3.2": + "integrity" "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "resolved" "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + "version" "8.3.2" + + "validator@^13.6.0": + "integrity" "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + "resolved" "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz" + "version" "13.7.0" + + "webidl-conversions@^3.0.0": + "integrity" "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + "version" "3.0.1" + + "whatwg-url@^5.0.0": + "integrity" "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=" + "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "tr46" "~0.0.3" + "webidl-conversions" "^3.0.0" + + "which@2.0.2": + "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "isexe" "^2.0.0" + + "workerpool@6.2.0": + "integrity" "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==" + "resolved" "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" + "version" "6.2.0" + + "wrap-ansi@^7.0.0": + "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "ansi-styles" "^4.0.0" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + + "wrappy@1": + "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "version" "1.0.2" + + "ws@*", "ws@^7.4.5": + "integrity" "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==" + "resolved" "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" + "version" "7.5.7" + + "ws@^8.5.0": + "integrity" "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==" + "resolved" "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" + "version" "8.5.0" + + "y18n@^5.0.5": + "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + "version" "5.0.8" + + "yargs-parser@^20.2.2", "yargs-parser@20.2.4": + "integrity" "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + "version" "20.2.4" + + "yargs-parser@^21.0.0": + "integrity" "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz" + "version" "21.0.1" + + "yargs-unparser@2.0.0": + "integrity" "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==" + "resolved" "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "camelcase" "^6.0.0" + "decamelize" "^4.0.0" + "flat" "^5.0.2" + "is-plain-obj" "^2.1.0" + + "yargs@^17.2.1": + "integrity" "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz" + "version" "17.4.1" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.3" + "y18n" "^5.0.5" + "yargs-parser" "^21.0.0" + + "yargs@16.2.0": + "integrity" "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + "version" "16.2.0" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.0" + "y18n" "^5.0.5" + "yargs-parser" "^20.2.2" + + "yn@^2.0.0": + "integrity" "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" + "resolved" "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" + "version" "2.0.0" + + "yocto-queue@^0.1.0": + "integrity" "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + "version" "0.1.0" diff --git a/yarn.lock b/yarn.lock index 2abce6f17..8a5ddc119 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,1570 +2,1636 @@ # yarn lockfile v1 -"@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" - integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== +"@babel/runtime@^7.10.5", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2": + "integrity" "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==" + "resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz" + "version" "7.17.9" dependencies: - regenerator-runtime "^0.13.4" + "regenerator-runtime" "^0.13.4" -"@blockworks-foundation/mango-client@3.3.15": - version "3.3.15" - resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-client/-/mango-client-3.3.15.tgz#f08c849780357a09e727d86964ebc50b472225fa" - integrity sha512-66JUf+DtKjoN4o9MAi/YsW0xTpcSHsL+XzaPaQ9XT3Gx6anje1AtXPpeKJmInBcivGRrsXPX+NJxc6O6kyzUag== +"@blockworks-foundation/mango-client@^3.4.5": + "integrity" "sha512-veV3tfUfSZ8gN2I0u2gCj+dSQcD0QB1Imo2XuUdv0IUKb4Um8KoBxxpv1fxVHQ2J5RRSCYNW6DhPiNEnZYhbXg==" + "resolved" "https://registry.npmjs.org/@blockworks-foundation/mango-client/-/mango-client-3.4.8.tgz" + "version" "3.4.8" dependencies: - "@project-serum/anchor" "^0.16.2" + "@project-serum/anchor" "^0.21.0" "@project-serum/serum" "0.13.55" "@project-serum/sol-wallet-adapter" "^0.2.0" "@solana/spl-token" "^0.1.6" - "@solana/web3.js" "^1.31.0" - big.js "^6.1.1" - bn.js "^5.2.0" - buffer-layout "^1.2.1" - cross-fetch "^3.1.5" - dotenv "^10.0.0" - yargs "^17.0.1" - -"@ethersproject/bytes@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c" - integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog== - dependencies: - "@ethersproject/logger" "^5.5.0" - -"@ethersproject/logger@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d" - integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg== + "@solana/web3.js" "^1.37.1" + "big.js" "^6.1.1" + "bn.js" "^5.1.0" + "buffer-layout" "^1.2.1" + "cross-fetch" "^3.1.5" + "dotenv" "^10.0.0" + "toformat" "^2.0.0" + "yargs" "^17.0.1" + +"@ethersproject/bytes@^5.6.0": + "integrity" "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==" + "resolved" "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz" + "version" "5.6.1" + dependencies: + "@ethersproject/logger" "^5.6.0" + +"@ethersproject/logger@^5.6.0": + "integrity" "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" + "resolved" "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz" + "version" "5.6.0" "@ethersproject/sha2@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.5.0.tgz#a40a054c61f98fd9eee99af2c3cc6ff57ec24db7" - integrity sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA== + "integrity" "sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA==" + "resolved" "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.6.0.tgz" + "version" "5.6.0" + dependencies: + "@ethersproject/bytes" "^5.6.0" + "@ethersproject/logger" "^5.6.0" + "hash.js" "1.1.7" + +"@marinade.finance/marinade-ts-sdk@3.0.0": + "integrity" "sha512-Ip/U+Yy8fP+FuY09raZOYLew/eSrL09Dxm79e5gwCv58h7TcvdtXOSzh6cLOxHqeaBPsyffMc+pvoUsFcw+WWA==" + "resolved" "https://registry.npmjs.org/@marinade.finance/marinade-ts-sdk/-/marinade-ts-sdk-3.0.0.tgz" + "version" "3.0.0" dependencies: - "@ethersproject/bytes" "^5.5.0" - "@ethersproject/logger" "^5.5.0" - hash.js "1.1.7" + "@project-serum/anchor" "^0.18.2" + "@solana/spl-token" "^0.1.8" + "borsh" "^0.6.0" + "bs58" "^5.0.0" "@project-serum/anchor@^0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.11.1.tgz#155bff2c70652eafdcfd5559c81a83bb19cec9ff" - integrity sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA== + "integrity" "sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA==" + "resolved" "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.11.1.tgz" + "version" "0.11.1" dependencies: "@project-serum/borsh" "^0.2.2" "@solana/web3.js" "^1.17.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.0" - camelcase "^5.3.1" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/anchor@^0.16.2": - version "0.16.2" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.16.2.tgz#b8b4ec4c749d59a224108f8d82ab68217ef752ae" - integrity sha512-wOJwObd4wOZ5tRRMCKYjeMNsEmf7vuC71KQRnw6wthhErL8c/818n4gYIZCf/1ZPl/8WPruIlmtQHDSEyy2+0Q== + "base64-js" "^1.5.1" + "bn.js" "^5.1.2" + "bs58" "^4.0.1" + "buffer-layout" "^1.2.0" + "camelcase" "^5.3.1" + "crypto-hash" "^1.3.0" + "eventemitter3" "^4.0.7" + "find" "^0.3.0" + "js-sha256" "^0.9.0" + "pako" "^2.0.3" + "snake-case" "^3.0.4" + "toml" "^3.0.0" + +"@project-serum/anchor@^0.18.2": + "integrity" "sha512-uyjiN/3Ipp+4hrZRm/hG18HzGLZyvP790LXrCsGO3IWxSl28YRhiGEpKnZycfMW94R7nxdUoE3wY67V+ZHSQBQ==" + "resolved" "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.18.2.tgz" + "version" "0.18.2" dependencies: "@project-serum/borsh" "^0.2.2" "@solana/web3.js" "^1.17.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.0" - camelcase "^5.3.1" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" + "base64-js" "^1.5.1" + "bn.js" "^5.1.2" + "bs58" "^4.0.1" + "buffer-layout" "^1.2.0" + "camelcase" "^5.3.1" + "crypto-hash" "^1.3.0" + "eventemitter3" "^4.0.7" + "find" "^0.3.0" + "js-sha256" "^0.9.0" + "pako" "^2.0.3" + "snake-case" "^3.0.4" + "toml" "^3.0.0" "@project-serum/anchor@^0.21.0": - version "0.21.0" - resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.21.0.tgz#ad5fb33744991ec1900cdb2fd22707c908b12b5f" - integrity sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA== + "integrity" "sha512-flRuW/F+iC8mitNokx82LOXyND7Dyk6n5UUPJpQv/+NfySFrNFlzuQZaBZJ4CG5g9s8HS/uaaIz1nVkDR8V/QA==" + "resolved" "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.21.0.tgz" + "version" "0.21.0" dependencies: "@project-serum/borsh" "^0.2.4" "@solana/web3.js" "^1.17.0" - base64-js "^1.5.1" - bn.js "^5.1.2" - bs58 "^4.0.1" - buffer-layout "^1.2.2" - camelcase "^5.3.1" - cross-fetch "^3.1.5" - crypto-hash "^1.3.0" - eventemitter3 "^4.0.7" - find "^0.3.0" - js-sha256 "^0.9.0" - pako "^2.0.3" - snake-case "^3.0.4" - toml "^3.0.0" - -"@project-serum/borsh@^0.2.2": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.3.tgz#1d705c5887484cb6a127dd5feff58e90cbfcb558" - integrity sha512-lH9zEYADZE3cxrgiFym8+jbUE3NM/LH+WOKYcUjs65CT10Q64Hv45bcAAa/phwYk4Tpz0uQ1x+ergFaAoGt67Q== - dependencies: - bn.js "^5.1.2" - buffer-layout "^1.2.0" - -"@project-serum/borsh@^0.2.4": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.5.tgz#6059287aa624ecebbfc0edd35e4c28ff987d8663" - integrity sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q== - dependencies: - bn.js "^5.1.2" - buffer-layout "^1.2.0" + "base64-js" "^1.5.1" + "bn.js" "^5.1.2" + "bs58" "^4.0.1" + "buffer-layout" "^1.2.2" + "camelcase" "^5.3.1" + "cross-fetch" "^3.1.5" + "crypto-hash" "^1.3.0" + "eventemitter3" "^4.0.7" + "find" "^0.3.0" + "js-sha256" "^0.9.0" + "pako" "^2.0.3" + "snake-case" "^3.0.4" + "toml" "^3.0.0" + +"@project-serum/anchor@0.24.2": + "integrity" "sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA==" + "resolved" "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz" + "version" "0.24.2" + dependencies: + "@project-serum/borsh" "^0.2.5" + "@solana/web3.js" "^1.36.0" + "base64-js" "^1.5.1" + "bn.js" "^5.1.2" + "bs58" "^4.0.1" + "buffer-layout" "^1.2.2" + "camelcase" "^5.3.1" + "cross-fetch" "^3.1.5" + "crypto-hash" "^1.3.0" + "eventemitter3" "^4.0.7" + "js-sha256" "^0.9.0" + "pako" "^2.0.3" + "snake-case" "^3.0.4" + "toml" "^3.0.0" + +"@project-serum/borsh@^0.2.2", "@project-serum/borsh@^0.2.4", "@project-serum/borsh@^0.2.5": + "integrity" "sha512-UmeUkUoKdQ7rhx6Leve1SssMR/Ghv8qrEiyywyxSWg7ooV7StdpPBhciiy5eB3T0qU1BXvdRNC8TdrkxK7WC5Q==" + "resolved" "https://registry.npmjs.org/@project-serum/borsh/-/borsh-0.2.5.tgz" + "version" "0.2.5" + dependencies: + "bn.js" "^5.1.2" + "buffer-layout" "^1.2.0" "@project-serum/serum@0.13.55": - version "0.13.55" - resolved "https://registry.yarnpkg.com/@project-serum/serum/-/serum-0.13.55.tgz#2ac44fe7b07651274eb57ac54ea9325789df5dd7" - integrity sha512-SPQ4NsuNbBJO3mLGnTYbjt47WCXoNIcW2C9xv0gNXyG62dxgONsAEEgErKv1gT34hWCMPsXFSpatnX6ppriq7w== + "integrity" "sha512-SPQ4NsuNbBJO3mLGnTYbjt47WCXoNIcW2C9xv0gNXyG62dxgONsAEEgErKv1gT34hWCMPsXFSpatnX6ppriq7w==" + "resolved" "https://registry.npmjs.org/@project-serum/serum/-/serum-0.13.55.tgz" + "version" "0.13.55" dependencies: "@project-serum/anchor" "^0.11.1" "@solana/spl-token" "^0.1.6" "@solana/web3.js" "^1.21.0" - bn.js "^5.1.2" - buffer-layout "^1.2.0" + "bn.js" "^5.1.2" + "buffer-layout" "^1.2.0" "@project-serum/sol-wallet-adapter@^0.2.0": - version "0.2.6" - resolved "https://registry.yarnpkg.com/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz#b4cd25a566294354427c97c26d716112b91a0107" - integrity sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g== + "integrity" "sha512-cpIb13aWPW8y4KzkZAPDgw+Kb+DXjCC6rZoH74MGm3I/6e/zKyGnfAuW5olb2zxonFqsYgnv7ev8MQnvSgJ3/g==" + "resolved" "https://registry.npmjs.org/@project-serum/sol-wallet-adapter/-/sol-wallet-adapter-0.2.6.tgz" + "version" "0.2.6" + dependencies: + "bs58" "^4.0.1" + "eventemitter3" "^4.0.7" + +"@solana/buffer-layout-utils@^0.2.0": + "integrity" "sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==" + "resolved" "https://registry.npmjs.org/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz" + "version" "0.2.0" dependencies: - bs58 "^4.0.1" - eventemitter3 "^4.0.7" + "@solana/buffer-layout" "^4.0.0" + "@solana/web3.js" "^1.32.0" + "bigint-buffer" "^1.1.5" + "bignumber.js" "^9.0.1" -"@solana/buffer-layout@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326" - integrity sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w== +"@solana/buffer-layout@^4.0.0": + "integrity" "sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==" + "resolved" "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz" + "version" "4.0.0" dependencies: - buffer "~6.0.3" + "buffer" "~6.0.3" "@solana/spl-token@^0.1.6", "@solana/spl-token@^0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.1.8.tgz#f06e746341ef8d04165e21fc7f555492a2a0faa6" - integrity sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ== + "integrity" "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==" + "resolved" "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz" + "version" "0.1.8" dependencies: "@babel/runtime" "^7.10.5" "@solana/web3.js" "^1.21.0" - bn.js "^5.1.0" - buffer "6.0.3" - buffer-layout "^1.2.0" - dotenv "10.0.0" + "bn.js" "^5.1.0" + "buffer" "6.0.3" + "buffer-layout" "^1.2.0" + "dotenv" "10.0.0" -"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0": - version "1.31.0" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.31.0.tgz#7a313d4c1a90b77f27ddbfe845a10d6883e06452" - integrity sha512-7nHHx1JNFnrt15e9y8m38I/EJCbaB+bFC3KZVM1+QhybCikFxGMtGA5r7PDC3GEL1R2RZA8yKoLkDKo3vzzqnw== - dependencies: - "@babel/runtime" "^7.12.5" - "@ethersproject/sha2" "^5.5.0" - "@solana/buffer-layout" "^3.0.0" - bn.js "^5.0.0" - borsh "^0.4.0" - bs58 "^4.0.1" - buffer "6.0.1" - cross-fetch "^3.1.4" - jayson "^3.4.4" - js-sha3 "^0.8.0" - rpc-websockets "^7.4.2" - secp256k1 "^4.0.2" - superstruct "^0.14.2" - tweetnacl "^1.0.0" - -"@solana/web3.js@^1.31.0": - version "1.34.0" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.34.0.tgz#33becf2c7e87497d73406374185e54e0b7bc235d" - integrity sha512-6QvqN2DqEELvuV+5yUQM8P9fRiSG+6SzQ58HjumJqODu14r7eu5HXVWEymvKAvMLGME+0TmAdJHjw9xD5NgUWA== +"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.2.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0", "@solana/web3.js@1.42.0": + "integrity" "sha512-QqGh5DWzrgsWRx4sCPDQIm3390b7buPR16tZI61slQaQwJ2ymrSXPQCe4PPTJEIlzGjCV3dkn2vpT2R32BfK2Q==" + "resolved" "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.42.0.tgz" + "version" "1.42.0" dependencies: "@babel/runtime" "^7.12.5" "@ethersproject/sha2" "^5.5.0" - "@solana/buffer-layout" "^3.0.0" - bn.js "^5.0.0" - borsh "^0.4.0" - bs58 "^4.0.1" - buffer "6.0.1" - cross-fetch "^3.1.4" - jayson "^3.4.4" - js-sha3 "^0.8.0" - rpc-websockets "^7.4.2" - secp256k1 "^4.0.2" - superstruct "^0.14.2" - tweetnacl "^1.0.0" - -"@solana/web3.js@^1.35.0": - version "1.35.0" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.35.0.tgz#a2d09add241f48a370470a5c4db8596cb13f0dc6" - integrity sha512-eKf2rPoWEyVq7QsgAQKNqxODvPsb0vqSwwg2xRY1e49Fn5Qh29m2FiLcYHRS/xhPu/7b/5gsD+RzO3BWozOeZQ== + "@solana/buffer-layout" "^4.0.0" + "@solana/buffer-layout-utils" "^0.2.0" + "bn.js" "^5.0.0" + "borsh" "^0.7.0" + "bs58" "^4.0.1" + "buffer" "6.0.1" + "cross-fetch" "^3.1.4" + "fast-stable-stringify" "^1.0.0" + "jayson" "^3.4.4" + "js-sha3" "^0.8.0" + "rpc-websockets" "^7.4.2" + "secp256k1" "^4.0.2" + "superstruct" "^0.14.2" + "tweetnacl" "^1.0.0" + +"@solana/web3.js@^1.37.1", "@solana/web3.js@^1.5.0": + "integrity" "sha512-1f4Njy98f5dKa/x8fvMG3EaY4e5UNEXYRqCpAHpY8MkfROnedZOFHk+w6CD3+7UjJzjdQJzD7YdwYEQErEVYWQ==" + "resolved" "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.43.2.tgz" + "version" "1.43.2" dependencies: "@babel/runtime" "^7.12.5" "@ethersproject/sha2" "^5.5.0" - "@solana/buffer-layout" "^3.0.0" - bn.js "^5.0.0" - borsh "^0.4.0" - bs58 "^4.0.1" - buffer "6.0.1" - cross-fetch "^3.1.4" - jayson "^3.4.4" - js-sha3 "^0.8.0" - rpc-websockets "^7.4.2" - secp256k1 "^4.0.2" - superstruct "^0.14.2" - tweetnacl "^1.0.0" - -"@types/bn.js@^4.11.5": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" + "@solana/buffer-layout" "^4.0.0" + "bigint-buffer" "^1.1.5" + "bn.js" "^5.0.0" + "borsh" "^0.7.0" + "bs58" "^4.0.1" + "buffer" "6.0.1" + "fast-stable-stringify" "^1.0.0" + "jayson" "^3.4.4" + "js-sha3" "^0.8.0" + "node-fetch" "2" + "rpc-websockets" "^7.4.2" + "secp256k1" "^4.0.2" + "superstruct" "^0.14.2" + "tweetnacl" "^1.0.0" "@types/chai@^4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.0.tgz#23509ebc1fa32f1b4d50d6a66c4032d5b8eaabdc" - integrity sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw== + "integrity" "sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==" + "resolved" "https://registry.npmjs.org/@types/chai/-/chai-4.3.1.tgz" + "version" "4.3.1" "@types/connect@^3.4.33": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + "integrity" "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==" + "resolved" "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + "version" "3.4.35" dependencies: "@types/node" "*" "@types/express-serve-static-core@^4.17.9": - version "4.17.26" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.26.tgz#5d9a8eeecb9d5f9d7fc1d85f541512a84638ae88" - integrity sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ== + "integrity" "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==" + "resolved" "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz" + "version" "4.17.28" dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" "@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + "integrity" "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + "resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" + "version" "0.0.29" "@types/lodash@^4.14.159": - version "4.14.178" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" - integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== + "integrity" "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==" + "resolved" "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz" + "version" "4.14.182" "@types/mocha@^9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.0.tgz#baf17ab2cca3fcce2d322ebc30454bff487efad5" - integrity sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg== + "integrity" "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==" + "resolved" "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" + "version" "9.1.1" -"@types/node@*": - version "16.11.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10" - integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw== - -"@types/node@^12.12.54": - version "12.20.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.37.tgz#abb38afa9d6e8a2f627a8cb52290b3c80fbe61ed" - integrity sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA== +"@types/node@*", "@types/node@^12.12.54": + "integrity" "sha512-5e6QNb9bkeh4Hni4ktLqUZuUqnGTX/kou2aZkXyxtuYaHXgBm+In1SHR9V+7kDzWzjB08KC2uqt2doDi7cuAAA==" + "resolved" "https://registry.npmjs.org/@types/node/-/node-12.20.49.tgz" + "version" "12.20.49" "@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + "integrity" "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "resolved" "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + "version" "6.9.7" "@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "integrity" "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "resolved" "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" + "version" "1.2.4" "@types/ws@^7.4.4": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== + "integrity" "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==" + "resolved" "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" + "version" "7.4.7" dependencies: "@types/node" "*" "@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -"@uxdprotocol/uxd-client@=5.0.16": - version "5.0.16" - resolved "https://npm.pkg.github.com/download/@uxdprotocol/uxd-client/5.0.16/cbff5eff3e7eabf4112775afe3f1363f1f9eb994df553d57cbfe4d2bd429fcbc#5418bcc3ea5dff3bca76109325b472324580985d" - integrity sha512-wV7Hbq7v644zfaD59+rOhac7fPwSuWZj3c/KXJC6Mx639hzjFLz0O36+BHDE8KRYJ6uv9h2x58tUHvBwfb2/tQ== - dependencies: - "@blockworks-foundation/mango-client" "3.3.15" - "@project-serum/anchor" "^0.21.0" - camelcase "^5.3.1" - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1, base64-js@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -big.js@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.1.1.tgz#63b35b19dc9775c94991ee5db7694880655d5537" - integrity sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" - integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== - -borsh@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.4.0.tgz#9dd6defe741627f1315eac2a73df61421f6ddb9f" - integrity sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g== - dependencies: - "@types/bn.js" "^4.11.5" - bn.js "^5.0.0" - bs58 "^4.0.0" - text-encoding-utf-8 "^1.0.2" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - -buffer-from@^1.0.0, buffer-from@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-layout@^1.2.0, buffer-layout@^1.2.1, buffer-layout@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" - integrity sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA== - -buffer@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" - integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buffer@6.0.3, buffer@~6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -bufferutil@^4.0.1: - version "4.0.5" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.5.tgz#da9ea8166911cc276bf677b8aed2d02d31f59028" - integrity sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A== - dependencies: - node-gyp-build "^4.3.0" - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" - integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== - -chai@^4.3.6: - version "4.3.6" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" - integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - 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" + "integrity" "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" + "resolved" "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" + "version" "1.1.2" + +"@uxd-protocol/uxd-client@file:../solana-usds-client": + "resolved" "file:../solana-usds-client" + "version" "2.0.0-beta.3" + dependencies: + "@blockworks-foundation/mango-client" "3.4.7" + "@marinade.finance/marinade-ts-sdk" "3.0.0" + "@project-serum/anchor" "0.24.2" + "@solana/spl-token" "0.1.8" + "@solana/web3.js" "1.42.0" + "camelcase" "5.3.1" + +"ansi-colors@4.1.1": + "integrity" "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "resolved" "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" + "version" "4.1.1" + +"ansi-regex@^5.0.1": + "integrity" "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "resolved" "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + "version" "5.0.1" + +"ansi-styles@^4.0.0", "ansi-styles@^4.1.0": + "integrity" "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + "resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + "version" "4.3.0" + dependencies: + "color-convert" "^2.0.1" + +"anymatch@~3.1.2": + "integrity" "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==" + "resolved" "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + "version" "3.1.2" + dependencies: + "normalize-path" "^3.0.0" + "picomatch" "^2.0.4" + +"argparse@^2.0.1": + "integrity" "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "resolved" "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + "version" "2.0.1" + +"arrify@^1.0.0": + "integrity" "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "resolved" "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + "version" "1.0.1" + +"assertion-error@^1.1.0": + "integrity" "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + "resolved" "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" + "version" "1.1.0" + +"balanced-match@^1.0.0": + "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + "version" "1.0.2" + +"base-x@^3.0.2": + "integrity" "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==" + "resolved" "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" + "version" "3.0.9" + dependencies: + "safe-buffer" "^5.0.1" + +"base-x@^4.0.0": + "integrity" "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + "resolved" "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz" + "version" "4.0.0" + +"base64-js@^1.3.1", "base64-js@^1.5.1": + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "resolved" "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + "version" "1.5.1" + +"big.js@^6.1.1": + "integrity" "sha512-1vObw81a8ylZO5ePrtMay0n018TcftpTA5HFKDaSuiUDBo8biRBtjIobw60OpwuvrGk+FsxKamqN4cnmj/eXdg==" + "resolved" "https://registry.npmjs.org/big.js/-/big.js-6.1.1.tgz" + "version" "6.1.1" + +"bigint-buffer@^1.1.5": + "integrity" "sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==" + "resolved" "https://registry.npmjs.org/bigint-buffer/-/bigint-buffer-1.1.5.tgz" + "version" "1.1.5" + dependencies: + "bindings" "^1.3.0" + +"bignumber.js@^9.0.1": + "integrity" "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + "resolved" "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz" + "version" "9.0.2" + +"binary-extensions@^2.0.0": + "integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + "version" "2.2.0" + +"bindings@^1.3.0": + "integrity" "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==" + "resolved" "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + "version" "1.5.0" + dependencies: + "file-uri-to-path" "1.0.0" + +"bn.js@^4.11.9": + "integrity" "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + "version" "4.12.0" + +"bn.js@^5.0.0", "bn.js@^5.1.0", "bn.js@^5.1.2", "bn.js@^5.2.0": + "integrity" "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + "resolved" "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz" + "version" "5.2.0" + +"borsh@^0.6.0": + "integrity" "sha512-sl5k89ViqsThXQpYa9XDtz1sBl3l1lI313cFUY1HKr+wvMILnb+58xpkqTNrYbelh99dY7K8usxoCusQmqix9Q==" + "resolved" "https://registry.npmjs.org/borsh/-/borsh-0.6.0.tgz" + "version" "0.6.0" + dependencies: + "bn.js" "^5.2.0" + "bs58" "^4.0.0" + "text-encoding-utf-8" "^1.0.2" + +"borsh@^0.7.0": + "integrity" "sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==" + "resolved" "https://registry.npmjs.org/borsh/-/borsh-0.7.0.tgz" + "version" "0.7.0" + dependencies: + "bn.js" "^5.2.0" + "bs58" "^4.0.0" + "text-encoding-utf-8" "^1.0.2" + +"brace-expansion@^1.1.7": + "integrity" "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" + "resolved" "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + "version" "1.1.11" + dependencies: + "balanced-match" "^1.0.0" + "concat-map" "0.0.1" + +"braces@~3.0.2": + "integrity" "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==" + "resolved" "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + "version" "3.0.2" + dependencies: + "fill-range" "^7.0.1" + +"brorand@^1.1.0": + "integrity" "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + "resolved" "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + "version" "1.1.0" + +"browser-stdout@1.3.1": + "integrity" "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + "resolved" "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" + "version" "1.3.1" + +"bs58@^4.0.0", "bs58@^4.0.1": + "integrity" "sha1-vhYedsNU9veIrkBx9j806MTwpCo=" + "resolved" "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" + "version" "4.0.1" + dependencies: + "base-x" "^3.0.2" + +"bs58@^5.0.0": + "integrity" "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==" + "resolved" "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "base-x" "^4.0.0" + +"buffer-from@^1.0.0", "buffer-from@^1.1.0": + "integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + "version" "1.1.2" + +"buffer-layout@^1.2.0", "buffer-layout@^1.2.1", "buffer-layout@^1.2.2": + "integrity" "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" + "resolved" "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz" + "version" "1.2.2" + +"buffer@~6.0.3": + "integrity" "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + "version" "6.0.3" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.2.1" + +"buffer@6.0.1": + "integrity" "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz" + "version" "6.0.1" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.2.1" + +"buffer@6.0.3": + "integrity" "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==" + "resolved" "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + "version" "6.0.3" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.2.1" + +"bufferutil@^4.0.1": + "integrity" "sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw==" + "resolved" "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.6.tgz" + "version" "4.0.6" + dependencies: + "node-gyp-build" "^4.3.0" + +"camelcase@^5.3.1": + "integrity" "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + "version" "5.3.1" + +"camelcase@^6.0.0": + "integrity" "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + "resolved" "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + "version" "6.3.0" + +"chai@^4.3.6": + "integrity" "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==" + "resolved" "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz" + "version" "4.3.6" + dependencies: + "assertion-error" "^1.1.0" + "check-error" "^1.0.2" + "deep-eql" "^3.0.1" + "get-func-name" "^2.0.0" + "loupe" "^2.3.1" + "pathval" "^1.1.1" + "type-detect" "^4.0.5" + +"chalk@^4.1.0", "chalk@^4.1.2": + "integrity" "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + "resolved" "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "ansi-styles" "^4.1.0" + "supports-color" "^7.1.0" + +"check-error@^1.0.2": + "integrity" "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + "resolved" "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" + "version" "1.0.2" + +"chokidar@3.5.3": + "integrity" "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==" + "resolved" "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + "version" "3.5.3" + 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" optionalDependencies: - fsevents "~2.3.2" - -circular-json@^0.5.9: - version "0.5.9" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" - integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -commander@^2.20.3: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -cross-fetch@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" - integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== - dependencies: - node-fetch "2.6.1" - -cross-fetch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -crypto-hash@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/crypto-hash/-/crypto-hash-1.3.0.tgz#b402cb08f4529e9f4f09346c3e275942f845e247" - integrity sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg== - -dateformat@^4.5.1: - version "4.6.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" - integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== - -debug@4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -delay@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" - integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== - -diff@5.0.0, diff@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^3.1.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -dotenv@10.0.0, dotenv@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" - integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== - -elliptic@^6.5.2: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - 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" - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= - dependencies: - es6-promise "^4.0.3" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eventemitter3@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -eyes@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" - integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/find/-/find-0.3.0.tgz#4082e8fc8d8320f1a382b5e4f521b9bc50775cb8" - integrity sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw== - dependencies: - traverse-chain "~0.1.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -fs-extra@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" - integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -fsu@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fsu/-/fsu-1.1.1.tgz#bd36d3579907c59d85b257a75b836aa9e0c31834" - integrity sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.9" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" - integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - -jayson@^3.4.4: - version "3.6.5" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.6.5.tgz#e560bcad4daf098c7391f46ba8efc9d6f34a4102" - integrity sha512-wmOjX+eQcnCDyPF4KORomaIj9wj3h0B5VEbeD0+2VHfTfErB+h1zpR7oBkgCZp36AFjp3+a4CLz6U72BYpFHAw== + "fsevents" "~2.3.2" + +"cliui@^7.0.2": + "integrity" "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==" + "resolved" "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + "version" "7.0.4" + dependencies: + "string-width" "^4.2.0" + "strip-ansi" "^6.0.0" + "wrap-ansi" "^7.0.0" + +"color-convert@^2.0.1": + "integrity" "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + "resolved" "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + "version" "2.0.1" + dependencies: + "color-name" "~1.1.4" + +"color-name@~1.1.4": + "integrity" "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + "version" "1.1.4" + +"commander@^2.20.3": + "integrity" "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "resolved" "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + "version" "2.20.3" + +"concat-map@0.0.1": + "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "resolved" "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + "version" "0.0.1" + +"cross-fetch@^3.1.4", "cross-fetch@^3.1.5": + "integrity" "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==" + "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" + "version" "3.1.5" + dependencies: + "node-fetch" "2.6.7" + +"crypto-hash@^1.3.0": + "integrity" "sha512-lyAZ0EMyjDkVvz8WOeVnuCPvKVBXcMv1l5SVqO1yC7PzTwrD/pPje/BIRbWhMoPe436U+Y2nD7f5bFx0kt+Sbg==" + "resolved" "https://registry.npmjs.org/crypto-hash/-/crypto-hash-1.3.0.tgz" + "version" "1.3.0" + +"dateformat@^4.5.1": + "integrity" "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==" + "resolved" "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz" + "version" "4.6.3" + +"debug@4.3.3": + "integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" + "resolved" "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" + "version" "4.3.3" + dependencies: + "ms" "2.1.2" + +"decamelize@^4.0.0": + "integrity" "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" + "resolved" "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" + "version" "4.0.0" + +"deep-eql@^3.0.1": + "integrity" "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==" + "resolved" "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" + "version" "3.0.1" + dependencies: + "type-detect" "^4.0.0" + +"delay@^5.0.0": + "integrity" "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + "resolved" "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz" + "version" "5.0.0" + +"diff@^3.1.0": + "integrity" "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + "resolved" "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" + "version" "3.5.0" + +"diff@^5.0.0", "diff@5.0.0": + "integrity" "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" + "resolved" "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" + "version" "5.0.0" + +"dot-case@^3.0.4": + "integrity" "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==" + "resolved" "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "no-case" "^3.0.4" + "tslib" "^2.0.3" + +"dotenv@^10.0.0", "dotenv@10.0.0": + "integrity" "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz" + "version" "10.0.0" + +"elliptic@^6.5.4": + "integrity" "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==" + "resolved" "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" + "version" "6.5.4" + 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" + +"emoji-regex@^8.0.0": + "integrity" "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "resolved" "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + "version" "8.0.0" + +"es6-promise@^4.0.3": + "integrity" "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + "resolved" "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" + "version" "4.2.8" + +"es6-promisify@^5.0.0": + "integrity" "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=" + "resolved" "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "es6-promise" "^4.0.3" + +"escalade@^3.1.1": + "integrity" "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "resolved" "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + "version" "3.1.1" + +"escape-html@^1.0.3": + "integrity" "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "resolved" "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + "version" "1.0.3" + +"escape-string-regexp@4.0.0": + "integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + "version" "4.0.0" + +"eventemitter3@^4.0.7": + "integrity" "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "resolved" "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + "version" "4.0.7" + +"eyes@^0.1.8": + "integrity" "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + "resolved" "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz" + "version" "0.1.8" + +"fast-stable-stringify@^1.0.0": + "integrity" "sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==" + "resolved" "https://registry.npmjs.org/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz" + "version" "1.0.0" + +"file-uri-to-path@1.0.0": + "integrity" "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + "resolved" "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + "version" "1.0.0" + +"fill-range@^7.0.1": + "integrity" "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==" + "resolved" "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "to-regex-range" "^5.0.1" + +"find-up@5.0.0": + "integrity" "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==" + "resolved" "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "locate-path" "^6.0.0" + "path-exists" "^4.0.0" + +"find@^0.3.0": + "integrity" "sha512-iSd+O4OEYV/I36Zl8MdYJO0xD82wH528SaCieTVHhclgiYNe9y+yPKSwK+A7/WsmHL1EZ+pYUJBXWTL5qofksw==" + "resolved" "https://registry.npmjs.org/find/-/find-0.3.0.tgz" + "version" "0.3.0" + dependencies: + "traverse-chain" "~0.1.0" + +"flat@^5.0.2": + "integrity" "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" + "resolved" "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + "version" "5.0.2" + +"fs-extra@^10.0.0": + "integrity" "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==" + "resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + "version" "10.1.0" + dependencies: + "graceful-fs" "^4.2.0" + "jsonfile" "^6.0.1" + "universalify" "^2.0.0" + +"fs.realpath@^1.0.0": + "integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + "version" "1.0.0" + +"fsevents@~2.3.2": + "integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==" + "resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + "version" "2.3.2" + +"fsu@^1.1.1": + "integrity" "sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==" + "resolved" "https://registry.npmjs.org/fsu/-/fsu-1.1.1.tgz" + "version" "1.1.1" + +"get-caller-file@^2.0.5": + "integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + "version" "2.0.5" + +"get-func-name@^2.0.0": + "integrity" "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + "resolved" "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" + "version" "2.0.0" + +"glob-parent@~5.1.2": + "integrity" "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==" + "resolved" "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + "version" "5.1.2" + dependencies: + "is-glob" "^4.0.1" + +"glob@7.2.0": + "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" + "resolved" "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" + "version" "7.2.0" + dependencies: + "fs.realpath" "^1.0.0" + "inflight" "^1.0.4" + "inherits" "2" + "minimatch" "^3.0.4" + "once" "^1.3.0" + "path-is-absolute" "^1.0.0" + +"graceful-fs@^4.1.6", "graceful-fs@^4.2.0": + "integrity" "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + "version" "4.2.10" + +"growl@1.10.5": + "integrity" "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + "resolved" "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz" + "version" "1.10.5" + +"has-flag@^4.0.0": + "integrity" "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "resolved" "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + "version" "4.0.0" + +"hash.js@^1.0.0", "hash.js@^1.0.3", "hash.js@1.1.7": + "integrity" "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==" + "resolved" "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + "version" "1.1.7" + dependencies: + "inherits" "^2.0.3" + "minimalistic-assert" "^1.0.1" + +"he@1.2.0": + "integrity" "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + "resolved" "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + "version" "1.2.0" + +"hmac-drbg@^1.0.1": + "integrity" "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=" + "resolved" "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + "version" "1.0.1" + dependencies: + "hash.js" "^1.0.3" + "minimalistic-assert" "^1.0.0" + "minimalistic-crypto-utils" "^1.0.1" + +"ieee754@^1.2.1": + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "resolved" "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + "version" "1.2.1" + +"inflight@^1.0.4": + "integrity" "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" + "resolved" "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + "version" "1.0.6" + dependencies: + "once" "^1.3.0" + "wrappy" "1" + +"inherits@^2.0.3", "inherits@^2.0.4", "inherits@2": + "integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + "version" "2.0.4" + +"is-binary-path@~2.1.0": + "integrity" "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==" + "resolved" "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "binary-extensions" "^2.0.0" + +"is-extglob@^2.1.1": + "integrity" "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "resolved" "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + "version" "2.1.1" + +"is-fullwidth-code-point@^3.0.0": + "integrity" "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "resolved" "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + "version" "3.0.0" + +"is-glob@^4.0.1", "is-glob@~4.0.1": + "integrity" "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==" + "resolved" "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + "version" "4.0.3" + dependencies: + "is-extglob" "^2.1.1" + +"is-number@^7.0.0": + "integrity" "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "resolved" "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + "version" "7.0.0" + +"is-plain-obj@^2.1.0": + "integrity" "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + "resolved" "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + "version" "2.1.0" + +"is-unicode-supported@^0.1.0": + "integrity" "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + "resolved" "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + "version" "0.1.0" + +"isexe@^2.0.0": + "integrity" "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "resolved" "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + "version" "2.0.0" + +"isomorphic-ws@^4.0.1": + "integrity" "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + "resolved" "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz" + "version" "4.0.1" + +"jayson@^3.4.4": + "integrity" "sha512-f71uvrAWTtrwoww6MKcl9phQTC+56AopLyEenWvKVAIMz+q0oVGj6tenLZ7Z6UiPBkJtKLj4kt0tACllFQruGQ==" + "resolved" "https://registry.npmjs.org/jayson/-/jayson-3.6.6.tgz" + "version" "3.6.6" dependencies: "@types/connect" "^3.4.33" "@types/express-serve-static-core" "^4.17.9" "@types/lodash" "^4.14.159" "@types/node" "^12.12.54" "@types/ws" "^7.4.4" - JSONStream "^1.3.5" - commander "^2.20.3" - delay "^5.0.0" - es6-promisify "^5.0.0" - eyes "^0.1.8" - isomorphic-ws "^4.0.1" - json-stringify-safe "^5.0.1" - lodash "^4.17.20" - uuid "^3.4.0" - ws "^7.4.5" - -js-sha256@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/js-sha256/-/js-sha256-0.9.0.tgz#0b89ac166583e91ef9123644bd3c5334ce9d0966" - integrity sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA== - -js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + "commander" "^2.20.3" + "delay" "^5.0.0" + "es6-promisify" "^5.0.0" + "eyes" "^0.1.8" + "isomorphic-ws" "^4.0.1" + "json-stringify-safe" "^5.0.1" + "JSONStream" "^1.3.5" + "lodash" "^4.17.20" + "uuid" "^8.3.2" + "ws" "^7.4.5" + +"js-sha256@^0.9.0": + "integrity" "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + "resolved" "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz" + "version" "0.9.0" + +"js-sha3@^0.8.0": + "integrity" "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + "resolved" "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz" + "version" "0.8.0" "js-tokens@^3.0.0 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + "version" "4.0.0" -js-yaml@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== +"js-yaml@4.1.0": + "integrity" "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==" + "resolved" "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + "version" "4.1.0" dependencies: - argparse "^2.0.1" + "argparse" "^2.0.1" -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +"json-stringify-safe@^5.0.1": + "integrity" "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "resolved" "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + "version" "5.0.1" -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== +"json5@^1.0.1": + "integrity" "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==" + "resolved" "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" + "version" "1.0.1" dependencies: - minimist "^1.2.0" + "minimist" "^1.2.0" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== +"jsonfile@^6.0.1": + "integrity" "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" + "resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + "version" "6.1.0" dependencies: - universalify "^2.0.0" + "universalify" "^2.0.0" optionalDependencies: - graceful-fs "^4.1.6" + "graceful-fs" "^4.1.6" + +"jsonparse@^1.2.0": + "integrity" "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + "resolved" "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" + "version" "1.3.1" -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= +"JSONStream@^1.3.5": + "integrity" "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==" + "resolved" "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + "version" "1.3.5" + dependencies: + "jsonparse" "^1.2.0" + "through" ">=2.2.7 <3" -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" +"locate-path@^6.0.0": + "integrity" "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==" + "resolved" "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + "version" "6.0.0" + dependencies: + "p-locate" "^5.0.0" -lodash.isempty@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" - integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4= +"lodash.isempty@^4.4.0": + "integrity" "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=" + "resolved" "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz" + "version" "4.4.0" -lodash.isfunction@^3.0.9: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" - integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== +"lodash.isfunction@^3.0.9": + "integrity" "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==" + "resolved" "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz" + "version" "3.0.9" -lodash.isobject@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" - integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0= +"lodash.isobject@^3.0.2": + "integrity" "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=" + "resolved" "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz" + "version" "3.0.2" -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= +"lodash.isstring@^4.0.1": + "integrity" "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + "resolved" "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" + "version" "4.0.1" -lodash@^4.17.20: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +"lodash@^4.17.20": + "integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + "version" "4.17.21" -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== +"log-symbols@4.1.0": + "integrity" "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==" + "resolved" "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + "version" "4.1.0" dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" + "chalk" "^4.1.0" + "is-unicode-supported" "^0.1.0" -loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== +"loose-envify@^1.4.0": + "integrity" "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" + "resolved" "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + "version" "1.4.0" dependencies: - js-tokens "^3.0.0 || ^4.0.0" + "js-tokens" "^3.0.0 || ^4.0.0" -loupe@^2.3.1: - version "2.3.3" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.3.tgz#5a92027d54cfb6de4c327d3c3b705561d394d3c6" - integrity sha512-krIV4Cf1BIGIx2t1e6tucThhrBemUnIUjMtD2vN4mrMxnxpBvrcosBSpooqunBqP/hOEEV1w/Cr1YskGtqw5Jg== +"loupe@^2.3.1": + "integrity" "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==" + "resolved" "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" + "version" "2.3.4" dependencies: - get-func-name "^2.0.0" + "get-func-name" "^2.0.0" -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== +"lower-case@^2.0.2": + "integrity" "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==" + "resolved" "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" + "version" "2.0.2" dependencies: - tslib "^2.0.3" + "tslib" "^2.0.3" -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +"make-error@^1.1.1": + "integrity" "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "resolved" "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + "version" "1.3.6" -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== +"minimalistic-assert@^1.0.0", "minimalistic-assert@^1.0.1": + "integrity" "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "resolved" "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + "version" "1.0.1" -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= +"minimalistic-crypto-utils@^1.0.1": + "integrity" "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + "resolved" "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + "version" "1.0.1" -minimatch@3.0.4, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== +"minimatch@^3.0.4": + "integrity" "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + "version" "3.1.2" dependencies: - brace-expansion "^1.1.7" + "brace-expansion" "^1.1.7" + +"minimatch@4.2.1": + "integrity" "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==" + "resolved" "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" + "version" "4.2.1" + dependencies: + "brace-expansion" "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +"minimist@^1.2.0", "minimist@^1.2.6": + "integrity" "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + "version" "1.2.6" -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== +"mkdirp@^0.5.1": + "integrity" "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==" + "resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + "version" "0.5.6" dependencies: - minimist "^1.2.5" + "minimist" "^1.2.6" -mocha@^9.2.1: - version "9.2.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" - integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== +"mocha@^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X", "mocha@^9.2.1", "mocha@>=7": + "integrity" "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==" + "resolved" "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" + "version" "9.2.2" dependencies: "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.3" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - growl "1.10.5" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.2.0" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mochawesome-report-generator@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/mochawesome-report-generator/-/mochawesome-report-generator-6.0.1.tgz#7314f43c3e61247b0ea48ce2dda0813ca6fdd705" - integrity sha512-/+RoE/lD7QTJBh7VsymdQOTqS8QuB94xKJCJXxZ3fy3JsDdPNgTBgUlEOR99r+2W1zPgEWVhRBU1Tl9fe6kI+w== - dependencies: - chalk "^4.1.2" - dateformat "^4.5.1" - escape-html "^1.0.3" - fs-extra "^10.0.0" - fsu "^1.1.1" - lodash.isfunction "^3.0.9" - opener "^1.5.2" - prop-types "^15.7.2" - tcomb "^3.2.17" - tcomb-validation "^3.3.0" - validator "^13.6.0" - yargs "^17.2.1" - -mochawesome@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/mochawesome/-/mochawesome-7.0.1.tgz#c7c65350232bed7c3ae5f6bb79a2d55b71f51baa" - integrity sha512-2FTU7KVNDiKohi4IG3IVmJ2OTy0Nm0Q2RjueK9hsj7blbkcrpFVH209cP8P4egi+LBidKdX+QmtN3thJde2yiQ== - dependencies: - chalk "^4.1.2" - diff "^5.0.0" - json-stringify-safe "^5.0.1" - lodash.isempty "^4.4.0" - lodash.isfunction "^3.0.9" - lodash.isobject "^3.0.2" - lodash.isstring "^4.0.1" - mochawesome-report-generator "^6.0.1" - strip-ansi "^6.0.1" - uuid "^8.3.2" - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nanoid@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" - integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" - integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -opener@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" - integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -pako@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" - integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -picomatch@^2.0.4, picomatch@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -prop-types@^15.7.2: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -rpc-websockets@^7.4.2: - version "7.4.16" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.4.16.tgz#eb701cdef577d4357ba5f526d50e25f370396fac" - integrity sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ== - dependencies: - "@babel/runtime" "^7.11.2" - circular-json "^0.5.9" - eventemitter3 "^4.0.7" - uuid "^8.3.0" - ws "^7.4.5" + "ansi-colors" "4.1.1" + "browser-stdout" "1.3.1" + "chokidar" "3.5.3" + "debug" "4.3.3" + "diff" "5.0.0" + "escape-string-regexp" "4.0.0" + "find-up" "5.0.0" + "glob" "7.2.0" + "growl" "1.10.5" + "he" "1.2.0" + "js-yaml" "4.1.0" + "log-symbols" "4.1.0" + "minimatch" "4.2.1" + "ms" "2.1.3" + "nanoid" "3.3.1" + "serialize-javascript" "6.0.0" + "strip-json-comments" "3.1.1" + "supports-color" "8.1.1" + "which" "2.0.2" + "workerpool" "6.2.0" + "yargs" "16.2.0" + "yargs-parser" "20.2.4" + "yargs-unparser" "2.0.0" + +"mochawesome-report-generator@^6.2.0": + "integrity" "sha512-Ghw8JhQFizF0Vjbtp9B0i//+BOkV5OWcQCPpbO0NGOoxV33o+gKDYU0Pr2pGxkIHnqZ+g5mYiXF7GMNgAcDpSg==" + "resolved" "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-6.2.0.tgz" + "version" "6.2.0" + dependencies: + "chalk" "^4.1.2" + "dateformat" "^4.5.1" + "escape-html" "^1.0.3" + "fs-extra" "^10.0.0" + "fsu" "^1.1.1" + "lodash.isfunction" "^3.0.9" + "opener" "^1.5.2" + "prop-types" "^15.7.2" + "tcomb" "^3.2.17" + "tcomb-validation" "^3.3.0" + "validator" "^13.6.0" + "yargs" "^17.2.1" + +"mochawesome@^7.0.1": + "integrity" "sha512-Vkb3jR5GZ1cXohMQQ73H3cZz7RoxGjjUo0G5hu0jLaW+0FdUxUwg3Cj29bqQdh0rFcnyV06pWmqmi5eBPnEuNQ==" + "resolved" "https://registry.npmjs.org/mochawesome/-/mochawesome-7.1.3.tgz" + "version" "7.1.3" + dependencies: + "chalk" "^4.1.2" + "diff" "^5.0.0" + "json-stringify-safe" "^5.0.1" + "lodash.isempty" "^4.4.0" + "lodash.isfunction" "^3.0.9" + "lodash.isobject" "^3.0.2" + "lodash.isstring" "^4.0.1" + "mochawesome-report-generator" "^6.2.0" + "strip-ansi" "^6.0.1" + "uuid" "^8.3.2" + +"ms@2.1.2": + "integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + "version" "2.1.2" + +"ms@2.1.3": + "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + "version" "2.1.3" + +"nanoid@3.3.1": + "integrity" "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" + "version" "3.3.1" + +"no-case@^3.0.4": + "integrity" "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==" + "resolved" "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz" + "version" "3.0.4" + dependencies: + "lower-case" "^2.0.2" + "tslib" "^2.0.3" + +"node-addon-api@^2.0.0": + "integrity" "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz" + "version" "2.0.2" + +"node-fetch@2", "node-fetch@2.6.7": + "integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" + "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" + "version" "2.6.7" + dependencies: + "whatwg-url" "^5.0.0" + +"node-gyp-build@^4.2.0", "node-gyp-build@^4.3.0": + "integrity" "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==" + "resolved" "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz" + "version" "4.4.0" + +"normalize-path@^3.0.0", "normalize-path@~3.0.0": + "integrity" "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "resolved" "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + "version" "3.0.0" + +"object-assign@^4.1.1": + "integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + "version" "4.1.1" + +"once@^1.3.0": + "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" + "resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + "version" "1.4.0" + dependencies: + "wrappy" "1" + +"opener@^1.5.2": + "integrity" "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + "resolved" "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz" + "version" "1.5.2" + +"p-limit@^3.0.2": + "integrity" "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==" + "resolved" "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + "version" "3.1.0" + dependencies: + "yocto-queue" "^0.1.0" + +"p-locate@^5.0.0": + "integrity" "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==" + "resolved" "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "p-limit" "^3.0.2" + +"pako@^2.0.3": + "integrity" "sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==" + "resolved" "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz" + "version" "2.0.4" + +"path-exists@^4.0.0": + "integrity" "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "resolved" "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + "version" "4.0.0" + +"path-is-absolute@^1.0.0": + "integrity" "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "resolved" "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + "version" "1.0.1" + +"pathval@^1.1.1": + "integrity" "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==" + "resolved" "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" + "version" "1.1.1" + +"picomatch@^2.0.4", "picomatch@^2.2.1": + "integrity" "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "resolved" "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + "version" "2.3.1" + +"prop-types@^15.7.2": + "integrity" "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==" + "resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" + "version" "15.8.1" + dependencies: + "loose-envify" "^1.4.0" + "object-assign" "^4.1.1" + "react-is" "^16.13.1" + +"randombytes@^2.1.0": + "integrity" "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==" + "resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + "version" "2.1.0" + dependencies: + "safe-buffer" "^5.1.0" + +"react-is@^16.13.1": + "integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + "version" "16.13.1" + +"readdirp@~3.6.0": + "integrity" "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==" + "resolved" "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + "version" "3.6.0" + dependencies: + "picomatch" "^2.2.1" + +"regenerator-runtime@^0.13.4": + "integrity" "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" + "version" "0.13.9" + +"require-directory@^2.1.1": + "integrity" "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "resolved" "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + "version" "2.1.1" + +"rpc-websockets@^7.4.2": + "integrity" "sha512-bVu+4qM5CkGVlTqJa6FaAxLbb5uRnyH4te7yjFvoCzbnif7PT4BcvXtNTprHlNvsH+/StB81zUQicxMrUrIomA==" + "resolved" "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.18.tgz" + "version" "7.4.18" + dependencies: + "@babel/runtime" "^7.17.2" + "eventemitter3" "^4.0.7" + "uuid" "^8.3.2" + "ws" "^8.5.0" optionalDependencies: - bufferutil "^4.0.1" - utf-8-validate "^5.0.2" + "bufferutil" "^4.0.1" + "utf-8-validate" "^5.0.2" -safe-buffer@^5.0.1, safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +"safe-buffer@^5.0.1", "safe-buffer@^5.1.0": + "integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + "version" "5.2.1" -secp256k1@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" - integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== +"secp256k1@^4.0.2": + "integrity" "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==" + "resolved" "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz" + "version" "4.0.3" dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" + "elliptic" "^6.5.4" + "node-addon-api" "^2.0.0" + "node-gyp-build" "^4.2.0" -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== +"serialize-javascript@6.0.0": + "integrity" "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==" + "resolved" "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" + "version" "6.0.0" dependencies: - randombytes "^2.1.0" + "randombytes" "^2.1.0" -snake-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" - integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== +"snake-case@^3.0.4": + "integrity" "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==" + "resolved" "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" + "version" "3.0.4" dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" + "dot-case" "^3.0.4" + "tslib" "^2.0.3" -source-map-support@^0.5.6: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== +"source-map-support@^0.5.6": + "integrity" "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" + "resolved" "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + "version" "0.5.21" dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" + "buffer-from" "^1.0.0" + "source-map" "^0.6.0" -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +"source-map@^0.6.0": + "integrity" "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "resolved" "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + "version" "0.6.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== +"string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.3": + "integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + "resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + "version" "4.2.3" dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" + "emoji-regex" "^8.0.0" + "is-fullwidth-code-point" "^3.0.0" + "strip-ansi" "^6.0.1" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +"strip-ansi@^6.0.0", "strip-ansi@^6.0.1": + "integrity" "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + "resolved" "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + "version" "6.0.1" dependencies: - ansi-regex "^5.0.1" + "ansi-regex" "^5.0.1" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +"strip-bom@^3.0.0": + "integrity" "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "resolved" "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + "version" "3.0.0" -strip-json-comments@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +"strip-json-comments@3.1.1": + "integrity" "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + "resolved" "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + "version" "3.1.1" -superstruct@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" - integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== +"superstruct@^0.14.2": + "integrity" "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" + "resolved" "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz" + "version" "0.14.2" -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== +"supports-color@^7.1.0": + "integrity" "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + "version" "7.2.0" dependencies: - has-flag "^4.0.0" + "has-flag" "^4.0.0" -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== +"supports-color@8.1.1": + "integrity" "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==" + "resolved" "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + "version" "8.1.1" dependencies: - has-flag "^4.0.0" + "has-flag" "^4.0.0" -tcomb-validation@^3.3.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/tcomb-validation/-/tcomb-validation-3.4.1.tgz#a7696ec176ce56a081d9e019f8b732a5a8894b65" - integrity sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA== +"tcomb-validation@^3.3.0": + "integrity" "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==" + "resolved" "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz" + "version" "3.4.1" dependencies: - tcomb "^3.0.0" + "tcomb" "^3.0.0" -tcomb@^3.0.0, tcomb@^3.2.17: - version "3.2.29" - resolved "https://registry.yarnpkg.com/tcomb/-/tcomb-3.2.29.tgz#32404fe9456d90c2cf4798682d37439f1ccc386c" - integrity sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ== +"tcomb@^3.0.0", "tcomb@^3.2.17": + "integrity" "sha512-di2Hd1DB2Zfw6StGv861JoAF5h/uQVu/QJp2g8KVbtfKnoHdBQl5M32YWq6mnSYBQ1vFFrns5B1haWJL7rKaOQ==" + "resolved" "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz" + "version" "3.2.29" -text-encoding-utf-8@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" - integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== +"text-encoding-utf-8@^1.0.2": + "integrity" "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + "resolved" "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz" + "version" "1.0.2" "through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -traverse-chain@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1" - integrity sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE= - -ts-mocha@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-9.0.2.tgz#c1ef0248874d04a0f26dd9bd8d88e617a8d82ab1" - integrity sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw== - dependencies: - ts-node "7.0.1" + "integrity" "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "resolved" "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + "version" "2.3.8" + +"to-regex-range@^5.0.1": + "integrity" "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==" + "resolved" "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + "version" "5.0.1" + dependencies: + "is-number" "^7.0.0" + +"toformat@^2.0.0": + "integrity" "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" + "resolved" "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz" + "version" "2.0.0" + +"toml@^3.0.0": + "integrity" "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" + "resolved" "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz" + "version" "3.0.0" + +"tr46@~0.0.3": + "integrity" "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + "resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + "version" "0.0.3" + +"traverse-chain@~0.1.0": + "integrity" "sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE=" + "resolved" "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz" + "version" "0.1.0" + +"ts-mocha@^9.0.2": + "integrity" "sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw==" + "resolved" "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz" + "version" "9.0.2" + dependencies: + "ts-node" "7.0.1" optionalDependencies: - tsconfig-paths "^3.5.0" - -ts-node@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" - integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.5.6" - yn "^2.0.0" - -tsconfig-paths@^3.5.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" - integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== + "tsconfig-paths" "^3.5.0" + +"ts-node@7.0.1": + "integrity" "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==" + "resolved" "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" + "version" "7.0.1" + dependencies: + "arrify" "^1.0.0" + "buffer-from" "^1.1.0" + "diff" "^3.1.0" + "make-error" "^1.1.1" + "minimist" "^1.2.0" + "mkdirp" "^0.5.1" + "source-map-support" "^0.5.6" + "yn" "^2.0.0" + +"tsconfig-paths@^3.5.0": + "integrity" "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==" + "resolved" "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz" + "version" "3.14.1" dependencies: "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tslib@^2.0.3: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - -tweetnacl@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-detect@^4.0.0, type-detect@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -typescript@^4.5.5: - version "4.5.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" - integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -utf-8-validate@^5.0.2: - version "5.0.7" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.7.tgz#c15a19a6af1f7ad9ec7ddc425747ca28c3644922" - integrity sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q== - dependencies: - node-gyp-build "^4.3.0" - -uuid@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.3.0, uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -validator@^13.6.0: - version "13.7.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" - integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -ws@^7.4.5: - version "7.5.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" - integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^21.0.0: - version "21.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" - integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.0.1, yargs@^17.2.1: - version "17.3.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" - integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.0.0" - -yn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" - integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + "json5" "^1.0.1" + "minimist" "^1.2.6" + "strip-bom" "^3.0.0" + +"tslib@^2.0.3": + "integrity" "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "resolved" "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" + "version" "2.4.0" + +"tweetnacl@^1.0.0": + "integrity" "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + "resolved" "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" + "version" "1.0.3" + +"type-detect@^4.0.0", "type-detect@^4.0.5": + "integrity" "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + "resolved" "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + "version" "4.0.8" + +"typescript@^4.5.5": + "integrity" "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==" + "resolved" "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz" + "version" "4.6.3" + +"universalify@^2.0.0": + "integrity" "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "resolved" "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + "version" "2.0.0" + +"utf-8-validate@^5.0.2": + "integrity" "sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q==" + "resolved" "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.9.tgz" + "version" "5.0.9" + dependencies: + "node-gyp-build" "^4.3.0" + +"uuid@^8.3.2": + "integrity" "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "resolved" "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + "version" "8.3.2" + +"validator@^13.6.0": + "integrity" "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + "resolved" "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz" + "version" "13.7.0" + +"webidl-conversions@^3.0.0": + "integrity" "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + "resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + "version" "3.0.1" + +"whatwg-url@^5.0.0": + "integrity" "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=" + "resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + "version" "5.0.0" + dependencies: + "tr46" "~0.0.3" + "webidl-conversions" "^3.0.0" + +"which@2.0.2": + "integrity" "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + "resolved" "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + "version" "2.0.2" + dependencies: + "isexe" "^2.0.0" + +"workerpool@6.2.0": + "integrity" "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==" + "resolved" "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" + "version" "6.2.0" + +"wrap-ansi@^7.0.0": + "integrity" "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + "resolved" "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + "version" "7.0.0" + dependencies: + "ansi-styles" "^4.0.0" + "string-width" "^4.1.0" + "strip-ansi" "^6.0.0" + +"wrappy@1": + "integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + "version" "1.0.2" + +"ws@*", "ws@^7.4.5": + "integrity" "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==" + "resolved" "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" + "version" "7.5.7" + +"ws@^8.5.0": + "integrity" "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==" + "resolved" "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" + "version" "8.5.0" + +"y18n@^5.0.5": + "integrity" "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "resolved" "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + "version" "5.0.8" + +"yargs-parser@^20.2.2", "yargs-parser@20.2.4": + "integrity" "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" + "version" "20.2.4" + +"yargs-parser@^21.0.0": + "integrity" "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" + "resolved" "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz" + "version" "21.0.1" + +"yargs-unparser@2.0.0": + "integrity" "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==" + "resolved" "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "camelcase" "^6.0.0" + "decamelize" "^4.0.0" + "flat" "^5.0.2" + "is-plain-obj" "^2.1.0" + +"yargs@^17.0.1": + "integrity" "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz" + "version" "17.5.1" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.3" + "y18n" "^5.0.5" + "yargs-parser" "^21.0.0" + +"yargs@^17.2.1": + "integrity" "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz" + "version" "17.4.1" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.3" + "y18n" "^5.0.5" + "yargs-parser" "^21.0.0" + +"yargs@16.2.0": + "integrity" "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==" + "resolved" "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + "version" "16.2.0" + dependencies: + "cliui" "^7.0.2" + "escalade" "^3.1.1" + "get-caller-file" "^2.0.5" + "require-directory" "^2.1.1" + "string-width" "^4.2.0" + "y18n" "^5.0.5" + "yargs-parser" "^20.2.2" + +"yn@^2.0.0": + "integrity" "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=" + "resolved" "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz" + "version" "2.0.0" + +"yocto-queue@^0.1.0": + "integrity" "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "resolved" "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + "version" "0.1.0"