From 90f19686645efb31404414a24d7a0968ed8e8bc4 Mon Sep 17 00:00:00 2001 From: codewithgun Date: Tue, 24 Dec 2024 11:57:39 +0800 Subject: [PATCH] fix: cli to use v3 position and support token2022 --- Cargo.lock | 2798 +++-- Cargo.toml | 17 +- cli/Cargo.toml | 9 +- cli/src/args.rs | 466 +- cli/src/instructions/add_liquidity.rs | 116 +- cli/src/instructions/check_my_balance.rs | 229 - cli/src/instructions/claim_fee.rs | 95 +- cli/src/instructions/claim_reward.rs | 84 +- cli/src/instructions/close_position.rs | 66 +- .../instructions/close_preset_parameter.rs | 44 +- cli/src/instructions/fund_reward.rs | 69 +- cli/src/instructions/increase_length.rs | 45 +- cli/src/instructions/initialize_bin_array.rs | 44 +- .../initialize_bin_array_with_bin_range.rs | 30 +- .../initialize_bin_array_with_price_range.rs | 42 +- ...ize_customizable_permissionless_lb_pair.rs | 142 +- cli/src/instructions/initialize_lb_pair.rs | 107 +- .../initialize_permission_lb_pair.rs | 132 +- cli/src/instructions/initialize_position.rs | 61 +- .../initialize_position_with_price_range.rs | 43 +- .../initialize_preset_parameter.rs | 89 +- cli/src/instructions/initialize_reward.rs | 56 +- cli/src/instructions/list_all_binstep.rs | 102 +- cli/src/instructions/mod.rs | 81 +- cli/src/instructions/remove_liquidity.rs | 116 +- .../remove_liquidity_by_price_range.rs | 321 +- cli/src/instructions/seed_liquidity.rs | 342 +- .../seed_liquidity_from_operator.rs | 280 +- .../instructions/seed_liquidity_single_bin.rs | 280 +- .../seed_liquidity_single_bin_by_operator.rs | 340 +- cli/src/instructions/set_activation_point.rs | 28 +- .../set_pre_activation_duration.rs | 38 +- .../set_pre_activation_swap_address.rs | 36 +- cli/src/instructions/show_pair.rs | 74 +- cli/src/instructions/show_position.rs | 39 + .../instructions/show_preset_parameters.rs | 33 + cli/src/instructions/simulate_swap_demand.rs | 88 - cli/src/instructions/swap_exact_in.rs | 162 +- cli/src/instructions/swap_exact_out.rs | 96 +- .../instructions/swap_with_price_impact.rs | 171 +- cli/src/instructions/toggle_pair_status.rs | 35 +- .../instructions/update_reward_duration.rs | 51 +- cli/src/instructions/update_reward_funder.rs | 32 +- cli/src/instructions/utils.rs | 254 +- cli/src/instructions/withdraw_protocol_fee.rs | 104 +- cli/src/main.rs | 705 +- cli/src/math.rs | 154 +- commons/Cargo.toml | 9 +- commons/src/content_loaders/mod.rs | 2 + commons/src/content_loaders/position_v3.rs | 37 + commons/src/conversions/mod.rs | 3 + commons/src/conversions/token_program_flag.rs | 27 + commons/src/extensions/lb_pair.rs | 26 + commons/src/extensions/mod.rs | 3 + commons/src/extensions/position_v3.rs | 35 + commons/src/lib.rs | 5 + commons/src/pda.rs | 17 +- commons/src/rpc_client_extension.rs | 26 + commons/src/seeds.rs | 4 + commons/tests/helpers/utils.rs | 18 +- programs/lb_clmm/Cargo.toml | 42 - programs/lb_clmm/Xargo.toml | 2 - programs/lb_clmm/src/constants.rs | 123 - programs/lb_clmm/src/errors.rs | 203 - programs/lb_clmm/src/events.rs | 232 - .../admin/close_preset_parameter.rs | 28 - .../admin/initialize_preset_parameters.rs | 59 - .../instructions/admin/initialize_reward.rs | 47 - .../lb_clmm/src/instructions/admin/mod.rs | 21 - .../admin/set_activation_point.rs | 20 - .../admin/set_pre_activation_duration.rs | 19 - .../admin/set_pre_activation_swap_address.rs | 11 - .../instructions/admin/toggle_pair_status.rs | 17 - .../admin/update_fee_parameters.rs | 26 - .../admin/update_reward_duration.rs | 32 - .../admin/update_reward_funder.rs | 20 - .../lb_clmm/src/instructions/claim_fee.rs | 55 - .../lb_clmm/src/instructions/claim_reward.rs | 46 - .../src/instructions/close_position.rs | 40 - .../create_position/initialize_position.rs | 28 - .../initialize_position_by_operator.rs | 61 - .../initialize_position_pda.rs | 41 - .../src/instructions/create_position/mod.rs | 7 - .../src/instructions/deposit/add_liquidity.rs | 99 - .../deposit/add_liquidity_by_strategy.rs | 403 - .../add_liquidity_by_strategy_one_side.rs | 70 - .../deposit/add_liquidity_by_weight.rs | 107 - .../add_liquidity_by_weight_one_side.rs | 146 - .../add_liquidity_single_side_precise.rs | 21 - .../lb_clmm/src/instructions/deposit/mod.rs | 13 - .../lb_clmm/src/instructions/fund_reward.rs | 36 - .../instructions/increase_oracle_length.rs | 24 - .../src/instructions/initialize_bin_array.rs | 31 - .../initialize_bin_array_bitmap_extension.rs | 29 - ...ize_customizable_permissionless_lb_pair.rs | 122 - .../initialize_permission_lb_pair.rs | 116 - .../initialize_permissionless_lb_pair.rs | 100 - .../src/instructions/initialize_pool/mod.rs | 7 - .../src/instructions/migrate_bin_array.rs | 11 - .../src/instructions/migrate_position.rs | 53 - programs/lb_clmm/src/instructions/mod.rs | 20 - .../src/instructions/position_authorize.rs | 30 - programs/lb_clmm/src/instructions/swap.rs | 79 - .../instructions/update_fees_and_rewards.rs | 33 - .../instructions/update_position_operator.rs | 13 - .../lb_clmm/src/instructions/withdraw/mod.rs | 5 - .../withdraw/remove_all_liquidity.rs | 9 - .../instructions/withdraw/remove_liquidity.rs | 28 - .../withdraw_ineligible_reward.rs | 32 - .../src/instructions/withdraw_protocol_fee.rs | 37 - programs/lb_clmm/src/lib.rs | 387 - .../lb_clmm/src/manager/bin_array_manager.rs | 159 - programs/lb_clmm/src/manager/mod.rs | 1 - programs/lb_clmm/src/math/bin_math.rs | 24 - programs/lb_clmm/src/math/mod.rs | 7 - programs/lb_clmm/src/math/price_math.rs | 19 - programs/lb_clmm/src/math/safe_math.rs | 114 - programs/lb_clmm/src/math/u128x128_math.rs | 43 - programs/lb_clmm/src/math/u64x64_math.rs | 209 - programs/lb_clmm/src/math/utils_math.rs | 73 - .../lb_clmm/src/math/weight_to_amounts.rs | 295 - .../lb_clmm/src/pair_action_access/base.rs | 73 - .../customizable_permissionless_lb_pair.rs | 89 - .../lb_clmm/src/pair_action_access/mod.rs | 9 - .../src/pair_action_access/permission_pair.rs | 163 - .../pair_action_access/permissionless_pair.rs | 68 - programs/lb_clmm/src/state/bin.rs | 543 - .../src/state/bin_array_bitmap_extension.rs | 276 - programs/lb_clmm/src/state/lb_pair.rs | 766 -- programs/lb_clmm/src/state/mod.rs | 7 - programs/lb_clmm/src/state/oracle.rs | 256 - programs/lb_clmm/src/state/parameters.rs | 193 - programs/lb_clmm/src/state/position.rs | 366 - .../lb_clmm/src/state/preset_parameters.rs | 149 - programs/lb_clmm/src/utils/mod.rs | 2 - programs/lb_clmm/src/utils/pda.rs | 134 - programs/lb_clmm/src/utils/seeds.rs | 19 - target/idl/lb_clmm.json | 5097 -------- target/types/lb_clmm.ts | 10189 ---------------- 139 files changed, 4934 insertions(+), 26608 deletions(-) delete mode 100644 cli/src/instructions/check_my_balance.rs create mode 100644 cli/src/instructions/show_position.rs create mode 100644 cli/src/instructions/show_preset_parameters.rs delete mode 100644 cli/src/instructions/simulate_swap_demand.rs create mode 100644 commons/src/content_loaders/mod.rs create mode 100644 commons/src/content_loaders/position_v3.rs create mode 100644 commons/src/conversions/token_program_flag.rs create mode 100644 commons/src/extensions/position_v3.rs create mode 100644 commons/src/rpc_client_extension.rs delete mode 100644 programs/lb_clmm/Cargo.toml delete mode 100644 programs/lb_clmm/Xargo.toml delete mode 100644 programs/lb_clmm/src/constants.rs delete mode 100644 programs/lb_clmm/src/errors.rs delete mode 100644 programs/lb_clmm/src/events.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/close_preset_parameter.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/initialize_preset_parameters.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/initialize_reward.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/mod.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/set_activation_point.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/set_pre_activation_duration.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/set_pre_activation_swap_address.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/toggle_pair_status.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/update_fee_parameters.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/update_reward_duration.rs delete mode 100644 programs/lb_clmm/src/instructions/admin/update_reward_funder.rs delete mode 100644 programs/lb_clmm/src/instructions/claim_fee.rs delete mode 100644 programs/lb_clmm/src/instructions/claim_reward.rs delete mode 100644 programs/lb_clmm/src/instructions/close_position.rs delete mode 100644 programs/lb_clmm/src/instructions/create_position/initialize_position.rs delete mode 100644 programs/lb_clmm/src/instructions/create_position/initialize_position_by_operator.rs delete mode 100644 programs/lb_clmm/src/instructions/create_position/initialize_position_pda.rs delete mode 100644 programs/lb_clmm/src/instructions/create_position/mod.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/add_liquidity.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy_one_side.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight_one_side.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/add_liquidity_single_side_precise.rs delete mode 100644 programs/lb_clmm/src/instructions/deposit/mod.rs delete mode 100644 programs/lb_clmm/src/instructions/fund_reward.rs delete mode 100644 programs/lb_clmm/src/instructions/increase_oracle_length.rs delete mode 100644 programs/lb_clmm/src/instructions/initialize_bin_array.rs delete mode 100644 programs/lb_clmm/src/instructions/initialize_bin_array_bitmap_extension.rs delete mode 100644 programs/lb_clmm/src/instructions/initialize_pool/initialize_customizable_permissionless_lb_pair.rs delete mode 100644 programs/lb_clmm/src/instructions/initialize_pool/initialize_permission_lb_pair.rs delete mode 100644 programs/lb_clmm/src/instructions/initialize_pool/initialize_permissionless_lb_pair.rs delete mode 100644 programs/lb_clmm/src/instructions/initialize_pool/mod.rs delete mode 100644 programs/lb_clmm/src/instructions/migrate_bin_array.rs delete mode 100644 programs/lb_clmm/src/instructions/migrate_position.rs delete mode 100644 programs/lb_clmm/src/instructions/mod.rs delete mode 100644 programs/lb_clmm/src/instructions/position_authorize.rs delete mode 100644 programs/lb_clmm/src/instructions/swap.rs delete mode 100644 programs/lb_clmm/src/instructions/update_fees_and_rewards.rs delete mode 100644 programs/lb_clmm/src/instructions/update_position_operator.rs delete mode 100644 programs/lb_clmm/src/instructions/withdraw/mod.rs delete mode 100644 programs/lb_clmm/src/instructions/withdraw/remove_all_liquidity.rs delete mode 100644 programs/lb_clmm/src/instructions/withdraw/remove_liquidity.rs delete mode 100644 programs/lb_clmm/src/instructions/withdraw_ineligible_reward.rs delete mode 100644 programs/lb_clmm/src/instructions/withdraw_protocol_fee.rs delete mode 100644 programs/lb_clmm/src/lib.rs delete mode 100644 programs/lb_clmm/src/manager/bin_array_manager.rs delete mode 100644 programs/lb_clmm/src/manager/mod.rs delete mode 100644 programs/lb_clmm/src/math/bin_math.rs delete mode 100644 programs/lb_clmm/src/math/mod.rs delete mode 100644 programs/lb_clmm/src/math/price_math.rs delete mode 100644 programs/lb_clmm/src/math/safe_math.rs delete mode 100644 programs/lb_clmm/src/math/u128x128_math.rs delete mode 100644 programs/lb_clmm/src/math/u64x64_math.rs delete mode 100644 programs/lb_clmm/src/math/utils_math.rs delete mode 100644 programs/lb_clmm/src/math/weight_to_amounts.rs delete mode 100644 programs/lb_clmm/src/pair_action_access/base.rs delete mode 100644 programs/lb_clmm/src/pair_action_access/customizable_permissionless_lb_pair.rs delete mode 100644 programs/lb_clmm/src/pair_action_access/mod.rs delete mode 100644 programs/lb_clmm/src/pair_action_access/permission_pair.rs delete mode 100644 programs/lb_clmm/src/pair_action_access/permissionless_pair.rs delete mode 100644 programs/lb_clmm/src/state/bin.rs delete mode 100644 programs/lb_clmm/src/state/bin_array_bitmap_extension.rs delete mode 100644 programs/lb_clmm/src/state/lb_pair.rs delete mode 100644 programs/lb_clmm/src/state/mod.rs delete mode 100644 programs/lb_clmm/src/state/oracle.rs delete mode 100644 programs/lb_clmm/src/state/parameters.rs delete mode 100644 programs/lb_clmm/src/state/position.rs delete mode 100644 programs/lb_clmm/src/state/preset_parameters.rs delete mode 100644 programs/lb_clmm/src/utils/mod.rs delete mode 100644 programs/lb_clmm/src/utils/pda.rs delete mode 100644 programs/lb_clmm/src/utils/seeds.rs delete mode 100644 target/idl/lb_clmm.json delete mode 100644 target/types/lb_clmm.ts diff --git a/Cargo.lock b/Cargo.lock index e1edcace..16642d37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,12 +12,27 @@ dependencies = [ "regex", ] +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.4.3" @@ -67,14 +82,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom 0.2.10", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -109,87 +125,79 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" +checksum = "e5f619f1d04f53621925ba8a2e633ba5a6081f2ae14758cbb67f38fd823e0a3e" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.63", - "quote 1.0.29", - "regex", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-attribute-account" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" +checksum = "e7f2a3e1df4685f18d12a943a9f2a7456305401af21a07c9fe076ef9ecd6e400" dependencies = [ "anchor-syn", - "anyhow", "bs58 0.5.0", - "proc-macro2 1.0.63", - "quote 1.0.29", - "rustversion", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-attribute-constant" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" +checksum = "9423945cb55627f0b30903288e78baf6f62c6c8ab28fb344b6b25f1ffee3dca7" dependencies = [ "anchor-syn", - "proc-macro2 1.0.63", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-attribute-error" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" +checksum = "93ed12720033cc3c3bf3cfa293349c2275cd5ab99936e33dd4bf283aaad3e241" dependencies = [ "anchor-syn", - "proc-macro2 1.0.63", - "quote 1.0.29", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-attribute-event" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" +checksum = "eef4dc0371eba2d8c8b54794b0b0eb786a234a559b77593d6f80825b6d2c77a2" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-attribute-program" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" +checksum = "b18c4f191331e078d4a6a080954d1576241c29c56638783322a18d308ab27e4f" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.63", - "quote 1.0.29", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-client" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" +checksum = "cb48c4a7911038da546dc752655a29fa49f6bd50ebc1edca218bac8da1012acd" dependencies = [ "anchor-lang", "anyhow", @@ -206,33 +214,44 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" +checksum = "5de10d6e9620d3bcea56c56151cad83c5992f50d5960b3a9bebc4a50390ddc3c" dependencies = [ "anchor-syn", - "anyhow", - "proc-macro2 1.0.63", - "quote 1.0.29", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e2e5be518ec6053d90a2a7f26843dbee607583c779e6c8395951b9739bdfbe" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.3", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-derive-space" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" +checksum = "1ecc31d19fa54840e74b7a979d44bcea49d70459de846088a1d71e87ba53c419" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "anchor-lang" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" +checksum = "35da4785497388af0553586d55ebdc08054a8b1724720ef2749d313494f2b8ad" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -241,6 +260,7 @@ dependencies = [ "anchor-attribute-event", "anchor-attribute-program", "anchor-derive-accounts", + "anchor-derive-serde", "anchor-derive-space", "arrayref", "base64 0.13.1", @@ -254,31 +274,31 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f860599da1c2354e7234c768783049eb42e2f54509ecfc942d2e0076a2da7b" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" dependencies = [ "anchor-lang", "solana-program", - "spl-associated-token-account", - "spl-token", - "spl-token-2022", + "spl-associated-token-account 2.3.0", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", ] [[package]] name = "anchor-syn" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" +checksum = "d9101b84702fed2ea57bd22992f75065da5648017135b844283a2f6d74f27825" dependencies = [ "anyhow", "bs58 0.5.0", "heck 0.3.3", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "syn 1.0.109", "thiserror", ] @@ -361,6 +381,20 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +[[package]] +name = "aquamarine" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da02abba9f9063d786eab1509833ebb2fac0f966862ca59439c76b9c566760" +dependencies = [ + "include_dir", + "itertools", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-bn254" version = "0.4.0" @@ -402,7 +436,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools", - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", "paste", "rustc_version", @@ -415,7 +449,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "quote 1.0.29", + "quote", "syn 1.0.109", ] @@ -425,10 +459,10 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -454,7 +488,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.3", + "num-bigint 0.4.4", ] [[package]] @@ -463,8 +497,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -478,12 +512,6 @@ dependencies = [ "rand 0.8.5", ] -[[package]] -name = "array-bytes" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" - [[package]] name = "arrayref" version = "0.3.7" @@ -524,10 +552,10 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -536,8 +564,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -560,9 +588,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.3.15" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" dependencies = [ "brotli", "flate2", @@ -583,13 +611,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -609,6 +637,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide 0.8.2", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + [[package]] name = "base64" version = "0.12.3" @@ -623,9 +666,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -641,7 +684,7 @@ checksum = "7f31f3af01c5c65a07985c804d3366560e6fa7883d640a122819b14ec327482c" dependencies = [ "autocfg", "libm", - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-integer", "num-traits", ] @@ -656,25 +699,19 @@ dependencies = [ ] [[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.6.3" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "bitmaps" @@ -699,9 +736,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.4.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec", @@ -756,6 +793,16 @@ dependencies = [ "hashbrown 0.13.2", ] +[[package]] +name = "borsh" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d4d6dafc1a3bb54687538972158f07b2c948bc57d5890df22c0739098b3028" +dependencies = [ + "borsh-derive 1.3.0", + "cfg_aliases", +] + [[package]] name = "borsh-derive" version = "0.9.3" @@ -765,7 +812,7 @@ dependencies = [ "borsh-derive-internal 0.9.3", "borsh-schema-derive-internal 0.9.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.63", + "proc-macro2", "syn 1.0.109", ] @@ -778,18 +825,32 @@ dependencies = [ "borsh-derive-internal 0.10.3", "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.63", + "proc-macro2", "syn 1.0.109", ] +[[package]] +name = "borsh-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" +dependencies = [ + "once_cell", + "proc-macro-crate 2.0.2", + "proc-macro2", + "quote", + "syn 2.0.90", + "syn_derive", +] + [[package]] name = "borsh-derive-internal" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -799,8 +860,8 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -810,8 +871,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -821,16 +882,16 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "brotli" -version = "3.4.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -839,9 +900,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.5.1" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -895,16 +956,16 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -915,16 +976,16 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -965,11 +1026,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" dependencies = [ "jobserver", + "libc", + "shlex", ] [[package]] @@ -978,6 +1041,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.31" @@ -1019,10 +1088,10 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim 0.8.0", "textwrap 0.11.0", - "unicode-width", + "unicode-width 0.1.11", "vec_map", ] @@ -1033,7 +1102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", - "bitflags", + "bitflags 1.3.2", "clap_lex 0.2.4", "indexmap 1.9.3", "once_cell", @@ -1071,9 +1140,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -1093,7 +1162,7 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "cli" -version = "0.4.0" +version = "0.5.0" dependencies = [ "anchor-client", "anchor-lang", @@ -1104,14 +1173,16 @@ dependencies = [ "clap 4.4.7", "commons", "dlmm_interface", - "proptest", "rand 0.8.5", "rust_decimal", "serde", "serde_json", "serde_json_any_key", "shellexpand", - "spl-associated-token-account", + "solana-account-decoder", + "spl-associated-token-account 1.1.3", + "spl-memo 3.0.1", + "spl-transfer-hook-interface 0.5.0", "tokio", ] @@ -1142,7 +1213,9 @@ dependencies = [ "anchor-spl", "anyhow", "assert_matches", + "async-trait", "bincode", + "bytemuck", "dlmm_interface", "num-integer", "num-traits", @@ -1150,7 +1223,7 @@ dependencies = [ "solana-program", "solana-program-test", "solana-sdk", - "spl-associated-token-account", + "spl-associated-token-account 1.1.3", "tokio", ] @@ -1165,15 +1238,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width", - "windows-sys 0.45.0", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -1204,9 +1277,9 @@ checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] name = "core-foundation" @@ -1244,11 +1317,10 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ - "cfg-if", "crossbeam-utils", ] @@ -1278,12 +1350,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -1352,10 +1421,10 @@ checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "strsim 0.10.0", - "syn 2.0.23", + "syn 2.0.90", ] [[package]] @@ -1365,18 +1434,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", - "quote 1.0.29", - "syn 2.0.23", + "quote", + "syn 2.0.90", ] [[package]] name = "dashmap" -version = "4.0.2" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "num_cpus", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core", "rayon", ] @@ -1404,7 +1476,7 @@ dependencies = [ "asn1-rs", "displaydoc", "nom", - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", "rusticata-macros", ] @@ -1414,6 +1486,9 @@ name = "deranged" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] [[package]] name = "derivation-path" @@ -1427,8 +1502,8 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -1444,6 +1519,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.9.0" @@ -1500,9 +1581,9 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -1511,7 +1592,7 @@ version = "0.9.0" dependencies = [ "borsh 0.10.3", "bytemuck", - "num-derive", + "num-derive 0.3.3", "num-traits", "serde", "solana-program", @@ -1519,28 +1600,34 @@ dependencies = [ ] [[package]] -name = "dlopen" -version = "0.1.8" +name = "dlopen2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e80ad39f814a9abe68583cd50a2d45c8a67561c3361ab8da240587dda80937" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" dependencies = [ - "dlopen_derive", - "lazy_static", + "dlopen2_derive", "libc", + "once_cell", "winapi", ] [[package]] -name = "dlopen_derive" -version = "0.1.4" +name = "dlopen2_derive" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f236d9e1b1fbd81cea0f9cbdc8dcc7e8ebcd80e6659cd7cb2ad5f6c05946c581" +checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ - "libc", - "quote 0.6.13", - "syn 0.15.44", + "proc-macro2", + "quote", + "syn 2.0.90", ] +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + [[package]] name = "eager" version = "0.1.0" @@ -1579,7 +1666,7 @@ dependencies = [ "derivation-path", "ed25519-dalek", "hmac 0.12.1", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -1589,22 +1676,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0042ff8246a363dbe77d2ceedb073339e85a804b9a47636c6e016a9a32c05f" dependencies = [ "enum-ordinalize", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "either" -version = "1.8.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" @@ -1617,22 +1704,22 @@ dependencies = [ [[package]] name = "enum-iterator" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add3873b5dd076766ee79c8e406ad1a472c385476b9e38849f8eec24f1be689" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -1641,11 +1728,11 @@ version = "3.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf1fa3f06bbff1ea5b1a9c7b14aa992a39657db60a2759457328d7e058f49ee" dependencies = [ - "num-bigint 0.4.3", + "num-bigint 0.4.4", "num-traits", - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -1669,23 +1756,12 @@ checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" [[package]] name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1696,12 +1772,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.9.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "feature-probe" @@ -1728,7 +1801,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.7.1", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", ] [[package]] @@ -1739,13 +1821,19 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + [[package]] name = "funty" version = "2.0.0" @@ -1754,9 +1842,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1769,9 +1857,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1779,15 +1867,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1796,38 +1884,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1888,6 +1976,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "goblin" version = "0.5.4" @@ -1951,7 +2045,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", ] [[package]] @@ -1960,6 +2054,12 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "heck" version = "0.3.3" @@ -2083,7 +2183,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -2092,13 +2192,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.20.9", + "rustls", "tokio", "tokio-rustls", ] @@ -2127,132 +2228,270 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "idna" -version = "0.4.0" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "im" -version = "15.1.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "bitmaps", - "rand_core 0.6.4", - "rand_xoshiro", - "rayon", - "serde", - "sized-chunks", - "typenum", - "version_check", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "index_list" -version = "0.2.11" +name = "icu_locid_transform_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70891286cb8e844fdfcf1178b47569699f9e20b5ecc4b45a6240a64771444638" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] -name = "indexmap" -version = "1.9.3" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "indexmap" -version = "2.0.0" +name = "icu_normalizer_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", -] +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] -name = "indicatif" -version = "0.17.7" +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "instant" -version = "0.1.12" +name = "icu_properties_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ - "cfg-if", + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys 0.48.0", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] -name = "ipnet" -version = "2.9.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "itertools" -version = "0.10.5" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "either", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "itoa" -version = "1.0.8" +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "include_dir" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "index_list" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70891286cb8e844fdfcf1178b47569699f9e20b5ecc4b45a6240a64771444638" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width 0.1.11", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2288,9 +2527,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libm" @@ -2346,11 +2585,29 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint 0.4.4", + "thiserror", +] + [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -2364,9 +2621,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -2417,16 +2674,16 @@ dependencies = [ "serde_json", "shellexpand", "solana-transaction-status", - "spl-associated-token-account", + "spl-associated-token-account 1.1.3", "tokio", "ureq", ] [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2488,26 +2745,51 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +dependencies = [ + "adler2", +] + [[package]] name = "mio" -version = "0.7.14" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "log", - "miow", - "ntapi", - "winapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", ] [[package]] -name = "miow" -version = "0.3.7" +name = "mockall" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" dependencies = [ - "winapi", + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -2526,8 +2808,8 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -2537,7 +2819,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", @@ -2555,13 +2837,10 @@ dependencies = [ ] [[package]] -name = "ntapi" -version = "0.3.7" +name = "normalize-line-endings" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num" @@ -2590,9 +2869,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -2609,17 +2888,34 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -2660,7 +2956,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2691,6 +2986,15 @@ dependencies = [ "num_enum_derive 0.6.1", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive 0.7.3", +] + [[package]] name = "num_enum_derive" version = "0.5.11" @@ -2698,8 +3002,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro-crate 1.3.1", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -2710,9 +3014,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate 1.3.1", - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -2721,6 +3037,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + [[package]] name = "oid-registry" version = "0.6.1" @@ -2797,22 +3122,11 @@ checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" dependencies = [ "Inflector", "proc-macro-error", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2820,21 +3134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2885,9 +3185,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "percentage" @@ -2913,9 +3213,9 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -2971,12 +3271,48 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "predicates" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" + +[[package]] +name = "predicates-tree" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -2993,7 +3329,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.12", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", ] [[package]] @@ -3003,8 +3349,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", "version_check", ] @@ -3015,49 +3361,20 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "version_check", ] [[package]] name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.63" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] -[[package]] -name = "proptest" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" -dependencies = [ - "bit-set", - "bitflags", - "byteorder", - "lazy_static", - "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rand_xorshift", - "regex-syntax 0.6.29", - "rusty-fork", - "tempfile", - "unarray", -] - [[package]] name = "ptr_meta" version = "0.1.4" @@ -3073,8 +3390,8 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -3088,82 +3405,76 @@ dependencies = [ ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "qualifier_attr" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] [[package]] name = "quinn" -version = "0.9.4" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e8b432585672228923edbbf64b8b12c14e1112f62e88737655b4a083dbcd78e" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.20.9", + "rustls", "thiserror", "tokio", "tracing", - "webpki", ] [[package]] name = "quinn-proto" -version = "0.9.6" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand 0.8.5", "ring 0.16.20", "rustc-hash", - "rustls 0.20.9", + "rustls", "rustls-native-certs", "slab", "thiserror", "tinyvec", "tracing", - "webpki", ] [[package]] name = "quinn-udp" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ + "bytes", "libc", - "quinn-proto", - "socket2", + "socket2 0.5.8", "tracing", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "quote" -version = "0.6.13" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ - "proc-macro2 0.4.30", + "proc-macro2", ] [[package]] -name = "quote" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" -dependencies = [ - "proc-macro2 1.0.63", -] - -[[package]] -name = "radium" -version = "0.7.0" +name = "radium" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" @@ -3238,15 +3549,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_xorshift" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -3258,9 +3560,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3268,14 +3570,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -3296,7 +3596,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -3305,7 +3605,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -3314,7 +3614,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -3330,38 +3630,32 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89089e897c013b3deb627116ae56a6955a72b8bed395c9526af31c9fe528b484" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.7.3", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.3.0" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa250384981ea14565685dea16a9ccc4d1c541a13f82b9c168572264d1df8c56" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.3", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.7.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" @@ -3374,12 +3668,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.17" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "async-compression", - "base64 0.21.4", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -3396,11 +3690,13 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.20.9", + "rustls", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", "tokio-rustls", "tokio-util 0.7.2", @@ -3409,7 +3705,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.22.6", + "webpki-roots 0.25.3", "winreg", ] @@ -3465,8 +3761,8 @@ version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] @@ -3485,13 +3781,13 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -3538,9 +3834,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3568,35 +3864,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustls" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" -dependencies = [ - "log", - "ring 0.16.20", - "sct", - "webpki", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.3", @@ -3622,7 +3905,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", ] [[package]] @@ -3637,21 +3920,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" - -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -3679,9 +3950,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scroll" @@ -3698,9 +3969,9 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -3725,7 +3996,7 @@ version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -3744,46 +4015,56 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "seqlock" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b5c67b6f14ecc5b86c66fa63d76b5092352678545a8a3cdae80aef5128371910" +dependencies = [ + "parking_lot", +] [[package]] name = "serde" -version = "1.0.167" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.11" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -3827,16 +4108,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ "darling", - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] -name = "sha-1" -version = "0.10.1" +name = "sha1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -3858,9 +4139,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -3913,6 +4194,12 @@ dependencies = [ "dirs", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -3934,6 +4221,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "sized-chunks" version = "0.6.5" @@ -3955,9 +4248,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -3969,14 +4262,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "solana-account-decoder" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850d5d9dc8fa6ea42f4e61c78e296bbbce5a3531ff4cb3c58ef36ee31781049c" +checksum = "b109fd3a106e079005167e5b0e6f6d2c88bbedec32530837b584791a8b5abf36" dependencies = [ "Inflector", - "base64 0.21.4", + "base64 0.21.7", "bincode", "bs58 0.4.0", "bv", @@ -3984,25 +4287,87 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "solana-address-lookup-table-program", "solana-config-program", "solana-sdk", - "spl-token", - "spl-token-2022", + "spl-token 4.0.0", + "spl-token-2022 1.0.0", + "spl-token-group-interface", + "spl-token-metadata-interface", "thiserror", "zstd", ] +[[package]] +name = "solana-accounts-db" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec9829d10d521f3ed5e50c12d2b62784e2901aa484a92c2aa3924151da046139" +dependencies = [ + "arrayref", + "bincode", + "blake3", + "bv", + "bytemuck", + "byteorder", + "bzip2", + "crossbeam-channel", + "dashmap", + "flate2", + "fnv", + "im", + "index_list", + "itertools", + "lazy_static", + "log", + "lz4", + "memmap2", + "modular-bitfield", + "num-derive 0.4.2", + "num-traits", + "num_cpus", + "num_enum 0.7.3", + "ouroboros", + "percentage", + "qualifier_attr", + "rand 0.8.5", + "rayon", + "regex", + "rustc_version", + "seqlock", + "serde", + "serde_derive", + "smallvec", + "solana-bucket-map", + "solana-config-program", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-nohash-hasher", + "solana-program-runtime", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", + "static_assertions", + "strum", + "strum_macros", + "tar", + "tempfile", + "thiserror", +] + [[package]] name = "solana-address-lookup-table-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7f867cde478a078d4c4ceb113f4f9ac7e29c2efea98f80a2b30cdcd7be83c5" +checksum = "f3527a26138b5deb126f13c27743f3d95ac533abee5979e4113f6d59ef919cc6" dependencies = [ "bincode", "bytemuck", "log", - "num-derive", + "num-derive 0.4.2", "num-traits", "rustc_version", "serde", @@ -4016,11 +4381,11 @@ dependencies = [ [[package]] name = "solana-banks-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46f22d9f8a0b253165260f44c360dd6a2a49b2731f18cbfda818e3ae0ad9112" +checksum = "e58fa66e1e240097665e7f87b267aa8e976ea3fcbd86918c8fd218c875395ada" dependencies = [ - "borsh 0.10.3", + "borsh 1.3.0", "futures", "solana-banks-interface", "solana-program", @@ -4033,9 +4398,9 @@ dependencies = [ [[package]] name = "solana-banks-interface" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068d206e9fb611684b61c95b7692d099a89b28e6e376fa0f17620198539de371" +checksum = "f54d0a4334c153eadaa0326296a47a92d110c1cc975075fd6e1a7b67067f9812" dependencies = [ "serde", "solana-sdk", @@ -4044,13 +4409,14 @@ dependencies = [ [[package]] name = "solana-banks-server" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e04de401b9177ef6016f24693b871e9f7c47b49a98e3ee1b794f2ae2cfa2438" +checksum = "8cbe287a0f859362de9b155fabd44e479eba26d5d80e07a7d021297b7b06ecba" dependencies = [ "bincode", "crossbeam-channel", "futures", + "solana-accounts-db", "solana-banks-interface", "solana-client", "solana-runtime", @@ -4063,15 +4429,15 @@ dependencies = [ [[package]] name = "solana-bpf-loader-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eaf42dbfe8a42b80e24f2c087a3935d6e7bb49886313b006d88fb04fdc2a02f" +checksum = "a8cc27ceda9a22804d73902f5d718ff1331aa53990c2665c90535f6b182db259" dependencies = [ "bincode", "byteorder", "libsecp256k1", "log", - "rand 0.7.3", + "scopeguard", "solana-measure", "solana-program-runtime", "solana-sdk", @@ -4082,16 +4448,17 @@ dependencies = [ [[package]] name = "solana-bucket-map" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e050e58ea0c422f9db10d987b2a10992f103209454f70d54f6208b14ec5546a0" +checksum = "ca55ec9b8d01d2e3bba9fad77b27c9a8fd51fe12475549b93a853d921b653139" dependencies = [ "bv", + "bytemuck", "log", "memmap2", "modular-bitfield", - "num_enum 0.6.1", - "rand 0.7.3", + "num_enum 0.7.3", + "rand 0.8.5", "solana-measure", "solana-sdk", "tempfile", @@ -4099,14 +4466,13 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c99636da9a4acad58d0e8142e36395ece48fc41c396e297e702b6a789b190f" +checksum = "074ef478856a45d5627270fbc6b331f91de9aae7128242d9e423931013fb8a2a" dependencies = [ "chrono", "clap 2.34.0", "rpassword", - "solana-perf", "solana-remote-wallet", "solana-sdk", "thiserror", @@ -4117,19 +4483,19 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acc7a437165d8fcfac3c63963e394f0ea497b5d2a75159bb3a1ed75dbeb36a7e" +checksum = "24a9f32c42402c4b9484d5868ac74b7e0a746e3905d8bfd756e1203e50cbb87e" dependencies = [ "async-trait", "bincode", + "dashmap", "futures", "futures-util", - "indexmap 1.9.3", + "indexmap 2.7.0", "indicatif", "log", "quinn", - "rand 0.7.3", "rayon", "solana-connection-cache", "solana-measure", @@ -4150,9 +4516,9 @@ dependencies = [ [[package]] name = "solana-compute-budget-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c90fdaafdc41a4ba0a760af5491bd79f02d1d1eae6926b7796561681c843e4" +checksum = "6af050a6e0b402e322aa21f5441c7e27cdd52624a2d659f455b68afd7cda218c" dependencies = [ "solana-program-runtime", "solana-sdk", @@ -4160,9 +4526,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f9f2201c7e526581511fa6525e281518be5cabaee82bd5b29fe4b78744148d" +checksum = "9d75b803860c0098e021a26f0624129007c15badd5b0bc2fbd9f0e1a73060d3b" dependencies = [ "bincode", "chrono", @@ -4174,16 +4540,17 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee52de352e10e53b252df0815d685a9c6f3e8d3baa0f65e214dfcd247db0e21" +checksum = "b9306ede13e8ceeab8a096bcf5fa7126731e44c201ca1721ea3c38d89bcd4111" dependencies = [ "async-trait", "bincode", + "crossbeam-channel", "futures-util", - "indexmap 1.9.3", + "indexmap 2.7.0", "log", - "rand 0.7.3", + "rand 0.8.5", "rayon", "rcgen", "solana-measure", @@ -4193,34 +4560,50 @@ dependencies = [ "tokio", ] +[[package]] +name = "solana-cost-model" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c852790063f7646a1c5199234cc82e1304b55a3b3fb8055a0b5c8b0393565c1c" +dependencies = [ + "lazy_static", + "log", + "rustc_version", + "solana-address-lookup-table-program", + "solana-bpf-loader-program", + "solana-compute-budget-program", + "solana-config-program", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-loader-v4-program", + "solana-metrics", + "solana-program-runtime", + "solana-sdk", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", +] + [[package]] name = "solana-frozen-abi" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361cc834e5fbbe1a73f1d904fcb8ab052a665e5be6061bd1ba7ab478d7d17c9c" +checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" dependencies = [ - "ahash 0.8.3", - "blake3", "block-buffer 0.10.4", "bs58 0.4.0", "bv", - "byteorder", - "cc", "either", "generic-array", - "getrandom 0.1.16", "im", "lazy_static", "log", "memmap2", - "once_cell", - "rand_core 0.6.4", "rustc_version", "serde", "serde_bytes", "serde_derive", - "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "solana-frozen-abi-macro", "subtle", "thiserror", @@ -4228,24 +4611,23 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575d875dc050689f9f88c542e292e295e2f081d4e96e0df297981e45cbad8824" +checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "rustc_version", - "syn 2.0.23", + "syn 2.0.90", ] [[package]] name = "solana-loader-v4-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4f1e56ce753307a1b169ad2ef3b9af024c93d4db6f6cd6659794c57635f32ff" +checksum = "78b58f70f5883b0f26a6011ed23f76c493a3f22df63aec46cfe8e1b9bf82b5cc" dependencies = [ "log", - "rand 0.7.3", "solana-measure", "solana-program-runtime", "solana-sdk", @@ -4254,9 +4636,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00faf7aa6a3f47c542bd45d2d7f13af9a382d993e647976a676fe1b0eec4eb2" +checksum = "121d36ffb3c6b958763312cbc697fbccba46ee837d3a0aa4fc0e90fcb3b884f3" dependencies = [ "env_logger", "lazy_static", @@ -4265,9 +4647,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e19c6e1b35df3c212619a7995ae3576fa92ab15ecfc065899f21385cbe45c95" +checksum = "5c01a7f9cdc9d9d37a3d5651b2fe7ec9d433c2a3470b9f35897e373b421f0737" dependencies = [ "log", "solana-sdk", @@ -4275,9 +4657,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10e62760a5f87d836169eb3bb446bae174181db07d2c8016be36de49c04fd432" +checksum = "71e36052aff6be1536bdf6f737c6e69aca9dbb6a2f3f582e14ecb0ddc0cd66ce" dependencies = [ "crossbeam-channel", "gethostname", @@ -4285,23 +4667,24 @@ dependencies = [ "log", "reqwest", "solana-sdk", + "thiserror", ] [[package]] name = "solana-net-utils" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308c4c36c634d418589cf1df121d143819feff81932de81640de3d64878934eb" +checksum = "2a1f5c6be9c5b272866673741e1ebc64b2ea2118e5c6301babbce526fdfb15f4" dependencies = [ "bincode", "clap 3.2.25", "crossbeam-channel", "log", "nix", - "rand 0.7.3", + "rand 0.8.5", "serde", "serde_derive", - "socket2", + "socket2 0.5.8", "solana-logger", "solana-sdk", "solana-version", @@ -4309,27 +4692,35 @@ dependencies = [ "url", ] +[[package]] +name = "solana-nohash-hasher" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" + [[package]] name = "solana-perf" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d44a4998ba6d9b37e89399d9ce2812e84489dd4665df619fb23366e1c2ec1b" +checksum = "28acaf22477566a0fbddd67249ea5d859b39bacdb624aff3fadd3c5745e2643c" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", "bincode", "bv", "caps", "curve25519-dalek", - "dlopen", - "dlopen_derive", + "dlopen2", "fnv", "lazy_static", "libc", "log", "nix", - "rand 0.7.3", + "rand 0.8.5", "rayon", + "rustc_version", "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", "solana-metrics", "solana-rayon-threadlimit", "solana-sdk", @@ -4338,21 +4729,21 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9863ff5c6e828015bec331c26fb53e48352a264a9be682e7e078d2c3b3e93b46" +checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" dependencies = [ "ark-bn254", "ark-ec", "ark-ff", "ark-serialize", - "array-bytes", - "base64 0.21.4", + "base64 0.21.7", "bincode", - "bitflags", + "bitflags 2.6.0", "blake3", "borsh 0.10.3", "borsh 0.9.3", + "borsh 1.3.0", "bs58 0.4.0", "bv", "bytemuck", @@ -4366,21 +4757,21 @@ dependencies = [ "lazy_static", "libc", "libsecp256k1", + "light-poseidon", "log", "memoffset 0.9.0", - "num-bigint 0.4.3", - "num-derive", + "num-bigint 0.4.4", + "num-derive 0.4.2", "num-traits", - "parking_lot 0.12.1", - "rand 0.7.3", - "rand_chacha 0.2.2", + "parking_lot", + "rand 0.8.5", "rustc_version", "rustversion", "serde", "serde_bytes", "serde_derive", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.10.8", "solana-frozen-abi", "solana-frozen-abi-macro", @@ -4393,21 +4784,21 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05813d4d2e141ab4449cf684cc5b05512dfaabb7251561c5bb1ccf1e4221b210" +checksum = "fbf0c3eab2a80f514289af1f422c121defb030937643c43b117959d6f1932fb5" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bincode", "eager", "enum-iterator", "itertools", "libc", "log", - "num-derive", + "num-derive 0.4.2", "num-traits", "percentage", - "rand 0.7.3", + "rand 0.8.5", "rustc_version", "serde", "solana-frozen-abi", @@ -4421,18 +4812,19 @@ dependencies = [ [[package]] name = "solana-program-test" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff9f8e67fdf7306ae8ff3bb546534ecf064e6ed38e0489fee3579fa1016bd645" +checksum = "c1382a5768ff738e283770ee331d0a4fa04aa1aceed8eb820a97094c93d53b72" dependencies = [ "assert_matches", "async-trait", - "base64 0.21.4", + "base64 0.21.7", "bincode", "chrono-humanize", "crossbeam-channel", "log", "serde", + "solana-accounts-db", "solana-banks-client", "solana-banks-interface", "solana-banks-server", @@ -4442,15 +4834,17 @@ dependencies = [ "solana-runtime", "solana-sdk", "solana-vote-program", + "solana_rbpf", + "test-case", "thiserror", "tokio", ] [[package]] name = "solana-pubsub-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd0753cdde1710f50d58bd40a45e58f5368a25dabff6b18ba635c3d6959a558" +checksum = "b064e76909d33821b80fdd826e6757251934a52958220c92639f634bea90366d" dependencies = [ "crossbeam-channel", "futures-util", @@ -4473,9 +4867,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d96abde446eaa903d16961cfd3a6e98dc0d680b9edd61c39938c61548d53e" +checksum = "5a90e40ee593f6e9ddd722d296df56743514ae804975a76d47e7afed4e3da244" dependencies = [ "async-mutex", "async-trait", @@ -4485,9 +4879,8 @@ dependencies = [ "log", "quinn", "quinn-proto", - "quinn-udp", "rcgen", - "rustls 0.20.9", + "rustls", "solana-connection-cache", "solana-measure", "solana-metrics", @@ -4501,9 +4894,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ab62fc62458271d746678a3f5625e1654e3cb42a8f318ef4f1ea25991bb085" +checksum = "66468f9c014992167de10cc68aad6ac8919a8c8ff428dc88c0d2b4da8c02b8b7" dependencies = [ "lazy_static", "num_cpus", @@ -4511,16 +4904,16 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863f10b8c2a893d1ec85b3ae8020c714512a67302b80c24dde0016eea4034a7c" +checksum = "c191019f4d4f84281a6d0dd9a43181146b33019627fc394e42e08ade8976b431" dependencies = [ "console", "dialoguer", "log", - "num-derive", + "num-derive 0.4.2", "num-traits", - "parking_lot 0.12.1", + "parking_lot", "qstring", "semver", "solana-sdk", @@ -4530,12 +4923,12 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df04998cef2d0fe1291599b69acafc7f8cd87305d7f1525c8ae10aef1cc5411c" +checksum = "36ed4628e338077c195ddbf790693d410123d17dec0a319b5accb4aaee3fb15c" dependencies = [ "async-trait", - "base64 0.21.4", + "base64 0.21.7", "bincode", "bs58 0.4.0", "indicatif", @@ -4556,11 +4949,11 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2912ddbff841fbce1e30b0b9a420993c63b6cc7866e5f0af3740fcd6d85bb8" +checksum = "83c913551faa4a1ae4bbfef6af19f3a5cf847285c05b4409e37c8993b3444229" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bs58 0.4.0", "jsonrpc-core", "reqwest", @@ -4572,15 +4965,15 @@ dependencies = [ "solana-sdk", "solana-transaction-status", "solana-version", - "spl-token-2022", + "spl-token-2022 1.0.0", "thiserror", ] [[package]] name = "solana-rpc-client-nonce-utils" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d31100f6cc340dd322f57d00a334fa0a96f628ba86b04fcda1f84307deb14c31" +checksum = "1a47b6bb1834e6141a799db62bbdcf80d17a7d58d7bc1684c614e01a7293d7cf" dependencies = [ "clap 2.34.0", "solana-clap-utils", @@ -4591,11 +4984,13 @@ dependencies = [ [[package]] name = "solana-runtime" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebf6db318fd94457b1e69a481dcf43c6fd4f44e264b35f2489f0a1c6f7736e50" +checksum = "73a12e1270121e1ca6a4e86d6d0f5c339f0811a8435161d9eee54cbb0a083859" dependencies = [ + "aquamarine", "arrayref", + "base64 0.21.7", "bincode", "blake3", "bv", @@ -4615,25 +5010,29 @@ dependencies = [ "lru", "lz4", "memmap2", + "mockall", "modular-bitfield", - "num-derive", + "num-derive 0.4.2", "num-traits", "num_cpus", - "num_enum 0.6.1", - "once_cell", + "num_enum 0.7.3", "ouroboros", "percentage", - "rand 0.7.3", + "qualifier_attr", + "rand 0.8.5", "rayon", "regex", "rustc_version", "serde", "serde_derive", + "serde_json", + "solana-accounts-db", "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-bucket-map", "solana-compute-budget-program", "solana-config-program", + "solana-cost-model", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-loader-v4-program", @@ -4645,6 +5044,8 @@ dependencies = [ "solana-sdk", "solana-stake-program", "solana-system-program", + "solana-version", + "solana-vote", "solana-vote-program", "solana-zk-token-proof-program", "solana-zk-token-sdk", @@ -4660,15 +5061,15 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "621e6973766420162541b26e7974783d32d5471571610da30c5bb0b6263046c9" +checksum = "580ad66c2f7a4c3cb3244fe21440546bd500f5ecb955ad9826e92a78dded8009" dependencies = [ "assert_matches", - "base64 0.21.4", + "base64 0.21.7", "bincode", - "bitflags", - "borsh 0.10.3", + "bitflags 2.6.0", + "borsh 1.3.0", "bs58 0.4.0", "bytemuck", "byteorder", @@ -4685,13 +5086,14 @@ dependencies = [ "libsecp256k1", "log", "memmap2", - "num-derive", + "num-derive 0.4.2", "num-traits", - "num_enum 0.6.1", + "num_enum 0.7.3", "pbkdf2 0.11.0", "qstring", + "qualifier_attr", "rand 0.7.3", - "rand_chacha 0.2.2", + "rand 0.8.5", "rustc_version", "rustversion", "serde", @@ -4699,8 +5101,9 @@ dependencies = [ "serde_derive", "serde_json", "serde_with", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.10.8", + "siphasher", "solana-frozen-abi", "solana-frozen-abi-macro", "solana-logger", @@ -4713,22 +5116,28 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd177a74fb3a0a362f1292c027d668eff609ac189f08b78158324587a0a4f8d1" +checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" dependencies = [ "bs58 0.4.0", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "rustversion", - "syn 2.0.23", + "syn 2.0.90", ] +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + [[package]] name = "solana-send-transaction-service" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f275f96dd61f421bda5c9cde7698d85348824f7fa2a8c4544ad24692ac50cd8" +checksum = "3218f670f582126a3859c4fd152e922b93b3748a636bb143f970391925723577" dependencies = [ "crossbeam-channel", "log", @@ -4742,9 +5151,9 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5421decf09671329c4786ed209acfe986bb51272f91e13e4744b13a69c800680" +checksum = "eeb3e0d2dc7080b9fa61b34699b176911684f5e04e8df4b565b2b6c962bb4321" dependencies = [ "bincode", "log", @@ -4757,16 +5166,16 @@ dependencies = [ [[package]] name = "solana-streamer" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3942a60afb0282b07ef0f3c32078145ab7545cbed2cac98f1ec4b9f63016df62" +checksum = "f8476e41ad94fe492e8c06697ee35912cf3080aae0c9e9ac6430835256ccf056" dependencies = [ "async-channel", "bytes", "crossbeam-channel", "futures-util", "histogram", - "indexmap 1.9.3", + "indexmap 2.7.0", "itertools", "libc", "log", @@ -4776,10 +5185,10 @@ dependencies = [ "pkcs8", "quinn", "quinn-proto", - "quinn-udp", - "rand 0.7.3", + "rand 0.8.5", "rcgen", - "rustls 0.20.9", + "rustls", + "smallvec", "solana-metrics", "solana-perf", "solana-sdk", @@ -4790,9 +5199,9 @@ dependencies = [ [[package]] name = "solana-system-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6101d189dc10a96388c695ca1d9f23f74f0fd96330f6adefafd7d6999a20ff6e" +checksum = "26f31e04f5baad7cbc2281fea312c4e48277da42a93a0ba050b74edc5a74d63c" dependencies = [ "bincode", "log", @@ -4804,9 +5213,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d712aaf7701a4504521fc09f1743c647edf596e3852a64f6d66b2e5a822388f8" +checksum = "d8c02245d0d232430e79dc0d624aa42d50006097c3aec99ac82ac299eaa3a73f" dependencies = [ "bincode", "log", @@ -4819,17 +5228,16 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb32f7443f80cb45e244d514a706b030b5a71ef86b0436c1d39cbfff5491b4" +checksum = "67251506ed03de15f1347b46636b45c47da6be75015b4a13f0620b21beb00566" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 1.9.3", + "indexmap 2.7.0", "indicatif", "log", - "rand 0.7.3", "rayon", "solana-connection-cache", "solana-measure", @@ -4844,14 +5252,14 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aed485ddb4268b4e4ec64012016cd54ba3a4142377a99706fc3ab7768eb2bea" +checksum = "2d3d36db1b2ab2801afd5482aad9fb15ed7959f774c81a77299fdd0ddcf839d4" dependencies = [ "Inflector", - "base64 0.21.4", + "base64 0.21.7", "bincode", - "borsh 0.9.3", + "borsh 0.10.3", "bs58 0.4.0", "lazy_static", "log", @@ -4859,20 +5267,19 @@ dependencies = [ "serde_derive", "serde_json", "solana-account-decoder", - "solana-address-lookup-table-program", "solana-sdk", - "spl-associated-token-account", - "spl-memo", - "spl-token", - "spl-token-2022", + "spl-associated-token-account 2.3.0", + "spl-memo 4.0.0", + "spl-token 4.0.0", + "spl-token-2022 1.0.0", "thiserror", ] [[package]] name = "solana-udp-client" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c92798affef44c1ae2a694006209608044e99106b7945966d53586f5a95d9e2" +checksum = "3a754a3c2265eb02e0c35aeaca96643951f03cee6b376afe12e0cf8860ffccd1" dependencies = [ "async-trait", "solana-connection-cache", @@ -4885,9 +5292,9 @@ dependencies = [ [[package]] name = "solana-version" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80a20dfea2afed91761ab3fecc8f96b973a742dc7728f3e343711efe6e8e05f" +checksum = "f44776bd685cc02e67ba264384acc12ef2931d01d1a9f851cb8cdbd3ce455b9e" dependencies = [ "log", "rustc_version", @@ -4899,15 +5306,34 @@ dependencies = [ "solana-sdk", ] +[[package]] +name = "solana-vote" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5983370c95b615dc5f5d0e85414c499f05380393c578749bcd14c114c77c9bc" +dependencies = [ + "crossbeam-channel", + "itertools", + "log", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", + "solana-vote-program", + "thiserror", +] + [[package]] name = "solana-vote-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8b719e077cc9e42b8965dd06ff6b5f09fa2a436f2297efdcf471c05d187a6c" +checksum = "25810970c91feb579bd3f67dca215fce971522e42bfd59696af89c5dfebd997c" dependencies = [ "bincode", "log", - "num-derive", + "num-derive 0.4.2", "num-traits", "rustc_version", "serde", @@ -4923,13 +5349,12 @@ dependencies = [ [[package]] name = "solana-zk-token-proof-program" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5404829f9236ac760a943a4e2f16be6f180ce4a07e1bbb9d538dcfa62b98888c" +checksum = "1be1c15d4aace575e2de73ebeb9b37bac455e89bee9a8c3531f47ac5066b33e1" dependencies = [ "bytemuck", - "getrandom 0.1.16", - "num-derive", + "num-derive 0.4.2", "num-traits", "solana-program-runtime", "solana-sdk", @@ -4938,12 +5363,12 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.16.15" +version = "1.18.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61aabdec9fe1b311dce5d21fa5bd58fbaa985e8003e0d0aedf3795113aacc1ea" +checksum = "7cbdf4249b6dfcbba7d84e2b53313698043f60f8e22ce48286e6fbe8a17c8d16" dependencies = [ "aes-gcm-siv", - "base64 0.21.4", + "base64 0.21.7", "bincode", "bytemuck", "byteorder", @@ -4952,7 +5377,7 @@ dependencies = [ "itertools", "lazy_static", "merlin", - "num-derive", + "num-derive 0.4.2", "num-traits", "rand 0.7.3", "serde", @@ -4967,9 +5392,9 @@ dependencies = [ [[package]] name = "solana_rbpf" -version = "0.6.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d4ba1e58947346e360fabde0697029d36ba83c42f669199b16a8931313cf29" +checksum = "da5d083187e3b3f453e140f292c09186881da8a02a7b5e27f645ee26de3d9cc5" dependencies = [ "byteorder", "combine", @@ -5014,11 +5439,62 @@ checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" dependencies = [ "assert_matches", "borsh 0.9.3", - "num-derive", + "num-derive 0.3.3", + "num-traits", + "solana-program", + "spl-token 3.5.0", + "spl-token-2022 0.6.1", + "thiserror", +] + +[[package]] +name = "spl-associated-token-account" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" +dependencies = [ + "assert_matches", + "borsh 0.10.3", + "num-derive 0.4.2", "num-traits", "solana-program", - "spl-token", - "spl-token-2022", + "spl-token 4.0.0", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "spl-discriminator" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.90", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.90", "thiserror", ] @@ -5031,6 +5507,81 @@ dependencies = [ "solana-program", ] +[[package]] +name = "spl-memo" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" +dependencies = [ + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.90", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "615d381f48ddd2bb3c57c7f7fb207591a2a05054639b18a62e785117dd7a8683" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + [[package]] name = "spl-token" version = "3.5.0" @@ -5039,31 +5590,186 @@ checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" dependencies = [ "arrayref", "bytemuck", - "num-derive", - "num-traits", - "num_enum 0.5.11", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.5.11", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.5.11", + "solana-program", + "solana-zk-token-sdk", + "spl-memo 3.0.1", + "spl-token 3.5.0", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.3", + "solana-program", + "solana-zk-token-sdk", + "spl-memo 4.0.0", + "spl-pod", + "spl-token 4.0.0", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.3.0", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.3", + "solana-program", + "solana-security-txt", + "solana-zk-token-sdk", + "spl-memo 4.0.0", + "spl-pod", + "spl-token 4.0.0", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.4.1", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.4.0", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.5.1", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825a69d531baa1ff261a29b98fcf08e134249e624052a6b60183bb2eab2fa8ae" +dependencies = [ + "arrayref", + "bytemuck", "solana-program", - "thiserror", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.5.1", + "spl-type-length-value", ] [[package]] -name = "spl-token-2022" -version = "0.6.1" +name = "spl-type-length-value" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" dependencies = [ - "arrayref", "bytemuck", - "num-derive", - "num-traits", - "num_enum 0.5.11", "solana-program", - "solana-zk-token-sdk", - "spl-memo", - "spl-token", - "thiserror", + "spl-discriminator", + "spl-pod", + "spl-program-error", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -5098,8 +5804,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "rustversion", "syn 1.0.109", ] @@ -5118,47 +5824,86 @@ checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" [[package]] name = "syn" -version = "0.15.44" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "syn" -version = "1.0.109" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "unicode-ident", ] [[package]] -name = "syn" -version = "2.0.23" +name = "syn_derive" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "unicode-ident", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.90", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", - "unicode-xid 0.2.4", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -5208,23 +5953,21 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee42b4e559f17bce0385ebf511a7beb67d5cc33c12c96b7f4e9789919d9c10f" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", + "proc-macro2", + "quote", "syn 1.0.109", ] [[package]] name = "tempfile" -version = "3.6.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ - "autocfg", "cfg-if", "fastrand", - "redox_syscall 0.3.5", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -5236,13 +5979,52 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "test-case-macros" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "test-case-core", +] + [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.11", ] [[package]] @@ -5253,22 +6035,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -5283,12 +6065,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.26" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79d09ac6b08c1ab3906a2f7cc2e81a0e27c7ae89c63812df75e52bef0751e07" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -5296,16 +6080,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.12" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c65469ed6b3a4809d987a41eb1dc918e9bc1d92211cbad7ae82931846f7451" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ + "num-conv", "time-core", ] @@ -5328,6 +6113,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -5345,44 +6140,41 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.14.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d0183f6f6001549ab68f8c7585093bb732beefbcf6d23a10b9b95c73a1dd49" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", - "num_cpus", - "once_cell", - "parking_lot 0.11.2", + "parking_lot", "pin-project-lite", "signal-hook-registry", + "socket2 0.5.8", "tokio-macros", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 1.0.109", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.20.9", + "rustls", "tokio", - "webpki", ] [[package]] @@ -5403,9 +6195,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.12" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -5414,18 +6206,17 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.17.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.20.9", + "rustls", "tokio", "tokio-rustls", "tungstenite", - "webpki", - "webpki-roots 0.22.6", + "webpki-roots 0.25.3", ] [[package]] @@ -5478,9 +6269,20 @@ version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.7.0", "toml_datetime", - "winnow", + "winnow 0.4.8", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.7.0", + "toml_datetime", + "winnow 0.5.40", ] [[package]] @@ -5507,9 +6309,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -5554,24 +6356,23 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" -version = "0.17.3" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ - "base64 0.13.1", "byteorder", "bytes", + "data-encoding", "http", "httparse", "log", "rand 0.8.5", - "rustls 0.20.9", - "sha-1", + "rustls", + "sha1", "thiserror", "url", "utf-8", - "webpki", - "webpki-roots 0.22.6", + "webpki-roots 0.24.0", ] [[package]] @@ -5580,18 +6381,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "unarray" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" - -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - [[package]] name = "unicode-ident" version = "1.0.10" @@ -5620,10 +6409,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] -name = "unicode-xid" -version = "0.1.0" +name = "unicode-width" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unicode-xid" @@ -5668,11 +6457,11 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "flate2", "log", "once_cell", - "rustls 0.21.10", + "rustls", "rustls-webpki", "serde", "serde_json", @@ -5692,9 +6481,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -5707,6 +6496,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.1" @@ -5743,15 +6544,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - [[package]] name = "walkdir" version = "2.4.0" @@ -5785,26 +6577,26 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -5822,32 +6614,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ - "quote 1.0.29", + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" @@ -5859,23 +6651,13 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring 0.17.3", - "untrusted 0.9.0", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "webpki", + "rustls-webpki", ] [[package]] @@ -5924,30 +6706,6 @@ dependencies = [ "windows-targets 0.48.1", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -5963,22 +6721,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.6", ] [[package]] @@ -5998,25 +6750,20 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" @@ -6025,15 +6772,9 @@ checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -6043,15 +6784,9 @@ checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -6061,15 +6796,15 @@ checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -6079,15 +6814,9 @@ checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -6097,15 +6826,9 @@ checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -6115,15 +6838,9 @@ checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -6133,9 +6850,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -6146,15 +6863,37 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -6200,6 +6939,71 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure 0.13.1", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure 0.13.1", +] + [[package]] name = "zeroize" version = "1.3.0" @@ -6215,9 +7019,31 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.63", - "quote 1.0.29", - "syn 2.0.23", + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ffd89985..a99f33f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,18 +3,22 @@ members = ["cli", "market_making", "commons", "dlmm_interface"] resolver = "2" [workspace.dependencies] -anchor-lang = "0.28.0" -anchor-spl = "0.28.0" -anchor-client = "0.28.0" +anchor-lang = "0.29.0" +anchor-spl = "0.29.0" +anchor-client = "0.29.0" -solana-sdk = "1.16.0" +solana-sdk = "1.17.0" spl-associated-token-account = "1" -solana-transaction-status = "1.16.0" +solana-transaction-status = "1.17.0" +solana-account-decoder = "1.17.0" +spl-memo = "3.0.0" +spl-transfer-hook-interface = "0.5.0" serde_json = "1.0.48" serde = "1.0.104" bincode = "1.3.3" bs58 = "0.5.0" +bytemuck = "1.13.1" clap = "4.3.3" shellexpand = "3.1.0" @@ -30,7 +34,8 @@ num-traits = "0.2.16" hyper = "0.14.17" routerify = "3" -tokio = "~1.14.1" +tokio = "^1.0" +async-trait = "0.1.0" anyhow = "1.0.71" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index e1f9c795..16c41366 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cli" -version = "0.4.0" +version = "0.5.0" edition = "2021" description = "cli" authors = ["tian "] @@ -21,10 +21,11 @@ spl-associated-token-account = { workspace = true } rand = { workspace = true } tokio = { workspace = true, features = ["full", "parking_lot"] } bincode = { workspace = true } +spl-memo = { workspace = true, features = ["no-entrypoint"] } +spl-transfer-hook-interface = { workspace = true } +solana-account-decoder = { workspace = true } + bigdecimal = "0.4.2" serde = "1.0.167" serde_json = "1.0.100" serde_json_any_key = "2.0.0" - -[dev-dependencies] -proptest = "1.2.0" diff --git a/cli/src/args.rs b/cli/src/args.rs index e8ce0528..e0a261a8 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -1,4 +1,4 @@ -use anchor_client::solana_sdk::pubkey::Pubkey; +use crate::instructions::*; use anchor_client::Cluster; use clap::*; @@ -25,7 +25,7 @@ pub struct ConfigOverride { pub priority_fee: u64, } -fn parse_bin_liquidity_removal(src: &str) -> Result<(i32, f64), Error> { +pub fn parse_bin_liquidity_removal(src: &str) -> Result<(i32, f64), Error> { let mut parsed_str: Vec<&str> = src.split(',').collect(); let bps_to_remove = parsed_str @@ -41,7 +41,7 @@ fn parse_bin_liquidity_removal(src: &str) -> Result<(i32, f64), Error> { Ok((bin_id, bps_to_remove)) } -fn parse_bin_liquidity_distribution(src: &str) -> Result<(i32, f64, f64), Error> { +pub fn parse_bin_liquidity_distribution(src: &str) -> Result<(i32, f64, f64), Error> { let mut parsed_str: Vec<&str> = src.split(',').collect(); let dist_y = parsed_str @@ -70,335 +70,53 @@ pub enum SelectiveRounding { } #[derive(Parser, Debug)] -pub enum Command { +pub enum DLMMCommand { /// Create a new liquidity pair. - InitializePair { - /// Preset parameter pubkey. Get the pubkey from list_all_binstep command. - preset_parameter: Pubkey, - /// Token X mint of the liquidity pair. Eg: BTC. This should be the base token. - token_mint_x: Pubkey, - /// Token Y mint of the liquidity pair. Eg: USDC. This should be the quote token. - token_mint_y: Pubkey, - /// The initial price of the liquidity pair. Eg: 24123.12312412 USDC per 1 BTC. - initial_price: f64, - }, + InitializePair(InitLbPairParams), /// Initialize bin array for the given liquidity pair. Use InitializeBinArrayWithPriceRange or InitializeBinArrayWithBinRange for a more user friendly version. - InitializeBinArray { - /// Index of the bin array. - #[clap(long, allow_negative_numbers = true)] - bin_array_index: i64, - /// Address of the liquidity pair. - lb_pair: Pubkey, - }, + InitializeBinArray(InitBinArrayParams), /// Initialize bin array for the given liquidity pair based on price range. For example: Initialize bin arrays for BTC/USDC from 20000 -> 30000 price. - InitializeBinArrayWithPriceRange { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Lower bound of the price. - lower_price: f64, - /// Upper bound of the price. - upper_price: f64, - }, + InitializeBinArrayWithPriceRange(InitBinArrayWithPriceRangeParams), /// Initialize bin array for the given liquidity pair based on bin range. For example: Initialize bin arrays for BTC/USDC from bin 5660 -> 6600. - InitializeBinArrayWithBinRange { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Lower bound of the bin range. - #[clap(long, allow_negative_numbers = true)] - lower_bin_id: i32, - /// Upper bound of the bin range. - #[clap(long, allow_negative_numbers = true)] - upper_bin_id: i32, - }, + InitializeBinArrayWithBinRange(InitBinArrayWithBinRangeParams), /// Initialize position for the given liquidity pair based on price range. - InitializePositionWithPriceRange { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Lower bound of the price. - lower_price: f64, - /// Width of the position. Start with 1 until 70. - width: i32, - /// NFT mint for alpha access - nft_mint: Option, - }, + InitializePositionWithPriceRange(InitPositionWithPriceRangeParams), /// Initialize position for the given liquidity pair based on bin range. - InitializePosition { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Lower bound of the bin range. - #[clap(long, allow_negative_numbers = true)] - lower_bin_id: i32, - /// Width of the position. Start with 1 until 70. - width: i32, - /// NFT mint for alpha access - nft_mint: Option, - }, + InitializePosition(InitPositionParams), /// Deposit liquidity to the position of the given liquidity pair. - AddLiquidity { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Position for the deposit. - position: Pubkey, - /// Amount of token X to be deposited. - amount_x: u64, - /// Amount of token Y to be deposited. - amount_y: u64, - /// Liquidity distribution to the bins. "" where - /// DELTA_ID = Number of bins surrounding the active bin. This decide which bin the token is going to deposit to. For example: if the current active id is 5555, delta_ids is 1, the user will be depositing to bin 5554, 5555, and 5556. - /// DIST_X = Percentage of amount_x to be deposited to the bins. Must not > 1.0 - /// DIST_Y = Percentage of amount_y to be deposited to the bins. Must not > 1.0 - /// For example: --bin-liquidity-distribution "-1,0.0,0.25 0,0.75,0.75 1,0.25,0.0" - #[clap(long, value_parser = parse_bin_liquidity_distribution, value_delimiter = ' ', allow_hyphen_values = true)] - bin_liquidity_distribution: Vec<(i32, f64, f64)>, - }, + AddLiquidity(AddLiquidityParams), /// Remove liquidity from the position of the given liquidity pair. - RemoveLiquidity { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Bin liquidity information to be remove. "" where - /// BIN_ID = bin id to withdraw - /// BPS_TO_REMOVE = Percentage of position owned share to be removed. Maximum is 1.0f, which equivalent to 100%. - #[clap(long, value_parser = parse_bin_liquidity_removal, value_delimiter = ' ', allow_hyphen_values = true)] - bin_liquidity_removal: Vec<(i32, f64)>, - /// Position to be withdraw. - position: Pubkey, - }, + RemoveLiquidity(RemoveLiquidityParams), /// Trade token X -> Y, or vice versa. - SwapExactIn { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Amount of token to be sell. - amount_in: u64, - /// Buy direction. true = buy token Y, false = buy token X. - #[clap(long)] - swap_for_y: bool, - }, - SwapExactOut { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Amount of token to be buy. - amount_out: u64, - /// Buy direction. true = buy token Y, false = buy token X. - #[clap(long)] - swap_for_y: bool, - }, - SwapWithPriceImpact { - /// Address of the liquidity pair. - lb_pair: Pubkey, - /// Amount of token to be sell. - amount_in: u64, - /// Buy direction. true = buy token Y, false = buy token X. - #[clap(long)] - swap_for_y: bool, - /// Allowed price impact in bps. - price_impact_bps: u16, - }, + SwapExactIn(SwapExactInParams), + SwapExactOut(SwapExactOutParams), + SwapWithPriceImpact(SwapWithPriceImpactParams), /// Show information of the given liquidity pair. - ShowPair { - lb_pair: Pubkey, - }, + ShowPair(ShowPairParams), /// Show information of the given position. - ShowPosition { - position: Pubkey, - }, - - ClaimReward { - lb_pair: Pubkey, - reward_index: u64, - position: Pubkey, - }, - UpdateRewardDuration { - lb_pair: Pubkey, - reward_index: u64, - reward_duration: u64, - }, - UpdateRewardFunder { - lb_pair: Pubkey, - reward_index: u64, - funder: Pubkey, - }, + ShowPosition(ShowPositionParams), + ClaimReward(ClaimRewardParams), + UpdateRewardDuration(UpdateRewardDurationParams), + UpdateRewardFunder(UpdateRewardFunderParams), /// Close liquidity position. - ClosePosition { - /// Address of the position. - position: Pubkey, - }, + ClosePosition(ClosePositionParams), /// Claim fee - ClaimFee { - /// Address of the position. - position: Pubkey, - }, + ClaimFee(ClaimFeeParams), /// Increase an oracle observation sample length - IncreaseLength { - /// Address of the pair - lb_pair: Pubkey, - /// Length to add - length_to_add: u64, - }, - - ShowPresetParameter { - /// Preset parameter pubkey. Get from ListAllBinStep - preset_parameter: Pubkey, - }, - + IncreaseLength(IncreaseLengthParams), + ShowPresetParameter(ShowPresetAccountParams), ListAllBinStep, - - SimulateSwapDemand { - lb_pair: Pubkey, - x_amount: f64, // ex: 10 jup - y_amount: f64, // ex: 1k usdc - side_ratio: u64, - }, - - InitializeCustomizablePermissionlessLbPair { - /// Token X address - #[clap(long)] - token_mint_x: Pubkey, - /// Token Y address - #[clap(long)] - token_mint_y: Pubkey, - /// Bin step - #[clap(long)] - bin_step: u16, - /// Pool starting price - #[clap(long)] - initial_price: f64, - /// Base fee rate - #[clap(long)] - base_fee_bps: u16, - /// Pool activation (start trading) type. 0 = Slot based, 1 = Timestamp based - #[clap(long)] - activation_type: u8, - /// Indicate whether the launch pool have alpha vault - #[clap(long)] - has_alpha_vault: bool, - /// Initial price rounding - #[clap(long)] - selective_rounding: SelectiveRounding, - /// Pool activation point. None = Now - #[clap(long)] - activation_point: Option, - }, + InitializeCustomizablePermissionlessLbPair(InitCustomizablePermissionlessLbPairParam), /// Seed liquidity - SeedLiquidity { - /// Address of the pair - #[clap(long)] - lb_pair: Pubkey, - /// Base position path - #[clap(long)] - base_position_path: String, - /// Amount of x - #[clap(long)] - amount: u64, - /// Min price - #[clap(long)] - min_price: f64, - /// Max price - #[clap(long)] - max_price: f64, - /// Base pubkey - #[clap(long)] - base_pubkey: Pubkey, - /// Curvature - #[clap(long)] - curvature: f64, - /// Position owner path - #[clap(long)] - position_owner_path: String, - /// Max retries - #[clap(long)] - max_retries: u16, - }, + SeedLiquidity(SeedLiquidityParameters), /// Seed liquidity by operator - SeedLiquidityByOperator { - /// Address of the pair - #[clap(long)] - lb_pair: Pubkey, - /// Base position path - #[clap(long)] - base_position_path: String, - /// Amount of x - #[clap(long)] - amount: u64, - /// Min price - #[clap(long)] - min_price: f64, - /// Max price - #[clap(long)] - max_price: f64, - /// Base pubkey - #[clap(long)] - base_pubkey: Pubkey, - /// Curvature - #[clap(long)] - curvature: f64, - /// position owner - #[clap(long)] - position_owner: Pubkey, - /// fee owner - #[clap(long)] - fee_owner: Pubkey, - /// lock release point - #[clap(long)] - lock_release_point: u64, - /// Max retries - #[clap(long)] - max_retries: u16, - }, + SeedLiquidityByOperator(SeedLiquidityByOperatorParameters), - SeedLiquiditySingleBin { - /// Address of the pair - #[clap(long)] - lb_pair: Pubkey, - /// Base position path - #[clap(long)] - base_position_path: String, - /// Base position pubkey - #[clap(long)] - base_pubkey: Pubkey, - /// amount of x - #[clap(long)] - amount: u64, - #[clap(long)] - price: f64, - /// Position owner - #[clap(long)] - position_owner_path: String, - /// Selective rounding - #[clap(long)] - selective_rounding: SelectiveRounding, - }, + SeedLiquiditySingleBin(SeedLiquiditySingleBinParameters), - SeedLiquiditySingleBinByOperator { - /// Address of the pair - #[clap(long)] - lb_pair: Pubkey, - /// Base position path - #[clap(long)] - base_position_path: String, - /// Base position pubkey - #[clap(long)] - base_pubkey: Pubkey, - /// amount of x - #[clap(long)] - amount: u64, - /// price - #[clap(long)] - price: f64, - /// Position owner - #[clap(long)] - position_owner: Pubkey, - /// lock release point - #[clap(long)] - lock_release_point: u64, - /// fee owner - #[clap(long)] - fee_owner: Pubkey, - /// Selective rounding - #[clap(long)] - selective_rounding: SelectiveRounding, - }, + SeedLiquiditySingleBinByOperator(SeedLiquiditySingleBinByOperatorParameters), #[clap(flatten)] Admin(AdminCommand), @@ -410,125 +128,23 @@ pub struct Cli { #[clap(flatten)] pub config_override: ConfigOverride, #[clap(subcommand)] - pub command: Command, + pub command: DLMMCommand, } #[derive(Debug, Parser)] pub enum AdminCommand { /// Create a new permission liquidity pair. It allow liquidity fragmentation with exact bin step. - InitializePermissionPair { - /// Bin step of the liquidity pair. It decide the bps when between bins. - bin_step: u16, - /// Token X mint of the liquidity pair. Eg: BTC. This should be the base token. - token_mint_x: Pubkey, - /// Token Y mint of the liquidity pair. Eg: USDC. This should be the quote token. - token_mint_y: Pubkey, - /// The initial price of the liquidity pair. Eg: 24123.12312412 USDC per 1 BTC. - initial_price: f64, - /// Base keypair path - base_keypair_path: String, - /// Base fee bps - base_fee_bps: u16, - /// Lock duration for bootstrap liquidity position - lock_duration: u64, - /// Activation type - activation_type: u8, - }, - + InitializePermissionPair(InitPermissionLbPairParameters), /// Toggle pool status - TogglePoolStatus { - /// Address of the pair - lb_pair: Pubkey, - }, - + TogglePoolStatus(TogglePairStatusParams), /// Remove liquidity by price range - RemoveLiquidityByPriceRange { - /// Address of the pair - lb_pair: Pubkey, - // base position path - base_position_key: Pubkey, - /// min price - min_price: f64, - /// max price - max_price: f64, - }, - - CheckMyBalance { - /// Address of the pair - lb_pair: Pubkey, - // base position path - base_position_key: Pubkey, - /// min price - min_price: f64, - /// max price - max_price: f64, - }, - - SetActivationPoint { - /// Address of the pair - lb_pair: Pubkey, - /// Activation point - activation_point: u64, - }, - - WithdrawProtocolFee { - lb_pair: Pubkey, - amount_x: u64, - amount_y: u64, - }, - - InitializeReward { - lb_pair: Pubkey, - reward_mint: Pubkey, - reward_index: u64, - reward_duration: u64, - funder: Pubkey, - }, - FundReward { - lb_pair: Pubkey, - reward_index: u64, - funding_amount: u64, - }, - - InitializePresetParameter { - /// Bin step. Represent the price increment / decrement. - bin_step: u16, - /// Used for base fee calculation. base_fee_rate = base_factor * bin_step - base_factor: u16, - /// Filter period determine high frequency trading time window. - filter_period: u16, - /// Decay period determine when the volatile fee start decay / decrease. - decay_period: u16, - /// Reduction factor controls the volatile fee rate decrement rate. - reduction_factor: u16, - /// Used to scale the variable fee component depending on the dynamic of the market - variable_fee_control: u32, - /// Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate. - max_volatility_accumulator: u32, - /// Min bin id supported by the pool based on the configured bin step. - #[clap(long, allow_negative_numbers = true)] - min_bin_id: i32, - /// Max bin id supported by the pool based on the configured bin step. - max_bin_id: i32, - /// Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee - protocol_share: u16, - }, - ClosePresetParameter { - /// Preset parameter pubkey. Get from ListAllBinStep - preset_parameter: Pubkey, - }, - - SetPreActivationDuration { - /// Address of the pair - lb_pair: Pubkey, - /// Preactivation duration - pre_activation_duration: u16, - }, - - SetPreActivationSwapAddress { - /// Address of the pair - lb_pair: Pubkey, - /// Preactivation swap address - pre_activation_swap_address: Pubkey, - }, + RemoveLiquidityByPriceRange(RemoveLiquidityByPriceRangeParameters), + SetActivationPoint(SetActivationPointParam), + WithdrawProtocolFee(WithdrawProtocolFeeParams), + InitializeReward(InitializeRewardParams), + FundReward(FundRewardParams), + InitializePresetParameter(InitPresetParameters), + ClosePresetParameter(ClosePresetAccountParams), + SetPreActivationDuration(SetPreactivationDurationParam), + SetPreActivationSwapAddress(SetPreactivationSwapAddressParam), } diff --git a/cli/src/instructions/add_liquidity.rs b/cli/src/instructions/add_liquidity.rs index 25708bdb..70c074f3 100644 --- a/cli/src/instructions/add_liquidity.rs +++ b/cli/src/instructions/add_liquidity.rs @@ -1,34 +1,31 @@ -use std::ops::Deref; +use crate::*; +use instructions::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::instructions::deposit::add_liquidity::{BinLiquidityDistribution, LiquidityParameter}; - -use crate::instructions::utils::{get_bin_arrays_for_position, get_or_create_ata}; -use lb_clmm::constants::BASIS_POINT_MAX; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::{derive_bin_array_bitmap_extension, derive_event_authority_pda}; - -#[derive(Debug)] -pub struct AddLiquidityParam { +#[derive(Debug, Parser)] +pub struct AddLiquidityParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Position for the deposit. pub position: Pubkey, + /// Amount of token X to be deposited. pub amount_x: u64, + /// Amount of token Y to be deposited. pub amount_y: u64, + /// Liquidity distribution to the bins. "" where + /// DELTA_ID = Number of bins surrounding the active bin. This decide which bin the token is going to deposit to. For example: if the current active id is 5555, delta_ids is 1, the user will be depositing to bin 5554, 5555, and 5556. + /// DIST_X = Percentage of amount_x to be deposited to the bins. Must not > 1.0 + /// DIST_Y = Percentage of amount_y to be deposited to the bins. Must not > 1.0 + /// For example: --bin-liquidity-distribution "-1,0.0,0.25 0,0.75,0.75 1,0.25,0.0" + #[clap(long, value_parser = parse_bin_liquidity_distribution, value_delimiter = ' ', allow_hyphen_values = true)] pub bin_liquidity_distribution: Vec<(i32, f64, f64)>, } -pub async fn add_liquidity + Clone>( - params: AddLiquidityParam, +pub async fn execute_add_liquidity + Clone>( + params: AddLiquidityParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let AddLiquidityParam { + let AddLiquidityParams { lb_pair, position, amount_x, @@ -36,7 +33,15 @@ pub async fn add_liquidity + Clone>( bin_liquidity_distribution, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; let bin_liquidity_distribution = bin_liquidity_distribution .into_iter() @@ -47,7 +52,15 @@ pub async fn add_liquidity + Clone>( }) .collect::>(); - let [bin_array_lower, bin_array_upper] = get_bin_arrays_for_position(program, position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + + let bin_arrays_account_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; let user_token_x = get_or_create_ata( program, @@ -65,23 +78,17 @@ pub async fn add_liquidity + Clone>( ) .await?; - // TODO: id and price slippage let (bin_array_bitmap_extension, _bump) = derive_bin_array_bitmap_extension(lb_pair); - let bin_array_bitmap_extension = if program - .rpc() + + let bin_array_bitmap_extension = rpc_client .get_account(&bin_array_bitmap_extension) - .is_err() - { - None - } else { - Some(bin_array_bitmap_extension) - }; + .await + .map(|_| bin_array_bitmap_extension) + .unwrap_or(dlmm_interface::ID); let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::ModifyLiquidity { - bin_array_lower, - bin_array_upper, + let main_accounts: [AccountMeta; ADD_LIQUIDITY2_IX_ACCOUNTS_LEN] = AddLiquidity2Keys { lb_pair, bin_array_bitmap_extension, position, @@ -92,19 +99,47 @@ pub async fn add_liquidity + Clone>( sender: program.payer(), user_token_x, user_token_y, - // TODO: token 2022 - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, + token_x_program, + token_y_program, event_authority, - program: lb_clmm::ID, + program: dlmm_interface::ID, + memo_program: spl_memo::ID, + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); }; - let ix = instruction::AddLiquidity { + remaining_accounts.extend(bin_arrays_account_meta); + + let data = AddLiquidity2IxData(AddLiquidity2IxArgs { liquidity_parameter: LiquidityParameter { amount_x, amount_y, bin_liquidity_dist: bin_liquidity_distribution, }, + remaining_accounts_info, + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let add_liquidity_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, }; let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); @@ -112,8 +147,7 @@ pub async fn add_liquidity + Clone>( let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .args(ix) + .instruction(add_liquidity_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/check_my_balance.rs b/cli/src/instructions/check_my_balance.rs deleted file mode 100644 index 9347bbcd..00000000 --- a/cli/src/instructions/check_my_balance.rs +++ /dev/null @@ -1,229 +0,0 @@ -use crate::math::get_id_from_price; -use crate::math::price_per_token_to_per_lamport; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_spl::token_interface::Mint; -use anyhow::*; -use lb_clmm::constants::{MAX_BIN_PER_ARRAY, MAX_BIN_PER_POSITION}; -use lb_clmm::math::safe_math::SafeMath; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::math::u64x64_math::SCALE_OFFSET; -use lb_clmm::math::utils_math::safe_mul_shr_cast; -use lb_clmm::state::bin::Bin; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::state::position::PositionV2; -use lb_clmm::utils::pda::*; -use std::ops::Deref; -use std::result::Result::Ok; -#[derive(Debug)] -pub struct CheckMyBalanceParameters { - pub lb_pair: Pubkey, - pub base_position_key: Pubkey, - pub min_price: f64, - pub max_price: f64, -} - -pub async fn check_my_balance + Clone>( - params: CheckMyBalanceParameters, - program: &Program, -) -> Result<()> { - let CheckMyBalanceParameters { - lb_pair, - base_position_key, - min_price, - max_price, - } = params; - let lb_pair_state = program.account::(lb_pair).await?; - - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; - - let lb_pair_state: LbPair = program.account(lb_pair).await?; - - println!("active bin {}", lb_pair_state.active_id); - - let bin_step = lb_pair_state.bin_step; - let min_price_per_lamport = price_per_token_to_per_lamport( - min_price, - token_mint_base.decimals, - token_mint_quote.decimals, - ) - .context("price_per_token_to_per_lamport overflow")?; - let min_active_id = get_id_from_price(bin_step, &min_price_per_lamport, Rounding::Up) - .context("get_id_from_price overflow")?; - - let max_price_per_lamport = price_per_token_to_per_lamport( - max_price, - token_mint_base.decimals, - token_mint_quote.decimals, - ) - .context("price_per_token_to_per_lamport overflow")?; - let max_active_id = get_id_from_price(bin_step, &max_price_per_lamport, Rounding::Up) - .context("get_id_from_price overflow")?; - - let width = MAX_BIN_PER_POSITION as i32; - let mut total_amount_x = 0u64; - let mut total_amount_y = 0u64; - let mut total_fee_x_pending = 0u64; - let mut total_fee_y_pending = 0u64; - - for i in min_active_id..max_active_id { - let (position, _bump) = derive_position_pda(lb_pair, base_position_key, i, width); - match program.account::(position).await { - Ok(position_state) => { - let lower_bin_array_idx = - BinArray::bin_id_to_bin_array_index(position_state.lower_bin_id)?; - let upper_bin_array_idx = - lower_bin_array_idx.checked_add(1).context("MathOverflow")?; - - let mut bin_arrays = vec![]; - for i in lower_bin_array_idx..=upper_bin_array_idx { - let (bin_array, _bump) = derive_bin_array_pda(lb_pair, i.into()); - - match program.account::(bin_array).await { - Ok(bin_array_state) => bin_arrays.push(bin_array_state), - Err(_err) => {} - } - } - let bin_array_manager = BinArrayManager { - bin_arrays: &bin_arrays, - }; - for (i, &share) in position_state.liquidity_shares.iter().enumerate() { - if share == 0 { - continue; - } - let bin_id = position_state.from_idx_to_bin_id(i)?; - let bin = bin_array_manager.get_bin(bin_id)?; - let (amount_x, amount_y) = bin.calculate_out_amount(share)?; - total_amount_x = total_amount_x.safe_add(amount_x).unwrap(); - total_amount_y = total_amount_y.safe_add(amount_y).unwrap(); - } - - let (fee_x_pending, fee_y_pending) = - bin_array_manager.get_total_fee_pending(&position_state)?; - total_fee_x_pending = total_fee_x_pending.checked_add(fee_x_pending).unwrap(); - total_fee_y_pending = total_fee_y_pending.checked_add(fee_y_pending).unwrap(); - } - Err(_err) => continue, // TODO handle rpc call here - } - } - let total_amount_x = - total_amount_x as f64 / (10u64.pow(token_mint_base.decimals as u32) as f64); - let total_amount_y = - total_amount_y as f64 / (10u64.pow(token_mint_quote.decimals as u32) as f64); - - let total_fee_x_pending = - total_fee_x_pending as f64 / (10u64.pow(token_mint_base.decimals as u32) as f64); - let total_fee_y_pending = - total_fee_y_pending as f64 / (10u64.pow(token_mint_quote.decimals as u32) as f64); - - println!( - "amount_x {total_amount_x} amount_y {total_amount_y} fee_x_pending {total_fee_x_pending} fee_y_pending {total_fee_y_pending}" - ); - Ok(()) -} - -pub struct BinArrayManager<'a> { - bin_arrays: &'a Vec, -} -impl<'a> BinArrayManager<'a> { - pub fn get_bin(&self, bin_id: i32) -> anyhow::Result<&Bin> { - let bin_array_idx = BinArray::bin_id_to_bin_array_index(bin_id)?; - match self - .bin_arrays - .iter() - .find(|ba| ba.index == bin_array_idx as i64) - { - Some(bin_array) => Ok(bin_array.get_bin(bin_id)?), - None => Err(anyhow::Error::msg("Cannot get bin")), - } - } - - pub fn get_lower_upper_bin_id(&self) -> Result<(i32, i32)> { - let lower_bin_array_idx = self.bin_arrays[0].index as i32; - let upper_bin_array_idx = self.bin_arrays[self.bin_arrays.len() - 1].index as i32; - - let lower_bin_id = lower_bin_array_idx - .safe_mul(MAX_BIN_PER_ARRAY as i32) - .map_err(|_| anyhow::Error::msg("math is overflow"))?; - let upper_bin_id = upper_bin_array_idx - .safe_mul(MAX_BIN_PER_ARRAY as i32) - .map_err(|_| anyhow::Error::msg("math is overflow"))? - .safe_add(MAX_BIN_PER_ARRAY as i32) - .map_err(|_| anyhow::Error::msg("math is overflow"))? - .safe_sub(1) - .map_err(|_| anyhow::Error::msg("math is overflow"))?; - - Ok((lower_bin_id, upper_bin_id)) - } - - /// Update reward + fee earning - pub fn get_total_fee_pending(&self, position: &PositionV2) -> Result<(u64, u64)> { - let (bin_arrays_lower_bin_id, bin_arrays_upper_bin_id) = self.get_lower_upper_bin_id()?; - - // Make sure that the bin arrays cover all the bins of the position. - // TODO: Should we? Maybe we shall update only the bins the user are interacting with, and allow chunk for claim reward. - if position.lower_bin_id < bin_arrays_lower_bin_id - && position.upper_bin_id > bin_arrays_upper_bin_id - { - return Err(anyhow::Error::msg("Bin array is not correct")); - } - - let mut total_fee_x = 0u64; - let mut total_fee_y = 0u64; - for bin_id in position.lower_bin_id..=position.upper_bin_id { - let bin = self.get_bin(bin_id)?; - let (fee_x_pending, fee_y_pending) = - BinArrayManager::get_fee_pending_for_a_bin(position, bin_id, bin)?; - total_fee_x = fee_x_pending - .safe_add(total_fee_x) - .map_err(|_| anyhow::Error::msg("math is overflow"))?; - total_fee_y = fee_y_pending - .safe_add(total_fee_y) - .map_err(|_| anyhow::Error::msg("math is overflow"))?; - } - - Ok((total_fee_x, total_fee_y)) - } - - fn get_fee_pending_for_a_bin( - position: &PositionV2, - bin_id: i32, - bin: &Bin, - ) -> Result<(u64, u64)> { - let idx = position.get_idx(bin_id)?; - - let fee_infos = &position.fee_infos[idx]; - - let fee_x_per_token_stored = bin.fee_amount_x_per_token_stored; - - let new_fee_x: u64 = safe_mul_shr_cast( - position.liquidity_shares[idx], - fee_x_per_token_stored - .safe_sub(fee_infos.fee_x_per_token_complete) - .map_err(|_| anyhow::Error::msg("math is overflow"))?, - SCALE_OFFSET, - Rounding::Down, - )?; - - let fee_x_pending = new_fee_x - .safe_add(fee_infos.fee_x_pending) - .map_err(|_| anyhow::Error::msg("math is overflow"))?; - - let fee_y_per_token_stored = bin.fee_amount_y_per_token_stored; - let new_fee_y: u64 = safe_mul_shr_cast( - position.liquidity_shares[idx], - fee_y_per_token_stored - .safe_sub(fee_infos.fee_y_per_token_complete) - .map_err(|_| anyhow::Error::msg("math is overflow"))?, - SCALE_OFFSET, - Rounding::Down, - )?; - - let fee_y_pending = new_fee_y - .safe_add(fee_infos.fee_y_pending) - .map_err(|_| anyhow::Error::msg("math is overflow"))?; - - Ok((fee_x_pending, fee_y_pending)) - } -} diff --git a/cli/src/instructions/claim_fee.rs b/cli/src/instructions/claim_fee.rs index 8f68cffd..8dc8132c 100644 --- a/cli/src/instructions/claim_fee.rs +++ b/cli/src/instructions/claim_fee.rs @@ -1,22 +1,30 @@ -use super::utils::{get_bin_arrays_for_position, get_or_create_ata}; -use anchor_client::{ - solana_client::rpc_config::RpcSendTransactionConfig, solana_sdk::signer::Signer, Program, -}; -use anchor_lang::prelude::Pubkey; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::state::{lb_pair::LbPair, position::Position}; -use lb_clmm::utils::pda::derive_event_authority_pda; -use std::ops::Deref; - -pub async fn claim_fee + Clone>( - position: Pubkey, +use crate::*; +use instructions::*; + +#[derive(Debug, Parser)] +pub struct ClaimFeeParams { + pub position: Pubkey, +} + +pub async fn execute_claim_fee + Clone>( + params: ClaimFeeParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let position_state: Position = program.account(position).await?; - let lb_pair_state: LbPair = program.account(position_state.lb_pair).await?; + let ClaimFeeParams { position } = params; + + let rpc_client = program.async_rpc(); + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&position_state.global_data.lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let user_token_x = get_or_create_ata( program, @@ -25,6 +33,7 @@ pub async fn claim_fee + Clone>( program.payer(), ) .await?; + let user_token_y = get_or_create_ata( program, transaction_config, @@ -33,33 +42,67 @@ pub async fn claim_fee + Clone>( ) .await?; - let [bin_array_lower, bin_array_upper] = get_bin_arrays_for_position(program, position).await?; + let bin_arrays_account_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; + + let [token_program_x, token_program_y] = lb_pair_state.get_token_programs()?; let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::ClaimFee { - bin_array_lower, - bin_array_upper, - lb_pair: position_state.lb_pair, + let main_accounts: [AccountMeta; CLAIM_FEE2_IX_ACCOUNTS_LEN] = dlmm_interface::ClaimFee2Keys { + lb_pair: position_state.global_data.lb_pair, sender: program.payer(), position, reserve_x: lb_pair_state.reserve_x, reserve_y: lb_pair_state.reserve_y, - token_program: anchor_spl::token::ID, + token_program_x, + token_program_y, token_x_mint: lb_pair_state.token_x_mint, token_y_mint: lb_pair_state.token_y_mint, user_token_x, user_token_y, event_authority, - program: lb_clmm::ID, + program: dlmm_interface::ID, + memo_program: spl_memo::id(), + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); }; - let ix = instruction::ClaimFee {}; + remaining_accounts.extend(bin_arrays_account_meta); + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let data = ClaimFee2IxData(ClaimFee2IxArgs { + min_bin_id: position_state.global_data.lower_bin_id, + max_bin_id: position_state.global_data.upper_bin_id, // TODO: Pass in bin id from args, or dynamically check based on position + remaining_accounts_info, + }) + .try_to_vec()?; + + let claim_fee_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(claim_fee_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/claim_reward.rs b/cli/src/instructions/claim_reward.rs index 6bf38958..a138cfc0 100644 --- a/cli/src/instructions/claim_reward.rs +++ b/cli/src/instructions/claim_reward.rs @@ -1,21 +1,14 @@ -use crate::instructions::utils::{get_bin_arrays_for_position, get_or_create_ata}; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::*; -use std::ops::Deref; - -#[derive(Debug)] +use crate::*; +use instructions::*; + +#[derive(Debug, Parser)] pub struct ClaimRewardParams { pub lb_pair: Pubkey, pub reward_index: u64, pub position: Pubkey, } -pub async fn claim_reward + Clone>( +pub async fn execute_claim_reward + Clone>( params: ClaimRewardParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -26,38 +19,85 @@ pub async fn claim_reward + Clone>( position, } = params; + let rpc_client = program.async_rpc(); let (reward_vault, _bump) = derive_reward_vault_pda(lb_pair, reward_index); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + let reward_info = lb_pair_state.reward_infos[reward_index as usize]; let reward_mint = reward_info.mint; + let reward_mint_program = rpc_client.get_account(&reward_mint).await?.owner; + let user_token_account = get_or_create_ata(program, transaction_config, reward_mint, program.payer()).await?; - let [bin_array_lower, bin_array_upper] = get_bin_arrays_for_position(program, position).await?; + let bin_arrays_account_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::ClaimReward { - bin_array_lower, - bin_array_upper, + let main_accounts: [AccountMeta; CLAIM_REWARD2_IX_ACCOUNTS_LEN] = ClaimReward2Keys { lb_pair, reward_vault, reward_mint, - token_program: anchor_spl::token::ID, + memo_program: spl_memo::ID, + token_program: reward_mint_program, position, user_token_account, sender: program.payer(), event_authority, - program: lb_clmm::ID, + program: dlmm_interface::ID, + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityMining(reward_index as usize), + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); }; - let ix = instruction::ClaimReward { reward_index }; + remaining_accounts.extend(bin_arrays_account_meta); + + let data = ClaimReward2IxData(ClaimReward2IxArgs { + reward_index, + min_bin_id: position_state.global_data.lower_bin_id, // TODO: implement this + max_bin_id: position_state.global_data.upper_bin_id, + remaining_accounts_info, + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let claim_reward_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(claim_reward_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/close_position.rs b/cli/src/instructions/close_position.rs index 3f489914..c820eca2 100644 --- a/cli/src/instructions/close_position.rs +++ b/cli/src/instructions/close_position.rs @@ -1,46 +1,54 @@ -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::solana_sdk::signer::Signer; -use anchor_client::Program; -use anchor_lang::prelude::Pubkey; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::state::position::Position; -use lb_clmm::utils::pda::derive_event_authority_pda; -use std::ops::Deref; - -use super::utils::get_bin_arrays_for_position; - -pub async fn close_position + Clone>( - position: Pubkey, +use crate::*; + +#[derive(Debug, Parser)] +pub struct ClosePositionParams { + pub position: Pubkey, +} + +pub async fn execute_close_position + Clone>( + params: ClosePositionParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let position_state: Position = program.account(position).await?; - let [bin_array_lower, bin_array_upper] = get_bin_arrays_for_position(program, position).await?; + let ClosePositionParams { position } = params; + + let rpc_client = program.async_rpc(); + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + + let bin_arrays_account_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::ClosePosition { - bin_array_lower, - bin_array_upper, - lb_pair: position_state.lb_pair, - sender: position_state.owner, - rent_receiver: position_state.owner, + let main_accounts: [AccountMeta; CLOSE_POSITION2_IX_ACCOUNTS_LEN] = ClosePosition2Keys { + sender: position_state.global_data.owner, + rent_receiver: position_state.global_data.owner, position, event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + } + .into(); - let ix = instruction::ClosePosition {}; + let data = ClosePosition2IxData.try_to_vec()?; let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); + let accounts = [main_accounts.to_vec(), bin_arrays_account_meta].concat(); + + let close_position_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; + let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .args(ix) + .instruction(close_position_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/close_preset_parameter.rs b/cli/src/instructions/close_preset_parameter.rs index 1f509513..80ab1bd9 100644 --- a/cli/src/instructions/close_preset_parameter.rs +++ b/cli/src/instructions/close_preset_parameter.rs @@ -1,31 +1,37 @@ -use std::ops::Deref; +use crate::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_lang::ToAccountMetas; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; +#[derive(Debug, Parser)] +pub struct ClosePresetAccountParams { + /// Preset parameter pubkey. Get from ListAllBinStep + pub preset_parameter: Pubkey, +} -pub async fn close_preset_parameter + Clone>( - preset_parameter: Pubkey, +pub async fn execute_close_preset_parameter + Clone>( + params: ClosePresetAccountParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result { - let accounts = accounts::ClosePresetParameter { - admin: program.payer(), - rent_receiver: program.payer(), - preset_parameter, - } - .to_account_metas(None); + let ClosePresetAccountParams { preset_parameter } = params; + + let accounts: [AccountMeta; CLOSE_PRESET_PARAMETER_IX_ACCOUNTS_LEN] = + ClosePresetParameterKeys { + admin: program.payer(), + rent_receiver: program.payer(), + preset_parameter, + } + .into(); + + let data = ClosePresetParameter2IxData; - let ix = instruction::ClosePresetParameter {}; + let instruction = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data: data.try_to_vec()?, + }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(instruction) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/fund_reward.rs b/cli/src/instructions/fund_reward.rs index 11aec20f..d4912d7b 100644 --- a/cli/src/instructions/fund_reward.rs +++ b/cli/src/instructions/fund_reward.rs @@ -1,22 +1,14 @@ -use crate::instructions::utils::get_or_create_ata; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::*; -use std::ops::Deref; - -#[derive(Debug)] +use crate::*; +use instructions::*; + +#[derive(Debug, Parser)] pub struct FundRewardParams { pub lb_pair: Pubkey, pub reward_index: u64, pub funding_amount: u64, } -pub async fn fund_reward + Clone>( +pub async fn execute_fund_reward + Clone>( params: FundRewardParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -27,14 +19,21 @@ pub async fn fund_reward + Clone>( funding_amount, } = params; - let (reward_vault, _bump) = Pubkey::find_program_address( - &[lb_pair.as_ref(), reward_index.to_le_bytes().as_ref()], - &lb_clmm::ID, - ); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + + let (reward_vault, _bump) = derive_reward_vault_pda(lb_pair, reward_index); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&reward_vault, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + let reward_info = lb_pair_state.reward_infos[reward_index as usize]; let reward_mint = reward_info.mint; + let reward_mint_program = rpc_client.get_account(&reward_mint).await?.owner; + let funder_token_account = get_or_create_ata(program, transaction_config, reward_mint, program.payer()).await?; @@ -43,28 +42,48 @@ pub async fn fund_reward + Clone>( let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::FundReward { + let reward_transfer_hook_accounts = + get_extra_account_metas_for_transfer_hook(reward_mint, program.async_rpc()).await?; + + let remaining_accounts_info = RemainingAccountsInfo { + slices: vec![RemainingAccountsSlice { + accounts_type: AccountsType::TransferHookReward, + length: reward_transfer_hook_accounts.len() as u8, + }], + }; + + let main_accounts: [AccountMeta; FUND_REWARD_IX_ACCOUNTS_LEN] = FundRewardKeys { lb_pair, reward_vault, reward_mint, funder: program.payer(), funder_token_account, bin_array, - token_program: anchor_spl::token::ID, + token_program: reward_mint_program, event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + } + .into(); - let ix = instruction::FundReward { + let data = FundRewardIxData(FundRewardIxArgs { reward_index, amount: funding_amount, carry_forward: true, + remaining_accounts_info, + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), reward_transfer_hook_accounts].concat(); + + let fund_reward_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(fund_reward_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/increase_length.rs b/cli/src/instructions/increase_length.rs index a900356e..0305bf81 100644 --- a/cli/src/instructions/increase_length.rs +++ b/cli/src/instructions/increase_length.rs @@ -1,22 +1,13 @@ -use std::ops::Deref; +use crate::*; +use anchor_client::solana_sdk; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{ - solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, solana_sdk::system_program, Program, -}; - -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::utils::pda::{derive_event_authority_pda, derive_oracle_pda}; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct IncreaseLengthParams { pub lb_pair: Pubkey, pub length_to_add: u64, } -pub async fn increase_length + Clone>( +pub async fn execute_increase_length + Clone>( params: IncreaseLengthParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -29,20 +20,28 @@ pub async fn increase_length + Clone>( let (oracle, _) = derive_oracle_pda(lb_pair); let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::IncreaseOracleLength { - funder: program.payer(), - oracle, - system_program: system_program::ID, - event_authority, - program: lb_clmm::ID, + let accounts: [AccountMeta; INCREASE_ORACLE_LENGTH_IX_ACCOUNTS_LEN] = + IncreaseOracleLengthKeys { + funder: program.payer(), + oracle, + system_program: solana_sdk::system_program::ID, + event_authority, + program: dlmm_interface::ID, + } + .into(); + + let data = + IncreaseOracleLengthIxData(IncreaseOracleLengthIxArgs { length_to_add }).try_to_vec()?; + + let increase_length_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; - let ix = instruction::IncreaseOracleLength { length_to_add }; - let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(increase_length_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_bin_array.rs b/cli/src/instructions/initialize_bin_array.rs index c2fb2232..27c5cd98 100644 --- a/cli/src/instructions/initialize_bin_array.rs +++ b/cli/src/instructions/initialize_bin_array.rs @@ -1,46 +1,48 @@ -use std::ops::Deref; +use crate::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::utils::pda::*; - -#[derive(Debug)] -pub struct InitBinArrayParameters { - pub lb_pair: Pubkey, +#[derive(Debug, Parser)] +pub struct InitBinArrayParams { + /// Index of the bin array. + #[clap(long, allow_negative_numbers = true)] pub bin_array_index: i64, + /// Address of the liquidity pair. + pub lb_pair: Pubkey, } -pub async fn initialize_bin_array + Clone>( - params: InitBinArrayParameters, +pub async fn execute_initialize_bin_array + Clone>( + params: InitBinArrayParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result { - let InitBinArrayParameters { + let InitBinArrayParams { lb_pair, bin_array_index, } = params; let (bin_array, _bump) = derive_bin_array_pda(lb_pair, bin_array_index); - let accounts = accounts::InitializeBinArray { + let accounts: [AccountMeta; INITIALIZE_BIN_ARRAY_IX_ACCOUNTS_LEN] = InitializeBinArrayKeys { bin_array, funder: program.payer(), lb_pair, - system_program: anchor_client::solana_sdk::system_program::ID, - }; + system_program: solana_sdk::system_program::ID, + } + .into(); - let ix = instruction::InitializeBinArray { + let data = InitializeBinArrayIxData(InitializeBinArrayIxArgs { index: bin_array_index, + }) + .try_to_vec()?; + + let init_bin_array_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(init_bin_array_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_bin_array_with_bin_range.rs b/cli/src/instructions/initialize_bin_array_with_bin_range.rs index 72a78c76..7431f98f 100644 --- a/cli/src/instructions/initialize_bin_array_with_bin_range.rs +++ b/cli/src/instructions/initialize_bin_array_with_bin_range.rs @@ -1,25 +1,24 @@ -use std::ops::Deref; +use crate::*; +use instructions::*; -use crate::instructions::initialize_bin_array::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anyhow::*; -use lb_clmm::state::bin::BinArray; - -#[derive(Debug)] -pub struct InitBinArrayWithBinRangeParameters { +#[derive(Debug, Parser)] +pub struct InitBinArrayWithBinRangeParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Lower bound of the bin range. + #[clap(long, allow_negative_numbers = true)] pub lower_bin_id: i32, + /// Upper bound of the bin range. + #[clap(long, allow_negative_numbers = true)] pub upper_bin_id: i32, } -pub async fn initialize_bin_array_with_bin_range + Clone>( - params: InitBinArrayWithBinRangeParameters, +pub async fn execute_initialize_bin_array_with_bin_range + Clone>( + params: InitBinArrayWithBinRangeParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result> { - let InitBinArrayWithBinRangeParameters { + let InitBinArrayWithBinRangeParams { lb_pair, lower_bin_id, upper_bin_id, @@ -31,11 +30,12 @@ pub async fn initialize_bin_array_with_bin_range let upper_bin_array_idx = BinArray::bin_id_to_bin_array_index(upper_bin_id)?; for idx in lower_bin_array_idx..=upper_bin_array_idx { - let params = InitBinArrayParameters { + let params = InitBinArrayParams { bin_array_index: idx.into(), lb_pair, }; - let bin_array_pubkey = initialize_bin_array(params, program, transaction_config).await?; + let bin_array_pubkey = + execute_initialize_bin_array(params, program, transaction_config).await?; bin_arrays_pubkey.push(bin_array_pubkey); } diff --git a/cli/src/instructions/initialize_bin_array_with_price_range.rs b/cli/src/instructions/initialize_bin_array_with_price_range.rs index b2f91a59..96098c3b 100644 --- a/cli/src/instructions/initialize_bin_array_with_price_range.rs +++ b/cli/src/instructions/initialize_bin_array_with_price_range.rs @@ -1,38 +1,36 @@ -use std::ops::Deref; - -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anyhow::*; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::state::lb_pair::LbPair; +use crate::*; +use instructions::*; use rust_decimal::Decimal; -use crate::math::get_id_from_price; - -use super::initialize_bin_array_with_bin_range::{ - initialize_bin_array_with_bin_range, InitBinArrayWithBinRangeParameters, -}; - -#[derive(Debug)] -pub struct InitBinArrayWithPriceRangeParameters { +#[derive(Debug, Parser)] +pub struct InitBinArrayWithPriceRangeParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Lower bound of the price. pub lower_price: f64, + /// Upper bound of the price. pub upper_price: f64, } -pub async fn initialize_bin_array_with_price_range + Clone>( - params: InitBinArrayWithPriceRangeParameters, +pub async fn execute_initialize_bin_array_with_price_range< + C: Deref + Clone, +>( + params: InitBinArrayWithPriceRangeParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result> { - let InitBinArrayWithPriceRangeParameters { + let InitBinArrayWithPriceRangeParams { lb_pair, lower_price, upper_price, } = params; - let lb_pair_state = program.account::(lb_pair).await?; + let rpc_client = program.async_rpc(); + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let lower_bin_id = get_id_from_price( lb_pair_state.bin_step, @@ -48,11 +46,11 @@ pub async fn initialize_bin_array_with_price_range, + /// Initial price rounding + #[clap(long)] pub selective_rounding: SelectiveRounding, + /// Pool activation point. None = Now + #[clap(long)] + pub activation_point: Option, } -pub async fn initialize_customizable_permissionless_lb_pair< +pub async fn execute_initialize_customizable_permissionless_lb_pair< C: Deref + Clone, >( - params: InitCustomizablePermissionlessLbPairParameters, + params: InitCustomizablePermissionlessLbPairParam, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result { - let InitCustomizablePermissionlessLbPairParameters { + let InitCustomizablePermissionlessLbPairParam { bin_step, token_mint_x, token_mint_y, @@ -48,8 +53,16 @@ pub async fn initialize_customizable_permissionless_lb_pair< selective_rounding, } = params; - let token_mint_base: Mint = program.account(token_mint_x).await?; - let token_mint_quote: Mint = program.account(token_mint_y).await?; + let rpc_client = program.async_rpc(); + let mut accounts = rpc_client + .get_multiple_accounts(&[token_mint_x, token_mint_y]) + .await?; + + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let price_per_lamport = price_per_token_to_per_lamport( initial_price, @@ -78,42 +91,63 @@ pub async fn initialize_customizable_permissionless_lb_pair< let (oracle, _bump) = derive_oracle_pda(lb_pair); let (event_authority, _bump) = derive_event_authority_pda(); + let user_token_x = get_or_create_ata(program, transaction_config, token_mint_x, program.payer()).await?; - let accounts = accounts::InitializeCustomizablePermissionlessLbPair { - lb_pair, - bin_array_bitmap_extension: None, - reserve_x, - reserve_y, - token_mint_x, - token_mint_y, - oracle, - funder: program.payer(), - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, - token_program: anchor_spl::token::ID, - event_authority, - user_token_x, - program: lb_clmm::ID, - }; - - let ix = instruction::InitializeCustomizablePermissionlessLbPair { - params: CustomizableParams { - active_id: computed_active_id, - bin_step, - base_factor: compute_base_factor_from_fee_bps(bin_step, base_fee_bps)?, - activation_type, - activation_point, - has_alpha_vault, - padding: [0u8; 64], + let token_badge_x = derive_token_badge_pda(token_mint_x).0; + let token_badge_x = rpc_client + .get_account(&token_badge_x) + .await + .ok() + .map(|_| token_badge_x) + .unwrap_or(dlmm_interface::ID); + + let accounts: [AccountMeta; INITIALIZE_CUSTOMIZABLE_PERMISSIONLESS_LB_PAIR2_IX_ACCOUNTS_LEN] = + InitializeCustomizablePermissionlessLbPair2Keys { + lb_pair, + bin_array_bitmap_extension: dlmm_interface::ID, + reserve_x, + reserve_y, + token_mint_x, + token_mint_y, + oracle, + funder: program.payer(), + system_program: solana_sdk::system_program::ID, + token_program_x: token_mint_base_account.owner, + token_program_y: token_mint_quote_account.owner, + token_badge_x, + event_authority, + user_token_x, + program: dlmm_interface::ID, + } + .into(); + + let data = InitializeCustomizablePermissionlessLbPair2IxData( + InitializeCustomizablePermissionlessLbPair2IxArgs { + params: CustomizableParams { + active_id: computed_active_id, + bin_step, + base_factor: compute_base_factor_from_fee_bps(bin_step, base_fee_bps)?, + activation_type, + activation_point, + has_alpha_vault, + base_fee_power_factor: 0, // TODO: Take this into consideration when compute_base_factor_from_fee_bps + padding: [0u8; 63], + }, }, + ) + .try_to_vec()?; + + let init_pair_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(init_pair_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_lb_pair.rs b/cli/src/instructions/initialize_lb_pair.rs index 0b1b61c0..18c6e751 100644 --- a/cli/src/instructions/initialize_lb_pair.rs +++ b/cli/src/instructions/initialize_lb_pair.rs @@ -1,39 +1,42 @@ -use std::ops::Deref; - -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_spl::token::Mint; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::state::preset_parameters::PresetParameter; -use lb_clmm::utils::pda::*; - -use crate::math::{get_id_from_price, price_per_token_to_per_lamport}; - -#[derive(Debug)] -pub struct InitLbPairParameters { +use crate::*; +use anchor_lang::AccountDeserialize; +use anchor_spl::token_interface::Mint; + +#[derive(Debug, Parser)] +pub struct InitLbPairParams { + /// Preset parameter pubkey. Get the pubkey from list_all_binstep command. + pub preset_parameter: Pubkey, + /// Token X mint of the liquidity pair. Eg: BTC. This should be the base token. pub token_mint_x: Pubkey, + /// Token Y mint of the liquidity pair. Eg: USDC. This should be the quote token. pub token_mint_y: Pubkey, - pub preset_parameter: Pubkey, + /// The initial price of the liquidity pair. Eg: 24123.12312412 USDC per 1 BTC. pub initial_price: f64, } -pub async fn initialize_lb_pair + Clone>( - params: InitLbPairParameters, +pub async fn execute_initialize_lb_pair + Clone>( + params: InitLbPairParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result { - let InitLbPairParameters { + let InitLbPairParams { preset_parameter, token_mint_x, token_mint_y, initial_price, } = params; - let token_mint_base: Mint = program.account(token_mint_x).await?; - let token_mint_quote: Mint = program.account(token_mint_y).await?; + let rpc_client = program.async_rpc(); + + let mut accounts = rpc_client + .get_multiple_accounts(&[token_mint_x, token_mint_y]) + .await?; + + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let price_per_lamport = price_per_token_to_per_lamport( initial_price, @@ -42,7 +45,12 @@ pub async fn initialize_lb_pair + Clone>( ) .context("price_per_token_to_per_lamport overflow")?; - let preset_parameter_state = program.account::(preset_parameter).await?; + let preset_parameter_state = rpc_client + .get_account_and_deserialize(&preset_parameter, |account| { + Ok(PresetParameter2Account::deserialize(&account.data)?.0) + }) + .await?; + let bin_step = preset_parameter_state.bin_step; let computed_active_id = get_id_from_price(bin_step, &price_per_lamport, Rounding::Up) @@ -64,34 +72,61 @@ pub async fn initialize_lb_pair + Clone>( let (oracle, _bump) = derive_oracle_pda(lb_pair); let (event_authority, _bump) = derive_event_authority_pda(); + let (token_badge_x, _bump) = derive_token_badge_pda(token_mint_x); + let (token_badge_y, _bump) = derive_token_badge_pda(token_mint_y); - let accounts = accounts::InitializeLbPair { + let accounts = rpc_client + .get_multiple_accounts(&[token_badge_x, token_badge_y]) + .await?; + + let token_badge_x = accounts[0] + .as_ref() + .map(|_| token_badge_x) + .unwrap_or(dlmm_interface::ID); + + let token_badge_y = accounts[1] + .as_ref() + .map(|_| token_badge_y) + .unwrap_or(dlmm_interface::ID); + + let accounts: [AccountMeta; INITIALIZE_LB_PAIR2_IX_ACCOUNTS_LEN] = InitializeLbPair2Keys { lb_pair, - bin_array_bitmap_extension: None, + bin_array_bitmap_extension: dlmm_interface::ID, reserve_x, reserve_y, token_mint_x, token_mint_y, oracle, funder: program.payer(), + token_badge_x, + token_badge_y, + token_program_x: token_mint_base_account.owner, + token_program_y: token_mint_quote_account.owner, preset_parameter, - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, - token_program: anchor_spl::token::ID, + system_program: solana_sdk::system_program::ID, event_authority, - program: lb_clmm::ID, - }; - - let ix = instruction::InitializeLbPair { - active_id: computed_active_id, - bin_step, + program: dlmm_interface::ID, + } + .into(); + + let data = InitializeLbPair2IxData(InitializeLbPair2IxArgs { + params: InitializeLbPair2Params { + active_id: computed_active_id, + padding: [0u8; 96], + }, + }) + .try_to_vec()?; + + let init_pair_ix = Instruction { + program_id: dlmm_interface::ID, + data, + accounts: accounts.to_vec(), }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(init_pair_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_permission_lb_pair.rs b/cli/src/instructions/initialize_permission_lb_pair.rs index c45f36e9..3900c7aa 100644 --- a/cli/src/instructions/initialize_permission_lb_pair.rs +++ b/cli/src/instructions/initialize_permission_lb_pair.rs @@ -1,35 +1,26 @@ -use std::ops::Deref; - -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::signature::Keypair; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_spl::token::Mint; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::instructions::initialize_pool::initialize_permission_lb_pair::InitPermissionPairIx; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::utils::pda::*; - -use crate::math::{ - compute_base_factor_from_fee_bps, find_swappable_min_max_bin_id, get_id_from_price, - price_per_token_to_per_lamport, -}; - -#[derive(Debug)] +use crate::*; +use anchor_lang::AccountDeserialize; +use anchor_spl::token_interface::Mint; + +#[derive(Debug, Parser)] pub struct InitPermissionLbPairParameters { + /// Bin step of the liquidity pair. It decide the bps when between bins. + pub bin_step: u16, + /// Token X mint of the liquidity pair. Eg: BTC. This should be the base token. pub token_mint_x: Pubkey, + /// Token Y mint of the liquidity pair. Eg: USDC. This should be the quote token. pub token_mint_y: Pubkey, - pub bin_step: u16, + /// The initial price of the liquidity pair. Eg: 24123.12312412 USDC per 1 BTC. pub initial_price: f64, + /// Base keypair path + pub base_keypair_path: String, + /// Base fee bps pub base_fee_bps: u16, - pub base_keypair: Keypair, - pub lock_duration: u64, + /// Activation type pub activation_type: u8, } -pub async fn initialize_permission_lb_pair + Clone>( +pub async fn execute_initialize_permission_lb_pair + Clone>( params: InitPermissionLbPairParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -39,14 +30,24 @@ pub async fn initialize_permission_lb_pair + Clon token_mint_x, token_mint_y, initial_price, + base_keypair_path, base_fee_bps, - base_keypair, - lock_duration, activation_type, } = params; - let token_mint_base: Mint = program.account(token_mint_x).await?; - let token_mint_quote: Mint = program.account(token_mint_y).await?; + let base_keypair = read_keypair_file(base_keypair_path).expect("base keypair file not found"); + + let rpc_client = program.async_rpc(); + + let mut accounts = rpc_client + .get_multiple_accounts(&[token_mint_x, token_mint_y]) + .await?; + + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let price_per_lamport = price_per_token_to_per_lamport( initial_price, @@ -71,42 +72,67 @@ pub async fn initialize_permission_lb_pair + Clon let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::InitializePermissionLbPair { - lb_pair, - bin_array_bitmap_extension: None, - reserve_x, - reserve_y, - token_mint_x, - token_mint_y, - oracle, - admin: program.payer(), - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, - token_program: anchor_spl::token::ID, - event_authority, - program: lb_clmm::ID, - base: base_keypair.pubkey(), - }; - - let (min_bin_id, max_bin_id) = find_swappable_min_max_bin_id(bin_step)?; - - let ix = instruction::InitializePermissionLbPair { + let (token_badge_x, _bump) = derive_token_badge_pda(token_mint_x); + let (token_badge_y, _bump) = derive_token_badge_pda(token_mint_y); + + let accounts = rpc_client + .get_multiple_accounts(&[token_badge_x, token_badge_y]) + .await?; + + let token_badge_x = accounts[0] + .as_ref() + .map(|_| token_badge_x) + .unwrap_or(dlmm_interface::ID); + + let token_badge_y = accounts[1] + .as_ref() + .map(|_| token_badge_y) + .unwrap_or(dlmm_interface::ID); + + let accounts: [AccountMeta; INITIALIZE_PERMISSION_LB_PAIR_IX_ACCOUNTS_LEN] = + InitializePermissionLbPairKeys { + lb_pair, + bin_array_bitmap_extension: dlmm_interface::ID, + reserve_x, + reserve_y, + token_mint_x, + token_mint_y, + token_badge_x, + token_badge_y, + token_program_x: token_mint_base_account.owner, + token_program_y: token_mint_quote_account.owner, + oracle, + admin: program.payer(), + rent: solana_sdk::sysvar::rent::ID, + system_program: solana_sdk::system_program::ID, + event_authority, + program: dlmm_interface::ID, + base: base_keypair.pubkey(), + } + .into(); + + let data = InitializePermissionLbPairIxData(InitializePermissionLbPairIxArgs { ix_data: InitPermissionPairIx { active_id: computed_active_id, bin_step, base_factor: compute_base_factor_from_fee_bps(bin_step, base_fee_bps)?, - max_bin_id, - min_bin_id, - lock_duration, activation_type, + base_fee_power_factor: 0, // TODO: Implement this + protocol_share: ILM_PROTOCOL_SHARE, }, + }) + .try_to_vec()?; + + let init_pair_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) + .instruction(init_pair_ix) .signer(&base_keypair) - .args(ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_position.rs b/cli/src/instructions/initialize_position.rs index 85bf61c8..448a5d86 100644 --- a/cli/src/instructions/initialize_position.rs +++ b/cli/src/instructions/initialize_position.rs @@ -1,71 +1,58 @@ -use std::ops::Deref; +use crate::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::signature::Keypair; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_lang::prelude::AccountMeta; -use anchor_lang::ToAccountMetas; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::utils::pda::derive_event_authority_pda; -use mpl_token_metadata::accounts::Metadata; -use spl_associated_token_account::get_associated_token_address; - -#[derive(Debug)] -pub struct InitPositionParameters { +#[derive(Debug, Parser)] +pub struct InitPositionParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Lower bound of the bin range. + #[clap(long, allow_negative_numbers = true)] pub lower_bin_id: i32, + /// Width of the position. Start with 1 until 70. pub width: i32, - pub nft_mint: Option, } -pub async fn initialize_position + Clone>( - params: InitPositionParameters, +pub async fn execute_initialize_position + Clone>( + params: InitPositionParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result { - let InitPositionParameters { + let InitPositionParams { lb_pair, lower_bin_id, width, - nft_mint, } = params; let position_keypair = Keypair::new(); let (event_authority, _bump) = derive_event_authority_pda(); - let mut accounts = accounts::InitializePosition { + let accounts: [AccountMeta; INITIALIZE_POSITION_IX_ACCOUNTS_LEN] = InitializePositionKeys { lb_pair, payer: program.payer(), position: position_keypair.pubkey(), owner: program.payer(), - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, + rent: solana_sdk::sysvar::rent::ID, + system_program: solana_sdk::system_program::ID, event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None); - - if let Some(nft_mint) = nft_mint { - let nft_ata = get_associated_token_address(&program.payer(), &nft_mint); - let (nft_metadata, _bump) = Metadata::find_pda(&nft_mint); - - accounts.push(AccountMeta::new_readonly(nft_ata, false)); - accounts.push(AccountMeta::new_readonly(nft_metadata, false)); + program: dlmm_interface::ID, } + .into(); - let ix = instruction::InitializePosition { + let data = InitializePositionIxData(InitializePositionIxArgs { lower_bin_id, width, + }) + .try_to_vec()?; + + let init_position_ix = Instruction { + program_id: dlmm_interface::ID, + data, + accounts: accounts.to_vec(), }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(init_position_ix) .signer(&position_keypair) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_position_with_price_range.rs b/cli/src/instructions/initialize_position_with_price_range.rs index d6573e99..1f6699ab 100644 --- a/cli/src/instructions/initialize_position_with_price_range.rs +++ b/cli/src/instructions/initialize_position_with_price_range.rs @@ -1,38 +1,36 @@ -use std::ops::Deref; - -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anyhow::*; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::state::lb_pair::LbPair; +use crate::*; +use instructions::*; use rust_decimal::Decimal; -use crate::math::get_id_from_price; - -use super::initialize_position::{initialize_position, InitPositionParameters}; - -#[derive(Debug)] -pub struct InitPositionWithPriceRangeParameters { +#[derive(Debug, Parser)] +pub struct InitPositionWithPriceRangeParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Lower bound of the price. pub lower_price: f64, + /// Width of the position. Start with 1 until 70. pub width: i32, - pub nft_mint: Option, } -pub async fn initialize_position_with_price_range + Clone>( - params: InitPositionWithPriceRangeParameters, +pub async fn execute_initialize_position_with_price_range< + C: Deref + Clone, +>( + params: InitPositionWithPriceRangeParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result { - let InitPositionWithPriceRangeParameters { + let InitPositionWithPriceRangeParams { lb_pair, lower_price, width, - nft_mint, } = params; - let lb_pair_state = program.account::(lb_pair).await?; + let rpc_client = program.async_rpc(); + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let lower_bin_id = get_id_from_price( lb_pair_state.bin_step, @@ -41,12 +39,11 @@ pub async fn initialize_position_with_price_range ) .context("get_id_from_price overflow")?; - let params = InitPositionParameters { + let params = InitPositionParams { lb_pair, lower_bin_id, width, - nft_mint, }; - initialize_position(params, program, transaction_config).await + execute_initialize_position(params, program, transaction_config).await } diff --git a/cli/src/instructions/initialize_preset_parameter.rs b/cli/src/instructions/initialize_preset_parameter.rs index 92cfee2a..f483a678 100644 --- a/cli/src/instructions/initialize_preset_parameter.rs +++ b/cli/src/instructions/initialize_preset_parameter.rs @@ -1,16 +1,11 @@ -use std::ops::Deref; +use solana_client::{ + rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, + rpc_filter::{Memcmp, RpcFilterType}, +}; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; +use crate::*; -use anchor_lang::ToAccountMetas; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::instructions::admin::initialize_preset_parameters::InitPresetParametersIx; -use lb_clmm::utils::pda::derive_preset_parameter_pda2; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct InitPresetParameters { /// Bin step. Represent the price increment / decrement. pub bin_step: u16, @@ -26,15 +21,13 @@ pub struct InitPresetParameters { pub variable_fee_control: u32, /// Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate. pub max_volatility_accumulator: u32, - /// Min bin id supported by the pool based on the configured bin step. - pub min_bin_id: i32, - /// Max bin id supported by the pool based on the configured bin step. - pub max_bin_id: i32, /// Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee pub protocol_share: u16, + /// Base fee power factor + pub base_fee_power_factor: u8, } -pub async fn initialize_preset_parameter + Clone>( +pub async fn execute_initialize_preset_parameter + Clone>( params: InitPresetParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -44,26 +37,53 @@ pub async fn initialize_preset_parameter + Clone> bin_step, decay_period, filter_period, - max_bin_id, max_volatility_accumulator, - min_bin_id, protocol_share, reduction_factor, variable_fee_control, + base_fee_power_factor, } = params; - let (preset_parameter, _bump) = derive_preset_parameter_pda2(bin_step, base_factor); + let rpc_client = program.async_rpc(); + + let preset_parameter_v2_count = rpc_client + .get_program_accounts_with_config( + &dlmm_interface::ID, + RpcProgramAccountsConfig { + filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( + 0, + &PRESET_PARAMETER2_ACCOUNT_DISCM, + ))]), + account_config: RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + data_slice: Some(UiDataSliceConfig { + offset: 0, + length: 0, + }), + ..Default::default() + }, + ..Default::default() + }, + ) + .await? + .len(); + + let index = preset_parameter_v2_count as u16; - let accounts = accounts::InitializePresetParameter { - preset_parameter, - admin: program.payer(), - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, - } - .to_account_metas(None); + let (preset_parameter, _bump) = + derive_preset_parameter_pda_v2(preset_parameter_v2_count as u16); - let ix = instruction::InitializePresetParameter { - ix: InitPresetParametersIx { + let accounts: [AccountMeta; INITIALIZE_PRESET_PARAMETER2_IX_ACCOUNTS_LEN] = + InitializePresetParameter2Keys { + preset_parameter, + admin: program.payer(), + system_program: solana_sdk::system_program::ID, + } + .into(); + + let data = InitializePresetParameter2IxData(InitializePresetParameter2IxArgs { + ix: InitPresetParameters2Ix { + index, bin_step, base_factor, filter_period, @@ -71,16 +91,21 @@ pub async fn initialize_preset_parameter + Clone> reduction_factor, variable_fee_control, max_volatility_accumulator, - min_bin_id, - max_bin_id, protocol_share, + base_fee_power_factor, }, + }) + .try_to_vec()?; + + let init_preset_param_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(init_preset_param_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/initialize_reward.rs b/cli/src/instructions/initialize_reward.rs index 8b4384e7..2ca4b958 100644 --- a/cli/src/instructions/initialize_reward.rs +++ b/cli/src/instructions/initialize_reward.rs @@ -1,13 +1,6 @@ -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use lb_clmm::utils::pda::derive_event_authority_pda; -use std::ops::Deref; +use crate::*; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct InitializeRewardParams { pub lb_pair: Pubkey, pub reward_mint: Pubkey, @@ -16,7 +9,7 @@ pub struct InitializeRewardParams { pub funder: Pubkey, } -pub async fn initialize_reward + Clone>( +pub async fn execute_initialize_reward + Clone>( params: InitializeRewardParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -29,35 +22,50 @@ pub async fn initialize_reward + Clone>( funder, } = params; - let (reward_vault, _bump) = Pubkey::find_program_address( - &[lb_pair.as_ref(), reward_index.to_le_bytes().as_ref()], - &lb_clmm::ID, - ); - + let (reward_vault, _bump) = derive_reward_vault_pda(lb_pair, reward_index); let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::InitializeReward { + let rpc_client = program.async_rpc(); + let reward_mint_account = rpc_client.get_account(&reward_mint).await?; + + let (token_badge, _bump) = derive_token_badge_pda(reward_mint); + let token_badge = rpc_client + .get_account(&token_badge) + .await + .ok() + .map(|_| token_badge) + .unwrap_or(dlmm_interface::ID); + + let accounts: [AccountMeta; INITIALIZE_REWARD_IX_ACCOUNTS_LEN] = InitializeRewardKeys { lb_pair, reward_vault, reward_mint, admin: program.payer(), - token_program: anchor_spl::token::ID, - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, + token_program: reward_mint_account.owner, + token_badge, + rent: solana_sdk::sysvar::rent::ID, + system_program: solana_sdk::system_program::ID, event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + } + .into(); - let ix: instruction::InitializeReward = instruction::InitializeReward { + let data = InitializeRewardIxData(InitializeRewardIxArgs { reward_index, reward_duration, funder, + }) + .try_to_vec()?; + + let instruction = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(instruction) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/list_all_binstep.rs b/cli/src/instructions/list_all_binstep.rs index 16a37934..728c964a 100644 --- a/cli/src/instructions/list_all_binstep.rs +++ b/cli/src/instructions/list_all_binstep.rs @@ -1,22 +1,94 @@ -use anchor_client::{solana_sdk::signer::Signer, Program}; -use lb_clmm::constants::FEE_PRECISION; -use lb_clmm::state::preset_parameters::PresetParameter; -use std::ops::Deref; +use solana_client::{ + rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, + rpc_filter::{Memcmp, RpcFilterType}, +}; -use anyhow::*; +use crate::*; -pub async fn list_all_binstep + Clone>( +pub async fn execute_list_all_bin_step + Clone>( program: &Program, ) -> Result<()> { - let preset_parameters = program.accounts::(vec![]).await?; - - for (key, param) in preset_parameters { - let base_fee = (param.bin_step as u128 * param.base_factor as u128 * 1000) as f64 - / FEE_PRECISION as f64; - println!( - "Preset Pubkey: {}. Bin step {}. Base fee: {}%", - key, param.bin_step, base_fee - ); + let rpc_client = program.async_rpc(); + + let account_config = RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + data_slice: Some(UiDataSliceConfig { + offset: 0, + length: 0, + }), + ..Default::default() + }; + + let preset_parameter_keys = rpc_client + .get_program_accounts_with_config( + &dlmm_interface::ID, + RpcProgramAccountsConfig { + filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( + 0, + &PRESET_PARAMETER_ACCOUNT_DISCM, + ))]), + account_config: account_config.clone(), + ..Default::default() + }, + ) + .await? + .into_iter() + .map(|(key, _)| key) + .collect::>(); + + let preset_parameter_v2_keys = rpc_client + .get_program_accounts_with_config( + &dlmm_interface::ID, + RpcProgramAccountsConfig { + filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new_base58_encoded( + 0, + &PRESET_PARAMETER2_ACCOUNT_DISCM, + ))]), + account_config, + ..Default::default() + }, + ) + .await? + .into_iter() + .map(|(key, _)| key) + .collect::>(); + + let all_versioned_keys = [preset_parameter_keys, preset_parameter_v2_keys].concat(); + + for keys in all_versioned_keys.chunks(100) { + let accounts = rpc_client.get_multiple_accounts(keys).await?; + for (key, account) in keys.iter().zip(accounts) { + if let Some(account) = account { + let mut disc = [0u8; 8]; + disc.copy_from_slice(&account.data[..8]); + + let (bin_step, base_factor, base_fee_power_factor) = match disc { + PRESET_PARAMETER_ACCOUNT_DISCM => { + let state = PresetParameterAccount::deserialize(&account.data)?.0; + (state.bin_step, state.base_factor, 0) + } + PRESET_PARAMETER2_ACCOUNT_DISCM => { + let state = PresetParameter2Account::deserialize(&account.data)?.0; + ( + state.bin_step, + state.base_factor, + state.base_fee_power_factor, + ) + } + _ => continue, + }; + + let base_fee = (u128::from(bin_step) + * u128::from(base_factor).pow(base_fee_power_factor.into()) + * 1000) as f64 + / FEE_PRECISION as f64; + + println!( + "Preset Pubkey: {}. Bin step {}. Base fee: {}%", + key, bin_step, base_fee + ); + } + } } Ok(()) diff --git a/cli/src/instructions/mod.rs b/cli/src/instructions/mod.rs index eef7053f..575ebd64 100644 --- a/cli/src/instructions/mod.rs +++ b/cli/src/instructions/mod.rs @@ -1,38 +1,113 @@ pub mod add_liquidity; -pub mod check_my_balance; +pub use add_liquidity::*; + pub mod claim_fee; +pub use claim_fee::*; + pub mod claim_reward; +pub use claim_reward::*; + pub mod close_position; +pub use close_position::*; + pub mod close_preset_parameter; +pub use close_preset_parameter::*; + pub mod fund_reward; +pub use fund_reward::*; + pub mod increase_length; +pub use increase_length::*; + pub mod initialize_bin_array; +pub use initialize_bin_array::*; + pub mod initialize_bin_array_with_bin_range; +pub use initialize_bin_array_with_bin_range::*; + pub mod initialize_bin_array_with_price_range; +pub use initialize_bin_array_with_price_range::*; + pub mod initialize_customizable_permissionless_lb_pair; +pub use initialize_customizable_permissionless_lb_pair::*; + pub mod initialize_lb_pair; +pub use initialize_lb_pair::*; + pub mod initialize_permission_lb_pair; +pub use initialize_permission_lb_pair::*; + pub mod initialize_position; +pub use initialize_position::*; + pub mod initialize_position_with_price_range; +pub use initialize_position_with_price_range::*; + pub mod initialize_preset_parameter; +pub use initialize_preset_parameter::*; + pub mod initialize_reward; +pub use initialize_reward::*; + pub mod list_all_binstep; +pub use list_all_binstep::*; + pub mod remove_liquidity; +pub use remove_liquidity::*; + pub mod remove_liquidity_by_price_range; +pub use remove_liquidity_by_price_range::*; + pub mod seed_liquidity; +pub use seed_liquidity::*; + pub mod seed_liquidity_from_operator; +pub use seed_liquidity_from_operator::*; + pub mod seed_liquidity_single_bin; +pub use seed_liquidity_single_bin::*; + pub mod seed_liquidity_single_bin_by_operator; +pub use seed_liquidity_single_bin_by_operator::*; + pub mod set_activation_point; +pub use set_activation_point::*; + pub mod set_pre_activation_duration; +pub use set_pre_activation_duration::*; + pub mod set_pre_activation_swap_address; +pub use set_pre_activation_swap_address::*; + pub mod show_pair; -pub mod simulate_swap_demand; +pub use show_pair::*; + pub mod swap_exact_in; +pub use swap_exact_in::*; + pub mod swap_exact_out; +pub use swap_exact_out::*; + pub mod swap_with_price_impact; +pub use swap_with_price_impact::*; + pub mod toggle_pair_status; +pub use toggle_pair_status::*; + pub mod update_reward_duration; +pub use update_reward_duration::*; + pub mod update_reward_funder; -pub mod utils; +pub use update_reward_funder::*; + +mod utils; +pub use utils::*; + pub mod withdraw_protocol_fee; +pub use withdraw_protocol_fee::*; + +pub mod show_position; +pub use show_position::*; + +pub mod show_preset_parameters; +pub use show_preset_parameters::*; diff --git a/cli/src/instructions/remove_liquidity.rs b/cli/src/instructions/remove_liquidity.rs index 0670c494..2a16acd6 100644 --- a/cli/src/instructions/remove_liquidity.rs +++ b/cli/src/instructions/remove_liquidity.rs @@ -1,40 +1,45 @@ -use std::ops::Deref; +use crate::*; +use instructions::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; - -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::constants::BASIS_POINT_MAX; -use lb_clmm::instruction; -use lb_clmm::instructions::withdraw::remove_liquidity::BinLiquidityReduction; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::{derive_bin_array_bitmap_extension, derive_event_authority_pda}; - -use crate::instructions::utils::{get_bin_arrays_for_position, get_or_create_ata}; - -pub struct RemoveLiquidityParameters { +#[derive(Debug, Parser)] +pub struct RemoveLiquidityParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, - pub position: Pubkey, + /// Bin liquidity information to be remove. "" where + /// BIN_ID = bin id to withdraw + /// BPS_TO_REMOVE = Percentage of position owned share to be removed. Maximum is 1.0f, which equivalent to 100%. + #[clap(long, value_parser = parse_bin_liquidity_removal, value_delimiter = ' ', allow_hyphen_values = true)] pub bin_liquidity_removal: Vec<(i32, f64)>, + /// Position to be withdraw. + pub position: Pubkey, } -pub async fn remove_liquidity + Clone>( - params: RemoveLiquidityParameters, +pub async fn execute_remove_liquidity + Clone>( + params: RemoveLiquidityParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let RemoveLiquidityParameters { + let RemoveLiquidityParams { lb_pair, position, bin_liquidity_removal, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); - let [bin_array_lower, bin_array_upper] = get_bin_arrays_for_position(program, position).await?; + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair, position]) + .await?; + + let lb_pair_account = accounts[0].take().context("lb_pair not found")?; + let position_account = accounts[1].take().context("position not found")?; + + let lb_pair_state = LbPairAccount::deserialize(&lb_pair_account.data)?.0; + let position_state = DynamicPosition::deserialize(&position_account.data)?; + + let bin_arrays_account_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; let user_token_x = get_or_create_ata( program, @@ -52,38 +57,52 @@ pub async fn remove_liquidity + Clone>( ) .await?; - // TODO: id and price slippage let (bin_array_bitmap_extension, _bump) = derive_bin_array_bitmap_extension(lb_pair); - let bin_array_bitmap_extension = if program - .rpc() + let bin_array_bitmap_extension = rpc_client .get_account(&bin_array_bitmap_extension) - .is_err() + .await + .map(|_| bin_array_bitmap_extension) + .unwrap_or(dlmm_interface::ID); + + let (event_authority, _bump) = derive_event_authority_pda(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? { - None - } else { - Some(bin_array_bitmap_extension) + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); }; - let (event_authority, _bump) = derive_event_authority_pda(); + remaining_accounts.extend(bin_arrays_account_meta); + + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; - let accounts = accounts::ModifyLiquidity { - bin_array_lower, - bin_array_upper, + let main_accounts: [AccountMeta; REMOVE_LIQUIDITY2_IX_ACCOUNTS_LEN] = RemoveLiquidity2Keys { + position, lb_pair, bin_array_bitmap_extension, - position, + user_token_x, + user_token_y, reserve_x: lb_pair_state.reserve_x, reserve_y: lb_pair_state.reserve_y, token_x_mint: lb_pair_state.token_x_mint, + token_x_program, token_y_mint: lb_pair_state.token_y_mint, + token_y_program, sender: program.payer(), - user_token_x, - user_token_y, - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, + memo_program: spl_memo::ID, event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + } + .into(); let bin_liquidity_removal = bin_liquidity_removal .into_iter() @@ -93,8 +112,18 @@ pub async fn remove_liquidity + Clone>( }) .collect::>(); - let ix = instruction::RemoveLiquidity { + let data = RemoveLiquidity2IxData(RemoveLiquidity2IxArgs { bin_liquidity_removal, + remaining_accounts_info, + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let remove_liquidity_ix = Instruction { + program_id: dlmm_interface::ID, + data, + accounts, }; let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); @@ -102,8 +131,7 @@ pub async fn remove_liquidity + Clone>( let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .args(ix) + .instruction(remove_liquidity_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/remove_liquidity_by_price_range.rs b/cli/src/instructions/remove_liquidity_by_price_range.rs index 22a966f0..50c335b0 100644 --- a/cli/src/instructions/remove_liquidity_by_price_range.rs +++ b/cli/src/instructions/remove_liquidity_by_price_range.rs @@ -1,33 +1,21 @@ -use crate::instructions::utils::get_or_create_ata; -use crate::math::{get_id_from_price, price_per_token_to_per_lamport}; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::solana_sdk::instruction::Instruction; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_lang::InstructionData; -use anchor_lang::ToAccountMetas; -use anchor_spl::token::Mint; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::constants::MAX_BIN_PER_POSITION; -use lb_clmm::instruction; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::state::position::Position; -use lb_clmm::utils::pda::*; -use std::ops::Deref; -use std::result::Result::Ok; - -#[derive(Debug)] +use crate::*; +use anchor_lang::AccountDeserialize; +use anchor_spl::token_interface::Mint; +use instructions::*; + +#[derive(Debug, Parser)] pub struct RemoveLiquidityByPriceRangeParameters { + /// Address of the pair pub lb_pair: Pubkey, + // base position path pub base_position_key: Pubkey, + /// min price pub min_price: f64, + /// max price pub max_price: f64, } -pub async fn remove_liquidity_by_price_range + Clone>( +pub async fn execute_remove_liquidity_by_price_range + Clone>( params: RemoveLiquidityByPriceRangeParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -39,11 +27,26 @@ pub async fn remove_liquidity_by_price_range + Cl max_price, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + let bin_step = lb_pair_state.bin_step; + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; + + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair_state.token_x_mint, lb_pair_state.token_y_mint]) + .await?; + + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let min_price_per_lamport = price_per_token_to_per_lamport( min_price, @@ -51,6 +54,7 @@ pub async fn remove_liquidity_by_price_range + Cl token_mint_quote.decimals, ) .context("price_per_token_to_per_lamport overflow")?; + let min_active_id = get_id_from_price(bin_step, &min_price_per_lamport, Rounding::Up) .context("get_id_from_price overflow")?; @@ -60,123 +64,172 @@ pub async fn remove_liquidity_by_price_range + Cl token_mint_quote.decimals, ) .context("price_per_token_to_per_lamport overflow")?; + let max_active_id = get_id_from_price(bin_step, &max_price_per_lamport, Rounding::Up) .context("get_id_from_price overflow")?; assert!(min_active_id < max_active_id); - println!("go here"); - let width = MAX_BIN_PER_POSITION as i32; + let user_token_x = get_or_create_ata( + program, + transaction_config, + lb_pair_state.token_x_mint, + program.payer(), + ) + .await?; + + let user_token_y = get_or_create_ata( + program, + transaction_config, + lb_pair_state.token_y_mint, + program.payer(), + ) + .await?; + + let (event_authority, _bump) = derive_event_authority_pda(); + + let (bin_array_bitmap_extension, _bump) = derive_bin_array_bitmap_extension(lb_pair); + let bin_array_bitmap_extension = rpc_client + .get_account(&bin_array_bitmap_extension) + .await + .map(|_| bin_array_bitmap_extension) + .unwrap_or(dlmm_interface::ID); + + let width = DEFAULT_BIN_PER_POSITION as i32; + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut transfer_hook_remaining_accounts = vec![]; + + if let Some((slices, remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + transfer_hook_remaining_accounts.extend(remaining_accounts); + }; + for i in min_active_id..=max_active_id { let (position, _bump) = derive_position_pda(lb_pair, base_position_key, i, width); - // if program.rpc().get_account_data(&position).is_ok() { - // let position_state: Position = program.account(position)?; - // println!("{position_state:?}"); - // } - // continue; - - match program.account::(position).await { - Ok(position_state) => { - let lower_bin_array_idx = - BinArray::bin_id_to_bin_array_index(position_state.lower_bin_id)?; - let upper_bin_array_idx = - lower_bin_array_idx.checked_add(1).context("MathOverflow")?; - - let (bin_array_lower, _bump) = - derive_bin_array_pda(lb_pair, lower_bin_array_idx.into()); - let (bin_array_upper, _bump) = - derive_bin_array_pda(lb_pair, upper_bin_array_idx.into()); - let user_token_x = get_or_create_ata( - program, - transaction_config, - lb_pair_state.token_x_mint, - program.payer(), - ) - .await?; - - let user_token_y = get_or_create_ata( - program, - transaction_config, - lb_pair_state.token_y_mint, - program.payer(), - ) - .await?; - let (event_authority, _bump) = derive_event_authority_pda(); - - let instructions = vec![ - ComputeBudgetInstruction::set_compute_unit_limit(1_400_000), - Instruction { - program_id: lb_clmm::ID, - accounts: accounts::ModifyLiquidity { - bin_array_lower, - bin_array_upper, - lb_pair, - bin_array_bitmap_extension: None, - position, - reserve_x: lb_pair_state.reserve_x, - reserve_y: lb_pair_state.reserve_y, - token_x_mint: lb_pair_state.token_x_mint, - token_y_mint: lb_pair_state.token_y_mint, - sender: program.payer(), - user_token_x, - user_token_y, - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, - event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::RemoveAllLiquidity {}.data(), - }, - Instruction { - program_id: lb_clmm::ID, - accounts: accounts::ClaimFee { - bin_array_lower, - bin_array_upper, - lb_pair, - sender: program.payer(), - position, - reserve_x: lb_pair_state.reserve_x, - reserve_y: lb_pair_state.reserve_y, - token_program: anchor_spl::token::ID, - token_x_mint: lb_pair_state.token_x_mint, - token_y_mint: lb_pair_state.token_y_mint, - user_token_x, - user_token_y, - event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::ClaimFee {}.data(), - }, - Instruction { - program_id: lb_clmm::ID, - accounts: accounts::ClosePosition { - lb_pair, - position, - bin_array_lower, - bin_array_upper, - rent_receiver: program.payer(), - sender: program.payer(), - event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::ClosePosition {}.data(), - }, - ]; - - let builder = program.request(); - let builder = instructions - .into_iter() - .fold(builder, |bld, ix| bld.instruction(ix)); - let signature = builder - .send_with_spinner_and_config(transaction_config) - .await?; - println!("close popsition min_bin_id {i} {signature}"); + let position_account = rpc_client.get_account(&position).await; + if let std::result::Result::Ok(account) = position_account { + let position_state = DynamicPosition::deserialize(account.data.as_ref())?; + + let bin_arrays_account_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; + + let remaining_accounts = [ + transfer_hook_remaining_accounts.clone(), + bin_arrays_account_meta, + ] + .concat(); + + let mut instructions = + vec![ComputeBudgetInstruction::set_compute_unit_limit(1_400_000)]; + + let main_accounts: [AccountMeta; REMOVE_LIQUIDITY_BY_RANGE2_IX_ACCOUNTS_LEN] = + RemoveLiquidityByRange2Keys { + position, + lb_pair, + bin_array_bitmap_extension, + user_token_x, + user_token_y, + reserve_x: lb_pair_state.reserve_x, + reserve_y: lb_pair_state.reserve_y, + token_x_mint: lb_pair_state.token_x_mint, + token_y_mint: lb_pair_state.token_y_mint, + sender: program.payer(), + token_x_program, + token_y_program, + memo_program: spl_memo::ID, + event_authority, + program: dlmm_interface::ID, + } + .into(); + + let data = RemoveLiquidityByRange2IxData(RemoveLiquidityByRange2IxArgs { + from_bin_id: position_state.global_data.lower_bin_id, + to_bin_id: position_state.global_data.upper_bin_id, + bps_to_remove: BASIS_POINT_MAX as u16, + remaining_accounts_info: remaining_accounts_info.clone(), + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts.clone()].concat(); + + let withdraw_all_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; + + instructions.push(withdraw_all_ix); + + let main_accounts: [AccountMeta; CLAIM_FEE2_IX_ACCOUNTS_LEN] = ClaimFee2Keys { + lb_pair, + position, + sender: program.payer(), + reserve_x: lb_pair_state.reserve_x, + reserve_y: lb_pair_state.reserve_y, + token_x_mint: lb_pair_state.token_x_mint, + token_y_mint: lb_pair_state.token_y_mint, + token_program_x: token_x_program, + token_program_y: token_y_program, + memo_program: spl_memo::ID, + event_authority, + program: dlmm_interface::ID, + user_token_x, + user_token_y, } - Err(_err) => continue, + .into(); + + let data = ClaimFee2IxData(ClaimFee2IxArgs { + min_bin_id: position_state.global_data.lower_bin_id, + max_bin_id: position_state.global_data.upper_bin_id, + remaining_accounts_info: remaining_accounts_info.clone(), + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts.clone()].concat(); + + let claim_fee_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; + + instructions.push(claim_fee_ix); + + let accounts: [AccountMeta; CLOSE_POSITION2_IX_ACCOUNTS_LEN] = ClosePosition2Keys { + position, + sender: program.payer(), + rent_receiver: program.payer(), + event_authority, + program: dlmm_interface::ID, + } + .into(); + + let data = ClosePosition2IxData.try_to_vec()?; + + let close_position_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, + }; + + instructions.push(close_position_ix); + + println!( + "Close position {}. Min bin id {}, Max bin id {}", + position, + position_state.global_data.lower_bin_id, + position_state.global_data.upper_bin_id + ); } } Ok(()) diff --git a/cli/src/instructions/seed_liquidity.rs b/cli/src/instructions/seed_liquidity.rs index 76074b1b..b0fe91bb 100644 --- a/cli/src/instructions/seed_liquidity.rs +++ b/cli/src/instructions/seed_liquidity.rs @@ -1,32 +1,16 @@ -use std::collections::HashMap; -use std::fs::File; -use std::io::{BufReader, BufWriter, Write}; -use std::ops::Deref; - -use crate::instructions::utils::get_or_create_ata; -use crate::math::{get_id_from_price, price_per_token_to_per_lamport}; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::solana_sdk::instruction::Instruction; -use anchor_client::solana_sdk::signature::Keypair; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_lang::InstructionData; -use anchor_lang::ToAccountMetas; -use anchor_spl::token::Mint; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::constants::{BASIS_POINT_MAX, MAX_BIN_PER_POSITION}; -use lb_clmm::instruction; -use lb_clmm::instructions::deposit::{BinLiquidityDistribution, LiquidityParameter}; -use lb_clmm::math::u128x128_math::Rounding; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::state::position::PositionV2; -use lb_clmm::utils::pda::*; -use rust_decimal::prelude::ToPrimitive; +use crate::*; +use anchor_lang::system_program; +use anchor_lang::AccountDeserialize; +use anchor_spl::token_interface::Mint; +use instructions::*; use serde::{Deserialize, Serialize}; use serde_json_any_key::*; - +use solana_sdk::sysvar; +use std::{ + collections::HashMap, + fs::File, + io::{BufReader, BufWriter, Write}, +}; #[derive(Serialize, Deserialize, Default)] pub struct DustDepositState { pub lb_pair: Pubkey, @@ -92,9 +76,9 @@ pub fn get_number_of_position_required_to_cover_range( .checked_sub(min_bin_id) .context("bin_delta overflow")?; let mut position_required = bin_delta - .checked_div(MAX_BIN_PER_POSITION as i32) + .checked_div(DEFAULT_BIN_PER_POSITION as i32) .context("position_required overflow")?; - let rem = bin_delta % MAX_BIN_PER_POSITION as i32; + let rem = bin_delta % DEFAULT_BIN_PER_POSITION as i32; if rem > 0 { position_required += 1; @@ -113,40 +97,51 @@ async fn get_or_create_position + Clone>( owner: &Keypair, transaction_config: RpcSendTransactionConfig, compute_unit_price_ix: Option, -) -> Result { +) -> Result { let (event_authority, _bump) = derive_event_authority_pda(); let base = base_keypair.pubkey(); + let rpc_client = program.async_rpc(); + let (position, _bump) = derive_position_pda(lb_pair, base, lower_bin_id, width); - if program.rpc().get_account_data(&position).is_err() { - let ix = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::InitializePositionPda { + if rpc_client.get_account_data(&position).await.is_err() { + let accounts: [AccountMeta; INITIALIZE_POSITION_PDA_IX_ACCOUNTS_LEN] = + InitializePositionPdaKeys { lb_pair, base, owner: owner.pubkey(), payer: program.payer(), position, - rent: anchor_client::solana_sdk::sysvar::rent::ID, - system_program: anchor_client::solana_sdk::system_program::ID, + rent: sysvar::rent::ID, + system_program: system_program::ID, event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::InitializePositionPda { - lower_bin_id, - width, + program: dlmm_interface::ID, } - .data(), + .into(); + + let data = InitializePositionPdaIxData(InitializePositionPdaIxArgs { + lower_bin_id, + width, + }) + .try_to_vec()?; + + let initialize_position_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; + let mut builder = program.request(); if let Some(compute_unit_price_ix) = compute_unit_price_ix { builder = builder.instruction(compute_unit_price_ix); } - builder = builder.instruction(ix).signer(base_keypair).signer(owner); + builder = builder + .instruction(initialize_position_ix) + .signer(base_keypair) + .signer(owner); let signature = builder .send_with_spinner_and_config(transaction_config) .await; @@ -157,7 +152,11 @@ async fn get_or_create_position + Clone>( signature?; } - let position_state: PositionV2 = program.account(position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; Ok(position_state) } @@ -165,7 +164,7 @@ async fn get_or_create_position + Clone>( pub async fn deposit + Clone>( program: &Program, position: Pubkey, - position_state: &PositionV2, + position_state: &DynamicPosition, lb_pair_state: &LbPair, user_token_x: Pubkey, user_token_y: Pubkey, @@ -184,43 +183,66 @@ pub async fn deposit + Clone>( vec![ComputeBudgetInstruction::set_compute_unit_limit(800_000)] }; - let lower_bin_array_idx = BinArray::bin_id_to_bin_array_index(position_state.lower_bin_id)?; + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; + + let bin_array_accounts_meta = position_state + .global_data + .get_bin_array_accounts_meta_coverage()?; + + let main_accounts: [AccountMeta; ADD_LIQUIDITY2_IX_ACCOUNTS_LEN] = AddLiquidity2Keys { + lb_pair: position_state.global_data.lb_pair, + position, + sender: program.payer(), + event_authority, + program: dlmm_interface::ID, + reserve_x: lb_pair_state.reserve_x, + reserve_y: lb_pair_state.reserve_y, + token_x_mint: lb_pair_state.token_x_mint, + token_y_mint: lb_pair_state.token_y_mint, + user_token_x, + user_token_y, + token_x_program, + token_y_program, + memo_program: spl_memo::ID, + bin_array_bitmap_extension: dlmm_interface::ID, + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; - let (bin_array_lower, _bump) = - derive_bin_array_pda(position_state.lb_pair, lower_bin_array_idx.into()); - let (bin_array_upper, _bump) = - derive_bin_array_pda(position_state.lb_pair, (lower_bin_array_idx + 1).into()); + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); + } - instructions.push(Instruction { - program_id: lb_clmm::ID, - accounts: accounts::ModifyLiquidity { - lb_pair: position_state.lb_pair, - position, - bin_array_bitmap_extension: None, - bin_array_lower, - bin_array_upper, - sender: program.payer(), - event_authority, - program: lb_clmm::ID, - reserve_x: lb_pair_state.reserve_x, - reserve_y: lb_pair_state.reserve_y, - token_x_mint: lb_pair_state.token_x_mint, - token_y_mint: lb_pair_state.token_y_mint, - user_token_x, - user_token_y, - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, - } - .to_account_metas(None), - data: instruction::AddLiquidity { - liquidity_parameter: LiquidityParameter { - amount_x: deposit_amount_x, - amount_y: 0, - bin_liquidity_dist: position_liquidity_distribution, - }, - } - .data(), - }); + remaining_accounts.extend(bin_array_accounts_meta); + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let data = AddLiquidityIxData(AddLiquidityIxArgs { + liquidity_parameter: LiquidityParameter { + amount_x: deposit_amount_x, + amount_y: deposit_amount_x, + bin_liquidity_dist: position_liquidity_distribution, + }, + }) + .try_to_vec()?; + + let deposit_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; + + instructions.push(deposit_ix); let builder = program.request(); let builder = instructions @@ -233,7 +255,7 @@ pub async fn deposit + Clone>( println!( "Seed liquidity min_bin_id {} max_bin_id {} Position {position}. Sig: {:#?}", - position_state.lower_bin_id, position_state.upper_bin_id, signature + position_state.global_data.lower_bin_id, position_state.global_data.upper_bin_id, signature ); Ok(signature?.to_string()) @@ -249,25 +271,31 @@ pub async fn create_position_bin_array_if_not_exists + Clone>( max_bin_id: i32, program: &Program, ) -> Result<(HashMap, u64)> { + let rpc_client = program.async_rpc(); let start_bin_array_index = BinArray::bin_id_to_bin_array_index(min_bin_id)?; let end_bin_array_index = BinArray::bin_id_to_bin_array_index(max_bin_id)?; @@ -358,7 +387,12 @@ pub async fn get_on_chain_bins_amount_x + Clone>( for bin_array_idx in start_bin_array_index..=end_bin_array_index { let (bin_array_pubkey, _bump) = derive_bin_array_pda(lb_pair, bin_array_idx.into()); - let bin_array = program.account::(bin_array_pubkey).await?; + + let bin_array = rpc_client + .get_account_and_deserialize(&bin_array_pubkey, |account| { + Ok(BinArrayAccount::deserialize(&account.data)?.0) + }) + .await?; let (mut lower_bin_id, _) = BinArray::get_bin_array_lower_upper_bin_id(bin_array_idx)?; @@ -430,19 +464,38 @@ pub fn write_dust_deposit_state(path: &str, dust_deposit_state: &DustDepositStat Ok(()) } -#[derive(Debug)] +#[derive(Debug, Parser, Clone)] pub struct SeedLiquidityParameters { + /// Address of the pair + #[clap(long)] pub lb_pair: Pubkey, - pub position_base_kp: Keypair, + /// Base position path + #[clap(long)] + pub base_position_path: String, + /// Amount of x + #[clap(long)] pub amount: u64, + /// Min price + #[clap(long)] pub min_price: f64, + /// Max price + #[clap(long)] pub max_price: f64, + /// Base pubkey + #[clap(long)] pub base_pubkey: Pubkey, - pub position_owner_kp: Keypair, + /// Curvature + #[clap(long)] pub curvature: f64, + /// Position owner path + #[clap(long)] + pub position_owner_path: String, + /// Max retries + #[clap(long)] + pub max_retries: u16, } -pub async fn seed_liquidity + Clone>( +pub async fn execute_seed_liquidity + Clone>( params: SeedLiquidityParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -450,15 +503,24 @@ pub async fn seed_liquidity + Clone>( ) -> Result<()> { let SeedLiquidityParameters { lb_pair, - position_base_kp, amount, min_price, max_price, - position_owner_kp, + position_owner_path, + base_position_path, base_pubkey, curvature, + .. } = params; + let position_base_kp = + read_keypair_file(base_position_path).expect("position base keypair file not found"); + + let position_owner_kp = + read_keypair_file(position_owner_path).expect("position owner keypair file not found"); + + let rpc_client = program.async_rpc(); + let progress_file_path = format!("{}_progress.json", lb_pair); let mut dust_deposit_state = read_dust_deposit_state(&progress_file_path)?; @@ -478,11 +540,23 @@ pub async fn seed_liquidity + Clone>( "Invalid position base key" ); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + let bin_step = lb_pair_state.bin_step; - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair_state.token_x_mint, lb_pair_state.token_y_mint]) + .await?; + + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let fund_amount = to_wei_amount(amount, token_mint_base.decimals)?; @@ -546,11 +620,11 @@ pub async fn seed_liquidity + Clone>( .map(|(bin_id, amount_x)| (*bin_id, *amount_x)) .collect(); - let width = MAX_BIN_PER_POSITION as i32; + let width = DEFAULT_BIN_PER_POSITION as i32; for i in 0..position_number { - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * i); - let upper_bin_id = lower_bin_id + MAX_BIN_PER_POSITION as i32 - 1; + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * i); + let upper_bin_id = lower_bin_id + DEFAULT_BIN_PER_POSITION as i32 - 1; create_position_bin_array_if_not_exists( program, @@ -583,11 +657,11 @@ pub async fn seed_liquidity + Clone>( } assert_eq!( - position_state.lower_bin_id, lower_bin_id, + position_state.global_data.lower_bin_id, lower_bin_id, "Position lower bin id not equals" ); assert_eq!( - position_state.upper_bin_id, upper_bin_id, + position_state.global_data.upper_bin_id, upper_bin_id, "Position upper bin id not equals" ); @@ -633,13 +707,22 @@ pub async fn seed_liquidity + Clone>( dust_deposit_state.dust_amount = leftover; for i in 0..position_number { - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * i); + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * i); let (position, _bump) = derive_position_pda(lb_pair, position_base_kp.pubkey(), lower_bin_id, width); - let position_state = program.account::(position).await?; - let position_liquidity_shares = position_state.liquidity_shares.to_vec(); + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + + let position_liquidity_shares = position_state + .position_bin_data + .iter() + .map(|position_bin_data| position_bin_data.liquidity_share) + .collect(); dust_deposit_state .position_shares .insert(position, position_liquidity_shares); @@ -670,20 +753,29 @@ pub async fn seed_liquidity + Clone>( ); for i in 0..position_number { - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * i); + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * i); let (position, _bump) = derive_position_pda(lb_pair, position_base_kp.pubkey(), lower_bin_id, width); - let position_state: PositionV2 = program.account(position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; let position_share_snapshot = position_share.get(&position).context("Missing snapshot")?; let mut dust_deposited = false; - for (i, share) in position_state.liquidity_shares.iter().enumerate() { + for (i, share) in position_state + .position_bin_data + .iter() + .map(|position_bin_data| position_bin_data.liquidity_share) + .enumerate() + { let snapshot_share = position_share_snapshot[i]; - if snapshot_share != *share { + if snapshot_share != share { dust_deposited = true; break; } @@ -694,7 +786,8 @@ pub async fn seed_liquidity + Clone>( } // Don't deposit to the last bin because c(last_bin + 1) - c(last_bin) will > amount - let upper_bin_id = std::cmp::min(position_state.upper_bin_id, max_bin_id - 1); + let upper_bin_id = + std::cmp::min(position_state.global_data.upper_bin_id, max_bin_id - 1); assert!( upper_bin_id < max_bin_id, @@ -736,14 +829,19 @@ pub async fn seed_liquidity + Clone>( // Shall be dust after redistribute if leftover > 0 { println!("Deposit dust {} to last semi bin", leftover); - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * (position_number - 1)); + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * (position_number - 1)); let (position, _bump) = derive_position_pda(lb_pair, position_base_kp.pubkey(), lower_bin_id, width); - let position_state: PositionV2 = program.account(position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + // Don't deposit to the last bin because c(last_bin + 1) - c(last_bin) will > amount - let upper_bin_id = std::cmp::min(position_state.upper_bin_id, max_bin_id - 1); + let upper_bin_id = std::cmp::min(position_state.global_data.upper_bin_id, max_bin_id - 1); assert!(upper_bin_id < max_bin_id, "Funding to last bin id"); @@ -820,7 +918,7 @@ fn get_bin_deposit_amount( assert!(c1 > c0); let amount_into_bin = c1 - c0; - amount_into_bin.to_u64().unwrap() + amount_into_bin } // c(p) = 5 * 10^8 ((p - 0.1)/0.7) ^ 1.25, where P = ui price diff --git a/cli/src/instructions/seed_liquidity_from_operator.rs b/cli/src/instructions/seed_liquidity_from_operator.rs index 317f0fb8..150c5a26 100644 --- a/cli/src/instructions/seed_liquidity_from_operator.rs +++ b/cli/src/instructions/seed_liquidity_from_operator.rs @@ -1,32 +1,22 @@ use std::collections::HashMap; -use std::ops::Deref; -use crate::instructions::seed_liquidity::{ +use crate::*; +use anchor_lang::AccountDeserialize; +use anchor_spl::{ + associated_token::get_associated_token_address_with_program_id, token_interface::Mint, +}; +use instructions::*; +use seed_liquidity::{ convert_min_max_ui_price_to_min_max_bin_id, create_position_bin_array_if_not_exists, deposit, deposit_amount_to_deposit_parameter, generate_amount_for_bins, generate_redistribute_amount_to_position_based_on_ratio, get_number_of_position_required_to_cover_range, get_on_chain_bins_amount_x, get_ui_price_from_id, read_dust_deposit_state, to_wei_amount, write_dust_deposit_state, }; -use crate::instructions::utils::get_or_create_ata; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::instruction::Instruction; -use anchor_client::solana_sdk::signature::Keypair; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_lang::InstructionData; -use anchor_lang::ToAccountMetas; -use anchor_spl::token::{spl_token, Mint}; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::constants::MAX_BIN_PER_POSITION; -use lb_clmm::instruction; -use lb_clmm::instructions::deposit::BinLiquidityDistribution; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::state::position::PositionV2; -use lb_clmm::utils::pda::*; -use spl_associated_token_account::get_associated_token_address; +use solana_sdk::{account_info::IntoAccountInfo, system_program}; use spl_associated_token_account::instruction::create_associated_token_account; +#[allow(clippy::too_many_arguments)] async fn get_or_create_position + Clone>( program: &Program, lb_pair: Pubkey, @@ -39,90 +29,118 @@ async fn get_or_create_position + Clone>( lock_release_point: u64, transaction_config: RpcSendTransactionConfig, compute_unit_price_ix: Option, -) -> Result { +) -> Result { let (event_authority, _bump) = derive_event_authority_pda(); let base = base_keypair.pubkey(); + let rpc_client = program.async_rpc(); + let (position, _bump) = derive_position_pda(lb_pair, base, lower_bin_id, width); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + + let [token_x_program, _token_y_program] = lb_pair_state.get_token_programs()?; - if program.rpc().get_account_data(&position).is_err() { + if rpc_client.get_account_data(&position).await.is_err() { let mut builder = program.request(); - let operator_token_x = - get_associated_token_address(&program.payer(), &lb_pair_state.token_x_mint); - let owner_token_x = get_associated_token_address(&owner, &lb_pair_state.token_x_mint); + if let Some(compute_unit_price_ix) = compute_unit_price_ix { + builder = builder.instruction(compute_unit_price_ix); + } + + let operator_token_x = get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_x_mint, + &token_x_program, + ); + + let owner_token_x = get_associated_token_address_with_program_id( + &owner, + &lb_pair_state.token_x_mint, + &token_x_program, + ); - match program.rpc().get_account(&owner_token_x) { - std::result::Result::Ok(value) => { - let bytes = value.data; - let mut amount_bytes = [0u8; 8]; - amount_bytes.copy_from_slice(&bytes[64..72]); - let amount = u64::from_le_bytes(amount_bytes); + match rpc_client.get_account(&owner_token_x).await { + std::result::Result::Ok(account) => { + let mut key_with_account = (owner_token_x, account); + let account_info = key_with_account.into_account_info(); + let amount = anchor_spl::token::accessor::amount(&account_info)?; if amount == 0 { - builder = builder.instruction(spl_token::instruction::transfer( - &spl_token::ID, - &operator_token_x, - &owner_token_x, - &program.payer(), - &[], + let transfer_ix = get_transfer_instruction( + operator_token_x, + owner_token_x, + lb_pair_state.token_x_mint, + program.payer(), + program.async_rpc(), 1, // send 1 lamport to prove ownership - )?); + ) + .await?; + builder = builder.instruction(transfer_ix); } } Err(_) => { - builder = builder - .instruction(create_associated_token_account( - &program.payer(), - &owner, - &lb_pair_state.token_x_mint, - &spl_token::ID, - )) - .instruction(spl_token::instruction::transfer( - &spl_token::ID, - &operator_token_x, - &owner_token_x, - &program.payer(), - &[], - 1, // send 1 lamport to prove ownership - )?); + let create_ata_ix = create_associated_token_account( + &program.payer(), + &owner, + &lb_pair_state.token_x_mint, + &token_x_program, + ); + + let transfer_ix = get_transfer_instruction( + operator_token_x, + owner_token_x, + lb_pair_state.token_x_mint, + program.payer(), + program.async_rpc(), + 1, // send 1 lamport to prove ownership + ) + .await?; + + builder = builder.instruction(create_ata_ix).instruction(transfer_ix); } } - let ix: Instruction = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::InitializePositionByOperator { + let accounts: [AccountMeta; INITIALIZE_POSITION_BY_OPERATOR_IX_ACCOUNTS_LEN] = + InitializePositionByOperatorKeys { lb_pair, base, owner, operator: program.payer(), payer: program.payer(), position, - system_program: anchor_client::solana_sdk::system_program::ID, - event_authority, + system_program: system_program::ID, operator_token_x, owner_token_x, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::InitializePositionByOperator { - lower_bin_id, - width, - fee_owner, - lock_release_point, + event_authority, + program: dlmm_interface::ID, } - .data(), + .into(); + + let data = InitializePositionByOperatorIxData(InitializePositionByOperatorIxArgs { + lower_bin_id, + width, + fee_owner, + lock_release_point, + }) + .try_to_vec()?; + + let init_position_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; - if let Some(compute_unit_price_ix) = compute_unit_price_ix { - builder = builder.instruction(compute_unit_price_ix); - } + builder = builder.instruction(init_position_ix); + builder = builder.signer(base_keypair); - builder = builder.instruction(ix).signer(base_keypair); let signature = builder .send_with_spinner_and_config(transaction_config) .await; + println!( "Create position: lower bin id {lower_bin_id} upper bin id {upper_bin_id} position {position}. signature {:#?}", signature @@ -130,26 +148,53 @@ async fn get_or_create_position + Clone>( signature?; } - let position_state: PositionV2 = program.account(position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; Ok(position_state) } -#[derive(Debug)] +#[derive(Debug, Parser, Clone)] pub struct SeedLiquidityByOperatorParameters { + /// Address of the pair + #[clap(long)] pub lb_pair: Pubkey, - pub position_base_kp: Keypair, + /// Base position path + #[clap(long)] + pub base_position_path: String, + /// Amount of x + #[clap(long)] pub amount: u64, + /// Min price + #[clap(long)] pub min_price: f64, + /// Max price + #[clap(long)] pub max_price: f64, + /// Base pubkey + #[clap(long)] pub base_pubkey: Pubkey, + /// Curvature + #[clap(long)] + pub curvature: f64, + /// position owner + #[clap(long)] pub position_owner: Pubkey, + /// fee owner + #[clap(long)] pub fee_owner: Pubkey, + /// lock release point + #[clap(long)] pub lock_release_point: u64, - pub curvature: f64, + /// Max retries + #[clap(long)] + pub max_retries: u16, } -pub async fn seed_liquidity_by_operator + Clone>( +pub async fn execute_seed_liquidity_by_operator + Clone>( params: SeedLiquidityByOperatorParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -157,17 +202,22 @@ pub async fn seed_liquidity_by_operator + Clone>( ) -> Result<()> { let SeedLiquidityByOperatorParameters { lb_pair, - position_base_kp, + base_position_path, amount, min_price, max_price, + base_pubkey, + curvature, position_owner, fee_owner, lock_release_point, - base_pubkey, - curvature, + .. } = params; + let position_base_kp = read_keypair_file(base_position_path.clone()) + .expect("position base keypair file not found"); + + let rpc_client = program.async_rpc(); let progress_file_path = format!("{}_progress.json", lb_pair); let mut dust_deposit_state = read_dust_deposit_state(&progress_file_path)?; @@ -187,11 +237,24 @@ pub async fn seed_liquidity_by_operator + Clone>( "Invalid position base key" ); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + let bin_step = lb_pair_state.bin_step; - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair_state.token_x_mint, lb_pair_state.token_y_mint]) + .await?; + + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + // TODO: Check unpack error + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let fund_amount = to_wei_amount(amount, token_mint_base.decimals)?; @@ -255,11 +318,11 @@ pub async fn seed_liquidity_by_operator + Clone>( .map(|(bin_id, amount_x)| (*bin_id, *amount_x)) .collect(); - let width = MAX_BIN_PER_POSITION as i32; + let width = DEFAULT_BIN_PER_POSITION as i32; for i in 0..position_number { - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * i); - let upper_bin_id = lower_bin_id + MAX_BIN_PER_POSITION as i32 - 1; + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * i); + let upper_bin_id = lower_bin_id + DEFAULT_BIN_PER_POSITION as i32 - 1; create_position_bin_array_if_not_exists( program, @@ -294,11 +357,11 @@ pub async fn seed_liquidity_by_operator + Clone>( } assert_eq!( - position_state.lower_bin_id, lower_bin_id, + position_state.global_data.lower_bin_id, lower_bin_id, "Position lower bin id not equals" ); assert_eq!( - position_state.upper_bin_id, upper_bin_id, + position_state.global_data.upper_bin_id, upper_bin_id, "Position upper bin id not equals" ); @@ -344,13 +407,23 @@ pub async fn seed_liquidity_by_operator + Clone>( dust_deposit_state.dust_amount = leftover; for i in 0..position_number { - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * i); + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * i); let (position, _bump) = derive_position_pda(lb_pair, position_base_kp.pubkey(), lower_bin_id, width); - let position_state = program.account::(position).await?; - let position_liquidity_shares = position_state.liquidity_shares.to_vec(); + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + + let position_liquidity_shares = position_state + .position_bin_data + .iter() + .map(|position_bin_data| position_bin_data.liquidity_share) + .collect(); + dust_deposit_state .position_shares .insert(position, position_liquidity_shares); @@ -381,20 +454,25 @@ pub async fn seed_liquidity_by_operator + Clone>( ); for i in 0..position_number { - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * i); + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * i); let (position, _bump) = derive_position_pda(lb_pair, position_base_kp.pubkey(), lower_bin_id, width); - let position_state: PositionV2 = program.account(position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; let position_share_snapshot = position_share.get(&position).context("Missing snapshot")?; let mut dust_deposited = false; - for (i, share) in position_state.liquidity_shares.iter().enumerate() { + for (i, position_bin_data) in position_state.position_bin_data.iter().enumerate() { + let share = position_bin_data.liquidity_share; let snapshot_share = position_share_snapshot[i]; - if snapshot_share != *share { + if snapshot_share != share { dust_deposited = true; break; } @@ -405,7 +483,8 @@ pub async fn seed_liquidity_by_operator + Clone>( } // Don't deposit to the last bin because c(last_bin + 1) - c(last_bin) will > amount - let upper_bin_id = std::cmp::min(position_state.upper_bin_id, max_bin_id - 1); + let upper_bin_id = + std::cmp::min(position_state.global_data.upper_bin_id, max_bin_id - 1); assert!( upper_bin_id < max_bin_id, @@ -447,14 +526,19 @@ pub async fn seed_liquidity_by_operator + Clone>( // Shall be dust after redistribute if leftover > 0 { println!("Deposit dust {} to last semi bin", leftover); - let lower_bin_id = min_bin_id + (MAX_BIN_PER_POSITION as i32 * (position_number - 1)); + let lower_bin_id = min_bin_id + (DEFAULT_BIN_PER_POSITION as i32 * (position_number - 1)); let (position, _bump) = derive_position_pda(lb_pair, position_base_kp.pubkey(), lower_bin_id, width); - let position_state: PositionV2 = program.account(position).await?; + let position_state = rpc_client + .get_account_and_deserialize(&position, |account| { + Ok(DynamicPosition::deserialize(&account.data)?) + }) + .await?; + // Don't deposit to the last bin because c(last_bin + 1) - c(last_bin) will > amount - let upper_bin_id = std::cmp::min(position_state.upper_bin_id, max_bin_id - 1); + let upper_bin_id = std::cmp::min(position_state.global_data.upper_bin_id, max_bin_id - 1); assert!(upper_bin_id < max_bin_id, "Funding to last bin id"); diff --git a/cli/src/instructions/seed_liquidity_single_bin.rs b/cli/src/instructions/seed_liquidity_single_bin.rs index 223b115f..fa0d064d 100644 --- a/cli/src/instructions/seed_liquidity_single_bin.rs +++ b/cli/src/instructions/seed_liquidity_single_bin.rs @@ -1,45 +1,36 @@ -use std::ops::Deref; - -use anchor_client::{ - solana_client::rpc_config::RpcSendTransactionConfig, - solana_sdk::{ - compute_budget::ComputeBudgetInstruction, instruction::Instruction, pubkey::Pubkey, - signature::Keypair, signer::Signer, - }, - Program, -}; -use anchor_lang::InstructionData; -use anchor_lang::ToAccountMetas; -use anchor_spl::token::Mint; -use anyhow::{Context, Result}; -use lb_clmm::{ - accounts, instruction, - instructions::deposit::{BinLiquidityDistribution, LiquidityParameter}, - math::u128x128_math::Rounding, - state::bin::BinArray, - utils::pda::{ - derive_bin_array_bitmap_extension, derive_bin_array_pda, derive_event_authority_pda, - }, -}; -use lb_clmm::{state::lb_pair::LbPair, utils::pda::derive_position_pda}; - -use crate::{ - instructions::{seed_liquidity::to_wei_amount, utils::get_or_create_ata}, - math::{get_id_from_price, get_precise_id_from_price, price_per_token_to_per_lamport}, - SelectiveRounding, -}; - +use crate::*; +use anchor_lang::system_program; +use anchor_lang::AccountDeserialize; +use anchor_spl::token_interface::Mint; +use instructions::*; +use seed_liquidity::to_wei_amount; +use solana_sdk::sysvar; + +#[derive(Debug, Parser)] pub struct SeedLiquiditySingleBinParameters { + /// Address of the pair + #[clap(long)] pub lb_pair: Pubkey, - pub position_base_kp: Keypair, + /// Base position path + #[clap(long)] + pub base_position_path: String, + /// Base position pubkey + #[clap(long)] + pub base_pubkey: Pubkey, + /// amount of x + #[clap(long)] pub amount: u64, + #[clap(long)] pub price: f64, - pub position_owner_kp: Keypair, - pub base_pubkey: Pubkey, + /// Position owner + #[clap(long)] + pub position_owner_path: String, + /// Selective rounding + #[clap(long)] pub selective_rounding: SelectiveRounding, } -pub async fn seed_liquidity_single_bin + Clone>( +pub async fn execute_seed_liquidity_single_bin + Clone>( params: SeedLiquiditySingleBinParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -47,26 +38,46 @@ pub async fn seed_liquidity_single_bin + Clone>( ) -> Result<()> { let SeedLiquiditySingleBinParameters { lb_pair, - position_base_kp, amount, price, - position_owner_kp, base_pubkey, selective_rounding, + base_position_path, + position_owner_path, } = params; + let position_base_kp = + read_keypair_file(base_position_path).expect("position base keypair file not found"); + + let position_owner_kp = + read_keypair_file(position_owner_path).expect("position owner keypair file not found"); + assert_eq!( position_base_kp.pubkey(), base_pubkey, "Invalid position base key" ); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let bin_step = lb_pair_state.bin_step; + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; + + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair_state.token_x_mint, lb_pair_state.token_y_mint]) + .await?; - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let native_amount = to_wei_amount(amount, token_mint_base.decimals)?; @@ -127,110 +138,153 @@ pub async fn seed_liquidity_single_bin + Clone>( let (bin_array_bitmap_extension, _bump) = derive_bin_array_bitmap_extension(lb_pair); if overflow_internal_bitmap_range { - let bitmap_extension_account = program.rpc().get_account(&bin_array_bitmap_extension); + let bitmap_extension_account = rpc_client.get_account(&bin_array_bitmap_extension).await; if bitmap_extension_account.is_err() { - let initialize_bitmap_extension = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::InitializeBinArrayBitmapExtension { + let accounts: [AccountMeta; INITIALIZE_BIN_ARRAY_BITMAP_EXTENSION_IX_ACCOUNTS_LEN] = + InitializeBinArrayBitmapExtensionKeys { lb_pair, bin_array_bitmap_extension, funder: program.payer(), - system_program: anchor_lang::system_program::ID, - rent: anchor_lang::solana_program::sysvar::rent::ID, + system_program: system_program::ID, + rent: sysvar::rent::ID, } - .to_account_metas(None), - data: instruction::InitializeBinArrayBitmapExtension {}.data(), + .into(); + + let data = InitializeBinArrayBitmapExtensionIxData.try_to_vec()?; + + let initialize_bitmap_extension_ix = Instruction { + accounts: accounts.to_vec(), + program_id: dlmm_interface::ID, + data, }; - instructions.push(initialize_bitmap_extension); + + instructions.push(initialize_bitmap_extension_ix); } } let bin_array_bitmap_extension = if overflow_internal_bitmap_range { - Some(bin_array_bitmap_extension) + bin_array_bitmap_extension } else { - Some(lb_clmm::ID) + dlmm_interface::ID }; - let initialize_position_ix = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::InitializePositionPda { - position, - base: base_pubkey, - payer: program.payer(), - owner: position_owner_kp.pubkey(), - lb_pair, - system_program: anchor_lang::system_program::ID, - rent: anchor_lang::solana_program::sysvar::rent::ID, - program: lb_clmm::ID, - event_authority, - } - .to_account_metas(None), - data: instruction::InitializePositionPda { - lower_bin_id: bin_id, - width: 1, - } - .data(), - }; - - instructions.push(initialize_position_ix); - for (bin_array, bin_array_index) in [ (lower_bin_array, lower_bin_array_index), (upper_bin_array, upper_bin_array_index), ] { - if program.rpc().get_account(&lower_bin_array).is_err() { - let initialize_bin_array_ix = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::InitializeBinArray { + if rpc_client.get_account(&lower_bin_array).await.is_err() { + let account: [AccountMeta; INITIALIZE_BIN_ARRAY_IX_ACCOUNTS_LEN] = + InitializeBinArrayKeys { lb_pair, bin_array, funder: program.payer(), - system_program: anchor_lang::system_program::ID, + system_program: system_program::ID, } - .to_account_metas(None), - data: instruction::InitializeBinArray { - index: bin_array_index.into(), - } - .data(), + .into(); + + let data = InitializeBinArrayIxData(InitializeBinArrayIxArgs { + index: bin_array_index.into(), + }) + .try_to_vec()?; + + let initialize_bin_array_ix = Instruction { + accounts: account.to_vec(), + program_id: dlmm_interface::ID, + data, }; instructions.push(initialize_bin_array_ix); } } - let deposit_ix = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::ModifyLiquidity { + let accounts: [AccountMeta; INITIALIZE_POSITION_PDA_IX_ACCOUNTS_LEN] = + InitializePositionPdaKeys { position, + base: base_pubkey, + payer: program.payer(), + owner: position_owner_kp.pubkey(), lb_pair, - bin_array_bitmap_extension, - user_token_x, - user_token_y, - reserve_x: lb_pair_state.reserve_x, - reserve_y: lb_pair_state.reserve_y, - token_x_mint: lb_pair_state.token_x_mint, - token_y_mint: lb_pair_state.token_y_mint, - bin_array_lower: lower_bin_array, - bin_array_upper: upper_bin_array, - sender: program.payer(), - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, + system_program: system_program::ID, + rent: sysvar::rent::ID, + program: dlmm_interface::ID, event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::AddLiquidity { - liquidity_parameter: LiquidityParameter { - amount_x: native_amount, - amount_y: 0, - bin_liquidity_dist: vec![BinLiquidityDistribution { - bin_id, - distribution_x: 10000, - distribution_y: 0, - }], - }, } - .data(), + .into(); + + let data = InitializePositionPdaIxData(InitializePositionPdaIxArgs { + lower_bin_id: bin_id, + width: 1, + }) + .try_to_vec()?; + + let initialize_position_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, + }; + + instructions.push(initialize_position_ix); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slice, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slice; + remaining_accounts.extend(transfer_hook_remaining_accounts); + } + + remaining_accounts.extend( + [lower_bin_array, upper_bin_array] + .into_iter() + .map(|key| AccountMeta::new(key, false)), + ); + + let main_accounts: [AccountMeta; ADD_LIQUIDITY2_IX_ACCOUNTS_LEN] = AddLiquidity2Keys { + position, + lb_pair, + bin_array_bitmap_extension, + user_token_x, + user_token_y, + reserve_x: lb_pair_state.reserve_x, + reserve_y: lb_pair_state.reserve_y, + token_x_mint: lb_pair_state.token_x_mint, + token_y_mint: lb_pair_state.token_y_mint, + sender: program.payer(), + token_x_program, + token_y_program, + event_authority, + program: dlmm_interface::ID, + memo_program: spl_memo::ID, + } + .into(); + + let data = AddLiquidity2IxData(AddLiquidity2IxArgs { + liquidity_parameter: LiquidityParameter { + amount_x: native_amount, + amount_y: 0, + bin_liquidity_dist: vec![BinLiquidityDistribution { + bin_id, + distribution_x: 10000, + distribution_y: 0, + }], + }, + remaining_accounts_info, + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let deposit_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, }; instructions.push(deposit_ix); diff --git a/cli/src/instructions/seed_liquidity_single_bin_by_operator.rs b/cli/src/instructions/seed_liquidity_single_bin_by_operator.rs index 825990e6..dd19690b 100644 --- a/cli/src/instructions/seed_liquidity_single_bin_by_operator.rs +++ b/cli/src/instructions/seed_liquidity_single_bin_by_operator.rs @@ -1,50 +1,47 @@ -use std::ops::Deref; - -use anchor_client::{ - solana_client::rpc_config::RpcSendTransactionConfig, - solana_sdk::{ - compute_budget::ComputeBudgetInstruction, instruction::Instruction, pubkey::Pubkey, - signature::Keypair, signer::Signer, - }, - Program, -}; -use anchor_lang::InstructionData; -use anchor_lang::ToAccountMetas; -use anchor_spl::token::{spl_token, Mint}; -use anyhow::{Context, Result}; -use lb_clmm::{ - accounts, instruction, - instructions::deposit::{BinLiquidityDistribution, LiquidityParameter}, - math::u128x128_math::Rounding, - state::bin::BinArray, - utils::pda::{ - derive_bin_array_bitmap_extension, derive_bin_array_pda, derive_event_authority_pda, - }, -}; -use lb_clmm::{state::lb_pair::LbPair, utils::pda::derive_position_pda}; -use spl_associated_token_account::{ - get_associated_token_address, instruction::create_associated_token_account, -}; - -use crate::{ - instructions::{seed_liquidity::to_wei_amount, utils::get_or_create_ata}, - math::{get_id_from_price, get_precise_id_from_price, price_per_token_to_per_lamport}, - SelectiveRounding, -}; - +use crate::*; +use anchor_lang::system_program; +use anchor_lang::AccountDeserialize; +use anchor_spl::associated_token::get_associated_token_address_with_program_id; +use anchor_spl::token_interface::Mint; +use instructions::*; +use seed_liquidity::to_wei_amount; +use solana_sdk::{account_info::IntoAccountInfo, sysvar}; +use spl_associated_token_account::instruction::create_associated_token_account; + +#[derive(Debug, Parser)] pub struct SeedLiquiditySingleBinByOperatorParameters { + /// Address of the pair + #[clap(long)] pub lb_pair: Pubkey, - pub position_base_kp: Keypair, + /// Base position path + #[clap(long)] + pub base_position_path: String, + /// Base position pubkey + #[clap(long)] + pub base_pubkey: Pubkey, + /// amount of x + #[clap(long)] pub amount: u64, + /// price + #[clap(long)] pub price: f64, + /// Position owner + #[clap(long)] pub position_owner: Pubkey, - pub base_pubkey: Pubkey, + /// lock release point + #[clap(long)] pub lock_release_point: u64, + /// fee owner + #[clap(long)] pub fee_owner: Pubkey, + /// Selective rounding + #[clap(long)] pub selective_rounding: SelectiveRounding, } -pub async fn seed_liquidity_single_bin_by_operator + Clone>( +pub async fn execute_seed_liquidity_single_bin_by_operator< + C: Deref + Clone, +>( params: SeedLiquiditySingleBinByOperatorParameters, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -52,28 +49,45 @@ pub async fn seed_liquidity_single_bin_by_operator Result<()> { let SeedLiquiditySingleBinByOperatorParameters { lb_pair, - position_base_kp, + base_position_path, + base_pubkey, amount, price, position_owner, - base_pubkey, lock_release_point, fee_owner, selective_rounding, } = params; + let position_base_kp = + read_keypair_file(base_position_path).expect("position base keypair file not found"); + assert_eq!( position_base_kp.pubkey(), base_pubkey, "Invalid position base key" ); - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let bin_step = lb_pair_state.bin_step; + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; + + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair_state.token_x_mint, lb_pair_state.token_y_mint]) + .await?; - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; + let token_mint_base_account = accounts[0].take().context("token_mint_base not found")?; + let token_mint_quote_account = accounts[1].take().context("token_mint_quote not found")?; + + let token_mint_base = Mint::try_deserialize(&mut token_mint_base_account.data.as_ref())?; + let token_mint_quote = Mint::try_deserialize(&mut token_mint_quote_account.data.as_ref())?; let native_amount = to_wei_amount(amount, token_mint_base.decimals)?; @@ -134,153 +148,211 @@ pub async fn seed_liquidity_single_bin_by_operator { - let bytes = value.data; - let mut amount_bytes = [0u8; 8]; - amount_bytes.copy_from_slice(&bytes[64..72]); - let amount = u64::from_le_bytes(amount_bytes); + match rpc_client.get_account(&owner_token_x).await { + std::result::Result::Ok(account) => { + let mut key_with_account = (owner_token_x, account); + let account_info = key_with_account.into_account_info(); + let amount = anchor_spl::token::accessor::amount(&account_info)?; if amount == 0 { - instructions.push(spl_token::instruction::transfer( - &spl_token::ID, - &operator_token_x, - &owner_token_x, - &program.payer(), - &[], + let transfer_ix = get_transfer_instruction( + operator_token_x, + owner_token_x, + lb_pair_state.token_x_mint, + program.payer(), + program.async_rpc(), 1, // send 1 lamport to prove ownership - )?); + ) + .await?; + + instructions.push(transfer_ix); } } Err(_) => { - instructions.push(create_associated_token_account( + let create_ata_ix = create_associated_token_account( &program.payer(), &position_owner, &lb_pair_state.token_x_mint, - &spl_token::ID, - )); - instructions.push(spl_token::instruction::transfer( - &spl_token::ID, - &operator_token_x, - &owner_token_x, - &program.payer(), - &[], + &token_x_program, + ); + + let transfer_ix = get_transfer_instruction( + operator_token_x, + owner_token_x, + lb_pair_state.token_x_mint, + program.payer(), + program.async_rpc(), 1, // send 1 lamport to prove ownership - )?) + ) + .await?; + + instructions.push(create_ata_ix); + instructions.push(transfer_ix); } } - let initialize_position_ix: Instruction = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::InitializePositionByOperator { + let accounts: [AccountMeta; INITIALIZE_POSITION_BY_OPERATOR_IX_ACCOUNTS_LEN] = + InitializePositionByOperatorKeys { lb_pair, base: base_pubkey, owner: position_owner, operator: program.payer(), payer: program.payer(), position, - system_program: anchor_client::solana_sdk::system_program::ID, + system_program: system_program::ID, event_authority, operator_token_x, owner_token_x, - program: lb_clmm::ID, + program: dlmm_interface::ID, } - .to_account_metas(None), - data: instruction::InitializePositionByOperator { - lower_bin_id: bin_id, - width: 1, - fee_owner, - lock_release_point, - } - .data(), + .into(); + + let data = InitializePositionByOperatorIxData(InitializePositionByOperatorIxArgs { + lower_bin_id: bin_id, + width: 1, + fee_owner, + lock_release_point, + }) + .try_to_vec()?; + + let initialize_position_ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; instructions.push(initialize_position_ix); + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slice, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slice; + remaining_accounts.extend(transfer_hook_remaining_accounts); + } + + remaining_accounts.extend( + [lower_bin_array, upper_bin_array] + .into_iter() + .map(|key| AccountMeta::new(key, false)), + ); + + let main_accounts: [AccountMeta; ADD_LIQUIDITY2_IX_ACCOUNTS_LEN] = AddLiquidity2Keys { + position, + lb_pair, + bin_array_bitmap_extension, + user_token_x, + user_token_y, + reserve_x: lb_pair_state.reserve_x, + reserve_y: lb_pair_state.reserve_y, + token_x_mint: lb_pair_state.token_x_mint, + token_y_mint: lb_pair_state.token_y_mint, + sender: program.payer(), + token_x_program, + token_y_program, + event_authority, + program: dlmm_interface::ID, + memo_program: spl_memo::ID, + } + .into(); + + let data = AddLiquidity2IxData(AddLiquidity2IxArgs { + liquidity_parameter: LiquidityParameter { + amount_x: native_amount, + amount_y: 0, + bin_liquidity_dist: vec![BinLiquidityDistribution { + bin_id, + distribution_x: 10000, + distribution_y: 0, + }], + }, + remaining_accounts_info, + }) + .try_to_vec()?; + + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + let deposit_ix = Instruction { - program_id: lb_clmm::ID, - accounts: accounts::ModifyLiquidity { - position, - lb_pair, - bin_array_bitmap_extension, - user_token_x, - user_token_y, - reserve_x: lb_pair_state.reserve_x, - reserve_y: lb_pair_state.reserve_y, - token_x_mint: lb_pair_state.token_x_mint, - token_y_mint: lb_pair_state.token_y_mint, - bin_array_lower: lower_bin_array, - bin_array_upper: upper_bin_array, - sender: program.payer(), - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, - event_authority, - program: lb_clmm::ID, - } - .to_account_metas(None), - data: instruction::AddLiquidity { - liquidity_parameter: LiquidityParameter { - amount_x: native_amount, - amount_y: 0, - bin_liquidity_dist: vec![BinLiquidityDistribution { - bin_id, - distribution_x: 10000, - distribution_y: 0, - }], - }, - } - .data(), + program_id: dlmm_interface::ID, + accounts, + data, }; instructions.push(deposit_ix); diff --git a/cli/src/instructions/set_activation_point.rs b/cli/src/instructions/set_activation_point.rs index d81ca922..edcb1c8f 100644 --- a/cli/src/instructions/set_activation_point.rs +++ b/cli/src/instructions/set_activation_point.rs @@ -1,19 +1,14 @@ -use std::ops::Deref; +use crate::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_lang::solana_program::instruction::Instruction; -use anchor_lang::{InstructionData, ToAccountMetas}; -use anyhow::*; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct SetActivationPointParam { + /// Address of the pair pub lb_pair: Pubkey, + /// Activation point pub activation_point: u64, } -pub async fn set_activation_point + Clone>( +pub async fn execute_set_activation_point + Clone>( params: SetActivationPointParam, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -23,18 +18,19 @@ pub async fn set_activation_point + Clone>( activation_point, } = params; - let accounts = lb_clmm::accounts::SetActivationPoint { + let accounts: [AccountMeta; SET_ACTIVATION_POINT_IX_ACCOUNTS_LEN] = SetActivationPointKeys { admin: program.payer(), lb_pair, } - .to_account_metas(None); + .into(); - let ix_data = lb_clmm::instruction::SetActivationPoint { activation_point }.data(); + let data = + SetActivationPointIxData(SetActivationPointIxArgs { activation_point }).try_to_vec()?; let set_activation_point_ix = Instruction { - accounts, - data: ix_data, - program_id: lb_clmm::ID, + accounts: accounts.to_vec(), + data, + program_id: dlmm_interface::ID, }; let request_builder = program.request(); diff --git a/cli/src/instructions/set_pre_activation_duration.rs b/cli/src/instructions/set_pre_activation_duration.rs index e11ad205..8cca8462 100644 --- a/cli/src/instructions/set_pre_activation_duration.rs +++ b/cli/src/instructions/set_pre_activation_duration.rs @@ -1,19 +1,12 @@ -use std::ops::Deref; +use crate::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_lang::solana_program::instruction::Instruction; -use anchor_lang::{InstructionData, ToAccountMetas}; -use anyhow::*; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct SetPreactivationDurationParam { pub lb_pair: Pubkey, pub pre_activation_duration: u16, } -pub async fn set_pre_activation_duration + Clone>( +pub async fn execute_set_pre_activation_duration + Clone>( params: SetPreactivationDurationParam, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -23,21 +16,22 @@ pub async fn set_pre_activation_duration + Clone> pre_activation_duration, } = params; - let accounts = lb_clmm::accounts::SetPreActivationInfo { - creator: program.payer(), - lb_pair, - } - .to_account_metas(None); + let accounts: [AccountMeta; SET_PRE_ACTIVATION_DURATION_IX_ACCOUNTS_LEN] = + SetPreActivationSwapAddressKeys { + creator: program.payer(), + lb_pair, + } + .into(); - let ix_data = lb_clmm::instruction::SetPreActivationDuration { - pre_activation_duration, - } - .data(); + let data = SetPreActivationDurationIxData(SetPreActivationDurationIxArgs { + pre_activation_duration: pre_activation_duration as u64, + }) + .try_to_vec()?; let set_pre_activation_slot_duration_ix = Instruction { - accounts, - data: ix_data, - program_id: lb_clmm::ID, + accounts: accounts.to_vec(), + data, + program_id: dlmm_interface::ID, }; let request_builder = program.request(); diff --git a/cli/src/instructions/set_pre_activation_swap_address.rs b/cli/src/instructions/set_pre_activation_swap_address.rs index 4140439f..75ae4ed0 100644 --- a/cli/src/instructions/set_pre_activation_swap_address.rs +++ b/cli/src/instructions/set_pre_activation_swap_address.rs @@ -1,19 +1,12 @@ -use std::ops::Deref; +use crate::*; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_lang::solana_program::instruction::Instruction; -use anchor_lang::{InstructionData, ToAccountMetas}; -use anyhow::*; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct SetPreactivationSwapAddressParam { pub lb_pair: Pubkey, pub pre_activation_swap_address: Pubkey, } -pub async fn set_pre_activation_swap_address + Clone>( +pub async fn execute_set_pre_activation_swap_address + Clone>( params: SetPreactivationSwapAddressParam, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -23,21 +16,22 @@ pub async fn set_pre_activation_swap_address + Cl pre_activation_swap_address, } = params; - let accounts = lb_clmm::accounts::SetPreActivationInfo { - creator: program.payer(), - lb_pair, - } - .to_account_metas(None); + let accounts: [AccountMeta; SET_PRE_ACTIVATION_SWAP_ADDRESS_IX_ACCOUNTS_LEN] = + SetPreActivationSwapAddressKeys { + creator: program.payer(), + lb_pair, + } + .into(); - let ix_data = lb_clmm::instruction::SetPreActivationSwapAddress { + let data = SetPreActivationSwapAddressIxData(SetPreActivationSwapAddressIxArgs { pre_activation_swap_address, - } - .data(); + }) + .try_to_vec()?; let set_pre_activation_swap_address_ix = Instruction { - accounts, - data: ix_data, - program_id: lb_clmm::ID, + accounts: accounts.to_vec(), + data, + program_id: dlmm_interface::ID, }; let request_builder = program.request(); diff --git a/cli/src/instructions/show_pair.rs b/cli/src/instructions/show_pair.rs index 75dc4b13..82468ba8 100644 --- a/cli/src/instructions/show_pair.rs +++ b/cli/src/instructions/show_pair.rs @@ -1,34 +1,57 @@ -use std::ops::Deref; - -use anchor_client::solana_client::rpc_filter::{Memcmp, RpcFilterType}; - -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; - -use anchor_spl::token::Mint; -use anyhow::*; - -use lb_clmm::constants::FEE_PRECISION; -use lb_clmm::math::price_math::get_price_from_id; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::lb_pair::LbPair; -use rust_decimal::prelude::{FromPrimitive, ToPrimitive}; +use crate::*; +use anchor_lang::AccountDeserialize; +use anchor_spl::token_interface::Mint; +use rust_decimal::prelude::*; use rust_decimal::Decimal; - -use crate::math::{price_per_lamport_to_price_per_token, q64x64_price_to_decimal}; +use solana_client::{ + rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, + rpc_filter::{Memcmp, RpcFilterType}, +}; fn fee_rate_to_fee_pct(fee_rate: u128) -> Option { let fee_rate = Decimal::from_u128(fee_rate)?.checked_div(Decimal::from(FEE_PRECISION))?; fee_rate.checked_mul(Decimal::ONE_HUNDRED) } -pub async fn show_pair + Clone>( - lb_pair: Pubkey, +#[derive(Debug, Parser)] +pub struct ShowPairParams { + pub lb_pair: Pubkey, +} + +pub async fn execute_show_pair + Clone>( + params: ShowPairParams, program: &Program, ) -> Result<()> { - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let ShowPairParams { lb_pair } = params; + let rpc_client = program.async_rpc(); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let lb_pair_filter = RpcFilterType::Memcmp(Memcmp::new_base58_encoded(16, &lb_pair.to_bytes())); - let mut bin_arrays: Vec<(Pubkey, BinArray)> = program.accounts(vec![lb_pair_filter]).await?; + let account_config = RpcAccountInfoConfig { + encoding: Some(UiAccountEncoding::Base64), + ..Default::default() + }; + let config = RpcProgramAccountsConfig { + filters: Some(vec![lb_pair_filter]), + account_config, + ..Default::default() + }; + + let mut bin_arrays: Vec<(Pubkey, BinArray)> = rpc_client + .get_program_accounts_with_config(&dlmm_interface::ID, config) + .await? + .into_iter() + .filter_map(|(key, account)| { + let bin_array = BinArrayAccount::deserialize(&account.data).ok()?; + Some((key, bin_array.0)) + }) + .collect(); + bin_arrays.sort_by(|a, b| a.1.index.cmp(&b.1.index)); println!("{:#?}", lb_pair_state); @@ -48,8 +71,15 @@ pub async fn show_pair + Clone>( } } - let x_mint: Mint = program.account(lb_pair_state.token_x_mint).await?; - let y_mint: Mint = program.account(lb_pair_state.token_y_mint).await?; + let mut accounts = rpc_client + .get_multiple_accounts(&[lb_pair_state.token_x_mint, lb_pair_state.token_y_mint]) + .await?; + + let token_x_account = accounts[0].take().context("token_mint_base not found")?; + let token_y_account = accounts[1].take().context("token_mint_quote not found")?; + + let x_mint = Mint::try_deserialize(&mut token_x_account.data.as_ref())?; + let y_mint = Mint::try_deserialize(&mut token_y_account.data.as_ref())?; let q64x64_price = get_price_from_id(lb_pair_state.active_id, lb_pair_state.bin_step)?; let decimal_price_per_lamport = diff --git a/cli/src/instructions/show_position.rs b/cli/src/instructions/show_position.rs new file mode 100644 index 00000000..294a1697 --- /dev/null +++ b/cli/src/instructions/show_position.rs @@ -0,0 +1,39 @@ +use crate::*; + +#[derive(Debug, Parser)] +pub struct ShowPositionParams { + pub position: Pubkey, +} + +pub async fn execute_show_position + Clone>( + params: ShowPositionParams, + program: &Program, +) -> Result<()> { + let ShowPositionParams { position } = params; + + let rpc_client = program.async_rpc(); + let position_account = rpc_client.get_account(&position).await?; + + let mut disc = [0u8; 8]; + disc.copy_from_slice(&position_account.data[..8]); + + match disc { + POSITION_ACCOUNT_DISCM => { + let position_state = PositionAccount::deserialize(&position_account.data)?.0; + println!("{:#?}", position_state); + } + POSITION_V2_ACCOUNT_DISCM => { + let position_state = PositionV2Account::deserialize(&position_account.data)?.0; + println!("{:#?}", position_state); + } + POSITION_V3_ACCOUNT_DISCM => { + let position_state = DynamicPosition::deserialize(&position_account.data)?; + println!("{:#?}", position_state); + } + _ => { + bail!("Not a valid position account"); + } + }; + + Ok(()) +} diff --git a/cli/src/instructions/show_preset_parameters.rs b/cli/src/instructions/show_preset_parameters.rs new file mode 100644 index 00000000..a6f8d02c --- /dev/null +++ b/cli/src/instructions/show_preset_parameters.rs @@ -0,0 +1,33 @@ +use crate::*; + +#[derive(Debug, Parser)] +pub struct ShowPresetAccountParams { + pub preset_parameter: Pubkey, +} + +pub async fn execute_show_preset_parameters + Clone>( + params: ShowPresetAccountParams, + program: &Program, +) -> Result<()> { + let ShowPresetAccountParams { preset_parameter } = params; + + let rpc_client = program.async_rpc(); + let account = rpc_client.get_account(&preset_parameter).await?; + + let mut disc = [0u8; 8]; + disc.copy_from_slice(&account.data[..8]); + + match disc { + PRESET_PARAMETER_ACCOUNT_DISCM => { + let preset_param_state = PresetParameterAccount::deserialize(&account.data)?.0; + println!("{:#?}", preset_param_state); + } + PRESET_PARAMETER2_ACCOUNT_DISCM => { + let preset_param_state = PresetParameter2Account::deserialize(&account.data)?.0; + println!("{:#?}", preset_param_state); + } + _ => bail!("Not a valid preset parameter account"), + } + + Ok(()) +} diff --git a/cli/src/instructions/simulate_swap_demand.rs b/cli/src/instructions/simulate_swap_demand.rs deleted file mode 100644 index c389de13..00000000 --- a/cli/src/instructions/simulate_swap_demand.rs +++ /dev/null @@ -1,88 +0,0 @@ -use crate::instructions::utils::get_or_create_ata; -use crate::swap; -use crate::SwapExactInParameters; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_spl::token::Mint; -use anyhow::*; -use lb_clmm::state::lb_pair::LbPair; -use rand::Rng; -use std::ops::Deref; -use std::result::Result::Ok; -#[derive(Debug)] -pub struct SimulateSwapDemandParameters { - pub lb_pair: Pubkey, - pub x_amount: f64, // ex: 10 jup - pub y_amount: f64, // ex: 1k jup - pub side_ratio: u64, -} - -pub async fn simulate_swap_demand + Clone>( - params: SimulateSwapDemandParameters, - program: &Program, - transaction_config: RpcSendTransactionConfig, -) -> Result<()> { - let SimulateSwapDemandParameters { - lb_pair, - x_amount, - y_amount, - side_ratio, - } = params; - - let lb_pair_state: LbPair = program.account(lb_pair).await?; - let token_mint_base: Mint = program.account(lb_pair_state.token_x_mint).await?; - let token_mint_quote: Mint = program.account(lb_pair_state.token_y_mint).await?; - - get_or_create_ata( - program, - transaction_config, - lb_pair_state.token_x_mint, - program.payer(), - ) - .await?; - get_or_create_ata( - program, - transaction_config, - lb_pair_state.token_y_mint, - program.payer(), - ) - .await?; - - // random amount - let mut rng = rand::thread_rng(); - loop { - let side = rng.gen_range(0..side_ratio); - if side == 0 { - // sell side - println!("try to sell {x_amount} jup"); - let amount_x = x_amount * (10u64.pow(token_mint_base.decimals as u32) as f64); - let params = SwapExactInParameters { - amount_in: amount_x.round() as u64, - lb_pair, - swap_for_y: true, - }; - match swap(params, program, transaction_config).await { - Ok(_) => {} - Err(err) => { - println!("{err}"); - } - } - } else { - // buy side - println!("try to buy with {y_amount} usd"); - let amount_y = y_amount * (10u64.pow(token_mint_quote.decimals as u32) as f64); - - let params = SwapExactInParameters { - amount_in: amount_y.round() as u64, - lb_pair, - swap_for_y: false, - }; - match swap(params, program, transaction_config).await { - Ok(_) => {} - Err(err) => { - println!("{err}"); - } - } - } - } -} diff --git a/cli/src/instructions/swap_exact_in.rs b/cli/src/instructions/swap_exact_in.rs index 96fd2c55..7f8ae1aa 100644 --- a/cli/src/instructions/swap_exact_in.rs +++ b/cli/src/instructions/swap_exact_in.rs @@ -1,63 +1,75 @@ use std::collections::HashMap; -use std::ops::Deref; - -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; - -use anchor_client::solana_sdk::clock::Clock; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::solana_sdk::sysvar::SysvarId; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_lang::solana_program::instruction::AccountMeta; -use anchor_lang::AccountDeserialize; -use anchor_spl::associated_token::get_associated_token_address; - -use anyhow::*; -use commons::quote::{get_bin_array_pubkeys_for_swap, quote_exact_in}; -use lb_clmm::accounts; -use lb_clmm::constants::BASIS_POINT_MAX; -use lb_clmm::instruction; - -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::*; - -#[derive(Debug)] -pub struct SwapExactInParameters { + +use crate::*; +use anchor_spl::associated_token::get_associated_token_address_with_program_id; +use instructions::*; +use solana_sdk::{clock::Clock, sysvar::SysvarId}; + +#[derive(Debug, Parser)] +pub struct SwapExactInParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Amount of token to be sell. pub amount_in: u64, + /// Buy direction. true = buy token Y, false = buy token X. + #[clap(long)] pub swap_for_y: bool, } -pub async fn swap + Clone>( - params: SwapExactInParameters, +pub async fn execute_swap + Clone>( + params: SwapExactInParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let SwapExactInParameters { + let SwapExactInParams { amount_in, lb_pair, swap_for_y, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; let (user_token_in, user_token_out) = if swap_for_y { ( - get_associated_token_address(&program.payer(), &lb_pair_state.token_x_mint), - get_associated_token_address(&program.payer(), &lb_pair_state.token_y_mint), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_x_mint, + &token_x_program, + ), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_y_mint, + &token_y_program, + ), ) } else { ( - get_associated_token_address(&program.payer(), &lb_pair_state.token_y_mint), - get_associated_token_address(&program.payer(), &lb_pair_state.token_x_mint), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_y_mint, + &token_y_program, + ), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_x_mint, + &token_x_program, + ), ) }; let (bitmap_extension_key, _bump) = derive_bin_array_bitmap_extension(lb_pair); - let bitmap_extension = program - .account::(bitmap_extension_key) + let bitmap_extension = rpc_client + .get_account_and_deserialize(&bitmap_extension_key, |account| { + Ok(BinArrayBitmapExtensionAccount::deserialize(&account.data)?.0) + }) .await .ok(); @@ -69,8 +81,7 @@ pub async fn swap + Clone>( 3, )?; - let bin_arrays = program - .async_rpc() + let bin_arrays = rpc_client .get_multiple_accounts(&bin_arrays_for_swap) .await? .into_iter() @@ -79,20 +90,18 @@ pub async fn swap + Clone>( let account = account?; Some(( key, - BinArray::try_deserialize(&mut account.data.as_ref()).ok()?, + BinArrayAccount::deserialize(account.data.as_ref()).ok()?.0, )) }) .collect::>>() .context("Failed to fetch bin arrays")?; - let clock = program - .async_rpc() - .get_account(&Clock::id()) - .await - .map(|account| { - let clock: Clock = bincode::deserialize(account.data.as_ref())?; - Ok(clock) - })??; + let clock = rpc_client.get_account(&Clock::id()).await.map(|account| { + let clock: Clock = bincode::deserialize(account.data.as_ref())?; + Ok(clock) + })??; + + let bin_array_keys = bin_arrays.iter().map(|(key, _)| *key).collect::>(); let quote = quote_exact_in( lb_pair, @@ -105,50 +114,75 @@ pub async fn swap + Clone>( clock.slot, )?; - let (event_authority, _bump) = - Pubkey::find_program_address(&[b"__event_authority"], &lb_clmm::ID); + let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::Swap { + let main_accounts: [AccountMeta; SWAP2_IX_ACCOUNTS_LEN] = Swap2Keys { lb_pair, bin_array_bitmap_extension: bitmap_extension .map(|_| bitmap_extension_key) - .or(Some(lb_clmm::ID)), + .unwrap_or(dlmm_interface::ID), reserve_x: lb_pair_state.reserve_x, reserve_y: lb_pair_state.reserve_y, token_x_mint: lb_pair_state.token_x_mint, token_y_mint: lb_pair_state.token_y_mint, - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, + token_x_program, + token_y_program, user: program.payer(), user_token_in, user_token_out, oracle: lb_pair_state.oracle, - host_fee_in: Some(lb_clmm::ID), + host_fee_in: dlmm_interface::ID, event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + memo_program: spl_memo::ID, + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); + } + + remaining_accounts.extend( + bin_array_keys + .into_iter() + .map(|key| AccountMeta::new(key, false)), + ); // 100 bps slippage let min_amount_out = quote.amount_out * 9900 / BASIS_POINT_MAX as u64; - let ix = instruction::Swap { + let data = Swap2IxData(Swap2IxArgs { amount_in, min_amount_out, - }; + remaining_accounts_info, + }) + .try_to_vec()?; - let remaining_accounts = bin_arrays_for_swap - .into_iter() - .map(|key| AccountMeta::new(key, false)) - .collect::>(); + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let swap_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .accounts(remaining_accounts) - .args(ix) + .instruction(swap_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/swap_exact_out.rs b/cli/src/instructions/swap_exact_out.rs index d3fdc09a..b4b94aa5 100644 --- a/cli/src/instructions/swap_exact_out.rs +++ b/cli/src/instructions/swap_exact_out.rs @@ -1,46 +1,38 @@ use std::collections::HashMap; -use std::ops::Deref; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; - -use anchor_client::solana_sdk::clock::Clock; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::solana_sdk::sysvar::SysvarId; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_lang::solana_program::instruction::AccountMeta; -use anchor_lang::AccountDeserialize; use anchor_spl::associated_token::get_associated_token_address; +use solana_sdk::{clock::Clock, sysvar::SysvarId}; -use anyhow::*; -use commons::quote::{get_bin_array_pubkeys_for_swap, quote_exact_out}; -use lb_clmm::accounts; -use lb_clmm::constants::BASIS_POINT_MAX; -use lb_clmm::instruction; - -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::*; +use crate::*; -#[derive(Debug)] -pub struct SwapExactOutParameters { +#[derive(Debug, Parser)] +pub struct SwapExactOutParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Amount of token to be buy. pub amount_out: u64, + /// Buy direction. true = buy token Y, false = buy token X. + #[clap(long)] pub swap_for_y: bool, } -pub async fn swap_exact_out + Clone>( - params: SwapExactOutParameters, +pub async fn execute_swap_exact_out + Clone>( + params: SwapExactOutParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let SwapExactOutParameters { + let SwapExactOutParams { amount_out, lb_pair, swap_for_y, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let (user_token_in, user_token_out) = if swap_for_y { ( @@ -56,8 +48,10 @@ pub async fn swap_exact_out + Clone>( let (bitmap_extension_key, _bump) = derive_bin_array_bitmap_extension(lb_pair); - let bitmap_extension = program - .account::(bitmap_extension_key) + let bitmap_extension = rpc_client + .get_account_and_deserialize(&bitmap_extension_key, |account| { + Ok(BinArrayBitmapExtensionAccount::deserialize(&account.data)?.0) + }) .await .ok(); @@ -69,8 +63,7 @@ pub async fn swap_exact_out + Clone>( 3, )?; - let bin_arrays = program - .async_rpc() + let bin_arrays = rpc_client .get_multiple_accounts(&bin_arrays_for_swap) .await? .into_iter() @@ -79,20 +72,16 @@ pub async fn swap_exact_out + Clone>( let account = account?; Some(( key, - BinArray::try_deserialize(&mut account.data.as_ref()).ok()?, + BinArrayAccount::deserialize(account.data.as_ref()).ok()?.0, )) }) .collect::>>() .context("Failed to fetch bin arrays")?; - let clock = program - .async_rpc() - .get_account(&Clock::id()) - .await - .map(|account| { - let clock: Clock = bincode::deserialize(account.data.as_ref())?; - Ok(clock) - })??; + let clock = rpc_client.get_account(&Clock::id()).await.map(|account| { + let clock: Clock = bincode::deserialize(account.data.as_ref())?; + Ok(clock) + })??; let quote = quote_exact_out( lb_pair, @@ -105,14 +94,13 @@ pub async fn swap_exact_out + Clone>( clock.slot, )?; - let (event_authority, _bump) = - Pubkey::find_program_address(&[b"__event_authority"], &lb_clmm::ID); + let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::Swap { + let main_accounts: [AccountMeta; SWAP_EXACT_OUT_IX_ACCOUNTS_LEN] = SwapExactOutKeys { lb_pair, bin_array_bitmap_extension: bitmap_extension .map(|_| bitmap_extension_key) - .or(Some(lb_clmm::ID)), + .unwrap_or(dlmm_interface::ID), reserve_x: lb_pair_state.reserve_x, reserve_y: lb_pair_state.reserve_y, token_x_mint: lb_pair_state.token_x_mint, @@ -123,33 +111,41 @@ pub async fn swap_exact_out + Clone>( user_token_in, user_token_out, oracle: lb_pair_state.oracle, - host_fee_in: Some(lb_clmm::ID), + host_fee_in: dlmm_interface::ID, event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + } + .into(); let in_amount = quote.amount_in + quote.fee; // 100 bps slippage let max_in_amount = in_amount * 10100 / BASIS_POINT_MAX as u64; - let ix = instruction::SwapExactOut { + let data = SwapExactOutIxData(SwapExactOutIxArgs { out_amount: amount_out, max_in_amount, - }; + }) + .try_to_vec()?; let remaining_accounts = bin_arrays_for_swap .into_iter() .map(|key| AccountMeta::new(key, false)) .collect::>(); + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let swap_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; + let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .accounts(remaining_accounts) - .args(ix) + .instruction(swap_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/swap_with_price_impact.rs b/cli/src/instructions/swap_with_price_impact.rs index 100f5a52..69d5565e 100644 --- a/cli/src/instructions/swap_with_price_impact.rs +++ b/cli/src/instructions/swap_with_price_impact.rs @@ -1,59 +1,78 @@ -use std::ops::Deref; +use std::collections::HashMap; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; +use anchor_spl::associated_token::get_associated_token_address_with_program_id; +use solana_sdk::{clock::Clock, sysvar::SysvarId}; -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_lang::solana_program::instruction::AccountMeta; -use anchor_spl::associated_token::get_associated_token_address; +use crate::*; -use anyhow::*; -use commons::quote::get_bin_array_pubkeys_for_swap; -use lb_clmm::accounts; -use lb_clmm::instruction; - -use lb_clmm::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::*; - -#[derive(Debug)] -pub struct SwapWithPriceImpactParameters { +#[derive(Debug, Parser)] +pub struct SwapWithPriceImpactParams { + /// Address of the liquidity pair. pub lb_pair: Pubkey, + /// Amount of token to be sell. pub amount_in: u64, + /// Buy direction. true = buy token Y, false = buy token X. + #[clap(long)] pub swap_for_y: bool, + /// Allowed price impact in bps. pub price_impact_bps: u16, } -pub async fn swap_with_price_impact + Clone>( - params: SwapWithPriceImpactParameters, +pub async fn execute_swap_with_price_impact + Clone>( + params: SwapWithPriceImpactParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let SwapWithPriceImpactParameters { + let SwapWithPriceImpactParams { amount_in, lb_pair, swap_for_y, price_impact_bps, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; let (user_token_in, user_token_out) = if swap_for_y { ( - get_associated_token_address(&program.payer(), &lb_pair_state.token_x_mint), - get_associated_token_address(&program.payer(), &lb_pair_state.token_y_mint), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_x_mint, + &token_x_program, + ), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_y_mint, + &token_y_program, + ), ) } else { ( - get_associated_token_address(&program.payer(), &lb_pair_state.token_y_mint), - get_associated_token_address(&program.payer(), &lb_pair_state.token_x_mint), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_y_mint, + &token_y_program, + ), + get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_x_mint, + &token_x_program, + ), ) }; let (bitmap_extension_key, _bump) = derive_bin_array_bitmap_extension(lb_pair); - let bitmap_extension = program - .account::(bitmap_extension_key) + let bitmap_extension = rpc_client + .get_account_and_deserialize(&bitmap_extension_key, |account| { + Ok(BinArrayBitmapExtensionAccount::deserialize(&account.data)?.0) + }) .await .ok(); @@ -65,48 +84,108 @@ pub async fn swap_with_price_impact + Clone>( 3, )?; - let (event_authority, _bump) = - Pubkey::find_program_address(&[b"__event_authority"], &lb_clmm::ID); + let bin_arrays = rpc_client + .get_multiple_accounts(&bin_arrays_for_swap) + .await? + .into_iter() + .zip(bin_arrays_for_swap.iter()) + .map(|(account, &key)| { + let account = account?; + Some(( + key, + BinArrayAccount::deserialize(account.data.as_ref()).ok()?.0, + )) + }) + .collect::>>() + .context("Failed to fetch bin arrays")?; + + let clock = rpc_client.get_account(&Clock::id()).await.map(|account| { + let clock: Clock = bincode::deserialize(account.data.as_ref())?; + Ok(clock) + })??; + + let bin_array_keys = bin_arrays.iter().map(|(key, _)| *key).collect::>(); + + let quote = quote_exact_in( + lb_pair, + &lb_pair_state, + amount_in, + swap_for_y, + bin_arrays, + bitmap_extension.as_ref(), + clock.unix_timestamp as u64, + clock.slot, + )?; - let accounts = accounts::Swap { + println!("{:#?}", quote); + + let (event_authority, _bump) = derive_event_authority_pda(); + + let main_accounts: [AccountMeta; SWAP2_IX_ACCOUNTS_LEN] = Swap2Keys { lb_pair, bin_array_bitmap_extension: bitmap_extension .map(|_| bitmap_extension_key) - .or(Some(lb_clmm::ID)), + .unwrap_or(dlmm_interface::ID), reserve_x: lb_pair_state.reserve_x, reserve_y: lb_pair_state.reserve_y, token_x_mint: lb_pair_state.token_x_mint, token_y_mint: lb_pair_state.token_y_mint, - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, + token_x_program, + token_y_program, user: program.payer(), user_token_in, user_token_out, oracle: lb_pair_state.oracle, - host_fee_in: Some(lb_clmm::ID), + host_fee_in: dlmm_interface::ID, event_authority, - program: lb_clmm::ID, - }; - - let ix = instruction::SwapWithPriceImpact { + program: dlmm_interface::ID, + memo_program: spl_memo::ID, + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); + } + + remaining_accounts.extend( + bin_array_keys + .into_iter() + .map(|key| AccountMeta::new(key, false)), + ); + + let data = SwapWithPriceImpact2IxData(SwapWithPriceImpact2IxArgs { amount_in, active_id: Some(lb_pair_state.active_id), + remaining_accounts_info, max_price_impact_bps: price_impact_bps, - }; + }) + .try_to_vec()?; - let remaining_accounts = bin_arrays_for_swap - .into_iter() - .map(|key| AccountMeta::new(key, false)) - .collect::>(); + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); + + let swap_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, + }; let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .accounts(remaining_accounts) - .args(ix) + .instruction(swap_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/toggle_pair_status.rs b/cli/src/instructions/toggle_pair_status.rs index 81e1332d..af09d782 100644 --- a/cli/src/instructions/toggle_pair_status.rs +++ b/cli/src/instructions/toggle_pair_status.rs @@ -1,28 +1,33 @@ -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::signer::Signer; -use anchor_client::Program; -use anchor_lang::prelude::Pubkey; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use std::ops::Deref; - -pub async fn toggle_pool_status + Clone>( +use crate::*; + +#[derive(Debug, Parser)] +pub struct TogglePairStatusParams { lb_pair: Pubkey, +} + +pub async fn execute_toggle_pool_status + Clone>( + params: TogglePairStatusParams, program: &Program, transaction_config: RpcSendTransactionConfig, ) -> Result<()> { - let accounts = accounts::TogglePairStatus { + let TogglePairStatusParams { lb_pair } = params; + + let accounts: [AccountMeta; TOGGLE_PAIR_STATUS_IX_ACCOUNTS_LEN] = TogglePairStatusKeys { admin: program.payer(), lb_pair, - }; + } + .into(); - let ix = instruction::TogglePairStatus {}; + let data = TogglePairStatusIxData.try_to_vec()?; + let instruction = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, + }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(instruction) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/update_reward_duration.rs b/cli/src/instructions/update_reward_duration.rs index 36e3d274..a784ec94 100644 --- a/cli/src/instructions/update_reward_duration.rs +++ b/cli/src/instructions/update_reward_duration.rs @@ -1,21 +1,13 @@ -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::lb_pair::LbPair; -use lb_clmm::utils::pda::*; -use std::ops::Deref; - -#[derive(Debug)] +use crate::*; + +#[derive(Debug, Parser)] pub struct UpdateRewardDurationParams { pub lb_pair: Pubkey, pub reward_index: u64, pub reward_duration: u64, } -pub async fn update_reward_duration + Clone>( +pub async fn execute_update_reward_duration + Clone>( params: UpdateRewardDurationParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -26,30 +18,43 @@ pub async fn update_reward_duration + Clone>( reward_duration, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; let active_bin_array_idx = BinArray::bin_id_to_bin_array_index(lb_pair_state.active_id)?; let (bin_array, _bump) = derive_bin_array_pda(lb_pair, active_bin_array_idx as i64); let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::UpdateRewardDuration { - lb_pair, - admin: program.payer(), - bin_array, - event_authority, - program: lb_clmm::ID, - }; + let accounts: [AccountMeta; UPDATE_REWARD_DURATION_IX_ACCOUNTS_LEN] = + UpdateRewardDurationKeys { + lb_pair, + admin: program.payer(), + bin_array, + event_authority, + program: dlmm_interface::ID, + } + .into(); - let ix = instruction::UpdateRewardDuration { + let data = UpdateRewardDurationIxData(UpdateRewardDurationIxArgs { reward_index, new_duration: reward_duration, + }) + .try_to_vec()?; + + let ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/update_reward_funder.rs b/cli/src/instructions/update_reward_funder.rs index 7768b104..00273bb2 100644 --- a/cli/src/instructions/update_reward_funder.rs +++ b/cli/src/instructions/update_reward_funder.rs @@ -1,20 +1,13 @@ -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; -use lb_clmm::utils::pda::derive_event_authority_pda; +use crate::*; -use std::ops::Deref; - -#[derive(Debug)] +#[derive(Debug, Parser)] pub struct UpdateRewardFunderParams { pub lb_pair: Pubkey, pub reward_index: u64, pub funder: Pubkey, } -pub async fn update_reward_funder + Clone>( +pub async fn execute_update_reward_funder + Clone>( params: UpdateRewardFunderParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -27,22 +20,29 @@ pub async fn update_reward_funder + Clone>( let (event_authority, _bump) = derive_event_authority_pda(); - let accounts = accounts::UpdateRewardFunder { + let accounts: [AccountMeta; UPDATE_REWARD_FUNDER_IX_ACCOUNTS_LEN] = UpdateRewardFunderKeys { lb_pair, admin: program.payer(), event_authority, - program: lb_clmm::ID, - }; + program: dlmm_interface::ID, + } + .into(); - let ix = instruction::UpdateRewardFunder { + let data = UpdateRewardFunderIxData(UpdateRewardFunderIxArgs { reward_index, new_funder: funder, + }) + .try_to_vec()?; + + let ix = Instruction { + program_id: dlmm_interface::ID, + accounts: accounts.to_vec(), + data, }; let request_builder = program.request(); let signature = request_builder - .accounts(accounts) - .args(ix) + .instruction(ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/instructions/utils.rs b/cli/src/instructions/utils.rs index 96d64841..3fc779ec 100644 --- a/cli/src/instructions/utils.rs +++ b/cli/src/instructions/utils.rs @@ -1,16 +1,87 @@ -use anchor_client::solana_sdk::signer::Signer; -use anchor_client::Program; -use lb_clmm::state::bin::BinArray; -use lb_clmm::state::position::Position; -use lb_clmm::utils::pda::derive_bin_array_pda; +use crate::*; +use anchor_client::solana_client::nonblocking::rpc_client::RpcClient; +use anchor_client::solana_client::rpc_client::RpcClient as BlockingRpcClient; +use anchor_spl::{ + associated_token::get_associated_token_address_with_program_id, + token::spl_token, + token_2022::spl_token_2022::extension::{transfer_hook, StateWithExtensions}, +}; +use solana_sdk::program_pack::Pack; use spl_associated_token_account::instruction::create_associated_token_account; -use std::ops::Deref; +use spl_transfer_hook_interface::offchain::add_extra_account_metas_for_execute; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; -use anchor_client::solana_sdk::pubkey::Pubkey; -use anchor_spl::associated_token::get_associated_token_address; -use anchor_spl::token::spl_token; -use anyhow::*; +pub async fn get_transfer_instruction( + from: Pubkey, + to: Pubkey, + mint: Pubkey, + owner: Pubkey, + rpc_client: RpcClient, + amount: u64, +) -> Result { + let account = rpc_client.get_account(&mint).await?; + + if account.owner.eq(&spl_token::ID) { + let mint_state = spl_token::state::Mint::unpack(account.data.as_ref())?; + Ok(spl_token::instruction::transfer_checked( + &account.owner, + &from, + &mint, + &to, + &owner, + &[], + amount, + mint_state.decimals, + )?) + } else { + let mint_state = + StateWithExtensions::::unpack( + account.data.as_ref(), + )?; + + let mut transfer_ix = + anchor_spl::token_2022::spl_token_2022::instruction::transfer_checked( + &account.owner, + &from, + &mint, + &to, + &owner, + &[], + amount, + mint_state.base.decimals, + )?; + + if let Some(transfer_hook_program_id) = transfer_hook::get_program_id(&mint_state) { + let blocking_rpc_client = BlockingRpcClient::new(rpc_client.url()); + + let data_fetcher = |address: Pubkey| { + let account = blocking_rpc_client + .get_account(&address) + .map(|account| account.data); + async move { + std::result::Result::Ok::< + Option>, + Box, + >(account.ok()) + } + }; + + add_extra_account_metas_for_execute( + &mut transfer_ix, + &transfer_hook_program_id, + &Pubkey::default(), + &mint, + &Pubkey::default(), + &Pubkey::default(), + 0, + data_fetcher, + ) + .await + .map_err(|e| anyhow!(e))?; + } + + Ok(transfer_ix) + } +} pub async fn get_or_create_ata + Clone>( program: &Program, @@ -18,44 +89,141 @@ pub async fn get_or_create_ata + Clone>( token_mint: Pubkey, wallet_address: Pubkey, ) -> Result { - let user_ata = get_associated_token_address(&wallet_address, &token_mint); - - let rpc_client = program.rpc(); - let user_ata_exists = rpc_client.get_account(&user_ata).is_ok(); - - match user_ata_exists { - true => Ok(user_ata), - false => { - let builder = program - .request() - .instruction(create_associated_token_account( - &program.payer(), - &wallet_address, - &token_mint, - &spl_token::ID, - )); - - builder - .send_with_spinner_and_config(transaction_config) + let rpc_client = program.async_rpc(); + let token_mint_owner = rpc_client.get_account(&token_mint).await?.owner; + + let user_ata = get_associated_token_address_with_program_id( + &wallet_address, + &token_mint, + &token_mint_owner, + ); + let user_ata_exists = rpc_client.get_account(&user_ata).await.is_ok(); + + if !user_ata_exists { + let builder = program + .request() + .instruction(create_associated_token_account( + &program.payer(), + &wallet_address, + &token_mint, + &token_mint_owner, + )); + + builder + .send_with_spinner_and_config(transaction_config) + .await?; + } + + Ok(user_ata) +} + +pub enum ActionType { + LiquidityProvision, + LiquidityMining(usize), +} + +pub async fn get_potential_token_2022_related_ix_data_and_accounts( + lb_pair: &LbPair, + rpc_client: RpcClient, + action_type: ActionType, +) -> Result, Vec)>> { + let potential_token_2022_mints = match action_type { + ActionType::LiquidityProvision => { + vec![ + (lb_pair.token_x_mint, AccountsType::TransferHookX), + (lb_pair.token_y_mint, AccountsType::TransferHookY), + ] + } + ActionType::LiquidityMining(idx) => { + vec![( + lb_pair.reward_infos[idx].mint, + AccountsType::TransferHookReward, + )] + } + }; + + let mut slices = vec![]; + let mut accounts = vec![]; + + for (mint, accounts_type) in potential_token_2022_mints { + let extra_account_metas = + get_extra_account_metas_for_transfer_hook(mint, RpcClient::new(rpc_client.url())) .await?; - Ok(user_ata) + + if !extra_account_metas.is_empty() { + slices.push(RemainingAccountsSlice { + accounts_type, + length: extra_account_metas.len() as u8, + }); + + accounts.extend(extra_account_metas); } } + + if !slices.is_empty() { + Ok(Some((slices, accounts))) + } else { + Ok(None) + } } -pub async fn get_bin_arrays_for_position + Clone>( - program: &Program, - position_address: Pubkey, -) -> Result<[Pubkey; 2]> { - let position: Position = program.account(position_address).await?; +pub async fn get_extra_account_metas_for_transfer_hook( + mint: Pubkey, + rpc_client: RpcClient, +) -> Result> { + let mint_account = rpc_client.get_account(&mint).await?; + if mint_account.owner.eq(&spl_token::ID) { + return Ok(vec![]); + } + + let mint_state = + StateWithExtensions::::unpack( + mint_account.data.as_ref(), + )?; - let lower_bin_array_idx = BinArray::bin_id_to_bin_array_index(position.lower_bin_id)?; - let upper_bin_array_idx = lower_bin_array_idx.checked_add(1).context("MathOverflow")?; + if let Some(transfer_hook_program_id) = transfer_hook::get_program_id(&mint_state) { + let mut transfer_ix = + anchor_spl::token_2022::spl_token_2022::instruction::transfer_checked( + &mint_account.owner, + &Pubkey::default(), + &mint, + &Pubkey::default(), + &Pubkey::default(), + &[], + 0, + mint_state.base.decimals, + )?; - let (lower_bin_array, _bump) = - derive_bin_array_pda(position.lb_pair, lower_bin_array_idx.into()); - let (upper_bin_array, _bump) = - derive_bin_array_pda(position.lb_pair, upper_bin_array_idx.into()); + let blocking_rpc_client = BlockingRpcClient::new(rpc_client.url()); + + let data_fetcher = |address: Pubkey| { + let account = blocking_rpc_client + .get_account(&address) + .map(|account| account.data); + async move { + std::result::Result::Ok::>, Box>( + account.ok(), + ) + } + }; + + add_extra_account_metas_for_execute( + &mut transfer_ix, + &transfer_hook_program_id, + &Pubkey::default(), + &mint, + &Pubkey::default(), + &Pubkey::default(), + 0, + data_fetcher, + ) + .await + .map_err(|e| anyhow!(e))?; + + // Skip 0 -> 4, source, mint, destination, authority + let transfer_hook_required_accounts = transfer_ix.accounts[5..].to_vec(); + return Ok(transfer_hook_required_accounts); + } - Ok([lower_bin_array, upper_bin_array]) + Ok(vec![]) } diff --git a/cli/src/instructions/withdraw_protocol_fee.rs b/cli/src/instructions/withdraw_protocol_fee.rs index 8d43a87c..12385522 100644 --- a/cli/src/instructions/withdraw_protocol_fee.rs +++ b/cli/src/instructions/withdraw_protocol_fee.rs @@ -1,25 +1,14 @@ -use std::ops::Deref; +use anchor_spl::associated_token::get_associated_token_address_with_program_id; -use anchor_client::solana_client::rpc_config::RpcSendTransactionConfig; - -use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use anchor_client::{solana_sdk::pubkey::Pubkey, solana_sdk::signer::Signer, Program}; -use anchor_spl::associated_token::get_associated_token_address; - -use anyhow::*; -use lb_clmm::accounts; -use lb_clmm::instruction; - -use lb_clmm::state::lb_pair::LbPair; - -#[derive(Debug)] +use crate::*; +#[derive(Debug, Parser)] pub struct WithdrawProtocolFeeParams { pub lb_pair: Pubkey, pub amount_x: u64, pub amount_y: u64, } -pub async fn withdraw_protocol_fee + Clone>( +pub async fn execute_withdraw_protocol_fee + Clone>( params: WithdrawProtocolFeeParams, program: &Program, transaction_config: RpcSendTransactionConfig, @@ -30,36 +19,79 @@ pub async fn withdraw_protocol_fee + Clone>( amount_y, } = params; - let lb_pair_state: LbPair = program.account(lb_pair).await?; + let rpc_client = program.async_rpc(); + + let lb_pair_state = rpc_client + .get_account_and_deserialize(&lb_pair, |account| { + Ok(LbPairAccount::deserialize(&account.data)?.0) + }) + .await?; + + let [token_x_program, token_y_program] = lb_pair_state.get_token_programs()?; + + let receiver_token_x = get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_x_mint, + &token_x_program, + ); + + let receiver_token_y = get_associated_token_address_with_program_id( + &program.payer(), + &lb_pair_state.token_y_mint, + &token_y_program, + ); + + let main_accounts: [AccountMeta; WITHDRAW_PROTOCOL_FEE_IX_ACCOUNTS_LEN] = + WithdrawProtocolFeeKeys { + lb_pair, + reserve_x: lb_pair_state.reserve_x, + reserve_y: lb_pair_state.reserve_y, + token_x_mint: lb_pair_state.token_x_mint, + token_y_mint: lb_pair_state.token_y_mint, + token_x_program, + token_y_program, + receiver_token_x, + receiver_token_y, + memo_program: spl_memo::ID, + } + .into(); + + let mut remaining_accounts_info = RemainingAccountsInfo { slices: vec![] }; + let mut remaining_accounts = vec![]; + + if let Some((slices, transfer_hook_remaining_accounts)) = + get_potential_token_2022_related_ix_data_and_accounts( + &lb_pair_state, + program.async_rpc(), + ActionType::LiquidityProvision, + ) + .await? + { + remaining_accounts_info.slices = slices; + remaining_accounts.extend(transfer_hook_remaining_accounts); + }; - let receiver_token_x = - get_associated_token_address(&program.payer(), &lb_pair_state.token_x_mint); + let data = WithdrawProtocolFeeIxData(WithdrawProtocolFeeIxArgs { + amount_x, + amount_y, + remaining_accounts_info, + }) + .try_to_vec()?; - let receiver_token_y = - get_associated_token_address(&program.payer(), &lb_pair_state.token_y_mint); + let accounts = [main_accounts.to_vec(), remaining_accounts].concat(); - let accounts = accounts::WithdrawProtocolFee { - lb_pair, - reserve_x: lb_pair_state.reserve_x, - reserve_y: lb_pair_state.reserve_y, - token_x_mint: lb_pair_state.token_x_mint, - token_y_mint: lb_pair_state.token_y_mint, - token_x_program: anchor_spl::token::ID, - token_y_program: anchor_spl::token::ID, - fee_owner: program.payer(), - receiver_token_x, - receiver_token_y, + let withdraw_ix = Instruction { + program_id: dlmm_interface::ID, + accounts, + data, }; - let ix = instruction::WithdrawProtocolFee { amount_x, amount_y }; - - let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(1_400_000); + let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(200_000); let request_builder = program.request(); let signature = request_builder .instruction(compute_budget_ix) - .accounts(accounts) - .args(ix) + .instruction(withdraw_ix) .send_with_spinner_and_config(transaction_config) .await; diff --git a/cli/src/main.rs b/cli/src/main.rs index c969a0b3..833747c2 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,88 +1,32 @@ -use std::rc::Rc; -use std::time::Duration; - use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; use anchor_client::solana_sdk::instruction::Instruction; -use anchor_client::Client; +use anchor_client::*; use anchor_client::{ solana_client::rpc_config::RpcSendTransactionConfig, + solana_sdk::pubkey::Pubkey, solana_sdk::{ commitment_config::CommitmentConfig, signer::{keypair::*, Signer}, }, }; +use anchor_lang::prelude::AccountMeta; use anyhow::*; use clap::*; +use commons::*; +use solana_account_decoder::*; +use std::ops::Deref; +use std::rc::Rc; +use std::time::Duration; mod args; mod instructions; mod math; use args::*; -use instructions::initialize_customizable_permissionless_lb_pair::InitCustomizablePermissionlessLbPairParameters; -use instructions::initialize_lb_pair::*; -use instructions::seed_liquidity_from_operator::{ - seed_liquidity_by_operator, SeedLiquidityByOperatorParameters, -}; -use instructions::seed_liquidity_single_bin::{ - seed_liquidity_single_bin, SeedLiquiditySingleBinParameters, -}; -use instructions::seed_liquidity_single_bin_by_operator::{ - seed_liquidity_single_bin_by_operator, SeedLiquiditySingleBinByOperatorParameters, -}; -use lb_clmm::state::preset_parameters::PresetParameter; - -use crate::instructions::initialize_bin_array_with_bin_range::{ - initialize_bin_array_with_bin_range, InitBinArrayWithBinRangeParameters, -}; -use crate::instructions::initialize_position_with_price_range::{ - initialize_position_with_price_range, InitPositionWithPriceRangeParameters, -}; -use crate::instructions::initialize_preset_parameter::InitPresetParameters; -use crate::{ - args::Command, - instructions::{ - add_liquidity::{add_liquidity, AddLiquidityParam}, - check_my_balance::{check_my_balance, CheckMyBalanceParameters}, - claim_fee::claim_fee, - claim_reward::*, - close_position::close_position, - close_preset_parameter::close_preset_parameter, - fund_reward::*, - increase_length::{increase_length, IncreaseLengthParams}, - initialize_bin_array::{initialize_bin_array, InitBinArrayParameters}, - initialize_bin_array_with_price_range::{ - initialize_bin_array_with_price_range, InitBinArrayWithPriceRangeParameters, - }, - initialize_customizable_permissionless_lb_pair::initialize_customizable_permissionless_lb_pair, - initialize_permission_lb_pair::{ - initialize_permission_lb_pair, InitPermissionLbPairParameters, - }, - initialize_position::{initialize_position, InitPositionParameters}, - initialize_preset_parameter::initialize_preset_parameter, - initialize_reward::*, - list_all_binstep::list_all_binstep, - remove_liquidity::{remove_liquidity, RemoveLiquidityParameters}, - remove_liquidity_by_price_range::{ - remove_liquidity_by_price_range, RemoveLiquidityByPriceRangeParameters, - }, - seed_liquidity::{seed_liquidity, SeedLiquidityParameters}, - set_activation_point::*, - set_pre_activation_duration::{set_pre_activation_duration, SetPreactivationDurationParam}, - set_pre_activation_swap_address::{ - set_pre_activation_swap_address, SetPreactivationSwapAddressParam, - }, - show_pair::show_pair, - simulate_swap_demand::{simulate_swap_demand, SimulateSwapDemandParameters}, - swap_exact_in::{swap, SwapExactInParameters}, - swap_exact_out::{swap_exact_out, SwapExactOutParameters}, - swap_with_price_impact::{swap_with_price_impact, SwapWithPriceImpactParameters}, - toggle_pair_status::toggle_pool_status, - update_reward_duration::*, - update_reward_funder::*, - withdraw_protocol_fee::{withdraw_protocol_fee, WithdrawProtocolFeeParams}, - }, -}; +use commons::rpc_client_extension::*; +use dlmm_interface::*; +use instructions::*; +use math::*; fn get_set_compute_unit_price_ix(micro_lamports: u64) -> Option { if micro_lamports > 0 { @@ -104,13 +48,14 @@ async fn main() -> Result<()> { println!("Wallet {:#?}", payer.pubkey()); let commitment_config = CommitmentConfig::confirmed(); + let client = Client::new_with_options( cli.config_override.cluster, Rc::new(Keypair::from_bytes(&payer.to_bytes())?), commitment_config, ); - let amm_program = client.program(lb_clmm::ID).unwrap(); + let program = client.program(dlmm_interface::ID).unwrap(); let transaction_config: RpcSendTransactionConfig = RpcSendTransactionConfig { skip_preflight: false, @@ -123,581 +68,173 @@ async fn main() -> Result<()> { let compute_unit_price_ix = get_set_compute_unit_price_ix(cli.config_override.priority_fee); match cli.command { - Command::InitializePair { - initial_price, - token_mint_x, - token_mint_y, - preset_parameter, - } => { - let params = InitLbPairParameters { - token_mint_x, - token_mint_y, - preset_parameter, - initial_price, - }; - initialize_lb_pair(params, &amm_program, transaction_config).await?; + DLMMCommand::InitializePair(params) => { + execute_initialize_lb_pair(params, &program, transaction_config).await?; } - Command::InitializeBinArray { - bin_array_index, - lb_pair, - } => { - let params = InitBinArrayParameters { - bin_array_index, - lb_pair, - }; - initialize_bin_array(params, &amm_program, transaction_config).await?; + DLMMCommand::InitializeBinArray(params) => { + execute_initialize_bin_array(params, &program, transaction_config).await?; } - Command::InitializeBinArrayWithPriceRange { - lower_price, - upper_price, - lb_pair, - } => { - let params = InitBinArrayWithPriceRangeParameters { - lb_pair, - lower_price, - upper_price, - }; - initialize_bin_array_with_price_range(params, &amm_program, transaction_config).await?; + DLMMCommand::InitializeBinArrayWithPriceRange(params) => { + execute_initialize_bin_array_with_price_range(params, &program, transaction_config) + .await?; } - Command::InitializeBinArrayWithBinRange { - lb_pair, - lower_bin_id, - upper_bin_id, - } => { - let params = InitBinArrayWithBinRangeParameters { - lb_pair, - lower_bin_id, - upper_bin_id, - }; - initialize_bin_array_with_bin_range(params, &amm_program, transaction_config).await?; + DLMMCommand::InitializeBinArrayWithBinRange(params) => { + execute_initialize_bin_array_with_bin_range(params, &program, transaction_config) + .await?; } - Command::InitializePositionWithPriceRange { - lb_pair, - lower_price, - width, - nft_mint, - } => { - let params = InitPositionWithPriceRangeParameters { - lb_pair, - lower_price, - width, - nft_mint, - }; - initialize_position_with_price_range(params, &amm_program, transaction_config).await?; + DLMMCommand::InitializePositionWithPriceRange(params) => { + execute_initialize_position_with_price_range(params, &program, transaction_config) + .await?; } - Command::InitializePosition { - lb_pair, - lower_bin_id, - width, - nft_mint, - } => { - let params = InitPositionParameters { - lb_pair, - lower_bin_id, - nft_mint, - width, - }; - initialize_position(params, &amm_program, transaction_config).await?; + DLMMCommand::InitializePosition(params) => { + execute_initialize_position(params, &program, transaction_config).await?; } - Command::AddLiquidity { - lb_pair, - position, - amount_x, - amount_y, - bin_liquidity_distribution, - } => { - let params = AddLiquidityParam { - lb_pair, - amount_x, - amount_y, - bin_liquidity_distribution, - position, - }; - add_liquidity(params, &amm_program, transaction_config).await?; + DLMMCommand::AddLiquidity(params) => { + execute_add_liquidity(params, &program, transaction_config).await?; } - Command::RemoveLiquidity { - lb_pair, - position, - bin_liquidity_removal, - } => { - let params = RemoveLiquidityParameters { - lb_pair, - position, - bin_liquidity_removal, - }; - remove_liquidity(params, &amm_program, transaction_config).await?; + DLMMCommand::RemoveLiquidity(params) => { + execute_remove_liquidity(params, &program, transaction_config).await?; } - Command::SwapExactIn { - lb_pair, - amount_in, - swap_for_y, - } => { - let params = SwapExactInParameters { - amount_in, - lb_pair, - swap_for_y, - }; - swap(params, &amm_program, transaction_config).await?; + DLMMCommand::SwapExactIn(params) => { + execute_swap(params, &program, transaction_config).await?; } - Command::ShowPair { lb_pair } => { - show_pair(lb_pair, &amm_program).await?; + DLMMCommand::ShowPair(params) => { + execute_show_pair(params, &program).await?; } - Command::ShowPosition { position } => { - let position: lb_clmm::state::position::Position = - amm_program.account(position).await?; - println!("{:#?}", position); + DLMMCommand::ShowPosition(params) => { + execute_show_position(params, &program).await?; } - - Command::ClaimReward { - lb_pair, - reward_index, - position, - } => { - let params = ClaimRewardParams { - lb_pair, - reward_index, - position, - }; - claim_reward(params, &amm_program, transaction_config).await?; + DLMMCommand::ClaimReward(params) => { + execute_claim_reward(params, &program, transaction_config).await?; } - Command::UpdateRewardDuration { - lb_pair, - reward_index, - reward_duration, - } => { - let params = UpdateRewardDurationParams { - lb_pair, - reward_index, - reward_duration, - }; - update_reward_duration(params, &amm_program, transaction_config).await?; + DLMMCommand::UpdateRewardDuration(params) => { + execute_update_reward_duration(params, &program, transaction_config).await?; } - Command::UpdateRewardFunder { - lb_pair, - reward_index, - funder, - } => { - let params = UpdateRewardFunderParams { - lb_pair, - reward_index, - funder, - }; - update_reward_funder(params, &amm_program, transaction_config).await?; + DLMMCommand::UpdateRewardFunder(params) => { + execute_update_reward_funder(params, &program, transaction_config).await?; } - Command::ClosePosition { position } => { - close_position(position, &amm_program, transaction_config).await?; + DLMMCommand::ClosePosition(params) => { + execute_close_position(params, &program, transaction_config).await?; } - Command::ClaimFee { position } => { - claim_fee(position, &amm_program, transaction_config).await?; + DLMMCommand::ClaimFee(params) => { + execute_claim_fee(params, &program, transaction_config).await?; } - Command::IncreaseLength { - lb_pair, - length_to_add, - } => { - let params = IncreaseLengthParams { - lb_pair, - length_to_add, - }; - increase_length(params, &amm_program, transaction_config).await?; + DLMMCommand::IncreaseLength(params) => { + execute_increase_length(params, &program, transaction_config).await?; } - - Command::ShowPresetParameter { preset_parameter } => { - let preset_param_state: PresetParameter = amm_program.account(preset_parameter).await?; - println!("{:#?}", preset_param_state); + DLMMCommand::ShowPresetParameter(params) => { + execute_show_preset_parameters(params, &program).await?; } - Command::ListAllBinStep => { - list_all_binstep(&amm_program).await?; - } - Command::SimulateSwapDemand { - lb_pair, - x_amount, - y_amount, - side_ratio, - } => { - let params = SimulateSwapDemandParameters { - lb_pair, - x_amount, - y_amount, - side_ratio, - }; - simulate_swap_demand(params, &amm_program, transaction_config).await?; + DLMMCommand::ListAllBinStep => { + execute_list_all_bin_step(&program).await?; } - Command::SwapExactOut { - lb_pair, - amount_out, - swap_for_y, - } => { - let params = SwapExactOutParameters { - lb_pair, - amount_out, - swap_for_y, - }; - swap_exact_out(params, &amm_program, transaction_config).await?; + DLMMCommand::SwapExactOut(params) => { + execute_swap_exact_out(params, &program, transaction_config).await?; } - Command::SwapWithPriceImpact { - lb_pair, - amount_in, - swap_for_y, - price_impact_bps, - } => { - let params = SwapWithPriceImpactParameters { - lb_pair, - amount_in, - swap_for_y, - price_impact_bps, - }; - swap_with_price_impact(params, &amm_program, transaction_config).await?; + DLMMCommand::SwapWithPriceImpact(params) => { + execute_swap_with_price_impact(params, &program, transaction_config).await?; } - Command::InitializeCustomizablePermissionlessLbPair { - token_mint_x, - token_mint_y, - bin_step, - initial_price, - base_fee_bps, - activation_type, - has_alpha_vault, - activation_point, - selective_rounding, - } => { - let params = InitCustomizablePermissionlessLbPairParameters { - token_mint_x, - token_mint_y, - bin_step, - initial_price, - base_fee_bps, - activation_point, - has_alpha_vault, - activation_type, - selective_rounding, - }; - initialize_customizable_permissionless_lb_pair( + DLMMCommand::InitializeCustomizablePermissionlessLbPair(params) => { + execute_initialize_customizable_permissionless_lb_pair( params, - &amm_program, + &program, transaction_config, ) .await?; } - Command::SeedLiquidity { - lb_pair, - base_position_path, - amount, - min_price, - max_price, - base_pubkey, - curvature, - position_owner_path, - max_retries, - } => { + DLMMCommand::SeedLiquidity(params) => { let mut retry_count = 0; - loop { - let position_base_kp = read_keypair_file(base_position_path.clone()) - .expect("position base keypair file not found"); - - let position_owner_kp = read_keypair_file(position_owner_path.clone()) - .expect("position owner keypair file not found"); - - let params = SeedLiquidityParameters { - lb_pair, - position_base_kp, - amount, - min_price, - max_price, - base_pubkey, - position_owner_kp, - curvature, - }; - if let Err(err) = seed_liquidity( - params, - &amm_program, - transaction_config, - compute_unit_price_ix.clone(), - ) - .await - { - println!("Error: {}", err); - retry_count += 1; - if retry_count >= max_retries { - println!("Exceeded max retries {}", max_retries); - break; - } - tokio::time::sleep(Duration::from_secs(16)).await; - } else { + while let Err(err) = execute_seed_liquidity( + params.clone(), + &program, + transaction_config, + compute_unit_price_ix.clone(), + ) + .await + { + println!("Error: {}", err); + retry_count += 1; + if retry_count >= params.max_retries { + println!("Exceeded max retries {}", params.max_retries); break; } + tokio::time::sleep(Duration::from_secs(16)).await; } } - Command::SeedLiquidityByOperator { - lb_pair, - base_position_path, - amount, - min_price, - max_price, - base_pubkey, - curvature, - position_owner, - fee_owner, - lock_release_point, - max_retries, - } => { + DLMMCommand::SeedLiquidityByOperator(params) => { let mut retry_count = 0; - loop { - let position_base_kp = read_keypair_file(base_position_path.clone()) - .expect("position base keypair file not found"); - - let params = SeedLiquidityByOperatorParameters { - lb_pair, - position_base_kp, - amount, - min_price, - max_price, - base_pubkey, - position_owner, - fee_owner, - lock_release_point, - curvature, - }; - if let Err(err) = seed_liquidity_by_operator( - params, - &amm_program, - transaction_config, - compute_unit_price_ix.clone(), - ) - .await - { - println!("Error: {}", err); - retry_count += 1; - if retry_count >= max_retries { - println!("Exceeded max retries {}", max_retries); - break; - } - tokio::time::sleep(Duration::from_secs(16)).await; - } else { + while let Err(err) = execute_seed_liquidity_by_operator( + params.clone(), + &program, + transaction_config, + compute_unit_price_ix.clone(), + ) + .await + { + println!("Error: {}", err); + retry_count += 1; + if retry_count >= params.max_retries { + println!("Exceeded max retries {}", params.max_retries); break; } + tokio::time::sleep(Duration::from_secs(16)).await; } } - Command::SeedLiquiditySingleBin { - lb_pair, - base_position_path, - base_pubkey, - amount, - price, - position_owner_path, - selective_rounding, - } => { - let position_base_kp = read_keypair_file(base_position_path) - .expect("position base keypair file not found"); - - let position_owner_kp = read_keypair_file(position_owner_path) - .expect("position owner keypair file not found"); - - let params = SeedLiquiditySingleBinParameters { - lb_pair, - position_base_kp, - amount, - price, - base_pubkey, - position_owner_kp, - selective_rounding, - }; - seed_liquidity_single_bin( + DLMMCommand::SeedLiquiditySingleBin(params) => { + execute_seed_liquidity_single_bin( params, - &amm_program, + &program, transaction_config, compute_unit_price_ix, ) .await?; } - Command::SeedLiquiditySingleBinByOperator { - lb_pair, - base_position_path, - base_pubkey, - amount, - price, - position_owner, - fee_owner, - lock_release_point, - selective_rounding, - } => { - let position_base_kp = read_keypair_file(base_position_path) - .expect("position base keypair file not found"); - - let params = SeedLiquiditySingleBinByOperatorParameters { - lb_pair, - position_base_kp, - amount, - price, - base_pubkey, - position_owner, - fee_owner, - lock_release_point, - selective_rounding, - }; - seed_liquidity_single_bin_by_operator( + DLMMCommand::SeedLiquiditySingleBinByOperator(params) => { + execute_seed_liquidity_single_bin_by_operator( params, - &amm_program, + &program, transaction_config, compute_unit_price_ix, ) .await?; } - Command::Admin(admin_command) => match admin_command { - AdminCommand::InitializePermissionPair { - bin_step, - token_mint_x, - token_mint_y, - initial_price, - base_keypair_path, - base_fee_bps, - lock_duration, - activation_type, - } => { - let base_keypair = - read_keypair_file(base_keypair_path).expect("base keypair file not found"); - let params = InitPermissionLbPairParameters { - base_keypair, - bin_step, - initial_price, - token_mint_x, - token_mint_y, - base_fee_bps, - lock_duration, - activation_type, - }; - initialize_permission_lb_pair(params, &amm_program, transaction_config).await?; + DLMMCommand::Admin(command) => match command { + AdminCommand::InitializePermissionPair(params) => { + execute_initialize_permission_lb_pair(params, &program, transaction_config).await?; } - AdminCommand::TogglePoolStatus { lb_pair } => { - toggle_pool_status(lb_pair, &amm_program, transaction_config).await?; + AdminCommand::TogglePoolStatus(params) => { + execute_toggle_pool_status(params, &program, transaction_config).await?; } - AdminCommand::RemoveLiquidityByPriceRange { - lb_pair, - base_position_key, - min_price, - max_price, - } => { - let params = RemoveLiquidityByPriceRangeParameters { - lb_pair, - base_position_key, - min_price, - max_price, - }; - remove_liquidity_by_price_range(params, &amm_program, transaction_config).await?; + AdminCommand::RemoveLiquidityByPriceRange(params) => { + execute_remove_liquidity_by_price_range(params, &program, transaction_config) + .await?; } - AdminCommand::CheckMyBalance { - lb_pair, - base_position_key, - min_price, - max_price, - } => { - let params = CheckMyBalanceParameters { - lb_pair, - base_position_key, - min_price, - max_price, - }; - check_my_balance(params, &amm_program).await?; + AdminCommand::SetActivationPoint(params) => { + execute_set_activation_point(params, &program, transaction_config).await?; } - AdminCommand::SetActivationPoint { - activation_point, - lb_pair, - } => { - let params = SetActivationPointParam { - activation_point, - lb_pair, - }; - set_activation_point(params, &amm_program, transaction_config).await?; + AdminCommand::ClosePresetParameter(params) => { + execute_close_preset_parameter(params, &program, transaction_config).await?; } - AdminCommand::ClosePresetParameter { preset_parameter } => { - close_preset_parameter(preset_parameter, &amm_program, transaction_config).await?; - } - AdminCommand::InitializePresetParameter { - bin_step, - base_factor, - filter_period, - decay_period, - reduction_factor, - variable_fee_control, - max_volatility_accumulator, - min_bin_id, - max_bin_id, - protocol_share, - } => { - let params = InitPresetParameters { - base_factor, - bin_step, - decay_period, - filter_period, - max_bin_id, - max_volatility_accumulator, - - min_bin_id, - protocol_share, - reduction_factor, - variable_fee_control, - }; - initialize_preset_parameter(params, &amm_program, transaction_config).await?; + AdminCommand::InitializePresetParameter(params) => { + execute_initialize_preset_parameter(params, &program, transaction_config).await?; } - AdminCommand::WithdrawProtocolFee { - lb_pair, - amount_x, - amount_y, - } => { - let params = WithdrawProtocolFeeParams { - lb_pair, - amount_x, - amount_y, - }; - withdraw_protocol_fee(params, &amm_program, transaction_config).await?; + AdminCommand::WithdrawProtocolFee(params) => { + execute_withdraw_protocol_fee(params, &program, transaction_config).await?; } - AdminCommand::FundReward { - lb_pair, - reward_index, - funding_amount, - } => { - let params = FundRewardParams { - lb_pair, - reward_index, - funding_amount, - }; - fund_reward(params, &amm_program, transaction_config).await?; + AdminCommand::FundReward(params) => { + execute_fund_reward(params, &program, transaction_config).await?; } - AdminCommand::InitializeReward { - lb_pair, - reward_mint, - reward_index, - reward_duration, - funder, - } => { - let params = InitializeRewardParams { - lb_pair, - reward_index, - reward_mint, - reward_duration, - funder, - }; - initialize_reward(params, &amm_program, transaction_config).await?; + AdminCommand::InitializeReward(params) => { + execute_initialize_reward(params, &program, transaction_config).await?; } - AdminCommand::SetPreActivationSwapAddress { - lb_pair, - pre_activation_swap_address, - } => { - let params = SetPreactivationSwapAddressParam { - lb_pair, - pre_activation_swap_address, - }; - set_pre_activation_swap_address(params, &amm_program, transaction_config).await?; + AdminCommand::SetPreActivationSwapAddress(params) => { + execute_set_pre_activation_swap_address(params, &program, transaction_config) + .await?; } - AdminCommand::SetPreActivationDuration { - lb_pair, - pre_activation_duration, - } => { - let params = SetPreactivationDurationParam { - lb_pair, - pre_activation_duration, - }; - set_pre_activation_duration(params, &amm_program, transaction_config).await?; + AdminCommand::SetPreActivationDuration(params) => { + execute_set_pre_activation_duration(params, &program, transaction_config).await?; } }, }; diff --git a/cli/src/math.rs b/cli/src/math.rs index 6a194655..2914206d 100644 --- a/cli/src/math.rs +++ b/cli/src/math.rs @@ -1,57 +1,12 @@ use anyhow::{anyhow, Result}; -use lb_clmm::constants::BASIS_POINT_MAX; -use lb_clmm::math::price_math::get_price_from_id; -use lb_clmm::math::u128x128_math::Rounding; +use commons::{BASIS_POINT_MAX, SCALE_OFFSET}; +use dlmm_interface::Rounding; use rust_decimal::MathematicalOps; use rust_decimal::{ prelude::{FromPrimitive, ToPrimitive}, Decimal, }; -pub fn find_swappable_min_max_bin_id(bin_step: u16) -> Result<(i32, i32)> { - let base = 1.0f64 + (bin_step as f64 / BASIS_POINT_MAX as f64); - let max_price_supported = 2.0f64.powi(64); // We use u64xu64 math - let n = (max_price_supported.log10() / base.log10()) as i32; - - let mut min_bin_id = -n; - let mut max_bin_id = n; - - let min_q64_price = 1; - let max_q64_price = u128::MAX; - - loop { - match get_price_from_id(min_bin_id, bin_step) { - Ok(price) => { - if price > min_q64_price { - break; - } else { - min_bin_id += 1; - } - } - Err(_) => { - min_bin_id += 1; - } - } - } - - loop { - match get_price_from_id(max_bin_id, bin_step) { - Ok(price) => { - if price < max_q64_price { - break; - } else { - max_bin_id -= 1; - } - } - Err(_) => { - max_bin_id -= 1; - } - } - } - - Ok((min_bin_id, max_bin_id)) -} - pub fn compute_base_factor_from_fee_bps(bin_step: u16, fee_bps: u16) -> Result { let computed_base_factor = fee_bps as f64 * 10_000.0f64 / bin_step as f64; @@ -107,7 +62,7 @@ pub fn get_id_from_price(bin_step: u16, price: &Decimal, rounding: Rounding) -> /// Convert Q64xQ64 price to human readable decimal. This is price per lamport. pub fn q64x64_price_to_decimal(q64x64_price: u128) -> Option { let q_price = Decimal::from_u128(q64x64_price)?; - let scale_off = Decimal::TWO.powu(lb_clmm::math::u64x64_math::SCALE_OFFSET.into()); + let scale_off = Decimal::TWO.powu(SCALE_OFFSET.into()); q_price.checked_div(scale_off) } @@ -137,106 +92,3 @@ pub fn price_per_lamport_to_price_per_token( .checked_mul(price_per_lamport)? .checked_div(one_ui_quote_token_amount) } - -#[cfg(test)] -mod tests { - use super::*; - use lb_clmm::math::{price_math::get_price_from_id, u64x64_math::SCALE_OFFSET}; - use proptest::proptest; - - proptest! { - #[test] - fn test_get_id_from_price_range( - bin_step in 1..=BASIS_POINT_MAX as u16, - price in 0.000000000000000001f64..=u64::MAX as f64 - ) { - let price = Decimal::from_f64(price); - assert!(price.is_some()); - let id = get_id_from_price(bin_step, &price.unwrap(), Rounding::Up); - assert!(id.is_some()); - } - } - - #[test] - fn test_q64x64_price_to_decimal() { - let q64x64_price: u128 = 408988714829317079040; - let decimal_price = q64x64_price_to_decimal(q64x64_price); - - assert!(decimal_price.is_some()); - assert_eq!( - decimal_price.unwrap().to_string(), - "22.17132265700000104402533907" - ); - } - - #[test] - fn test_price_per_lamport_to_price_per_token() { - let price_per_lamport = 0.211713226574294_f64; - let base_token_decimal = 8u8; - let quote_token_decimal = 6u8; - - let price_per_token = price_per_lamport_to_price_per_token( - price_per_lamport, - base_token_decimal, - quote_token_decimal, - ); - assert!(price_per_token.is_some()); - - let recomputed_price_per_lamport = price_per_token.unwrap() - * Decimal::TEN.powu(quote_token_decimal.into()) - / Decimal::TEN.powu(base_token_decimal.into()); - - let recomputed_price_per_lamport = recomputed_price_per_lamport.to_f64(); - assert!(recomputed_price_per_lamport.is_some()); - assert_eq!(Some(price_per_lamport), recomputed_price_per_lamport); - } - - #[test] - fn test_price_per_token_to_per_lamport() { - let price_per_token = 9.95769; - let base_token_decimal = 8u8; - let quote_token_decimal = 6u8; - - let price_per_lamport = price_per_token_to_per_lamport( - price_per_token, - base_token_decimal, - quote_token_decimal, - ); - assert!(price_per_lamport.is_some()); - - let recomputed_price_per_token = price_per_lamport.unwrap() - * Decimal::TEN.powu(base_token_decimal.into()) - / Decimal::TEN.powu(quote_token_decimal.into()); - - let recomputed_price_per_token = recomputed_price_per_token.to_f64(); - assert!(recomputed_price_per_token.is_some()); - - assert_eq!(Some(price_per_token), recomputed_price_per_token); - } - - #[test] - fn test_get_id_from_price() { - let bin_step = 15; - let quote_decimal = 6u8; - let price = Decimal::from_f64(208.929000).unwrap(); - - let computed_id = get_id_from_price(bin_step, &price, Rounding::Up); - assert!(computed_id.is_some()); - - let program_computed_price = get_price_from_id(computed_id.unwrap(), bin_step); - assert!(program_computed_price.is_ok()); - - let computed_price_fixed = Decimal::from_u128(program_computed_price.unwrap()); - assert!(computed_price_fixed.is_some()); - - let fixed_to_dec_scale_off = Decimal::TWO.powu(SCALE_OFFSET.into()); - - let computed_price_dec = (computed_price_fixed.unwrap() - * Decimal::TEN.powu(quote_decimal.into()) - / fixed_to_dec_scale_off) - .floor(); - - let computed_price = computed_price_dec.to_u64(); - assert_eq!(computed_price, Some(208929004)); - } -} diff --git a/commons/Cargo.toml b/commons/Cargo.toml index 8f282f6c..f74b9a12 100644 --- a/commons/Cargo.toml +++ b/commons/Cargo.toml @@ -5,10 +5,12 @@ edition = "2021" description = "Common libraries for DLMM" authors = ["tian "] + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] anchor-client = { workspace = true, features = ["async"] } +anchor-spl = { workspace = true } anyhow = { workspace = true } dlmm_interface = { path = "../dlmm_interface" } tokio = { workspace = true, features = ["full", "parking_lot"] } @@ -17,10 +19,11 @@ solana-sdk = { workspace = true } ruint = { workspace = true } num-traits = { workspace = true } num-integer = { workspace = true } +bytemuck = { workspace = true } +async-trait = { workspace = true } [dev-dependencies] -anchor-spl = { workspace = true } spl-associated-token-account = { workspace = true } -solana-program-test = "1.16.0" +solana-program-test = "1.17.0" assert_matches = "1.5.0" -solana-program = "1.16.0" +solana-program = "1.17.0" diff --git a/commons/src/content_loaders/mod.rs b/commons/src/content_loaders/mod.rs new file mode 100644 index 00000000..9b32c5d3 --- /dev/null +++ b/commons/src/content_loaders/mod.rs @@ -0,0 +1,2 @@ +mod position_v3; +pub use position_v3::*; diff --git a/commons/src/content_loaders/position_v3.rs b/commons/src/content_loaders/position_v3.rs new file mode 100644 index 00000000..56b26628 --- /dev/null +++ b/commons/src/content_loaders/position_v3.rs @@ -0,0 +1,37 @@ +use crate::*; +use dlmm_interface::{PositionBinData, PositionV3, PositionV3Account}; + +// std::mem::size_of is safe because PositionV3 implements bytemuck::Pod +pub const GLOBAL_DATA_SPACE: usize = 8 + std::mem::size_of::(); + +#[derive(Debug, Clone)] +pub struct DynamicPosition { + pub global_data: PositionV3, + pub position_bin_data: Vec, +} + +impl DynamicPosition { + // Same interface as solores + pub fn deserialize(buf: &[u8]) -> Result { + let global_data = PositionV3Account::deserialize(buf)?.0; + + let position_bin_bytes = &buf[GLOBAL_DATA_SPACE..]; + let position_bin_data = + bytemuck::cast_slice::(position_bin_bytes).to_owned(); + + Ok(Self { + global_data, + position_bin_data, + }) + } + + pub fn is_empty(&self) -> bool { + for bin in self.position_bin_data.iter() { + if bin.liquidity_share > 0 { + return false; + } + } + + true + } +} diff --git a/commons/src/conversions/mod.rs b/commons/src/conversions/mod.rs index ed179a9f..2770908a 100644 --- a/commons/src/conversions/mod.rs +++ b/commons/src/conversions/mod.rs @@ -6,3 +6,6 @@ pub use pair_type::*; pub mod activation_type; pub use activation_type::*; + +pub mod token_program_flag; +pub use token_program_flag::*; diff --git a/commons/src/conversions/token_program_flag.rs b/commons/src/conversions/token_program_flag.rs new file mode 100644 index 00000000..5d5779b9 --- /dev/null +++ b/commons/src/conversions/token_program_flag.rs @@ -0,0 +1,27 @@ +use dlmm_interface::TokenProgramFlags; +use std::ops::Deref; + +pub struct TokenProgramFlagWrapper(TokenProgramFlags); + +impl Deref for TokenProgramFlagWrapper { + type Target = TokenProgramFlags; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl TryFrom for TokenProgramFlagWrapper { + type Error = anyhow::Error; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(TokenProgramFlagWrapper(TokenProgramFlags::TokenProgram)), + 1 => Ok(TokenProgramFlagWrapper(TokenProgramFlags::TokenProgram2022)), + _ => Err(anyhow::anyhow!( + "Invalid TokenProgramFlags value: {}", + value + )), + } + } +} diff --git a/commons/src/extensions/lb_pair.rs b/commons/src/extensions/lb_pair.rs index 74c56329..ae8461c9 100644 --- a/commons/src/extensions/lb_pair.rs +++ b/commons/src/extensions/lb_pair.rs @@ -1,5 +1,9 @@ use crate::*; +use anchor_spl::token::spl_token; +use anchor_spl::token_2022::spl_token_2022; use ruint::aliases::U1024; +use solana_sdk::pubkey::Pubkey; +use std::ops::Deref; use std::ops::Shl; use std::ops::Shr; @@ -14,6 +18,7 @@ pub trait LbPairExtension { fn get_total_fee(&self) -> Result; fn get_base_fee(&self) -> Result; fn get_variable_fee(&self) -> Result; + fn get_token_programs(&self) -> Result<[Pubkey; 2]>; fn compute_variable_fee(&self, volatility_accumulator: u32) -> Result; fn compute_protocol_fee(&self, fee_amount: u64) -> Result; fn compute_fee_from_amount(&self, amount_with_fees: u64) -> Result; @@ -34,6 +39,27 @@ impl LbPairExtension for LbPair { Ok(self.status.try_into()?) } + fn get_token_programs(&self) -> Result<[Pubkey; 2]> { + let mut token_programs_id = [Pubkey::default(); 2]; + + for (i, token_program_flag) in [ + self.token_mint_x_program_flag, + self.token_mint_y_program_flag, + ] + .into_iter() + .enumerate() + { + let flag: TokenProgramFlagWrapper = token_program_flag.try_into()?; + let token_program_id = match flag.deref() { + TokenProgramFlags::TokenProgram => spl_token::ID, + TokenProgramFlags::TokenProgram2022 => spl_token_2022::ID, + }; + token_programs_id[i] = token_program_id; + } + + Ok(token_programs_id) + } + fn pair_type(&self) -> Result { Ok(self.pair_type.try_into()?) } diff --git a/commons/src/extensions/mod.rs b/commons/src/extensions/mod.rs index ba1c6d9e..2c9b5bb7 100644 --- a/commons/src/extensions/mod.rs +++ b/commons/src/extensions/mod.rs @@ -9,3 +9,6 @@ pub use bin::*; pub mod bin_array_bitmap; pub use bin_array_bitmap::*; + +pub mod position_v3; +pub use position_v3::*; diff --git a/commons/src/extensions/position_v3.rs b/commons/src/extensions/position_v3.rs new file mode 100644 index 00000000..74df7ea4 --- /dev/null +++ b/commons/src/extensions/position_v3.rs @@ -0,0 +1,35 @@ +use solana_sdk::{instruction::AccountMeta, pubkey::Pubkey}; + +use crate::*; + +pub trait PositionV3Extension { + fn get_bin_array_indexes_coverage(&self) -> Result<(i32, i32)>; + fn get_bin_array_keys_coverage(&self) -> Result>; + fn get_bin_array_accounts_meta_coverage(&self) -> Result>; +} + +impl PositionV3Extension for PositionV3 { + fn get_bin_array_indexes_coverage(&self) -> Result<(i32, i32)> { + let lower_bin_array_index = BinArray::bin_id_to_bin_array_index(self.lower_bin_id)?; + let upper_bin_array_index = BinArray::bin_id_to_bin_array_index(self.upper_bin_id)?; + Ok((lower_bin_array_index, upper_bin_array_index)) + } + + fn get_bin_array_keys_coverage(&self) -> Result> { + let (lower_bin_array_index, upper_bin_array_index) = + self.get_bin_array_indexes_coverage()?; + let mut bin_array_keys = Vec::new(); + for bin_array_index in lower_bin_array_index..=upper_bin_array_index { + bin_array_keys.push(derive_bin_array_pda(self.lb_pair, bin_array_index.into()).0); + } + Ok(bin_array_keys) + } + + fn get_bin_array_accounts_meta_coverage(&self) -> Result> { + let bin_array_keys = self.get_bin_array_keys_coverage()?; + Ok(bin_array_keys + .into_iter() + .map(|key| AccountMeta::new(key, false)) + .collect()) + } +} diff --git a/commons/src/lib.rs b/commons/src/lib.rs index 4ed777c6..f069a58b 100644 --- a/commons/src/lib.rs +++ b/commons/src/lib.rs @@ -24,3 +24,8 @@ pub use math::*; pub mod typedefs; pub use typedefs::*; + +pub mod content_loaders; +pub use content_loaders::*; + +pub mod rpc_client_extension; diff --git a/commons/src/pda.rs b/commons/src/pda.rs index 10f8cc2b..40075760 100644 --- a/commons/src/pda.rs +++ b/commons/src/pda.rs @@ -1,6 +1,4 @@ -use super::seeds::{ - self, BIN_ARRAY, BIN_ARRAY_BITMAP_SEED, ILM_BASE_KEY, ORACLE, PRESET_PARAMETER, -}; +use super::seeds::*; use anchor_client::solana_sdk::pubkey::Pubkey; use std::{cmp::max, cmp::min}; @@ -76,7 +74,7 @@ pub fn derive_position_pda( ) -> (Pubkey, u8) { Pubkey::find_program_address( &[ - seeds::POSITION.as_ref(), + POSITION, lb_pair.as_ref(), base.as_ref(), lower_bin_id.to_le_bytes().as_ref(), @@ -140,3 +138,14 @@ pub fn derive_preset_parameter_pda2(bin_step: u16, base_factor: u16) -> (Pubkey, &dlmm_interface::ID, ) } + +pub fn derive_preset_parameter_pda_v2(index: u16) -> (Pubkey, u8) { + Pubkey::find_program_address( + &[PRESET_PARAMETER2, &index.to_le_bytes()], + &dlmm_interface::ID, + ) +} + +pub fn derive_token_badge_pda(mint: Pubkey) -> (Pubkey, u8) { + Pubkey::find_program_address(&[TOKEN_BADGE, mint.as_ref()], &dlmm_interface::ID) +} diff --git a/commons/src/rpc_client_extension.rs b/commons/src/rpc_client_extension.rs new file mode 100644 index 00000000..e17f6c2c --- /dev/null +++ b/commons/src/rpc_client_extension.rs @@ -0,0 +1,26 @@ +use crate::*; +use anchor_client::solana_client::nonblocking::rpc_client::RpcClient; +use async_trait::async_trait; +use solana_sdk::{account::Account, pubkey::Pubkey}; + +#[async_trait] +pub trait RpcClientExtension { + async fn get_account_and_deserialize( + &self, + pubkey: &Pubkey, + deserialize_fn: fn(Account) -> Result, + ) -> Result; +} + +#[async_trait] +impl RpcClientExtension for RpcClient { + async fn get_account_and_deserialize( + &self, + pubkey: &Pubkey, + deserialize_fn: fn(Account) -> Result, + ) -> Result { + let account = self.get_account(pubkey).await?; + let data = deserialize_fn(account)?; + Ok(data) + } +} diff --git a/commons/src/seeds.rs b/commons/src/seeds.rs index 4b56ef6e..e67e5a6a 100644 --- a/commons/src/seeds.rs +++ b/commons/src/seeds.rs @@ -9,6 +9,10 @@ pub const BIN_ARRAY_BITMAP_SEED: &[u8] = b"bitmap"; pub const PRESET_PARAMETER: &[u8] = b"preset_parameter"; +pub const PRESET_PARAMETER2: &[u8] = b"preset_parameter2"; + pub const POSITION: &[u8] = b"position"; pub const ILM_BASE_KEY: Pubkey = pubkey!("MFGQxwAmB91SwuYX36okv2Qmdc9aMuHTwWGUrp4AtB1"); + +pub const TOKEN_BADGE: &[u8] = b"token_badge"; diff --git a/commons/tests/helpers/utils.rs b/commons/tests/helpers/utils.rs index 0ccfa1e1..e3745981 100644 --- a/commons/tests/helpers/utils.rs +++ b/commons/tests/helpers/utils.rs @@ -20,7 +20,7 @@ pub async fn process_and_assert_ok( all_signers.extend_from_slice(signers); let tx = Transaction::new_signed_with_payer( - &instructions, + instructions, Some(&payer.pubkey()), &all_signers, recent_blockhash, @@ -35,9 +35,17 @@ pub async fn get_or_create_ata( authority: &Pubkey, banks_client: &mut BanksClient, ) -> Pubkey { - let ata_address = get_associated_token_address(authority, token_mint); + let token_mint_owner = banks_client + .get_account(*token_mint) + .await + .ok() + .flatten() + .unwrap() + .owner; + let ata_address = + get_associated_token_address_with_program_id(authority, token_mint, &token_mint_owner); let ata_account = banks_client.get_account(ata_address).await.unwrap(); - if let None = ata_account { + if ata_account.is_none() { create_associated_token_account(payer, token_mint, authority, banks_client).await; } ata_address @@ -52,8 +60,8 @@ pub async fn create_associated_token_account( let ins = vec![ spl_associated_token_account::instruction::create_associated_token_account( &payer.pubkey(), - &authority, - &token_mint, + authority, + token_mint, &spl_token::id(), ), ]; diff --git a/programs/lb_clmm/Cargo.toml b/programs/lb_clmm/Cargo.toml deleted file mode 100644 index 3a68dff3..00000000 --- a/programs/lb_clmm/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -[package] -name = "lb_clmm" -version = "0.8.2" -description = "Created with Anchor" -edition = "2021" - -[lib] -crate-type = ["cdylib", "lib"] -name = "lb_clmm" - -[features] -no-entrypoint = [] -no-idl = [] -no-log-ix-name = [] -cpi = ["no-entrypoint"] -default = [] -localnet = [] -test-bpf = [] -staging = [] - -[dependencies] -anchor-lang = { version = "0.28.0", features = ["event-cpi"] } -anchor-spl = "0.28.0" -uint = "0.8.5" -bytemuck = { version = "1.13.1", features = ["derive", "min_const_generics"] } -ruint = "1.3.0" -num-traits = "0.2.16" -num-integer = "0.1.45" -mpl-token-metadata = "3.0.1" -solana-program = "1.16.0" -num_enum = "0.7.1" - -[dev-dependencies] -proptest = "1.2.0" -rand = "0.7.3" -solana-program-test = "1.16.0" -solana-sdk = "1.16.0" -async-trait = "0.1.52" -assert_matches = "1.5.0" -spl-associated-token-account = "1.0.3" -commons = { path = "../../commons" } -bincode = "1.3.3" diff --git a/programs/lb_clmm/Xargo.toml b/programs/lb_clmm/Xargo.toml deleted file mode 100644 index 475fb71e..00000000 --- a/programs/lb_clmm/Xargo.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.bpfel-unknown-unknown.dependencies.std] -features = [] diff --git a/programs/lb_clmm/src/constants.rs b/programs/lb_clmm/src/constants.rs deleted file mode 100644 index e0ca37a6..00000000 --- a/programs/lb_clmm/src/constants.rs +++ /dev/null @@ -1,123 +0,0 @@ -use anchor_lang::prelude::*; -use anchor_lang::solana_program::pubkey; - -// TODO: Macro to compute the constants which changes based on the bit system used ? -// Smallest step between bin is 0.01%, 1 bps -#[constant] -pub const BASIS_POINT_MAX: i32 = 10000; - -/// Maximum number of bin a bin array able to contains. -#[constant] -pub const MAX_BIN_PER_ARRAY: usize = 70; - -/// Maximum number of bin per position contains. -#[constant] -pub const MAX_BIN_PER_POSITION: usize = 70; - -/// Minimum bin ID supported. Computed based on 1 bps. -#[constant] -pub const MIN_BIN_ID: i32 = -443636; - -/// Maximum bin ID supported. Computed based on 1 bps. -#[constant] -pub const MAX_BIN_ID: i32 = 443636; - -/// Maximum fee rate. 10% -#[constant] -pub const MAX_FEE_RATE: u64 = 100_000_000; - -#[constant] -pub const FEE_PRECISION: u64 = 1_000_000_000; - -/// Maximum protocol share of the fee. 25% -#[constant] -pub const MAX_PROTOCOL_SHARE: u16 = 2_500; - -/// Host fee. 20% -#[constant] -pub const HOST_FEE_BPS: u16 = 2_000; - -pub const U24_MAX: u32 = 0xffffff; - -// Number of rewards supported by pool -#[constant] -pub const NUM_REWARDS: usize = 2; - -// Minimum reward duration -#[constant] -pub const MIN_REWARD_DURATION: u64 = 1; - -#[constant] -pub const MAX_REWARD_DURATION: u64 = 31536000; // 1 year = 365 * 24 * 3600 - -pub const DEFAULT_OBSERVATION_LENGTH: u64 = 100; -pub const SAMPLE_LIFETIME: u64 = 120; // 2 -#[constant] -pub const EXTENSION_BINARRAY_BITMAP_SIZE: usize = 12; - -#[constant] -pub const BIN_ARRAY_BITMAP_SIZE: i32 = 512; - -pub const MAX_BASE_FACTOR_STEP: u16 = 100; // 100 bps, 1% - -pub const MAX_FEE_UPDATE_WINDOW: i64 = 0; - -#[constant] -pub const MAX_REWARD_BIN_SPLIT: usize = 15; - -#[cfg(feature = "localnet")] -pub const SLOT_BUFFER: u64 = 5; - -// 1 slot ~400ms -#[cfg(not(feature = "localnet"))] -pub const SLOT_BUFFER: u64 = 9000; - -#[cfg(feature = "localnet")] -pub const TIME_BUFFER: u64 = 5; - -#[cfg(not(feature = "localnet"))] -pub const TIME_BUFFER: u64 = 3600; - -#[cfg(not(feature = "localnet"))] -pub const MAX_ACTIVATION_SLOT_DURATION: u64 = SLOT_BUFFER * 24 * 31; // 31 days - -#[cfg(feature = "localnet")] -pub const MAX_ACTIVATION_SLOT_DURATION: u64 = SLOT_BUFFER * 24; // 1 days - -#[cfg(not(feature = "localnet"))] -pub const MAX_ACTIVATION_TIME_DURATION: u64 = TIME_BUFFER * 24 * 31; // 31 days - -#[cfg(feature = "localnet")] -pub const MAX_ACTIVATION_TIME_DURATION: u64 = TIME_BUFFER * 24; // 1 days - -#[cfg(not(feature = "localnet"))] -pub const FIVE_MINUTES_SLOT_BUFFER: u64 = SLOT_BUFFER / 12; // 5 minutes - -#[cfg(feature = "localnet")] -pub const FIVE_MINUTES_SLOT_BUFFER: u64 = 5; - -#[cfg(not(feature = "localnet"))] -pub const FIVE_MINUTES_TIME_BUFFER: u64 = TIME_BUFFER / 12; // 5 minutes - -#[cfg(feature = "localnet")] -pub const FIVE_MINUTES_TIME_BUFFER: u64 = 5; - -// ILM token launch protocol fee -pub const ILM_PROTOCOL_SHARE: u16 = 2000; // 20% - -/// Maximum bin step -#[constant] -pub const MAX_BIN_STEP: u16 = 400; - -/// Maximum base fee, base_fee / 10^9 = fee_in_percentage -#[constant] -pub const MAX_BASE_FEE: u128 = 100_000_000; // 10% (10^9 * 10 / 100) - -/// Minimum base fee -#[constant] -pub const MIN_BASE_FEE: u128 = 100_000; // 0.01% (10^9 * 0.01 / 100) - -// Supported quote mints -const SOL: Pubkey = pubkey!("So11111111111111111111111111111111111111112"); -const USDC: Pubkey = pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); -pub const QUOTE_MINTS: [Pubkey; 2] = [SOL, USDC]; diff --git a/programs/lb_clmm/src/errors.rs b/programs/lb_clmm/src/errors.rs deleted file mode 100644 index 2b24126a..00000000 --- a/programs/lb_clmm/src/errors.rs +++ /dev/null @@ -1,203 +0,0 @@ -use anchor_lang::prelude::*; - -#[error_code] -#[derive(PartialEq)] -pub enum LBError { - #[msg("Invalid start bin index")] - InvalidStartBinIndex, - - #[msg("Invalid bin id")] - InvalidBinId, - - #[msg("Invalid input data")] - InvalidInput, - - #[msg("Exceeded amount slippage tolerance")] - ExceededAmountSlippageTolerance, - - #[msg("Exceeded bin slippage tolerance")] - ExceededBinSlippageTolerance, - - #[msg("Composition factor flawed")] - CompositionFactorFlawed, - - #[msg("Non preset bin step")] - NonPresetBinStep, - - #[msg("Zero liquidity")] - ZeroLiquidity, - - #[msg("Invalid position")] - InvalidPosition, - - #[msg("Bin array not found")] - BinArrayNotFound, - - #[msg("Invalid token mint")] - InvalidTokenMint, - - #[msg("Invalid account for single deposit")] - InvalidAccountForSingleDeposit, - - #[msg("Pair insufficient liquidity")] - PairInsufficientLiquidity, - - #[msg("Invalid fee owner")] - InvalidFeeOwner, - - #[msg("Invalid fee withdraw amount")] - InvalidFeeWithdrawAmount, - - #[msg("Invalid admin")] - InvalidAdmin, - - #[msg("Identical fee owner")] - IdenticalFeeOwner, - - #[msg("Invalid basis point")] - InvalidBps, - - #[msg("Math operation overflow")] - MathOverflow, - - #[msg("Type cast error")] - TypeCastFailed, - - #[msg("Invalid reward index")] - InvalidRewardIndex, - - #[msg("Invalid reward duration")] - InvalidRewardDuration, - - #[msg("Reward already initialized")] - RewardInitialized, - - #[msg("Reward not initialized")] - RewardUninitialized, - - #[msg("Identical funder")] - IdenticalFunder, - - #[msg("Reward campaign in progress")] - RewardCampaignInProgress, - - #[msg("Reward duration is the same")] - IdenticalRewardDuration, - - #[msg("Invalid bin array")] - InvalidBinArray, - - #[msg("Bin arrays must be continuous")] - NonContinuousBinArrays, - - #[msg("Invalid reward vault")] - InvalidRewardVault, - - #[msg("Position is not empty")] - NonEmptyPosition, - - #[msg("Unauthorized access")] - UnauthorizedAccess, - - #[msg("Invalid fee parameter")] - InvalidFeeParameter, - - #[msg("Missing oracle account")] - MissingOracle, - - #[msg("Insufficient observation sample")] - InsufficientSample, - - #[msg("Invalid lookup timestamp")] - InvalidLookupTimestamp, - - #[msg("Bitmap extension account is not provided")] - BitmapExtensionAccountIsNotProvided, - - #[msg("Cannot find non-zero liquidity binArrayId")] - CannotFindNonZeroLiquidityBinArrayId, - - #[msg("Bin id out of bound")] - BinIdOutOfBound, - - #[msg("Insufficient amount in for minimum out")] - InsufficientOutAmount, - - #[msg("Invalid position width")] - InvalidPositionWidth, - - #[msg("Excessive fee update")] - ExcessiveFeeUpdate, - - #[msg("Pool disabled")] - PoolDisabled, - - #[msg("Invalid pool type")] - InvalidPoolType, - - #[msg("Whitelist for wallet is full")] - ExceedMaxWhitelist, - - #[msg("Invalid index")] - InvalidIndex, - - #[msg("Reward not ended")] - RewardNotEnded, - - #[msg("Must withdraw ineligible reward")] - MustWithdrawnIneligibleReward, - - #[msg("Unauthorized address")] - UnauthorizedAddress, - - #[msg("Cannot update because operators are the same")] - OperatorsAreTheSame, - - #[msg("Withdraw to wrong token account")] - WithdrawToWrongTokenAccount, - - #[msg("Wrong rent receiver")] - WrongRentReceiver, - - #[msg("Already activated")] - AlreadyPassActivationPoint, - - #[msg("Swapped amount is exceeded max swapped amount")] - ExceedMaxSwappedAmount, - - #[msg("Invalid strategy parameters")] - InvalidStrategyParameters, - - #[msg("Liquidity locked")] - LiquidityLocked, - - #[msg("Bin range is not empty")] - BinRangeIsNotEmpty, - - #[msg("Amount out is not matched with exact amount out")] - NotExactAmountOut, - - #[msg("Invalid activation type")] - InvalidActivationType, - - #[msg("Invalid activation duration")] - InvalidActivationDuration, - - #[msg("Missing token amount as token launch owner proof")] - MissingTokenAmountAsTokenLaunchProof, - - #[msg("Quote token must be SOL or USDC")] - InvalidQuoteToken, - - #[msg("Invalid bin step")] - InvalidBinStep, - - #[msg("Invalid base fee")] - InvalidBaseFee, - - #[msg("Invalid pre-activation duration")] - InvalidPreActivationDuration, - - #[msg("Already pass pre-activation swap point")] - AlreadyPassPreActivationSwapPoint, -} diff --git a/programs/lb_clmm/src/events.rs b/programs/lb_clmm/src/events.rs deleted file mode 100644 index f8ff48f3..00000000 --- a/programs/lb_clmm/src/events.rs +++ /dev/null @@ -1,232 +0,0 @@ -use anchor_lang::event; -use anchor_lang::prelude::*; - -#[event] -pub struct CompositionFee { - // Sender's public key - pub from: Pubkey, - // Bin id - pub bin_id: i16, - // Amount of fee in token X - pub token_x_fee_amount: u64, - // Amount of fee in token Y - pub token_y_fee_amount: u64, - // Amount of protocol fee in token X - pub protocol_token_x_fee_amount: u64, - // Amount of protocol fee in token Y - pub protocol_token_y_fee_amount: u64, -} - -#[event] -pub struct AddLiquidity { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Sender's public key - pub from: Pubkey, - // Address of the position - pub position: Pubkey, - // Amount of token X, and Y deposited - pub amounts: [u64; 2], - // Pair active bin during deposit - pub active_bin_id: i32, -} - -#[event] -pub struct RemoveLiquidity { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Sender's public key - pub from: Pubkey, - // Address of the position - pub position: Pubkey, - // Amount of token X, and Y withdrawn - pub amounts: [u64; 2], - // Pair active bin during withdrawal - pub active_bin_id: i32, -} - -#[event] -pub struct Swap { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Address initiated the swap - pub from: Pubkey, - // Initial active bin ID - pub start_bin_id: i32, - // Finalized active bin ID - pub end_bin_id: i32, - // In token amount - pub amount_in: u64, - // Out token amount - pub amount_out: u64, - // Direction of the swap - pub swap_for_y: bool, - // Include protocol fee - pub fee: u64, - // Part of fee - pub protocol_fee: u64, - // Fee bps - pub fee_bps: u128, - // Host fee - pub host_fee: u64, -} - -#[event] -pub struct ClaimReward { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Position address - pub position: Pubkey, - // Owner of the position - pub owner: Pubkey, - // Index of the farm reward the owner is claiming - pub reward_index: u64, - // Total amount of reward claimed - pub total_reward: u64, -} - -#[event] -pub struct FundReward { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Address of the funder - pub funder: Pubkey, - // Index of the farm reward being funded - pub reward_index: u64, - // Amount of farm reward funded - pub amount: u64, -} - -#[event] -pub struct InitializeReward { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Mint address of the farm reward - pub reward_mint: Pubkey, - // Address of the funder - pub funder: Pubkey, - // Index of the farm reward being initialized - pub reward_index: u64, - // Duration of the farm reward in seconds - pub reward_duration: u64, -} - -#[event] -pub struct UpdateRewardDuration { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Index of the farm reward being updated - pub reward_index: u64, - // Old farm reward duration - pub old_reward_duration: u64, - // New farm reward duration - pub new_reward_duration: u64, -} - -#[event] -pub struct UpdateRewardFunder { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Index of the farm reward being updated - pub reward_index: u64, - // Address of the old farm reward funder - pub old_funder: Pubkey, - // Address of the new farm reward funder - pub new_funder: Pubkey, -} - -#[event] -pub struct PositionClose { - // Address of the position - pub position: Pubkey, - // Owner of the position - pub owner: Pubkey, -} - -#[event] -pub struct ClaimFee { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Address of the position - pub position: Pubkey, - // Owner of the position - pub owner: Pubkey, - // Fee amount in token X - pub fee_x: u64, - // Fee amount in token Y - pub fee_y: u64, -} - -#[event] -pub struct LbPairCreate { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Bin step - pub bin_step: u16, - // Address of token X - pub token_x: Pubkey, - // Address of token Y - pub token_y: Pubkey, -} - -#[event] -pub struct PositionCreate { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Address of the position - pub position: Pubkey, - // Owner of the position - pub owner: Pubkey, -} - -#[event] -pub struct FeeParameterUpdate { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Protocol share in BPS - pub protocol_share: u16, - // Base factor of base fee rate - pub base_factor: u16, -} - -#[event] -pub struct IncreaseObservation { - // Oracle address - pub oracle: Pubkey, - // Oracle length - pub new_observation_length: u64, -} - -#[event] -pub struct WithdrawIneligibleReward { - // Liquidity pool pair - pub lb_pair: Pubkey, - // Reward mint - pub reward_mint: Pubkey, - // Amount of ineligible reward withdrawn - pub amount: u64, -} - -#[event] -pub struct UpdatePositionOperator { - // Position public key - pub position: Pubkey, - // Old operator - pub old_operator: Pubkey, - // New operator - pub new_operator: Pubkey, -} - -#[event] -pub struct UpdatePositionLockReleasePoint { - // Position public key - pub position: Pubkey, - // Current point - pub current_point: u64, - // New lock release point - pub new_lock_release_point: u64, - // Old lock release point - pub old_lock_release_point: u64, - // Sender public key - pub sender: Pubkey, -} diff --git a/programs/lb_clmm/src/instructions/admin/close_preset_parameter.rs b/programs/lb_clmm/src/instructions/admin/close_preset_parameter.rs deleted file mode 100644 index 68edaf48..00000000 --- a/programs/lb_clmm/src/instructions/admin/close_preset_parameter.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::preset_parameters::PresetParameter; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct ClosePresetParameter<'info> { - #[account( - mut, - close = rent_receiver - )] - pub preset_parameter: Account<'info, PresetParameter>, - - #[account( - mut, - constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin - )] - pub admin: Signer<'info>, - - /// CHECK: Account to receive closed account rental SOL - #[account(mut)] - pub rent_receiver: UncheckedAccount<'info>, -} - -pub fn handle(_ctx: Context) -> Result<()> { - // Anchor handle everything - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/initialize_preset_parameters.rs b/programs/lb_clmm/src/instructions/admin/initialize_preset_parameters.rs deleted file mode 100644 index c0b1a83d..00000000 --- a/programs/lb_clmm/src/instructions/admin/initialize_preset_parameters.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::preset_parameters::PresetParameter; -use crate::utils::seeds::PRESET_PARAMETER; -use anchor_lang::prelude::*; - -#[derive(AnchorSerialize, AnchorDeserialize)] -pub struct InitPresetParametersIx { - /// Bin step. Represent the price increment / decrement. - pub bin_step: u16, - /// Used for base fee calculation. base_fee_rate = base_factor * bin_step - pub base_factor: u16, - /// Filter period determine high frequency trading time window. - pub filter_period: u16, - /// Decay period determine when the volatile fee start decay / decrease. - pub decay_period: u16, - /// Reduction factor controls the volatile fee rate decrement rate. - pub reduction_factor: u16, - /// Used to scale the variable fee component depending on the dynamic of the market - pub variable_fee_control: u32, - /// Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate. - pub max_volatility_accumulator: u32, - /// Min bin id supported by the pool based on the configured bin step. - pub min_bin_id: i32, - /// Max bin id supported by the pool based on the configured bin step. - pub max_bin_id: i32, - /// Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee - pub protocol_share: u16, -} - -#[derive(Accounts)] -#[instruction(ix: InitPresetParametersIx)] -pub struct InitializePresetParameter<'info> { - #[account( - init, - seeds = [ - PRESET_PARAMETER, - &ix.bin_step.to_le_bytes(), - &ix.base_factor.to_le_bytes() - ], - bump, - payer = admin, - space = 8 + PresetParameter::INIT_SPACE - )] - pub preset_parameter: Account<'info, PresetParameter>, - - #[account( - mut, - constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin - )] - pub admin: Signer<'info>, - - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle(ctx: Context, ix: InitPresetParametersIx) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/initialize_reward.rs b/programs/lb_clmm/src/instructions/admin/initialize_reward.rs deleted file mode 100644 index f577db3b..00000000 --- a/programs/lb_clmm/src/instructions/admin/initialize_reward.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(reward_index: u64)] -pub struct InitializeReward<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - reward_index.to_le_bytes().as_ref() - ], - bump, - payer = admin, - token::mint = reward_mint, - token::authority = lb_pair, - )] - pub reward_vault: Box>, - - pub reward_mint: Box>, - - #[account( - mut, - constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin, - )] - pub admin: Signer<'info>, - - pub token_program: Interface<'info, TokenInterface>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle( - ctx: Context, - index: u64, - reward_duration: u64, - funder: Pubkey, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/mod.rs b/programs/lb_clmm/src/instructions/admin/mod.rs deleted file mode 100644 index 00bf56f0..00000000 --- a/programs/lb_clmm/src/instructions/admin/mod.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub mod close_preset_parameter; -pub mod initialize_preset_parameters; -pub mod initialize_reward; -pub mod set_activation_point; -pub mod set_pre_activation_duration; -pub mod set_pre_activation_swap_address; -pub mod toggle_pair_status; -pub mod update_fee_parameters; -pub mod update_reward_duration; -pub mod update_reward_funder; - -pub use close_preset_parameter::*; -pub use initialize_preset_parameters::*; -pub use initialize_reward::*; -pub use set_activation_point::*; -pub use set_pre_activation_duration::*; -pub use set_pre_activation_swap_address::*; -pub use toggle_pair_status::*; -pub use update_fee_parameters::*; -pub use update_reward_duration::*; -pub use update_reward_funder::*; diff --git a/programs/lb_clmm/src/instructions/admin/set_activation_point.rs b/programs/lb_clmm/src/instructions/admin/set_activation_point.rs deleted file mode 100644 index 18346a83..00000000 --- a/programs/lb_clmm/src/instructions/admin/set_activation_point.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct SetActivationPoint<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - constraint = lb_pair.load()?.creator.eq(&admin.key()) @ LBError::UnauthorizedAccess, - )] - pub admin: Signer<'info>, -} - -pub fn handle(ctx: Context, activation_point: u64) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/set_pre_activation_duration.rs b/programs/lb_clmm/src/instructions/admin/set_pre_activation_duration.rs deleted file mode 100644 index 2c282816..00000000 --- a/programs/lb_clmm/src/instructions/admin/set_pre_activation_duration.rs +++ /dev/null @@ -1,19 +0,0 @@ -use crate::errors::LBError; -use crate::math::safe_math::SafeMath; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct SetPreActivationInfo<'info> { - #[account( - mut, - has_one = creator - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - pub creator: Signer<'info>, -} - -pub fn handle(ctx: Context, pre_activation_duration: u16) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/set_pre_activation_swap_address.rs b/programs/lb_clmm/src/instructions/admin/set_pre_activation_swap_address.rs deleted file mode 100644 index 871cd1eb..00000000 --- a/programs/lb_clmm/src/instructions/admin/set_pre_activation_swap_address.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::errors::LBError; -use anchor_lang::prelude::*; - -use super::set_pre_activation_duration::SetPreActivationInfo; - -pub fn handle( - ctx: Context, - pre_activation_swap_address: Pubkey, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/toggle_pair_status.rs b/programs/lb_clmm/src/instructions/admin/toggle_pair_status.rs deleted file mode 100644 index 5a53485c..00000000 --- a/programs/lb_clmm/src/instructions/admin/toggle_pair_status.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct TogglePairStatus<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account(constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin)] - pub admin: Signer<'info>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/update_fee_parameters.rs b/programs/lb_clmm/src/instructions/admin/update_fee_parameters.rs deleted file mode 100644 index 85730c11..00000000 --- a/programs/lb_clmm/src/instructions/admin/update_fee_parameters.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)] -pub struct FeeParameter { - /// Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee - pub protocol_share: u16, - /// Base factor for base fee rate - pub base_factor: u16, -} - -#[event_cpi] -#[derive(Accounts)] -pub struct UpdateFeeParameters<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account(constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin)] - pub admin: Signer<'info>, -} - -pub fn handle(ctx: Context, fee_parameter: FeeParameter) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/update_reward_duration.rs b/programs/lb_clmm/src/instructions/admin/update_reward_duration.rs deleted file mode 100644 index 3e34b998..00000000 --- a/programs/lb_clmm/src/instructions/admin/update_reward_duration.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::assert_eq_admin; -use crate::errors::LBError; -use crate::state::bin::BinArray; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(reward_index: u64)] -pub struct UpdateRewardDuration<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin, - )] - pub admin: Signer<'info>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array: AccountLoader<'info, BinArray>, -} - -pub fn handle( - ctx: Context, - index: u64, - new_reward_duration: u64, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/admin/update_reward_funder.rs b/programs/lb_clmm/src/instructions/admin/update_reward_funder.rs deleted file mode 100644 index f5b64bc9..00000000 --- a/programs/lb_clmm/src/instructions/admin/update_reward_funder.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::assert_eq_admin; -use crate::constants::NUM_REWARDS; -use crate::errors::LBError; -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(reward_index: u64)] -pub struct UpdateRewardFunder<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account(constraint = assert_eq_admin(admin.key()) @ LBError::InvalidAdmin)] - pub admin: Signer<'info>, -} - -pub fn handle(ctx: Context, index: u64, new_funder: Pubkey) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/claim_fee.rs b/programs/lb_clmm/src/instructions/claim_fee.rs deleted file mode 100644 index 89b9ea1b..00000000 --- a/programs/lb_clmm/src/instructions/claim_fee.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::authorize_claim_fee_position; -use crate::state::{bin::BinArray, lb_pair::LbPair, position::PositionV2}; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; -#[event_cpi] -#[derive(Accounts)] -pub struct ClaimFee<'info> { - #[account( - mut, - has_one = reserve_x, - has_one = reserve_y, - has_one = token_x_mint, - has_one = token_y_mint, - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair, - constraint = authorize_claim_fee_position(&position, sender.key())? - )] - pub position: AccountLoader<'info, PositionV2>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - pub sender: Signer<'info>, - - #[account(mut)] - pub reserve_x: Box>, - #[account(mut)] - pub reserve_y: Box>, - - #[account(mut)] - pub user_token_x: Box>, - #[account(mut)] - pub user_token_y: Box>, - - pub token_x_mint: Box>, - pub token_y_mint: Box>, - - pub token_program: Interface<'info, TokenInterface>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/claim_reward.rs b/programs/lb_clmm/src/instructions/claim_reward.rs deleted file mode 100644 index ad94894b..00000000 --- a/programs/lb_clmm/src/instructions/claim_reward.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::authorize_modify_position; -use crate::state::{bin::BinArray, lb_pair::LbPair, position::PositionV2}; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(reward_index: u64)] -pub struct ClaimReward<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair, - constraint = authorize_modify_position(&position, sender.key())? - )] - pub position: AccountLoader<'info, PositionV2>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - pub sender: Signer<'info>, - - #[account(mut)] - pub reward_vault: Box>, - pub reward_mint: Box>, - - #[account(mut)] - pub user_token_account: Box>, - - pub token_program: Interface<'info, TokenInterface>, -} - -// TODO: Should we pass in range of bin we are going to collect reward ? It could help us in heap / compute unit issue by chunking into multiple tx. -pub fn handle(ctx: Context, index: u64) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/close_position.rs b/programs/lb_clmm/src/instructions/close_position.rs deleted file mode 100644 index 184b2e8c..00000000 --- a/programs/lb_clmm/src/instructions/close_position.rs +++ /dev/null @@ -1,40 +0,0 @@ -use anchor_lang::prelude::*; - -use crate::authorize_modify_position; -use crate::state::{bin::BinArray, lb_pair::LbPair, position::PositionV2}; - -#[event_cpi] -#[derive(Accounts)] -pub struct ClosePosition<'info> { - #[account( - mut, - has_one = lb_pair, - constraint = authorize_modify_position(&position, sender.key())?, - close = rent_receiver - )] - pub position: AccountLoader<'info, PositionV2>, - - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - pub sender: Signer<'info>, - - /// CHECK: Account to receive closed account rental SOL - #[account(mut)] - pub rent_receiver: UncheckedAccount<'info>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/create_position/initialize_position.rs b/programs/lb_clmm/src/instructions/create_position/initialize_position.rs deleted file mode 100644 index 856a98c8..00000000 --- a/programs/lb_clmm/src/instructions/create_position/initialize_position.rs +++ /dev/null @@ -1,28 +0,0 @@ -use anchor_lang::prelude::*; - -use crate::state::{lb_pair::LbPair, position::PositionV2}; - -#[event_cpi] -#[derive(Accounts)] -pub struct InitializePosition<'info> { - #[account(mut)] - pub payer: Signer<'info>, - - #[account( - init, - payer = payer, - space = 8 + PositionV2::INIT_SPACE, - )] - pub position: AccountLoader<'info, PositionV2>, - - pub lb_pair: AccountLoader<'info, LbPair>, - - pub owner: Signer<'info>, - - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle(ctx: Context, lower_bin_id: i32, width: i32) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/create_position/initialize_position_by_operator.rs b/programs/lb_clmm/src/instructions/create_position/initialize_position_by_operator.rs deleted file mode 100644 index 37753c7f..00000000 --- a/programs/lb_clmm/src/instructions/create_position/initialize_position_by_operator.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::state::lb_pair::LbPair; -use crate::state::position::PositionV2; -use crate::utils::seeds; -use anchor_lang::prelude::*; -use anchor_spl::token::TokenAccount; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(lower_bin_id: i32, width: i32)] -pub struct InitializePositionByOperator<'info> { - #[account(mut)] - pub payer: Signer<'info>, - - pub base: Signer<'info>, - #[account( - init, - seeds = [ - seeds::POSITION.as_ref(), - lb_pair.key().as_ref(), - base.key().as_ref(), - lower_bin_id.to_le_bytes().as_ref(), - width.to_le_bytes().as_ref(), - ], - bump, - payer = payer, - space = 8 + PositionV2::INIT_SPACE, - )] - pub position: AccountLoader<'info, PositionV2>, - - pub lb_pair: AccountLoader<'info, LbPair>, - - /// CHECK: owner of position - pub owner: UncheckedAccount<'info>, - - /// operator - pub operator: Signer<'info>, - - #[account( - token::authority = operator, - token::mint = lb_pair.load()?.token_x_mint, - )] - pub operator_token_x: Account<'info, TokenAccount>, - - #[account( - token::authority = owner, - token::mint = lb_pair.load()?.token_x_mint, - )] - pub owner_token_x: Account<'info, TokenAccount>, - - pub system_program: Program<'info, System>, -} - -pub fn handle( - ctx: Context, - lower_bin_id: i32, - width: i32, - fee_owner: Pubkey, - lock_release_point: u64, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/create_position/initialize_position_pda.rs b/programs/lb_clmm/src/instructions/create_position/initialize_position_pda.rs deleted file mode 100644 index 251e271c..00000000 --- a/programs/lb_clmm/src/instructions/create_position/initialize_position_pda.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::state::lb_pair::LbPair; -use crate::state::position::PositionV2; -use crate::utils::seeds; -use anchor_lang::prelude::*; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(lower_bin_id: i32, width: i32)] -pub struct InitializePositionPda<'info> { - #[account(mut)] - pub payer: Signer<'info>, - - pub base: Signer<'info>, - #[account( - init, - seeds = [ - seeds::POSITION.as_ref(), - lb_pair.key().as_ref(), - base.key().as_ref(), - lower_bin_id.to_le_bytes().as_ref(), - width.to_le_bytes().as_ref(), - ], - bump, - payer = payer, - space = 8 + PositionV2::INIT_SPACE, - )] - pub position: AccountLoader<'info, PositionV2>, - - pub lb_pair: AccountLoader<'info, LbPair>, - - /// owner - pub owner: Signer<'info>, - - pub system_program: Program<'info, System>, - - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle(ctx: Context, lower_bin_id: i32, width: i32) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/create_position/mod.rs b/programs/lb_clmm/src/instructions/create_position/mod.rs deleted file mode 100644 index ffbcc566..00000000 --- a/programs/lb_clmm/src/instructions/create_position/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod initialize_position; -pub mod initialize_position_by_operator; -pub mod initialize_position_pda; - -pub use initialize_position::*; -pub use initialize_position_by_operator::*; -pub use initialize_position_pda::*; diff --git a/programs/lb_clmm/src/instructions/deposit/add_liquidity.rs b/programs/lb_clmm/src/instructions/deposit/add_liquidity.rs deleted file mode 100644 index 9186c0e7..00000000 --- a/programs/lb_clmm/src/instructions/deposit/add_liquidity.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::authorize_modify_position; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::position::PositionV2; -use crate::state::{bin::BinArray, lb_pair::LbPair}; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -pub struct CompositeDepositInfo { - pub liquidity_share: u128, - pub protocol_token_x_fee_amount: u64, - pub protocol_token_y_fee_amount: u64, -} - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug)] -pub struct BinLiquidityDistribution { - /// Define the bin ID wish to deposit to. - pub bin_id: i32, - /// DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin. - pub distribution_x: u16, - /// DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin. - pub distribution_y: u16, -} - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug)] -pub struct LiquidityParameter { - /// Amount of X token to deposit - pub amount_x: u64, - /// Amount of Y token to deposit - pub amount_y: u64, - /// Liquidity distribution to each bins - pub bin_liquidity_dist: Vec, -} - -#[event_cpi] -#[derive(Accounts)] -pub struct ModifyLiquidity<'info> { - #[account( - mut, - has_one = lb_pair, - constraint = authorize_modify_position(&position, sender.key())? - )] - pub position: AccountLoader<'info, PositionV2>, - - #[account( - mut, - has_one = reserve_x, - has_one = reserve_y, - has_one = token_x_mint, - has_one = token_y_mint, - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair, - )] - pub bin_array_bitmap_extension: Option>, - - #[account( - mut, - token::mint = token_x_mint - )] - pub user_token_x: Box>, - #[account( - mut, - token::mint = token_y_mint - )] - pub user_token_y: Box>, - - #[account(mut)] - pub reserve_x: Box>, - #[account(mut)] - pub reserve_y: Box>, - - pub token_x_mint: Box>, - pub token_y_mint: Box>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - pub sender: Signer<'info>, - pub token_x_program: Interface<'info, TokenInterface>, - pub token_y_program: Interface<'info, TokenInterface>, -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - liquidity_parameter: LiquidityParameter, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy.rs b/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy.rs deleted file mode 100644 index 24e7535f..00000000 --- a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy.rs +++ /dev/null @@ -1,403 +0,0 @@ -use crate::constants::MAX_BIN_PER_POSITION; -use crate::errors::LBError; -use crate::manager::bin_array_manager::BinArrayManager; -use crate::math::safe_math::SafeMath; -use crate::math::weight_to_amounts::{to_amount_ask_side, to_amount_bid_side, to_amount_both_side}; -use crate::ModifyLiquidity; -use anchor_lang::prelude::*; - -const DEFAULT_MIN_WEIGHT: u16 = 200; -const DEFAULT_MAX_WEIGHT: u16 = 2000; - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug, Default)] -pub struct LiquidityParameterByStrategy { - /// Amount of X token to deposit - pub amount_x: u64, - /// Amount of Y token to deposit - pub amount_y: u64, - /// Active bin that integrator observe off-chain - pub active_id: i32, - /// max active bin slippage allowed - pub max_active_bin_slippage: i32, - /// strategy parameters - pub strategy_parameters: StrategyParameters, -} - -pub fn validate_add_liquidity_by_strategy_params( - active_id: i32, - current_active_id: i32, - max_active_bin_slippage: i32, - strategy_parameters: &StrategyParameters, -) -> Result<()> { - let bin_count = strategy_parameters.bin_count()?; - require!(bin_count > 0, LBError::InvalidInput); - - require!(bin_count <= MAX_BIN_PER_POSITION, LBError::InvalidInput); - - let bin_shift = if active_id > current_active_id { - active_id - current_active_id - } else { - current_active_id - active_id - }; - - require!( - bin_shift <= max_active_bin_slippage, - LBError::ExceededBinSlippageTolerance - ); - Ok(()) -} - -impl LiquidityParameterByStrategy { - pub fn to_amounts_into_bin( - &self, - active_id: i32, - bin_step: u16, - amount_x_in_active_bin: u64, - amount_y_in_active_bin: u64, - ) -> Result> { - let min_bin_id = self.strategy_parameters.min_bin_id; - let max_bin_id = self.strategy_parameters.max_bin_id; - - match self.strategy_parameters.strategy_type { - StrategyType::SpotImBalanced => { - if active_id < min_bin_id || active_id > max_bin_id { - let weights = to_weight_spot_balanced(min_bin_id, max_bin_id); - return to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ); - } - let mut amounts_in_bin = vec![]; - if min_bin_id <= active_id { - let weights = to_weight_spot_balanced(min_bin_id, active_id); - let amounts_into_bid_side = - to_amount_bid_side(active_id, self.amount_y, &weights)?; - for &(bin_id, amount) in amounts_into_bid_side.iter() { - amounts_in_bin.push((bin_id, 0, amount)) - } - } - if active_id < max_bin_id { - let weights = to_weight_spot_balanced(active_id + 1, max_bin_id); - let amounts_into_ask_side = - to_amount_ask_side(active_id, self.amount_x, bin_step, &weights)?; - - for &(bin_id, amount) in amounts_into_ask_side.iter() { - amounts_in_bin.push((bin_id, amount, 0)) - } - } - Ok(amounts_in_bin) - } - StrategyType::CurveImBalanced => { - // ask side - if active_id < min_bin_id { - let weights = to_weight_descending_order(min_bin_id, max_bin_id); - return to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ); - } - // bid side - if active_id > max_bin_id { - let weights = to_weight_ascending_order(min_bin_id, max_bin_id); - return to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ); - } - let mut amounts_in_bin = vec![]; - if min_bin_id <= active_id { - let weights = to_weight_ascending_order(min_bin_id, active_id); - let amounts_into_bid_side = - to_amount_bid_side(active_id, self.amount_y, &weights)?; - for &(bin_id, amount) in amounts_into_bid_side.iter() { - amounts_in_bin.push((bin_id, 0, amount)) - } - } - if active_id < max_bin_id { - let weights = to_weight_descending_order(active_id + 1, max_bin_id); - let amounts_into_ask_side = - to_amount_ask_side(active_id, self.amount_x, bin_step, &weights)?; - - for &(bin_id, amount) in amounts_into_ask_side.iter() { - amounts_in_bin.push((bin_id, amount, 0)) - } - } - Ok(amounts_in_bin) - } - StrategyType::BidAskImBalanced => { - // ask side - if active_id < min_bin_id { - let weights = to_weight_ascending_order(min_bin_id, max_bin_id); - return to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ); - } - // bid side - if active_id > max_bin_id { - let weights = to_weight_descending_order(min_bin_id, max_bin_id); - return to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ); - } - let mut amounts_in_bin = vec![]; - if min_bin_id <= active_id { - let weights = to_weight_descending_order(min_bin_id, active_id); - let amounts_into_bid_side = - to_amount_bid_side(active_id, self.amount_y, &weights)?; - for &(bin_id, amount) in amounts_into_bid_side.iter() { - amounts_in_bin.push((bin_id, 0, amount)) - } - } - if active_id < max_bin_id { - let weights = to_weight_ascending_order(active_id + 1, max_bin_id); - let amounts_into_ask_side = - to_amount_ask_side(active_id, self.amount_x, bin_step, &weights)?; - - for &(bin_id, amount) in amounts_into_ask_side.iter() { - amounts_in_bin.push((bin_id, amount, 0)) - } - } - Ok(amounts_in_bin) - } - StrategyType::SpotBalanced => { - let weights = to_weight_spot_balanced(min_bin_id, max_bin_id); - to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ) - } - StrategyType::CurveBalanced => { - let weights = to_weight_curve(min_bin_id, max_bin_id, active_id)?; - to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ) - } - StrategyType::BidAskBalanced => { - let weights = to_weight_bid_ask(min_bin_id, max_bin_id, active_id)?; - to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &weights, - ) - } - _ => Err(LBError::InvalidStrategyParameters.into()), - } - } -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - liquidity_parameter: &LiquidityParameterByStrategy, -) -> Result<()> { - Ok(()) -} - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug)] -pub struct StrategyParameters { - /// min bin id - pub min_bin_id: i32, - /// max bin id - pub max_bin_id: i32, - /// strategy type - pub strategy_type: StrategyType, - /// parameters - pub parameteres: [u8; 64], -} - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug)] -pub enum StrategyType { - // spot one side - SpotOneSide, - // curve one side - CurveOneSide, - // bidAsk one side - BidAskOneSide, - // spot both side, balanced deposit - SpotBalanced, - // curve both side, balanced deposit - CurveBalanced, - // bid ask both side, balanced deposit - BidAskBalanced, - // spot both side, imbalanced deposit, only token y is added in active bin - SpotImBalanced, - // curve both side, imbalanced deposit, only token y is added in active bin - CurveImBalanced, - // bid ask both side, imbalanced deposit, only token y is added in active bin - BidAskImBalanced, -} - -pub fn to_weight_descending_order(min_bin_id: i32, max_bin_id: i32) -> Vec<(i32, u16)> { - let mut weights = vec![]; - for i in min_bin_id..=max_bin_id { - weights.push((i, (max_bin_id - i + 1) as u16)); - } - weights -} - -pub fn to_weight_ascending_order(min_bin_id: i32, max_bin_id: i32) -> Vec<(i32, u16)> { - let mut weights = vec![]; - for i in min_bin_id..=max_bin_id { - weights.push((i, (i - min_bin_id + 1) as u16)); - } - weights -} - -pub fn to_weight_spot_balanced(min_bin_id: i32, max_bin_id: i32) -> Vec<(i32, u16)> { - let mut weights = vec![]; - for i in min_bin_id..=max_bin_id { - weights.push((i, 1)); - } - weights -} - -pub fn to_weight_curve( - min_bin_id: i32, - max_bin_id: i32, - active_id: i32, -) -> Result> { - // only bid side - if active_id > max_bin_id { - return Ok(to_weight_ascending_order(min_bin_id, max_bin_id)); - } - // only ask side - if active_id < min_bin_id { - return Ok(to_weight_descending_order(min_bin_id, max_bin_id)); - } - let max_weight = DEFAULT_MAX_WEIGHT; - let min_weight = DEFAULT_MIN_WEIGHT; - - let diff_weight = max_weight.safe_sub(min_weight)?; - let diff_min_weight = if active_id > min_bin_id { - diff_weight.safe_div(active_id.safe_sub(min_bin_id)? as u16)? - } else { - 0 - }; - let diff_max_weight = if max_bin_id > active_id { - diff_weight.safe_div(max_bin_id.safe_sub(active_id)? as u16)? - } else { - 0 - }; - - let mut weights = vec![]; - for i in min_bin_id..=max_bin_id { - if i < active_id { - let delta_bin = (active_id - i) as u16; - let weight = max_weight - delta_bin * diff_min_weight; - weights.push((i, weight)); - } else if i > active_id { - let delta_bin = (i - active_id) as u16; - let weight = max_weight - delta_bin * diff_max_weight; - weights.push((i, weight)); - } else { - weights.push((i, max_weight)); - } - } - Ok(weights) -} - -pub fn to_weight_bid_ask( - min_bin_id: i32, - max_bin_id: i32, - active_id: i32, -) -> Result> { - // only bid side - if active_id > max_bin_id { - return Ok(to_weight_descending_order(min_bin_id, max_bin_id)); - } - // only ask side - if active_id < min_bin_id { - return Ok(to_weight_ascending_order(min_bin_id, max_bin_id)); - } - - let max_weight = DEFAULT_MAX_WEIGHT; - let min_weight = DEFAULT_MIN_WEIGHT; - - let diff_weight = max_weight.safe_sub(min_weight)?; - - let diff_min_weight = if active_id > min_bin_id { - diff_weight.safe_div(active_id.safe_sub(min_bin_id)? as u16)? - } else { - 0 - }; - let diff_max_weight = if max_bin_id > active_id { - diff_weight.safe_div(max_bin_id.safe_sub(active_id)? as u16)? - } else { - 0 - }; - - let mut weights = vec![]; - for i in min_bin_id..=max_bin_id { - if i < active_id { - let delta_bin = (active_id - i) as u16; - let weight = min_weight + delta_bin * diff_min_weight; - weights.push((i, weight)); - } else if i > active_id { - let delta_bin = (i - active_id) as u16; - let weight = min_weight + delta_bin * diff_max_weight; - weights.push((i, weight)); - } else { - weights.push((i, min_weight)); - } - } - Ok(weights) -} - -impl StrategyParameters { - pub fn bin_count(&self) -> Result { - let bin_count = self.max_bin_id.safe_sub(self.min_bin_id)?.safe_add(1)?; - Ok(bin_count as usize) - } -} - -impl Default for StrategyParameters { - fn default() -> Self { - StrategyParameters { - min_bin_id: 0, - max_bin_id: 0, - strategy_type: StrategyType::SpotBalanced, - parameteres: [0; 64], - } - } -} diff --git a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy_one_side.rs b/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy_one_side.rs deleted file mode 100644 index 047afaf2..00000000 --- a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_strategy_one_side.rs +++ /dev/null @@ -1,70 +0,0 @@ -use super::add_liquidity_by_strategy::StrategyParameters; -use super::to_weight_ascending_order; -use super::to_weight_descending_order; -use super::to_weight_spot_balanced; -use super::ModifyLiquidityOneSide; -use super::StrategyType; -use crate::errors::LBError; -use crate::math::weight_to_amounts::to_amount_ask_side; -use crate::math::weight_to_amounts::to_amount_bid_side; -use anchor_lang::prelude::*; - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug, Default)] -pub struct LiquidityParameterByStrategyOneSide { - /// Amount of X token or Y token to deposit - pub amount: u64, - /// Active bin that integrator observe off-chain - pub active_id: i32, - /// max active bin slippage allowed - pub max_active_bin_slippage: i32, - /// strategy parameters - pub strategy_parameters: StrategyParameters, -} - -impl LiquidityParameterByStrategyOneSide { - pub fn to_amounts_into_bin( - &self, - active_id: i32, - bin_step: u16, - deposit_for_y: bool, - ) -> Result> { - let min_bin_id = self.strategy_parameters.min_bin_id; - let max_bin_id = self.strategy_parameters.max_bin_id; - - let weights = match self.strategy_parameters.strategy_type { - StrategyType::SpotOneSide => Some(to_weight_spot_balanced( - self.strategy_parameters.min_bin_id, - self.strategy_parameters.max_bin_id, - )), - StrategyType::CurveOneSide => { - if deposit_for_y { - Some(to_weight_ascending_order(min_bin_id, max_bin_id)) - } else { - Some(to_weight_descending_order(min_bin_id, max_bin_id)) - } - } - StrategyType::BidAskOneSide => { - if deposit_for_y { - Some(to_weight_descending_order(min_bin_id, max_bin_id)) - } else { - Some(to_weight_ascending_order(min_bin_id, max_bin_id)) - } - } - _ => None, - } - .ok_or(LBError::InvalidStrategyParameters)?; - - if deposit_for_y { - to_amount_bid_side(active_id, self.amount, &weights) - } else { - to_amount_ask_side(active_id, self.amount, bin_step, &weights) - } - } -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidityOneSide<'info>>, - liquidity_parameter: &LiquidityParameterByStrategyOneSide, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight.rs b/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight.rs deleted file mode 100644 index 7d638efb..00000000 --- a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight.rs +++ /dev/null @@ -1,107 +0,0 @@ -use crate::constants::MAX_BIN_PER_POSITION; -use crate::errors::LBError; -use crate::math::weight_to_amounts::{to_amount_ask_side, to_amount_bid_side, to_amount_both_side}; -use crate::ModifyLiquidity; -use anchor_lang::prelude::*; - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug, Default)] -pub struct BinLiquidityDistributionByWeight { - /// Define the bin ID wish to deposit to. - pub bin_id: i32, - /// weight of liquidity distributed for this bin id - pub weight: u16, -} - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug)] -pub struct LiquidityParameterByWeight { - /// Amount of X token to deposit - pub amount_x: u64, - /// Amount of Y token to deposit - pub amount_y: u64, - /// Active bin that integrator observe off-chain - pub active_id: i32, - /// max active bin slippage allowed - pub max_active_bin_slippage: i32, - /// Liquidity distribution to each bins - pub bin_liquidity_dist: Vec, -} - -impl LiquidityParameterByWeight { - fn bin_count(&self) -> u32 { - self.bin_liquidity_dist.len() as u32 - } - - pub fn validate<'a, 'info>(&'a self, active_id: i32) -> Result<()> { - let bin_count = self.bin_count(); - require!(bin_count > 0, LBError::InvalidInput); - - require!( - bin_count <= MAX_BIN_PER_POSITION as u32, - LBError::InvalidInput - ); - - let bin_shift = if active_id > self.active_id { - active_id - self.active_id - } else { - self.active_id - active_id - }; - - require!( - bin_shift <= self.max_active_bin_slippage.into(), - LBError::ExceededBinSlippageTolerance - ); - - // bin dist must be in consecutive order and weight is non-zero - for (i, val) in self.bin_liquidity_dist.iter().enumerate() { - require!(val.weight != 0, LBError::InvalidInput); - // bin id must in right order - if i != 0 { - require!( - val.bin_id > self.bin_liquidity_dist[i - 1].bin_id, - LBError::InvalidInput - ); - } - } - let first_bin_id = self.bin_liquidity_dist[0].bin_id; - let last_bin_id = self.bin_liquidity_dist[self.bin_liquidity_dist.len() - 1].bin_id; - - if first_bin_id > active_id { - require!(self.amount_x != 0, LBError::InvalidInput); - } - if last_bin_id < active_id { - require!(self.amount_y != 0, LBError::InvalidInput); - } - - Ok(()) - } - - // require bin id to be sorted before doing this - pub fn to_amounts_into_bin<'a, 'info>( - &'a self, - active_id: i32, - bin_step: u16, - amount_x_in_active_bin: u64, // amount x in active bin - amount_y_in_active_bin: u64, // amount y in active bin - ) -> Result> { - to_amount_both_side( - active_id, - bin_step, - amount_x_in_active_bin, - amount_y_in_active_bin, - self.amount_x, - self.amount_y, - &self - .bin_liquidity_dist - .iter() - .map(|x| (x.bin_id, x.weight)) - .collect::>(), - ) - } -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: &Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - liquidity_parameter: &LiquidityParameterByWeight, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight_one_side.rs b/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight_one_side.rs deleted file mode 100644 index 7f7cf3d0..00000000 --- a/programs/lb_clmm/src/instructions/deposit/add_liquidity_by_weight_one_side.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::authorize_modify_position; -use crate::constants::MAX_BIN_PER_POSITION; -use crate::errors::LBError; -use crate::math::weight_to_amounts::to_amount_ask_side; -use crate::math::weight_to_amounts::to_amount_bid_side; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::position::PositionV2; -use crate::state::{bin::BinArray, lb_pair::LbPair}; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -use super::add_liquidity_by_weight::BinLiquidityDistributionByWeight; - -#[derive(AnchorSerialize, AnchorDeserialize, Eq, PartialEq, Clone, Debug)] -pub struct LiquidityOneSideParameter { - /// Amount of X token or Y token to deposit - pub amount: u64, - /// Active bin that integrator observe off-chain - pub active_id: i32, - /// max active bin slippage allowed - pub max_active_bin_slippage: i32, - /// Liquidity distribution to each bins - pub bin_liquidity_dist: Vec, -} - -impl LiquidityOneSideParameter { - fn bin_count(&self) -> u32 { - self.bin_liquidity_dist.len() as u32 - } - - fn validate<'a, 'info>(&'a self, active_id: i32) -> Result<()> { - require!(self.amount != 0, LBError::InvalidInput); - - let bin_count = self.bin_count(); - require!(bin_count > 0, LBError::InvalidInput); - - require!( - bin_count <= MAX_BIN_PER_POSITION as u32, - LBError::InvalidInput - ); - - let bin_shift = if active_id > self.active_id { - active_id - self.active_id - } else { - self.active_id - active_id - }; - - require!( - bin_shift <= self.max_active_bin_slippage.into(), - LBError::ExceededBinSlippageTolerance - ); - - // bin dist must be in consecutive order and weight is non-zero - for (i, val) in self.bin_liquidity_dist.iter().enumerate() { - require!(val.weight != 0, LBError::InvalidInput); - // bin id must in right order - if i != 0 { - require!( - val.bin_id > self.bin_liquidity_dist[i - 1].bin_id, - LBError::InvalidInput - ); - } - } - Ok(()) - } - - // require bin id to be sorted before doing this - fn to_amounts_into_bin<'a, 'info>( - &'a self, - active_id: i32, - bin_step: u16, - deposit_for_y: bool, - ) -> Result> { - if deposit_for_y { - to_amount_bid_side( - active_id, - self.amount, - &self - .bin_liquidity_dist - .iter() - .map(|x| (x.bin_id, x.weight)) - .collect::>(), - ) - } else { - to_amount_ask_side( - active_id, - self.amount, - bin_step, - &self - .bin_liquidity_dist - .iter() - .map(|x| (x.bin_id, x.weight)) - .collect::>(), - ) - } - } -} - -#[event_cpi] -#[derive(Accounts)] -pub struct ModifyLiquidityOneSide<'info> { - #[account( - mut, - has_one = lb_pair, - constraint = authorize_modify_position(&position, sender.key())? - )] - pub position: AccountLoader<'info, PositionV2>, - - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair, - )] - pub bin_array_bitmap_extension: Option>, - - #[account(mut)] - pub user_token: Box>, - - #[account(mut)] - pub reserve: Box>, - - pub token_mint: Box>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - pub sender: Signer<'info>, - pub token_program: Interface<'info, TokenInterface>, -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: &Context<'a, 'b, 'c, 'info, ModifyLiquidityOneSide<'info>>, - liquidity_parameter: &LiquidityOneSideParameter, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/deposit/add_liquidity_single_side_precise.rs b/programs/lb_clmm/src/instructions/deposit/add_liquidity_single_side_precise.rs deleted file mode 100644 index 85fce5ca..00000000 --- a/programs/lb_clmm/src/instructions/deposit/add_liquidity_single_side_precise.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::ModifyLiquidityOneSide; -use anchor_lang::prelude::*; - -#[derive(AnchorSerialize, AnchorDeserialize, Debug, Clone)] -pub struct AddLiquiditySingleSidePreciseParameter { - pub bins: Vec, - pub decompress_multiplier: u64, -} - -#[derive(AnchorSerialize, AnchorDeserialize, Debug, Clone)] -pub struct CompressedBinDepositAmount { - pub bin_id: i32, - pub amount: u32, -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidityOneSide<'info>>, - parameter: AddLiquiditySingleSidePreciseParameter, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/deposit/mod.rs b/programs/lb_clmm/src/instructions/deposit/mod.rs deleted file mode 100644 index d20613aa..00000000 --- a/programs/lb_clmm/src/instructions/deposit/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub mod add_liquidity; -pub mod add_liquidity_by_strategy; -pub mod add_liquidity_by_strategy_one_side; -pub mod add_liquidity_by_weight; -pub mod add_liquidity_by_weight_one_side; -pub mod add_liquidity_single_side_precise; - -pub use add_liquidity::*; -pub use add_liquidity_by_strategy::*; -pub use add_liquidity_by_strategy_one_side::*; -pub use add_liquidity_by_weight::*; -pub use add_liquidity_by_weight_one_side::*; -pub use add_liquidity_single_side_precise::*; diff --git a/programs/lb_clmm/src/instructions/fund_reward.rs b/programs/lb_clmm/src/instructions/fund_reward.rs deleted file mode 100644 index 0f58b2d8..00000000 --- a/programs/lb_clmm/src/instructions/fund_reward.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::state::{bin::BinArray, lb_pair::LbPair}; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(reward_index: u64)] -pub struct FundReward<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account(mut)] - pub reward_vault: Box>, - pub reward_mint: Box>, - #[account(mut)] - pub funder_token_account: Box>, - - pub funder: Signer<'info>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array: AccountLoader<'info, BinArray>, - - pub token_program: Interface<'info, TokenInterface>, -} - -pub fn handle( - ctx: Context, - index: u64, - amount: u64, - carry_forward: bool, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/increase_oracle_length.rs b/programs/lb_clmm/src/instructions/increase_oracle_length.rs deleted file mode 100644 index 2f1880bf..00000000 --- a/programs/lb_clmm/src/instructions/increase_oracle_length.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::state::oracle::Oracle; -use anchor_lang::prelude::*; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(length_to_add: u64)] -pub struct IncreaseOracleLength<'info> { - #[account( - mut, - realloc = Oracle::new_space(length_to_add, &oracle)?, - realloc::payer = funder, - realloc::zero = false - )] - pub oracle: AccountLoader<'info, Oracle>, - - #[account(mut)] - pub funder: Signer<'info>, - - pub system_program: Program<'info, System>, -} - -pub fn handle(ctx: Context, length_to_add: u64) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/initialize_bin_array.rs b/programs/lb_clmm/src/instructions/initialize_bin_array.rs deleted file mode 100644 index 4dc72cf0..00000000 --- a/programs/lb_clmm/src/instructions/initialize_bin_array.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::state::{bin::BinArray, lb_pair::LbPair}; -use crate::utils::seeds::BIN_ARRAY; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -#[instruction(index: i64)] -pub struct InitializeBinArray<'info> { - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - init, - payer = funder, - seeds = [ - BIN_ARRAY, - lb_pair.key().as_ref(), - &index.to_le_bytes() - ], - bump, - space = 8 + BinArray::INIT_SPACE - )] - pub bin_array: AccountLoader<'info, BinArray>, - - #[account(mut)] - pub funder: Signer<'info>, - - pub system_program: Program<'info, System>, -} - -pub fn handle(ctx: Context, index: i64) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/initialize_bin_array_bitmap_extension.rs b/programs/lb_clmm/src/instructions/initialize_bin_array_bitmap_extension.rs deleted file mode 100644 index dd59896b..00000000 --- a/programs/lb_clmm/src/instructions/initialize_bin_array_bitmap_extension.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::lb_pair::LbPair; -use crate::utils::seeds::BIN_ARRAY_BITMAP_SEED; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct InitializeBinArrayBitmapExtension<'info> { - pub lb_pair: AccountLoader<'info, LbPair>, - /// Initialize an account to store if a bin array is initialized. - #[account( - init, - seeds = [ - BIN_ARRAY_BITMAP_SEED, - lb_pair.key().as_ref(), - ], - bump, - payer = funder, - space = 8 + BinArrayBitmapExtension::INIT_SPACE - )] - pub bin_array_bitmap_extension: AccountLoader<'info, BinArrayBitmapExtension>, - #[account(mut)] - pub funder: Signer<'info>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/initialize_pool/initialize_customizable_permissionless_lb_pair.rs b/programs/lb_clmm/src/instructions/initialize_pool/initialize_customizable_permissionless_lb_pair.rs deleted file mode 100644 index ac8afa23..00000000 --- a/programs/lb_clmm/src/instructions/initialize_pool/initialize_customizable_permissionless_lb_pair.rs +++ /dev/null @@ -1,122 +0,0 @@ -use crate::constants::DEFAULT_OBSERVATION_LENGTH; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::lb_pair::LbPair; -use crate::state::oracle::Oracle; -use crate::state::preset_parameters::PresetParameter; -use crate::utils; -use crate::utils::seeds::BIN_ARRAY_BITMAP_SEED; -use crate::utils::seeds::ILM_BASE_KEY; -use crate::utils::seeds::ORACLE; -use anchor_lang::prelude::*; -use anchor_spl::token::Token; -use anchor_spl::token_interface::{Mint, TokenAccount}; -use std::cmp::{max, min}; - -#[derive(AnchorSerialize, AnchorDeserialize)] -pub struct CustomizableParams { - /// Pool price - pub active_id: i32, - /// Bin step - pub bin_step: u16, - /// Base factor - pub base_factor: u16, - /// Activation type. 0 = Slot, 1 = Time. Check ActivationType enum - pub activation_type: u8, - /// Whether the pool has an alpha vault - pub has_alpha_vault: bool, - /// Decide when does the pool start trade. None = Now - pub activation_point: Option, - /// Padding, for future use - pub padding: [u8; 64], -} - -#[event_cpi] -#[derive(Accounts)] -#[instruction(params: CustomizableParams)] -pub struct InitializeCustomizablePermissionlessLbPair<'info> { - #[account( - init, - seeds = [ - ILM_BASE_KEY.as_ref(), - min(token_mint_x.key(), token_mint_y.key()).as_ref(), - max(token_mint_x.key(), token_mint_y.key()).as_ref(), - ], - bump, - payer = funder, - space = 8 + LbPair::INIT_SPACE - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - init, - seeds = [ - BIN_ARRAY_BITMAP_SEED, - lb_pair.key().as_ref(), - ], - bump, - payer = funder, - space = 8 + BinArrayBitmapExtension::INIT_SPACE - )] - pub bin_array_bitmap_extension: Option>, - - #[account(constraint = token_mint_x.key() != token_mint_y.key())] - pub token_mint_x: Box>, - pub token_mint_y: Box>, - - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - token_mint_x.key().as_ref() - ], - bump, - payer = funder, - token::mint = token_mint_x, - token::authority = lb_pair, - )] - pub reserve_x: Box>, - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - token_mint_y.key().as_ref() - ], - bump, - payer = funder, - token::mint = token_mint_y, - token::authority = lb_pair, - )] - pub reserve_y: Box>, - - #[account( - init, - seeds = [ - ORACLE, - lb_pair.key().as_ref() - ], - bump, - payer = funder, - space = Oracle::space(DEFAULT_OBSERVATION_LENGTH) - )] - pub oracle: AccountLoader<'info, Oracle>, - - #[account( - token::authority = funder, - token::mint = token_mint_x, - )] - pub user_token_x: Box>, - - #[account(mut)] - pub funder: Signer<'info>, - - pub token_program: Program<'info, Token>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle( - ctx: Context, - params: CustomizableParams, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/initialize_pool/initialize_permission_lb_pair.rs b/programs/lb_clmm/src/instructions/initialize_pool/initialize_permission_lb_pair.rs deleted file mode 100644 index 984550ff..00000000 --- a/programs/lb_clmm/src/instructions/initialize_pool/initialize_permission_lb_pair.rs +++ /dev/null @@ -1,116 +0,0 @@ -use crate::assert_eq_launch_pool_admin; -use crate::constants::DEFAULT_OBSERVATION_LENGTH; -use crate::errors::LBError; -use crate::events::LbPairCreate; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::lb_pair::LbPair; -use crate::state::lb_pair::PairType; -use crate::state::oracle::Oracle; -use crate::state::preset_parameters::PresetParameter; -use crate::utils::seeds::BIN_ARRAY_BITMAP_SEED; -use crate::utils::seeds::ORACLE; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; -use std::cmp::{max, min}; - -#[derive(AnchorSerialize, AnchorDeserialize)] -pub struct InitPermissionPairIx { - pub active_id: i32, - pub bin_step: u16, - pub base_factor: u16, - pub min_bin_id: i32, - pub max_bin_id: i32, - pub lock_duration: u64, - pub activation_type: u8, -} - -#[event_cpi] -#[derive(Accounts)] -#[instruction(ix_data: InitPermissionPairIx)] -pub struct InitializePermissionLbPair<'info> { - pub base: Signer<'info>, - - #[account( - init, - seeds = [ - base.key().as_ref(), - min(token_mint_x.key(), token_mint_y.key()).as_ref(), - max(token_mint_x.key(), token_mint_y.key()).as_ref(), - &ix_data.bin_step.to_le_bytes(), - ], - bump, - payer = admin, - space = 8 + LbPair::INIT_SPACE - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - init, - seeds = [ - BIN_ARRAY_BITMAP_SEED, - lb_pair.key().as_ref(), - ], - bump, - payer = admin, - space = 8 + BinArrayBitmapExtension::INIT_SPACE - )] - pub bin_array_bitmap_extension: Option>, - - #[account(constraint = token_mint_x.key() != token_mint_y.key())] - pub token_mint_x: Box>, - pub token_mint_y: Box>, - - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - token_mint_x.key().as_ref() - ], - bump, - payer = admin, - token::mint = token_mint_x, - token::authority = lb_pair, - )] - pub reserve_x: Box>, - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - token_mint_y.key().as_ref() - ], - bump, - payer = admin, - token::mint = token_mint_y, - token::authority = lb_pair, - )] - pub reserve_y: Box>, - - #[account( - init, - seeds = [ - ORACLE, - lb_pair.key().as_ref() - ], - bump, - payer = admin, - space = Oracle::space(DEFAULT_OBSERVATION_LENGTH) - )] - pub oracle: AccountLoader<'info, Oracle>, - - #[account( - mut, - constraint = assert_eq_launch_pool_admin(admin.key()) @ LBError::InvalidAdmin, - )] - pub admin: Signer<'info>, - - pub token_program: Interface<'info, TokenInterface>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle( - ctx: Context, - ix_data: InitPermissionPairIx, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/initialize_pool/initialize_permissionless_lb_pair.rs b/programs/lb_clmm/src/instructions/initialize_pool/initialize_permissionless_lb_pair.rs deleted file mode 100644 index 05e910f2..00000000 --- a/programs/lb_clmm/src/instructions/initialize_pool/initialize_permissionless_lb_pair.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::constants::DEFAULT_OBSERVATION_LENGTH; -use crate::errors::LBError; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::lb_pair::LbPair; -use crate::state::oracle::Oracle; -use crate::state::preset_parameters::PresetParameter; -use crate::utils::seeds::BIN_ARRAY_BITMAP_SEED; -use crate::utils::seeds::ORACLE; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; -use std::cmp::{max, min}; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(active_id: i32, bin_step: u16)] -pub struct InitializeLbPair<'info> { - #[account( - init, - seeds = [ - min(token_mint_x.key(), token_mint_y.key()).as_ref(), - max(token_mint_x.key(), token_mint_y.key()).as_ref(), - &bin_step.to_le_bytes(), - &preset_parameter.base_factor.to_le_bytes() - ], - bump, - payer = funder, - space = 8 + LbPair::INIT_SPACE - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - init, - seeds = [ - BIN_ARRAY_BITMAP_SEED, - lb_pair.key().as_ref(), - ], - bump, - payer = funder, - space = 8 + BinArrayBitmapExtension::INIT_SPACE - )] - pub bin_array_bitmap_extension: Option>, - - #[account(constraint = token_mint_x.key() != token_mint_y.key())] - pub token_mint_x: Box>, - pub token_mint_y: Box>, - - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - token_mint_x.key().as_ref() - ], - bump, - payer = funder, - token::mint = token_mint_x, - token::authority = lb_pair, - )] - pub reserve_x: Box>, - #[account( - init, - seeds = [ - lb_pair.key().as_ref(), - token_mint_y.key().as_ref() - ], - bump, - payer = funder, - token::mint = token_mint_y, - token::authority = lb_pair, - )] - pub reserve_y: Box>, - - #[account( - init, - seeds = [ - ORACLE, - lb_pair.key().as_ref() - ], - bump, - payer = funder, - space = Oracle::space(DEFAULT_OBSERVATION_LENGTH) - )] - pub oracle: AccountLoader<'info, Oracle>, - - #[account( - constraint = bin_step == preset_parameter.bin_step @ LBError::NonPresetBinStep, - )] - pub preset_parameter: Account<'info, PresetParameter>, - - #[account(mut)] - pub funder: Signer<'info>, - - // #[account(address = Token2022::id())] - pub token_program: Interface<'info, TokenInterface>, - pub system_program: Program<'info, System>, - pub rent: Sysvar<'info, Rent>, -} - -pub fn handle(ctx: Context, active_id: i32, bin_step: u16) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/initialize_pool/mod.rs b/programs/lb_clmm/src/instructions/initialize_pool/mod.rs deleted file mode 100644 index 3f4ce8f4..00000000 --- a/programs/lb_clmm/src/instructions/initialize_pool/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod initialize_customizable_permissionless_lb_pair; -pub mod initialize_permission_lb_pair; -pub mod initialize_permissionless_lb_pair; - -pub use initialize_customizable_permissionless_lb_pair::*; -pub use initialize_permission_lb_pair::*; -pub use initialize_permissionless_lb_pair::*; diff --git a/programs/lb_clmm/src/instructions/migrate_bin_array.rs b/programs/lb_clmm/src/instructions/migrate_bin_array.rs deleted file mode 100644 index cd5bb75b..00000000 --- a/programs/lb_clmm/src/instructions/migrate_bin_array.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct MigrateBinArray<'info> { - pub lb_pair: AccountLoader<'info, LbPair>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/migrate_position.rs b/programs/lb_clmm/src/instructions/migrate_position.rs deleted file mode 100644 index d6315ac6..00000000 --- a/programs/lb_clmm/src/instructions/migrate_position.rs +++ /dev/null @@ -1,53 +0,0 @@ -use anchor_lang::prelude::*; - -use crate::state::{ - bin::BinArray, - lb_pair::LbPair, - position::{Position, PositionV2}, -}; - -#[event_cpi] -#[derive(Accounts)] -pub struct MigratePosition<'info> { - #[account( - init, - payer = owner, - space = 8 + PositionV2::INIT_SPACE, - )] - pub position_v2: AccountLoader<'info, PositionV2>, - - // TODO do we need to check whether it is pda? - #[account( - mut, - has_one = owner, - has_one = lb_pair, - close = rent_receiver - )] - pub position_v1: AccountLoader<'info, Position>, - - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - #[account(mut)] - pub owner: Signer<'info>, - - pub system_program: Program<'info, System>, - - /// CHECK: Account to receive closed account rental SOL - #[account(mut)] - pub rent_receiver: UncheckedAccount<'info>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/mod.rs b/programs/lb_clmm/src/instructions/mod.rs deleted file mode 100644 index 89061ad6..00000000 --- a/programs/lb_clmm/src/instructions/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -pub mod admin; -pub mod claim_fee; -pub mod claim_reward; -pub mod close_position; -pub mod create_position; -pub mod deposit; -pub mod fund_reward; -pub mod increase_oracle_length; -pub mod initialize_bin_array; -pub mod initialize_bin_array_bitmap_extension; -pub mod initialize_pool; -pub mod migrate_bin_array; -pub mod migrate_position; -pub mod position_authorize; -pub mod swap; -pub mod update_fees_and_rewards; -pub mod update_position_operator; -pub mod withdraw; -pub mod withdraw_ineligible_reward; -pub mod withdraw_protocol_fee; diff --git a/programs/lb_clmm/src/instructions/position_authorize.rs b/programs/lb_clmm/src/instructions/position_authorize.rs deleted file mode 100644 index 5af48029..00000000 --- a/programs/lb_clmm/src/instructions/position_authorize.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::{assert_eq_launch_pool_admin, state::position::PositionV2}; -use anchor_lang::prelude::*; - -pub fn authorize_modify_position<'info>( - position: &AccountLoader<'info, PositionV2>, - sender: Pubkey, -) -> Result { - let position = position.load()?; - return Ok(position.owner == sender || position.operator == sender); -} - -pub fn authorize_claim_fee_position<'info>( - position: &AccountLoader<'info, PositionV2>, - sender: Pubkey, -) -> Result { - let position = position.load()?; - - if position.fee_owner == Pubkey::default() { - Ok(position.owner == sender || position.operator == sender) - } else { - Ok(position.owner == sender - || position.operator == sender - || position.fee_owner == sender - || assert_eq_launch_pool_admin(sender)) - } -} - -pub trait PositionLiquidityFlowValidator { - fn validate_outflow_to_ata_of_position_owner(&self, owner: Pubkey) -> Result<()>; -} diff --git a/programs/lb_clmm/src/instructions/swap.rs b/programs/lb_clmm/src/instructions/swap.rs deleted file mode 100644 index ff4deece..00000000 --- a/programs/lb_clmm/src/instructions/swap.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::errors::LBError; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::lb_pair::*; -use crate::state::oracle::Oracle; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -#[event_cpi] -#[derive(Accounts)] -pub struct Swap<'info> { - #[account( - mut, - has_one = reserve_x, - has_one = reserve_y, - has_one = token_x_mint, - has_one = token_y_mint, - has_one = oracle, - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - has_one = lb_pair, - )] - pub bin_array_bitmap_extension: Option>, - - #[account(mut)] - pub reserve_x: Box>, - #[account(mut)] - pub reserve_y: Box>, - - #[account( - mut, - constraint = user_token_in.mint != user_token_out.mint @ LBError::InvalidTokenMint, - constraint = user_token_in.mint == token_x_mint.key() || user_token_in.mint == token_y_mint.key() @ LBError::InvalidTokenMint, - )] - pub user_token_in: Box>, - #[account( - mut, - constraint = user_token_out.mint == token_x_mint.key() || user_token_out.mint == token_y_mint.key() @ LBError::InvalidTokenMint, - )] - pub user_token_out: Box>, - - pub token_x_mint: Box>, - pub token_y_mint: Box>, - - #[account(mut)] - pub oracle: AccountLoader<'info, Oracle>, - - #[account(mut)] - pub host_fee_in: Option>>, - - pub user: Signer<'info>, - pub token_x_program: Interface<'info, TokenInterface>, - pub token_y_program: Interface<'info, TokenInterface>, -} - -pub fn handle_exact_in<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, Swap<'info>>, - amount_in: u64, - min_amount_out: u64, -) -> Result<()> { - Ok(()) -} - -pub fn handle_exact_out<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, Swap<'info>>, - max_in_amount: u64, - exact_out_amount: u64, -) -> Result<()> { - Ok(()) -} -pub fn handle_exact_in_with_price_impact<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, Swap<'info>>, - amount_in: u64, - active_id: Option, - max_price_impact_bps: u16, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/update_fees_and_rewards.rs b/programs/lb_clmm/src/instructions/update_fees_and_rewards.rs deleted file mode 100644 index d436b231..00000000 --- a/programs/lb_clmm/src/instructions/update_fees_and_rewards.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::authorize_modify_position; -use crate::state::{bin::BinArray, lb_pair::LbPair, position::PositionV2}; -use anchor_lang::prelude::*; - -#[derive(Accounts)] -pub struct UpdateFeesAndRewards<'info> { - #[account( - mut, - has_one = lb_pair, - constraint = authorize_modify_position(&position, owner.key())? - )] - pub position: AccountLoader<'info, PositionV2>, - - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_lower: AccountLoader<'info, BinArray>, - #[account( - mut, - has_one = lb_pair - )] - pub bin_array_upper: AccountLoader<'info, BinArray>, - - pub owner: Signer<'info>, -} - -pub fn handle(ctx: Context) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/update_position_operator.rs b/programs/lb_clmm/src/instructions/update_position_operator.rs deleted file mode 100644 index d2333ea8..00000000 --- a/programs/lb_clmm/src/instructions/update_position_operator.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::state::position::PositionV2; -use anchor_lang::prelude::*; -#[event_cpi] -#[derive(Accounts)] -pub struct UpdatePositionOperator<'info> { - #[account(mut, has_one = owner)] - pub position: AccountLoader<'info, PositionV2>, - pub owner: Signer<'info>, -} - -pub fn handle(ctx: Context, new_operator: Pubkey) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/withdraw/mod.rs b/programs/lb_clmm/src/instructions/withdraw/mod.rs deleted file mode 100644 index bd027f0f..00000000 --- a/programs/lb_clmm/src/instructions/withdraw/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod remove_all_liquidity; -pub mod remove_liquidity; - -pub use remove_all_liquidity::*; -pub use remove_liquidity::*; diff --git a/programs/lb_clmm/src/instructions/withdraw/remove_all_liquidity.rs b/programs/lb_clmm/src/instructions/withdraw/remove_all_liquidity.rs deleted file mode 100644 index c5d809e4..00000000 --- a/programs/lb_clmm/src/instructions/withdraw/remove_all_liquidity.rs +++ /dev/null @@ -1,9 +0,0 @@ -use anchor_lang::prelude::*; - -use crate::ModifyLiquidity; - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/withdraw/remove_liquidity.rs b/programs/lb_clmm/src/instructions/withdraw/remove_liquidity.rs deleted file mode 100644 index cdb2e1b7..00000000 --- a/programs/lb_clmm/src/instructions/withdraw/remove_liquidity.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::constants::BASIS_POINT_MAX; -use crate::ModifyLiquidity; -use crate::{errors::LBError, math::safe_math::SafeMath, state::position::PositionV2}; -use anchor_lang::prelude::*; -use ruint::aliases::U256; -#[derive(AnchorSerialize, AnchorDeserialize, Debug, Clone)] -pub struct BinLiquidityReduction { - pub bin_id: i32, - pub bps_to_remove: u16, -} - -pub fn calculate_shares_to_remove(bps: u16, bin_id: i32, position: &PositionV2) -> Result { - let share_in_bin = U256::from(position.get_liquidity_share_in_bin(bin_id)?); - - let share_to_remove: u128 = U256::from(bps) - .safe_mul(share_in_bin)? - .safe_div(U256::from(BASIS_POINT_MAX))? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?; - Ok(share_to_remove) -} - -pub fn handle<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - bin_liquidity_reduction: Vec, -) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/withdraw_ineligible_reward.rs b/programs/lb_clmm/src/instructions/withdraw_ineligible_reward.rs deleted file mode 100644 index bf676989..00000000 --- a/programs/lb_clmm/src/instructions/withdraw_ineligible_reward.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::state::{bin::BinArray, lb_pair::LbPair}; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -#[event_cpi] -#[derive(Accounts)] -#[instruction(reward_index: u64)] -pub struct WithdrawIneligibleReward<'info> { - #[account(mut)] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account(mut)] - pub reward_vault: Box>, - - pub reward_mint: Box>, - #[account(mut)] - pub funder_token_account: Box>, - - pub funder: Signer<'info>, - - #[account( - mut, - has_one = lb_pair - )] - pub bin_array: AccountLoader<'info, BinArray>, - - pub token_program: Interface<'info, TokenInterface>, -} - -pub fn handle(ctx: Context, index: u64) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/instructions/withdraw_protocol_fee.rs b/programs/lb_clmm/src/instructions/withdraw_protocol_fee.rs deleted file mode 100644 index 818144bb..00000000 --- a/programs/lb_clmm/src/instructions/withdraw_protocol_fee.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::state::lb_pair::LbPair; -use anchor_lang::prelude::*; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; - -#[derive(Accounts)] -pub struct WithdrawProtocolFee<'info> { - #[account( - mut, - has_one = reserve_x, - has_one = reserve_y, - has_one = token_x_mint, - has_one = token_y_mint, - )] - pub lb_pair: AccountLoader<'info, LbPair>, - - #[account(mut)] - pub reserve_x: Box>, - #[account(mut)] - pub reserve_y: Box>, - - pub token_x_mint: Box>, - pub token_y_mint: Box>, - - #[account(mut)] - pub receiver_token_x: Box>, - #[account(mut)] - pub receiver_token_y: Box>, - - pub fee_owner: Signer<'info>, - - pub token_x_program: Interface<'info, TokenInterface>, - pub token_y_program: Interface<'info, TokenInterface>, -} - -pub fn handle(ctx: Context, amount_x: u64, amount_y: u64) -> Result<()> { - Ok(()) -} diff --git a/programs/lb_clmm/src/lib.rs b/programs/lb_clmm/src/lib.rs deleted file mode 100644 index 1f5bbfea..00000000 --- a/programs/lb_clmm/src/lib.rs +++ /dev/null @@ -1,387 +0,0 @@ -#![allow(warnings)] - -use anchor_lang::prelude::*; - -pub mod constants; -pub mod errors; -pub mod events; -pub mod instructions; -pub mod manager; -pub mod math; -pub mod pair_action_access; -pub mod state; -pub mod utils; - -use instructions::admin::*; -use instructions::claim_fee::*; -use instructions::claim_reward::*; -use instructions::close_position::*; -use instructions::create_position::*; -use instructions::deposit::*; -use instructions::fund_reward::*; -use instructions::increase_oracle_length::*; -use instructions::initialize_bin_array::*; -use instructions::initialize_bin_array_bitmap_extension::*; -use instructions::initialize_pool::*; -use instructions::migrate_bin_array::*; -use instructions::migrate_position::*; -use instructions::position_authorize::*; -use instructions::swap::*; -use instructions::update_fees_and_rewards::*; -use instructions::update_position_operator::*; -use instructions::withdraw::*; -use instructions::withdraw_ineligible_reward::*; -use instructions::withdraw_protocol_fee::*; - -#[cfg(feature = "localnet")] -declare_id!("LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ"); - -#[cfg(feature = "staging")] -declare_id!("tLBro6JJuZNnpoad3p8pXKohE9f7f7tBZJpaeh6pXt1"); - -#[cfg(not(any(feature = "localnet", feature = "staging")))] -declare_id!("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo"); - -pub mod admin { - use super::*; - use anchor_lang::solana_program::pubkey; - - #[cfg(feature = "localnet")] - pub const ADMINS: [Pubkey; 1] = [pubkey!("bossj3JvwiNK7pvjr149DqdtJxf2gdygbcmEPTkb2F1")]; - - #[cfg(not(feature = "localnet"))] - pub const ADMINS: [Pubkey; 3] = [ - pubkey!("5unTfT2kssBuNvHPY6LbJfJpLqEcdMxGYLWHwShaeTLi"), - pubkey!("ChSAh3XXTxpp5n2EmgSCm6vVvVPoD1L9VrK3mcQkYz7m"), - pubkey!("DHLXnJdACTY83yKwnUkeoDjqi4QBbsYGa1v8tJL76ViX"), - ]; -} - -pub mod launch_pool_config_admins { - use super::*; - use anchor_lang::solana_program::pubkey; - - #[cfg(feature = "localnet")] - pub const ADMINS: [Pubkey; 1] = [pubkey!("bossj3JvwiNK7pvjr149DqdtJxf2gdygbcmEPTkb2F1")]; - - #[cfg(not(feature = "localnet"))] - pub const ADMINS: [Pubkey; 4] = [ - pubkey!("4Qo6nr3CqiynvnA3SsbBtzVT3B1pmqQW4dwf2nFmnzYp"), - pubkey!("5unTfT2kssBuNvHPY6LbJfJpLqEcdMxGYLWHwShaeTLi"), - pubkey!("ChSAh3XXTxpp5n2EmgSCm6vVvVPoD1L9VrK3mcQkYz7m"), - pubkey!("DHLXnJdACTY83yKwnUkeoDjqi4QBbsYGa1v8tJL76ViX"), - ]; -} - -/// Authorized pubkey to withdraw protocol fee -pub mod fee_owner { - use super::*; - - #[cfg(feature = "localnet")] - declare_id!("bossj3JvwiNK7pvjr149DqdtJxf2gdygbcmEPTkb2F1"); - - #[cfg(not(feature = "localnet"))] - declare_id!("6WaLrrRfReGKBYUSkmx2K6AuT21ida4j8at2SUiZdXu8"); -} - -pub fn assert_eq_admin(admin: Pubkey) -> bool { - crate::admin::ADMINS - .iter() - .any(|predefined_admin| predefined_admin.eq(&admin)) -} - -pub fn assert_eq_launch_pool_admin(admin: Pubkey) -> bool { - crate::launch_pool_config_admins::ADMINS - .iter() - .any(|predefined_launch_pool_admin| predefined_launch_pool_admin.eq(&admin)) -} - -#[program] -pub mod lb_clmm { - use super::*; - - pub fn initialize_lb_pair( - ctx: Context, - active_id: i32, - bin_step: u16, - ) -> Result<()> { - instructions::initialize_pool::initialize_permissionless_lb_pair::handle( - ctx, active_id, bin_step, - ) - } - - pub fn initialize_customizable_permissionless_lb_pair( - ctx: Context, - params: CustomizableParams, - ) -> Result<()> { - instructions::initialize_pool::initialize_customizable_permissionless_lb_pair::handle( - ctx, params, - ) - } - - pub fn initialize_permission_lb_pair( - ctx: Context, - ix_data: InitPermissionPairIx, - ) -> Result<()> { - instructions::initialize_pool::initialize_permission_lb_pair::handle(ctx, ix_data) - } - - pub fn initialize_bin_array_bitmap_extension( - ctx: Context, - ) -> Result<()> { - instructions::initialize_bin_array_bitmap_extension::handle(ctx) - } - - pub fn initialize_bin_array(ctx: Context, index: i64) -> Result<()> { - instructions::initialize_bin_array::handle(ctx, index) - } - - pub fn add_liquidity<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - liquidity_parameter: LiquidityParameter, - ) -> Result<()> { - instructions::deposit::add_liquidity::handle(ctx, liquidity_parameter) - } - pub fn add_liquidity_by_weight<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - liquidity_parameter: LiquidityParameterByWeight, - ) -> Result<()> { - instructions::deposit::add_liquidity_by_weight::handle(&ctx, &liquidity_parameter) - } - - pub fn add_liquidity_by_strategy<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - liquidity_parameter: LiquidityParameterByStrategy, - ) -> Result<()> { - instructions::deposit::add_liquidity_by_strategy::handle(ctx, &liquidity_parameter) - } - - pub fn add_liquidity_by_strategy_one_side<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidityOneSide<'info>>, - liquidity_parameter: LiquidityParameterByStrategyOneSide, - ) -> Result<()> { - instructions::deposit::add_liquidity_by_strategy_one_side::handle(ctx, &liquidity_parameter) - } - - pub fn add_liquidity_one_side<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidityOneSide<'info>>, - liquidity_parameter: LiquidityOneSideParameter, - ) -> Result<()> { - instructions::deposit::add_liquidity_by_weight_one_side::handle(&ctx, &liquidity_parameter) - } - - pub fn remove_liquidity<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - bin_liquidity_removal: Vec, - ) -> Result<()> { - instructions::withdraw::remove_liquidity::handle(ctx, bin_liquidity_removal) - } - - pub fn initialize_position( - ctx: Context, - lower_bin_id: i32, - width: i32, - ) -> Result<()> { - instructions::create_position::initialize_position::handle(ctx, lower_bin_id, width) - } - - pub fn initialize_position_pda( - ctx: Context, - lower_bin_id: i32, - width: i32, - ) -> Result<()> { - instructions::create_position::initialize_position_pda::handle(ctx, lower_bin_id, width) - } - - pub fn initialize_position_by_operator( - ctx: Context, - lower_bin_id: i32, - width: i32, - fee_owner: Pubkey, - lock_release_point: u64, - ) -> Result<()> { - instructions::create_position::initialize_position_by_operator::handle( - ctx, - lower_bin_id, - width, - fee_owner, - lock_release_point, - ) - } - - pub fn update_position_operator( - ctx: Context, - operator: Pubkey, - ) -> Result<()> { - instructions::update_position_operator::handle(ctx, operator) - } - - pub fn swap<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, Swap<'info>>, - amount_in: u64, - min_amount_out: u64, - ) -> Result<()> { - instructions::swap::handle_exact_in(ctx, amount_in, min_amount_out) - } - - pub fn withdraw_protocol_fee( - ctx: Context, - amount_x: u64, - amount_y: u64, - ) -> Result<()> { - instructions::withdraw_protocol_fee::handle(ctx, amount_x, amount_y) - } - - pub fn initialize_reward( - ctx: Context, - reward_index: u64, - reward_duration: u64, - funder: Pubkey, - ) -> Result<()> { - instructions::admin::initialize_reward::handle(ctx, reward_index, reward_duration, funder) - } - - pub fn fund_reward( - ctx: Context, - reward_index: u64, - amount: u64, - carry_forward: bool, - ) -> Result<()> { - instructions::fund_reward::handle(ctx, reward_index, amount, carry_forward) - } - - pub fn update_reward_funder( - ctx: Context, - reward_index: u64, - new_funder: Pubkey, - ) -> Result<()> { - instructions::admin::update_reward_funder::handle(ctx, reward_index, new_funder) - } - - pub fn update_reward_duration( - ctx: Context, - reward_index: u64, - new_duration: u64, - ) -> Result<()> { - instructions::admin::update_reward_duration::handle(ctx, reward_index, new_duration) - } - - pub fn claim_reward(ctx: Context, reward_index: u64) -> Result<()> { - instructions::claim_reward::handle(ctx, reward_index) - } - - pub fn claim_fee(ctx: Context) -> Result<()> { - instructions::claim_fee::handle(ctx) - } - - pub fn close_position(ctx: Context) -> Result<()> { - instructions::close_position::handle(ctx) - } - - pub fn update_fee_parameters( - ctx: Context, - fee_parameter: FeeParameter, - ) -> Result<()> { - instructions::admin::update_fee_parameters::handle(ctx, fee_parameter) - } - - pub fn increase_oracle_length( - ctx: Context, - length_to_add: u64, - ) -> Result<()> { - instructions::increase_oracle_length::handle(ctx, length_to_add) - } - - pub fn initialize_preset_parameter( - ctx: Context, - ix: InitPresetParametersIx, - ) -> Result<()> { - instructions::admin::initialize_preset_parameters::handle(ctx, ix) - } - - pub fn close_preset_parameter(ctx: Context) -> Result<()> { - instructions::admin::close_preset_parameter::handle(ctx) - } - - pub fn remove_all_liquidity<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidity<'info>>, - ) -> Result<()> { - instructions::withdraw::remove_all_liquidity::handle(ctx) - } - - pub fn toggle_pair_status(ctx: Context) -> Result<()> { - instructions::admin::toggle_pair_status::handle(ctx) - } - - pub fn migrate_position(ctx: Context) -> Result<()> { - instructions::migrate_position::handle(ctx) - } - - pub fn migrate_bin_array(ctx: Context) -> Result<()> { - instructions::migrate_bin_array::handle(ctx) - } - - pub fn update_fees_and_rewards(ctx: Context) -> Result<()> { - instructions::update_fees_and_rewards::handle(ctx) - } - - pub fn withdraw_ineligible_reward( - ctx: Context, - reward_index: u64, - ) -> Result<()> { - instructions::withdraw_ineligible_reward::handle(ctx, reward_index) - } - - pub fn set_activation_point( - ctx: Context, - activation_point: u64, - ) -> Result<()> { - instructions::admin::set_activation_point::handle(ctx, activation_point) - } - - pub fn add_liquidity_one_side_precise<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, ModifyLiquidityOneSide<'info>>, - parameter: AddLiquiditySingleSidePreciseParameter, - ) -> Result<()> { - instructions::deposit::add_liquidity_single_side_precise::handle(ctx, parameter) - } - - pub fn set_pre_activation_duration( - ctx: Context, - pre_activation_duration: u16, - ) -> Result<()> { - instructions::admin::set_pre_activation_duration::handle(ctx, pre_activation_duration) - } - - pub fn set_pre_activation_swap_address( - ctx: Context, - pre_activation_swap_address: Pubkey, - ) -> Result<()> { - instructions::admin::set_pre_activation_swap_address::handle( - ctx, - pre_activation_swap_address, - ) - } - - pub fn swap_exact_out<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, Swap<'info>>, - max_in_amount: u64, - out_amount: u64, - ) -> Result<()> { - instructions::swap::handle_exact_out(ctx, max_in_amount, out_amount) - } - - pub fn swap_with_price_impact<'a, 'b, 'c, 'info>( - ctx: Context<'a, 'b, 'c, 'info, Swap<'info>>, - amount_in: u64, - active_id: Option, - max_price_impact_bps: u16, - ) -> Result<()> { - instructions::swap::handle_exact_in_with_price_impact( - ctx, - amount_in, - active_id, - max_price_impact_bps, - ) - } -} diff --git a/programs/lb_clmm/src/manager/bin_array_manager.rs b/programs/lb_clmm/src/manager/bin_array_manager.rs deleted file mode 100644 index 984dc121..00000000 --- a/programs/lb_clmm/src/manager/bin_array_manager.rs +++ /dev/null @@ -1,159 +0,0 @@ -use crate::constants::MAX_BIN_PER_ARRAY; -use crate::errors::LBError; -use crate::state::bin::Bin; -use crate::state::lb_pair::LbPair; -use crate::{math::safe_math::SafeMath, state::bin::BinArray}; -use anchor_lang::prelude::*; -use std::cell::{Ref, RefMut}; - -/// A bin arrays container which make sure that the bin array are in continuous form. -pub struct BinArrayManager<'a, 'info> { - bin_arrays: &'a mut [RefMut<'info, BinArray>], -} - -impl<'a, 'info> BinArrayManager<'a, 'info> { - pub fn new(bin_arrays: &'a mut [RefMut<'info, BinArray>]) -> Result { - Ok(BinArrayManager { bin_arrays }) - } - - pub fn migrate_to_v2(&mut self) -> Result<()> { - // do it every step - for bin_array in self.bin_arrays.iter_mut() { - bin_array.migrate_to_v2()?; - } - Ok(()) - } - - pub fn get_zero_liquidity_flags(&self) -> Vec { - let mut flags = vec![]; - for bin_array in self.bin_arrays.iter() { - flags.push(bin_array.is_zero_liquidity()); - } - flags - } - - pub fn get_bin_array_index(&self, index: usize) -> Result { - let index = - i32::try_from(self.bin_arrays[index].index).map_err(|_| LBError::MathOverflow)?; - Ok(index) - } - - /// Validate whether the lower and upper bin array loaded aligned to lower bin id - pub fn validate_bin_arrays(&self, lower_bin_id: i32) -> Result<()> { - require!(self.bin_arrays.len() > 0, LBError::InvalidInput); - - let bin_array_0_index = BinArray::bin_id_to_bin_array_index(lower_bin_id)?; - - require!( - bin_array_0_index as i64 == self.bin_arrays[0].index, - LBError::InvalidInput - ); - - for i in 0..self.bin_arrays.len().saturating_sub(1) { - let current_bin_array = &self.bin_arrays[i]; - let next_bin_array = &self.bin_arrays[i + 1]; - - require!( - current_bin_array.index + 1 == next_bin_array.index, - LBError::NonContinuousBinArrays - ); - } - - Ok(()) - } - - pub fn get_lower_upper_bin_id(&self) -> Result<(i32, i32)> { - let lower_bin_array_idx = self.bin_arrays[0].index as i32; - let upper_bin_array_idx = self.bin_arrays[self.bin_arrays.len() - 1].index as i32; - - let lower_bin_id = lower_bin_array_idx.safe_mul(MAX_BIN_PER_ARRAY as i32)?; - let upper_bin_id = upper_bin_array_idx - .safe_mul(MAX_BIN_PER_ARRAY as i32)? - .safe_add(MAX_BIN_PER_ARRAY as i32)? - .safe_sub(1)?; - - Ok((lower_bin_id, upper_bin_id)) - } - - pub fn is_bin_id_within_range(&self, bin_id: i32) -> Result<()> { - let (lower_bin_id, upper_bin_id) = self.get_lower_upper_bin_id()?; - - require!( - bin_id >= lower_bin_id && bin_id <= upper_bin_id, - LBError::InvalidBinArray - ); - - Ok(()) - } - - // Update the rewards for active bin. If the active bin doesn't within the bin arrays, nothing will be updated. - pub fn update_rewards<'b>(&mut self, lb_pair: &mut RefMut<'b, LbPair>) -> Result<()> { - let current_timestamp = Clock::get()?.unix_timestamp; - - for bin_array in self.bin_arrays.iter_mut() { - if bin_array.is_bin_id_within_range(lb_pair.active_id).is_ok() { - bin_array.update_all_rewards(lb_pair, current_timestamp as u64)?; - break; - } - } - - Ok(()) - } - - pub fn get_continuous_bins(&'a self) -> impl Iterator { - self.bin_arrays - .iter() - .map(|ba| ba.bins.iter()) - .flat_map(|bins_iter| bins_iter) - } - - pub fn get_bin_arrays(&'a mut self) -> &'a mut [RefMut<'info, BinArray>] { - &mut self.bin_arrays - } - - pub fn get_bin(&self, bin_id: i32) -> Result<&Bin> { - let bin_array_idx = BinArray::bin_id_to_bin_array_index(bin_id)?; - match self - .bin_arrays - .iter() - .find(|ba| ba.index == bin_array_idx as i64) - { - Some(bin_array) => bin_array.get_bin(bin_id), - None => Err(LBError::InvalidBinArray.into()), - } - } - - pub fn get_bin_mut(&mut self, bin_id: i32) -> Result<&mut Bin> { - let bin_array_idx = BinArray::bin_id_to_bin_array_index(bin_id)?; - match self - .bin_arrays - .iter_mut() - .find(|ba| ba.index == bin_array_idx as i64) - { - Some(bin_array) => bin_array.get_bin_mut(bin_id), - None => Err(LBError::InvalidBinArray.into()), - } - } -} - -pub struct BinArrayManagerReadOnly<'a, 'info> { - bin_arrays: &'a [Ref<'info, BinArray>], -} - -impl<'a, 'info> BinArrayManagerReadOnly<'a, 'info> { - pub fn new(bin_arrays: &'a [Ref<'info, BinArray>]) -> Result { - Ok(BinArrayManagerReadOnly { bin_arrays }) - } - - pub fn get_bin(&self, bin_id: i32) -> Result<&Bin> { - let bin_array_idx = BinArray::bin_id_to_bin_array_index(bin_id)?; - match self - .bin_arrays - .iter() - .find(|ba| ba.index == bin_array_idx as i64) - { - Some(bin_array) => bin_array.get_bin(bin_id), - None => Err(LBError::InvalidBinArray.into()), - } - } -} diff --git a/programs/lb_clmm/src/manager/mod.rs b/programs/lb_clmm/src/manager/mod.rs deleted file mode 100644 index 26893817..00000000 --- a/programs/lb_clmm/src/manager/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod bin_array_manager; diff --git a/programs/lb_clmm/src/math/bin_math.rs b/programs/lb_clmm/src/math/bin_math.rs deleted file mode 100644 index b7cfe90c..00000000 --- a/programs/lb_clmm/src/math/bin_math.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::errors::LBError; - -use super::safe_math::SafeMath; -use super::u64x64_math::SCALE_OFFSET; -use anchor_lang::prelude::Result; -use ruint::aliases::U256; - -/// Calculate the amount of liquidity following the constant sum formula `L = price * x + y` -/// Price is in Q64x64 -pub fn get_liquidity(x: u64, y: u64, price: u128) -> Result { - // Q64x0 - let x: U256 = U256::from(x); - - // Multiplication do not require same Q number format. px is in Q64x64 - let price = U256::from(price); - let px = price.safe_mul(x)?; - - // When perform add, both must be same Q number format. Therefore << SCALE_OFFSET to make y and px Q64x64 - let y = u128::from(y).safe_shl(SCALE_OFFSET.into())?; - let y = U256::from(y); - // Liquidity represented with fractional part - let liquidity = px.safe_add(U256::from(y))?; - Ok(liquidity.try_into().map_err(|_| LBError::TypeCastFailed)?) -} diff --git a/programs/lb_clmm/src/math/mod.rs b/programs/lb_clmm/src/math/mod.rs deleted file mode 100644 index c503143a..00000000 --- a/programs/lb_clmm/src/math/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod bin_math; -pub mod price_math; -pub mod safe_math; -pub mod u128x128_math; -pub mod u64x64_math; -pub mod utils_math; -pub mod weight_to_amounts; diff --git a/programs/lb_clmm/src/math/price_math.rs b/programs/lb_clmm/src/math/price_math.rs deleted file mode 100644 index 4056c0ce..00000000 --- a/programs/lb_clmm/src/math/price_math.rs +++ /dev/null @@ -1,19 +0,0 @@ -use super::safe_math::SafeMath; -use super::u64x64_math::{pow, ONE, SCALE_OFFSET}; -use crate::constants::BASIS_POINT_MAX; -use crate::errors::LBError; -use anchor_lang::prelude::*; - -// In Trader Joe, the active_id need to be shifted by 2 ** 23 to get the actual ID. -// The reason is because they mint LP for each bin based on active_id using ERC1155, which the ID do not support negative - -/// Calculate price based on the given bin id. Eg: 1.0001 ^ 5555. The returned value is in Q64.64 -pub fn get_price_from_id(active_id: i32, bin_step: u16) -> Result { - // Make bin_step into Q64x64, and divided by BASIS_POINT_MAX. If bin_step = 1, we get 0.0001 in Q64x64 - let bps = u128::from(bin_step) - .safe_shl(SCALE_OFFSET.into())? - .safe_div(BASIS_POINT_MAX as u128)?; - // Add 1 to bps, we get 1.0001 in Q64.64 - let base = ONE.safe_add(bps)?; - pow(base, active_id).ok_or_else(|| LBError::MathOverflow.into()) -} diff --git a/programs/lb_clmm/src/math/safe_math.rs b/programs/lb_clmm/src/math/safe_math.rs deleted file mode 100644 index c429e623..00000000 --- a/programs/lb_clmm/src/math/safe_math.rs +++ /dev/null @@ -1,114 +0,0 @@ -use crate::errors::LBError; -use anchor_lang::solana_program::msg; -use ruint::aliases::U256; -use std::panic::Location; - -pub trait SafeMath: Sized { - fn safe_add(self, rhs: Self) -> Result; - fn safe_mul(self, rhs: Self) -> Result; - fn safe_div(self, rhs: Self) -> Result; - fn safe_rem(self, rhs: Self) -> Result; - fn safe_sub(self, rhs: Self) -> Result; - fn safe_shl(self, offset: T) -> Result; - fn safe_shr(self, offset: T) -> Result; -} - -macro_rules! checked_impl { - ($t:ty, $offset:ty) => { - impl SafeMath<$offset> for $t { - #[inline(always)] - fn safe_add(self, v: $t) -> Result<$t, LBError> { - match self.checked_add(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - - #[inline(always)] - fn safe_sub(self, v: $t) -> Result<$t, LBError> { - match self.checked_sub(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - - #[inline(always)] - fn safe_mul(self, v: $t) -> Result<$t, LBError> { - match self.checked_mul(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - - #[inline(always)] - fn safe_div(self, v: $t) -> Result<$t, LBError> { - match self.checked_div(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - - #[inline(always)] - fn safe_rem(self, v: $t) -> Result<$t, LBError> { - match self.checked_rem(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - - #[inline(always)] - fn safe_shl(self, v: $offset) -> Result<$t, LBError> { - match self.checked_shl(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - - #[inline(always)] - fn safe_shr(self, v: $offset) -> Result<$t, LBError> { - match self.checked_shr(v) { - Some(result) => Ok(result), - None => { - let caller = Location::caller(); - msg!("Math error thrown at {}:{}", caller.file(), caller.line()); - Err(LBError::MathOverflow) - } - } - } - } - }; -} - -checked_impl!(u16, u32); -checked_impl!(i32, u32); -checked_impl!(u32, u32); -checked_impl!(u64, u32); -checked_impl!(i64, u32); -checked_impl!(u128, u32); -checked_impl!(i128, u32); -checked_impl!(usize, u32); -checked_impl!(U256, usize); diff --git a/programs/lb_clmm/src/math/u128x128_math.rs b/programs/lb_clmm/src/math/u128x128_math.rs deleted file mode 100644 index d26dbf0c..00000000 --- a/programs/lb_clmm/src/math/u128x128_math.rs +++ /dev/null @@ -1,43 +0,0 @@ -use ruint::aliases::U256; - -// Round up, down -#[derive(PartialEq)] -pub enum Rounding { - Up, - Down, -} - -/// (x * y) / denominator -pub fn mul_div(x: u128, y: u128, denominator: u128, rounding: Rounding) -> Option { - if denominator == 0 { - return None; - } - - let x = U256::from(x); - let y = U256::from(y); - let denominator = U256::from(denominator); - - let prod = x.checked_mul(y)?; - - match rounding { - Rounding::Up => prod.div_ceil(denominator).try_into().ok(), - Rounding::Down => { - let (quotient, _) = prod.div_rem(denominator); - quotient.try_into().ok() - } - } -} - -/// (x * y) >> offset -#[inline] -pub fn mul_shr(x: u128, y: u128, offset: u8, rounding: Rounding) -> Option { - let denominator = 1u128.checked_shl(offset.into())?; - mul_div(x, y, denominator, rounding) -} - -/// (x << offset) / y -#[inline] -pub fn shl_div(x: u128, y: u128, offset: u8, rounding: Rounding) -> Option { - let scale = 1u128.checked_shl(offset.into())?; - mul_div(x, scale, y, rounding) -} diff --git a/programs/lb_clmm/src/math/u64x64_math.rs b/programs/lb_clmm/src/math/u64x64_math.rs deleted file mode 100644 index 61bebd31..00000000 --- a/programs/lb_clmm/src/math/u64x64_math.rs +++ /dev/null @@ -1,209 +0,0 @@ -use crate::constants::BASIS_POINT_MAX; -use ruint::aliases::U256; - -// Precision when converting from decimal to fixed point. Or the other way around. 10^12 -pub const PRECISION: u128 = 1_000_000_000_000; - -// Number of bits to scale. This will decide the position of the radix point. -pub const SCALE_OFFSET: u8 = 64; - -// Where does this value come from ? -// When smallest bin is used (1 bps), the maximum of bin limit is 887272 (Check: https://docs.traderjoexyz.com/concepts/bin-math). -// But in solana, the token amount is represented in 64 bits, therefore, it will be (1 + 0.0001)^n < 2 ** 64, solve for n, n ~= 443636 -// Then we calculate bits needed to represent 443636 exponential, 2^n >= 443636, ~= 19 -// If we convert 443636 to binary form, it will be 1101100010011110100 (19 bits). -// Which, the 19 bits are the bits the binary exponential will loop through. -// The 20th bit will be 0x80000, which the exponential already > the maximum number of bin Q64.64 can support -const MAX_EXPONENTIAL: u32 = 0x80000; // 1048576 - -// 1.0000... representation of 64x64 -pub const ONE: u128 = 1u128 << SCALE_OFFSET; - -pub fn pow(base: u128, exp: i32) -> Option { - // If exponent is negative. We will invert the result later by 1 / base^exp.abs() - let mut invert = exp.is_negative(); - - // When exponential is 0, result will always be 1 - if exp == 0 { - return Some(1u128 << 64); - } - - // Make the exponential positive. Which will compute the result later by 1 / base^exp - let exp: u32 = if invert { exp.abs() as u32 } else { exp as u32 }; - - // No point to continue the calculation as it will overflow the maximum value Q64.64 can support - if exp >= MAX_EXPONENTIAL { - return None; - } - - let mut squared_base = base; - let mut result = ONE; - - // When multiply the base twice, the number of bits double from 128 -> 256, which overflow. - // The trick here is to inverse the calculation, which make the upper 64 bits (number bits) to be 0s. - // For example: - // let base = 1.001, exp = 5 - // let neg = 1 / (1.001 ^ 5) - // Inverse the neg: 1 / neg - // By using a calculator, you will find out that 1.001^5 == 1 / (1 / 1.001^5) - if squared_base >= result { - // This inverse the base: 1 / base - squared_base = u128::MAX.checked_div(squared_base)?; - // If exponent is negative, the above already inverted the result. Therefore, at the end of the function, we do not need to invert again. - invert = !invert; - } - - // The following code is equivalent to looping through each binary value of the exponential. - // As explained in MAX_EXPONENTIAL, 19 exponential bits are enough to covert the full bin price. - // Therefore, there will be 19 if statements, which similar to the following pseudo code. - /* - let mut result = 1; - while exponential > 0 { - if exponential & 1 > 0 { - result *= base; - } - base *= base; - exponential >>= 1; - } - */ - - // From right to left - // squared_base = 1 * base^1 - // 1st bit is 1 - if exp & 0x1 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - // squared_base = base^2 - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - // 2nd bit is 1 - if exp & 0x2 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - // Example: - // If the base is 1.001, exponential is 3. Binary form of 3 is ..0011. The last 2 1's bit fulfill the above 2 bitwise condition. - // The result will be 1 * base^1 * base^2 == base^3. The process continues until reach the 20th bit - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x4 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x8 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x10 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x20 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x40 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x80 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x100 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x200 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x400 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x800 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x1000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x2000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x4000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x8000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x10000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x20000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - squared_base = (squared_base.checked_mul(squared_base)?) >> SCALE_OFFSET; - if exp & 0x40000 > 0 { - result = (result.checked_mul(squared_base)?) >> SCALE_OFFSET - } - - // Stop here as the next is 20th bit, which > MAX_EXPONENTIAL - if result == 0 { - return None; - } - - if invert { - result = u128::MAX.checked_div(result)?; - } - - Some(result) -} - -// Helper function to convert fixed point number to decimal with 10^12 precision. Decimal form is not being used in program, it's only for UI purpose. -pub fn to_decimal(value: u128) -> Option { - let value = U256::from(value); - let precision = U256::from(PRECISION); - let scaled_value = value.checked_mul(precision)?; - // ruint checked math is different with the rust std u128. If there's bit with 1 value being shifted out, it will return None. Therefore, we use overflowing_shr - let (scaled_down_value, _) = scaled_value.overflowing_shr(SCALE_OFFSET.into()); - scaled_down_value.try_into().ok() -} - -// Helper function to convert decimal with 10^12 precision to fixed point number -pub fn from_decimal(value: u128) -> Option { - let value = U256::from(value); - let precision = U256::from(PRECISION); - let (q_value, _) = value.overflowing_shl(SCALE_OFFSET.into()); - let fp_value = q_value.checked_div(precision)?; - fp_value.try_into().ok() -} - -// Helper function to get the base for price calculation. Eg: 1.001 in 64x64 representation -pub fn get_base(bin_step: u32) -> Option { - let quotient = u128::from(bin_step).checked_shl(SCALE_OFFSET.into())?; - let fraction = quotient.checked_div(BASIS_POINT_MAX as u128)?; - ONE.checked_add(fraction) -} diff --git a/programs/lb_clmm/src/math/utils_math.rs b/programs/lb_clmm/src/math/utils_math.rs deleted file mode 100644 index 184148dc..00000000 --- a/programs/lb_clmm/src/math/utils_math.rs +++ /dev/null @@ -1,73 +0,0 @@ -use super::{ - safe_math::SafeMath, - u128x128_math::{mul_div, mul_shr, shl_div, Rounding}, - u64x64_math::pow, -}; -use crate::errors::LBError; -use anchor_lang::prelude::Result; -use num_traits::cast::FromPrimitive; -use ruint::{aliases::U256, Uint}; - -#[inline] -pub fn safe_pow_cast(base: u128, exp: i32) -> Result { - T::from_u128(pow(base, exp).ok_or_else(|| LBError::MathOverflow)?) - .ok_or_else(|| LBError::TypeCastFailed.into()) -} - -#[inline] -pub fn safe_mul_div_cast( - x: u128, - y: u128, - denominator: u128, - rounding: Rounding, -) -> Result { - T::from_u128(mul_div(x, y, denominator, rounding).ok_or_else(|| LBError::MathOverflow)?) - .ok_or_else(|| LBError::TypeCastFailed.into()) -} - -#[inline] -pub fn safe_mul_div_cast_from_u64_to_u64(x: u64, y: u64, denominator: u64) -> Result { - let x = u128::from(x); - let y = u128::from(y); - let denominator = u128::from(denominator); - let result = u64::try_from(x.safe_mul(y)?.safe_div(denominator)?) - .map_err(|_| LBError::TypeCastFailed)?; - Ok(result) -} - -#[inline] -pub fn safe_mul_div_cast_from_u256_to_u64(x: u64, y: U256, denominator: U256) -> Result { - let x = U256::from(x); - // let denominator = U256::from(denominator); - let result = u64::try_from(x.safe_mul(y)?.safe_div(denominator)?) - .map_err(|_| LBError::TypeCastFailed)?; - Ok(result) -} - -#[inline] -pub fn safe_mul_shr_cast( - x: u128, - y: u128, - offset: u8, - rounding: Rounding, -) -> Result { - T::from_u128(mul_shr(x, y, offset, rounding).ok_or_else(|| LBError::MathOverflow)?) - .ok_or_else(|| LBError::TypeCastFailed.into()) -} - -#[inline] -pub fn safe_shl_div_cast( - x: u128, - y: u128, - offset: u8, - rounding: Rounding, -) -> Result { - T::from_u128(shl_div(x, y, offset, rounding).ok_or_else(|| LBError::MathOverflow)?) - .ok_or_else(|| LBError::TypeCastFailed.into()) -} - -pub const fn one() -> Uint { - let mut words = [0; LIMBS]; - words[0] = 1; - Uint::from_limbs(words) -} diff --git a/programs/lb_clmm/src/math/weight_to_amounts.rs b/programs/lb_clmm/src/math/weight_to_amounts.rs deleted file mode 100644 index cca09f54..00000000 --- a/programs/lb_clmm/src/math/weight_to_amounts.rs +++ /dev/null @@ -1,295 +0,0 @@ -use crate::errors::LBError; -use crate::math::price_math::get_price_from_id; -use crate::math::safe_math::SafeMath; -use crate::math::u64x64_math::SCALE_OFFSET; -use crate::math::utils_math::safe_mul_div_cast_from_u256_to_u64; -use crate::math::utils_math::safe_mul_div_cast_from_u64_to_u64; -use anchor_lang::prelude::*; -use ruint::aliases::U256; - -pub fn to_amount_bid_side( - active_id: i32, - amount: u64, - weights: &[(i32, u16)], -) -> Result> { - // get sum of weight - let mut total_weight = 0u64; - for &(bin_id, weight) in weights.iter() { - // skip all ask side - if bin_id > active_id { - // break because bin_id is in ascending order - break; - } - total_weight = total_weight.safe_add(weight.into())?; - } - if total_weight == 0 { - return Err(LBError::InvalidInput.into()); - } - let mut amounts = vec![]; - for &(bin_id, weight) in weights.iter() { - // skip all ask side - if bin_id > active_id { - amounts.push((bin_id, 0)); - } else { - amounts.push(( - bin_id, - safe_mul_div_cast_from_u64_to_u64(weight.into(), amount, total_weight)?, - )); - } - } - Ok(amounts) -} - -pub fn to_amount_ask_side( - active_id: i32, - amount: u64, - bin_step: u16, - weights: &[(i32, u16)], -) -> Result> { - // get sum of weight - let mut total_weight = U256::ZERO; - let mut weight_per_prices = vec![U256::ZERO; weights.len()]; - for (i, &(bin_id, weight)) in weights.iter().enumerate() { - // skip all bid side - if bin_id < active_id { - continue; - } - let weight_per_price = U256::from(weight) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(U256::from(get_price_from_id(bin_id, bin_step)?))?; - weight_per_prices[i] = weight_per_price; - total_weight = total_weight.safe_add(weight_per_price)?; - } - - if total_weight == U256::ZERO { - return Err(LBError::InvalidInput.into()); - } - - let mut amounts = vec![]; - for (i, &(bin_id, _weight)) in weights.iter().enumerate() { - // skip all bid side - if bin_id < active_id { - amounts.push((bin_id, 0)); - } else { - amounts.push(( - bin_id, - safe_mul_div_cast_from_u256_to_u64(amount, weight_per_prices[i], total_weight)?, - )); - } - } - Ok(amounts) -} - -fn get_active_bin_index(active_id: i32, weights: &[(i32, u16)]) -> Option { - for (i, &(bin_id, _weight)) in weights.iter().enumerate() { - if bin_id == active_id { - return Some(i); - } - // bin_id is sorted, so no need to check if bin cross - if bin_id > active_id { - break; - } - } - return None; -} - -pub fn to_amount_both_side( - active_id: i32, - bin_step: u16, - amount_x: u64, // amount_x in active bin - amount_y: u64, // amount_y in active bin - total_amount_x: u64, - total_amount_y: u64, - weights: &[(i32, u16)], -) -> Result> { - // only bid side - if active_id > weights[weights.len() - 1].0 { - let amounts = to_amount_bid_side(active_id, total_amount_y, weights)?; - - let amounts = amounts - .iter() - .map(|x| (x.0, 0, x.1)) - .collect::>(); - - return Ok(amounts); - } - // only ask side - if active_id < weights[0].0 { - let amounts = to_amount_ask_side(active_id, total_amount_x, bin_step, weights)?; - - let amounts = amounts - .iter() - .map(|x| (x.0, x.1, 0)) - .collect::>(); - - return Ok(amounts); - } - - match get_active_bin_index(active_id, weights) { - Some(index) => { - let (active_bin_id, active_weight) = weights[index]; - let p0 = U256::from(get_price_from_id(active_bin_id, bin_step)?); - - let (wx0, wy0) = if amount_x == 0 && amount_y == 0 { - // equal ratio if both amount_x and amount_y is zero - let wx0 = U256::from(active_weight) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(p0.safe_mul(U256::from(2))?)?; - - let wy0 = U256::from(active_weight) - .safe_shl(SCALE_OFFSET.into())? - .safe_div(U256::from(2))?; - (wx0, wy0) - } else { - let wx0 = if amount_x == 0 { - U256::ZERO - } else { - U256::from(active_weight) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div( - p0.safe_add( - U256::from(amount_y) - .safe_shl(SCALE_OFFSET.into())? - .safe_div(U256::from(amount_x))?, - )?, - )? - }; - let wy0 = if amount_y == 0 { - U256::ZERO - } else { - U256::from(active_weight) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div( - U256::from(1).safe_shl(SCALE_OFFSET.into())?.safe_add( - p0.safe_mul(U256::from(amount_x))? - .safe_div(U256::from(amount_y))?, - )?, - )? - }; - (wx0, wy0) - }; - - let mut total_weight_x = wx0; - let mut total_weight_y = wy0; - let mut weight_per_prices = vec![U256::ZERO; weights.len()]; - for (i, &(bin_id, weight)) in weights.iter().enumerate() { - if bin_id < active_id { - total_weight_y = total_weight_y - .safe_add(U256::from(weight).safe_shl(SCALE_OFFSET.into())?)?; - continue; - } - if bin_id > active_id { - let weight_per_price = U256::from(weight) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(U256::from(get_price_from_id(bin_id, bin_step)?))?; - weight_per_prices[i] = weight_per_price; - total_weight_x = total_weight_x.safe_add(weight_per_price)?; - continue; - } - } - // find k - let ky = U256::from(total_amount_y) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(total_weight_y)?; - - let kx = U256::from(total_amount_x) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(total_weight_x)?; - let k = kx.min(ky); - let mut amounts = vec![]; - for (i, &(bin_id, weight)) in weights.iter().enumerate() { - if bin_id < active_id { - let (amount_y_in_bin, _) = k - .safe_mul(U256::from(weight))? - .overflowing_shr(SCALE_OFFSET.into()); - amounts.push(( - bin_id, - 0, - u64::try_from(amount_y_in_bin).map_err(|_| LBError::TypeCastFailed)?, - )); - continue; - } - if bin_id > active_id { - let (amount_x_in_bin, _) = k - .safe_mul(weight_per_prices[i])? - .overflowing_shr((SCALE_OFFSET * 2).into()); - - amounts.push(( - bin_id, - u64::try_from(amount_x_in_bin).map_err(|_| LBError::TypeCastFailed)?, - 0, - )); - continue; - } - // else we are in active id - let (amount_x_in_bin, _) = - k.safe_mul(wx0)?.overflowing_shr((SCALE_OFFSET * 2).into()); - let (amount_y_in_bin, _) = - k.safe_mul(wy0)?.overflowing_shr((SCALE_OFFSET * 2).into()); - - amounts.push(( - bin_id, - u64::try_from(amount_x_in_bin).map_err(|_| LBError::TypeCastFailed)?, - u64::try_from(amount_y_in_bin).map_err(|_| LBError::TypeCastFailed)?, - )); - } - return Ok(amounts); - } - None => { - let mut total_weight_x = U256::ZERO; - let mut total_weight_y = U256::ZERO; - let mut weight_per_prices = vec![U256::ZERO; weights.len()]; - - for (i, &(bin_id, weight)) in weights.iter().enumerate() { - if bin_id < active_id { - total_weight_y = total_weight_y - .safe_add(U256::from(weight).safe_shl(SCALE_OFFSET.into())?)?; - continue; - } - if bin_id > active_id { - let weight_per_price = U256::from(weight) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(U256::from(get_price_from_id(bin_id, bin_step)?))?; - weight_per_prices[i] = weight_per_price; - total_weight_x = total_weight_x.safe_add(weight_per_price)?; - } - } - // find k - let ky = U256::from(total_amount_y) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(total_weight_y)?; - - let kx = U256::from(total_amount_x) - .safe_shl((SCALE_OFFSET * 2).into())? - .safe_div(total_weight_x)?; - let k = kx.min(ky); - - let mut amounts = vec![]; - for (i, &(bin_id, weight)) in weights.iter().enumerate() { - if bin_id < active_id { - let (amount_y_in_bin, _) = k - .safe_mul(U256::from(weight))? - .overflowing_shr(SCALE_OFFSET.into()); - amounts.push(( - bin_id, - 0, - u64::try_from(amount_y_in_bin).map_err(|_| LBError::TypeCastFailed)?, - )); - continue; - } - if bin_id > active_id { - let (amount_x_in_bin, _) = k - .safe_mul(weight_per_prices[i])? - .overflowing_shr((SCALE_OFFSET * 2).into()); - - amounts.push(( - bin_id, - u64::try_from(amount_x_in_bin).map_err(|_| LBError::TypeCastFailed)?, - 0, - )); - } - } - return Ok(amounts); - } - } -} \ No newline at end of file diff --git a/programs/lb_clmm/src/pair_action_access/base.rs b/programs/lb_clmm/src/pair_action_access/base.rs deleted file mode 100644 index 4ba23503..00000000 --- a/programs/lb_clmm/src/pair_action_access/base.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::errors::LBError; -use crate::math::safe_math::SafeMath; -use crate::pair_action_access::{ - CustomizablePermissionlessLbPairActionAccess, PermissionLbPairActionAccess, - PermissionlessLbPairActionAccess, -}; -use crate::state::lb_pair::LbPair; -use crate::state::lb_pair::PairType; -use anchor_lang::prelude::*; -use num_enum::{IntoPrimitive, TryFromPrimitive}; -use solana_program::pubkey::Pubkey; -#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[repr(u8)] -/// Type of the activation -pub enum ActivationType { - Slot, - Timestamp, -} - -pub trait LbPairTypeActionAccess { - fn validate_add_liquidity_access(&self) -> bool; - // in customizable permissionless pool, we doesn't allow user to deposit quote token in active bin before activation_point (because they can't withdraw liquidity before activation_point or do internal swap) - fn validate_deposit_quote_token_in_active_bin(&self) -> bool; - fn validate_remove_liquidity_access(&self, is_ask_side: bool) -> Result; - fn validate_swap_access(&self, sender: Pubkey) -> bool; - fn get_current_point(&self) -> u64; - fn validate_update_new_activation_point(&self, new_activation_point: u64) -> Result<()>; - fn validate_set_pre_activation_duration(&self, new_pre_activation_duration: u64) -> Result<()>; - fn validate_set_pre_activation_swap_address(&self) -> Result<()>; - fn validate_initialize_position_by_operator(&self) -> bool; - fn validate_initialize_position(&self) -> bool; - fn validate_initialize_bin_array(&self) -> bool; -} - -pub fn get_lb_pair_type_access_validator<'a>( - lb_pair: &'a LbPair, -) -> Result> { - let pair_type = PairType::try_from(lb_pair.pair_type).map_err(|_| LBError::InvalidPoolType)?; - match pair_type { - PairType::Permissionless => { - let pair_access_validator = PermissionlessLbPairActionAccess::new(lb_pair)?; - Ok(Box::new(pair_access_validator)) - } - PairType::Permission => { - let pair_access_validator = PermissionLbPairActionAccess::new(lb_pair)?; - Ok(Box::new(pair_access_validator)) - } - PairType::CustomizablePermissionless => { - let pair_access_validator = CustomizablePermissionlessLbPairActionAccess::new(lb_pair)?; - Ok(Box::new(pair_access_validator)) - } - } -} - -pub fn validate_activation_point( - activation_point: u64, - pre_activation_swap_duration: u64, - deposit_close_idle_duration: u64, - last_join_buffer: u64, - current_point: u64, -) -> Result<()> { - let pre_activation_swap_point = activation_point.safe_sub(pre_activation_swap_duration)?; - let vault_last_join_point = pre_activation_swap_point.safe_sub(deposit_close_idle_duration)?; - - let pre_last_join_point = vault_last_join_point.safe_sub(last_join_buffer)?; - - // Don't allow pool creation if no one can join even with bundle - require!( - pre_last_join_point >= current_point, - LBError::InvalidActivationDuration - ); - Ok(()) -} diff --git a/programs/lb_clmm/src/pair_action_access/customizable_permissionless_lb_pair.rs b/programs/lb_clmm/src/pair_action_access/customizable_permissionless_lb_pair.rs deleted file mode 100644 index 4a2f9732..00000000 --- a/programs/lb_clmm/src/pair_action_access/customizable_permissionless_lb_pair.rs +++ /dev/null @@ -1,89 +0,0 @@ -use crate::pair_action_access::ActivationType; -use crate::pair_action_access::LbPairTypeActionAccess; -use crate::state::lb_pair::{LbPair, PairStatus}; -use crate::{ - constants::{SLOT_BUFFER, TIME_BUFFER}, - errors::LBError, -}; -use anchor_lang::prelude::*; -use solana_program::pubkey::Pubkey; -pub struct CustomizablePermissionlessLbPairActionAccess { - is_enabled: bool, - pre_activation_swap_address: Pubkey, - activation_point: u64, - current_point: u64, - pre_activation_duration: u64, -} - -impl CustomizablePermissionlessLbPairActionAccess { - pub fn new(lb_pair: &LbPair) -> Result { - let activation_type = ActivationType::try_from(lb_pair.activation_type) - .map_err(|_| LBError::InvalidActivationType)?; - let (current_point, _) = match activation_type { - ActivationType::Slot => (Clock::get()?.slot, SLOT_BUFFER), - ActivationType::Timestamp => (Clock::get()?.unix_timestamp as u64, TIME_BUFFER), - }; - Ok(Self { - is_enabled: lb_pair.status == Into::::into(PairStatus::Enabled), - pre_activation_swap_address: lb_pair.pre_activation_swap_address, - activation_point: lb_pair.activation_point, - current_point, - pre_activation_duration: lb_pair.pre_activation_duration, - }) - } -} - -impl LbPairTypeActionAccess for CustomizablePermissionlessLbPairActionAccess { - fn validate_add_liquidity_access(&self) -> bool { - self.is_enabled - } - - fn validate_deposit_quote_token_in_active_bin(&self) -> bool { - self.current_point >= self.activation_point - } - - fn validate_remove_liquidity_access(&self, is_ask_side: bool) -> Result { - if is_ask_side { - // ask side can withdraw after 1 slot - Ok(self.current_point > self.activation_point) - } else { - Ok(true) - } - } - - fn validate_swap_access(&self, sender: Pubkey) -> bool { - let activation_point = if self.pre_activation_swap_address.eq(&sender) { - self.activation_point - .saturating_sub(self.pre_activation_duration) - } else { - self.activation_point - }; - - self.is_enabled && self.current_point >= activation_point - } - fn get_current_point(&self) -> u64 { - self.current_point - } - fn validate_set_pre_activation_duration( - &self, - _new_pre_activation_duration: u64, - ) -> Result<()> { - Err(LBError::UnauthorizedAccess.into()) - } - fn validate_update_new_activation_point(&self, _new_activation_point: u64) -> Result<()> { - Err(LBError::UnauthorizedAccess.into()) - } - fn validate_set_pre_activation_swap_address(&self) -> Result<()> { - Err(LBError::UnauthorizedAccess.into()) - } - - fn validate_initialize_position_by_operator(&self) -> bool { - self.current_point < self.activation_point - } - fn validate_initialize_position(&self) -> bool { - self.is_enabled - } - fn validate_initialize_bin_array(&self) -> bool { - self.is_enabled - } -} diff --git a/programs/lb_clmm/src/pair_action_access/mod.rs b/programs/lb_clmm/src/pair_action_access/mod.rs deleted file mode 100644 index 042b4753..00000000 --- a/programs/lb_clmm/src/pair_action_access/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod base; -pub mod customizable_permissionless_lb_pair; -pub mod permission_pair; -pub mod permissionless_pair; - -pub use base::*; -pub use customizable_permissionless_lb_pair::*; -pub use permission_pair::*; -pub use permissionless_pair::*; diff --git a/programs/lb_clmm/src/pair_action_access/permission_pair.rs b/programs/lb_clmm/src/pair_action_access/permission_pair.rs deleted file mode 100644 index 5745d1fc..00000000 --- a/programs/lb_clmm/src/pair_action_access/permission_pair.rs +++ /dev/null @@ -1,163 +0,0 @@ -use crate::constants::FIVE_MINUTES_SLOT_BUFFER; -use crate::constants::FIVE_MINUTES_TIME_BUFFER; -use crate::math::safe_math::SafeMath; -use crate::pair_action_access::validate_activation_point; -use crate::pair_action_access::ActivationType; -use crate::pair_action_access::LbPairTypeActionAccess; -use crate::state::lb_pair::{LbPair, PairStatus}; -use crate::{ - constants::{SLOT_BUFFER, TIME_BUFFER}, - errors::LBError, -}; -use anchor_lang::prelude::*; -use solana_program::pubkey::Pubkey; -pub struct PermissionLbPairActionAccess { - is_enabled: bool, - pre_activation_swap_address: Pubkey, - activation_point: u64, - current_point: u64, - pre_activation_duration: u64, - time_buffer: u64, - deposit_close_idle_duration: u64, - last_join_buffer: u64, -} - -impl PermissionLbPairActionAccess { - pub fn new(lb_pair: &LbPair) -> Result { - let activation_type = ActivationType::try_from(lb_pair.activation_type) - .map_err(|_| LBError::InvalidActivationType)?; - let (current_point, time_buffer, deposit_close_idle_duration, last_join_buffer) = - match activation_type { - ActivationType::Slot => ( - Clock::get()?.slot, - SLOT_BUFFER, - FIVE_MINUTES_SLOT_BUFFER, - FIVE_MINUTES_SLOT_BUFFER, - ), - ActivationType::Timestamp => ( - Clock::get()?.unix_timestamp as u64, - TIME_BUFFER, - FIVE_MINUTES_TIME_BUFFER, - FIVE_MINUTES_TIME_BUFFER, - ), - }; - Ok(Self { - is_enabled: lb_pair.status == Into::::into(PairStatus::Enabled), - pre_activation_swap_address: lb_pair.pre_activation_swap_address, - activation_point: lb_pair.activation_point, - current_point, - pre_activation_duration: lb_pair.pre_activation_duration, - time_buffer, - deposit_close_idle_duration, - last_join_buffer, - }) - } -} - -impl LbPairTypeActionAccess for PermissionLbPairActionAccess { - fn validate_add_liquidity_access(&self) -> bool { - self.is_enabled - } - - fn validate_deposit_quote_token_in_active_bin(&self) -> bool { - self.current_point >= self.activation_point - } - - fn validate_remove_liquidity_access(&self, _is_ask_side: bool) -> Result { - Ok(true) - } - - fn validate_swap_access(&self, sender: Pubkey) -> bool { - let activation_point = if self.pre_activation_swap_address.eq(&sender) { - self.activation_point - .saturating_sub(self.pre_activation_duration) - } else { - self.activation_point - }; - - self.is_enabled && self.current_point >= activation_point - } - fn get_current_point(&self) -> u64 { - self.current_point - } - - fn validate_set_pre_activation_duration(&self, new_pre_activation_duration: u64) -> Result<()> { - // doesnt allow to set this if pool doesn't link with an alpha-vault - if self.pre_activation_swap_address == Pubkey::default() { - return Err(LBError::UnauthorizedAccess.into()); - } - require!( - new_pre_activation_duration >= self.time_buffer, - LBError::InvalidPreActivationDuration - ); - validate_activation_point( - self.activation_point, - new_pre_activation_duration, - self.deposit_close_idle_duration, - self.last_join_buffer, - self.current_point, - )?; - Ok(()) - } - fn validate_update_new_activation_point(&self, new_activation_point: u64) -> Result<()> { - // Activation point was set - if self.activation_point != u64::MAX { - // Make sure it's not yet activated - require!( - self.current_point < self.activation_point, - LBError::AlreadyPassActivationPoint - ); - } - - require!( - new_activation_point > self.current_point, - LBError::InvalidInput - ); - - let buffer_time = new_activation_point.safe_sub(self.current_point)?; - require!(buffer_time > self.time_buffer, LBError::InvalidInput); - - if self.pre_activation_swap_address.ne(&Pubkey::default()) { - let pre_activation_swap_point = self - .activation_point - .safe_sub(self.pre_activation_duration)?; - // make sure the current pre_activation_swap_point hasn't reached - require!( - pre_activation_swap_point > self.current_point, - LBError::AlreadyPassPreActivationSwapPoint - ); - - validate_activation_point( - new_activation_point, - self.pre_activation_duration, - self.deposit_close_idle_duration, - self.last_join_buffer, - self.current_point, - )?; - } - - Ok(()) - } - - fn validate_set_pre_activation_swap_address(&self) -> Result<()> { - let pre_activation_start_point = self - .activation_point - .saturating_sub(self.pre_activation_duration); - // Don't allow update when the pool already enter pre-activation phase - require!( - self.current_point < pre_activation_start_point, - LBError::InvalidInput - ); - Ok(()) - } - - fn validate_initialize_position_by_operator(&self) -> bool { - self.current_point < self.activation_point - } - fn validate_initialize_position(&self) -> bool { - self.is_enabled - } - fn validate_initialize_bin_array(&self) -> bool { - self.is_enabled - } -} diff --git a/programs/lb_clmm/src/pair_action_access/permissionless_pair.rs b/programs/lb_clmm/src/pair_action_access/permissionless_pair.rs deleted file mode 100644 index a2c97cd1..00000000 --- a/programs/lb_clmm/src/pair_action_access/permissionless_pair.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::errors::LBError; -use crate::pair_action_access::ActivationType; -use crate::pair_action_access::LbPairTypeActionAccess; -use crate::state::lb_pair::{LbPair, PairStatus}; -use anchor_lang::prelude::*; -pub struct PermissionlessLbPairActionAccess { - is_enabled: bool, - current_point: u64, -} - -impl PermissionlessLbPairActionAccess { - pub fn new(lb_pair: &LbPair) -> Result { - let activation_type = ActivationType::try_from(lb_pair.activation_type) - .map_err(|_| LBError::InvalidActivationType)?; - let current_point = match activation_type { - ActivationType::Slot => Clock::get()?.slot, - ActivationType::Timestamp => Clock::get()?.unix_timestamp as u64, - }; - Ok(Self { - is_enabled: lb_pair.status == Into::::into(PairStatus::Enabled), - current_point, - }) - } -} - -impl LbPairTypeActionAccess for PermissionlessLbPairActionAccess { - fn validate_add_liquidity_access(&self) -> bool { - self.is_enabled - } - - fn validate_deposit_quote_token_in_active_bin(&self) -> bool { - true - } - - fn validate_remove_liquidity_access(&self, _is_ask_side: bool) -> Result { - Ok(true) - } - - fn validate_swap_access(&self, _sender: Pubkey) -> bool { - self.is_enabled - } - - fn get_current_point(&self) -> u64 { - self.current_point - } - fn validate_set_pre_activation_duration( - &self, - _new_pre_activation_duration: u64, - ) -> Result<()> { - Err(LBError::UnauthorizedAccess.into()) - } - fn validate_update_new_activation_point(&self, _new_activation_point: u64) -> Result<()> { - Err(LBError::UnauthorizedAccess.into()) - } - fn validate_set_pre_activation_swap_address(&self) -> Result<()> { - Err(LBError::UnauthorizedAccess.into()) - } - - fn validate_initialize_position_by_operator(&self) -> bool { - false - } - fn validate_initialize_position(&self) -> bool { - self.is_enabled - } - fn validate_initialize_bin_array(&self) -> bool { - self.is_enabled - } -} diff --git a/programs/lb_clmm/src/state/bin.rs b/programs/lb_clmm/src/state/bin.rs deleted file mode 100644 index 988b339c..00000000 --- a/programs/lb_clmm/src/state/bin.rs +++ /dev/null @@ -1,543 +0,0 @@ -use std::cell::RefMut; - -use super::lb_pair::LbPair; -use crate::{ - constants::{BASIS_POINT_MAX, MAX_BIN_ID, MAX_BIN_PER_ARRAY, MIN_BIN_ID, NUM_REWARDS}, - errors::*, - math::{ - price_math::get_price_from_id, - safe_math::SafeMath, - u128x128_math::Rounding, - u64x64_math::SCALE_OFFSET, - utils_math::{safe_mul_div_cast, safe_mul_shr_cast, safe_shl_div_cast}, - }, -}; -use anchor_lang::prelude::*; -use num_enum::{IntoPrimitive, TryFromPrimitive}; -use num_integer::Integer; -/// Calculate out token amount based on liquidity share and supply -#[inline] -pub fn get_out_amount( - liquidity_share: u128, - bin_token_amount: u64, - liquidity_supply: u128, -) -> Result { - if liquidity_supply == 0 { - return Ok(0); - } - - // liquidity_share * bin_token_amount / liquidity_supply - safe_mul_div_cast( - liquidity_share.into(), - bin_token_amount.into(), - liquidity_supply.into(), - Rounding::Down, - ) -} - -/// Calculate liquidity share upon deposit -#[inline] -pub fn get_liquidity_share( - in_liquidity: u128, - bin_liquidity: u128, - liquidity_supply: u128, -) -> Result { - safe_mul_div_cast( - in_liquidity.into(), - liquidity_supply.into(), - bin_liquidity.into(), - Rounding::Down, - ) -} - -#[derive(Debug)] -pub struct SwapResult { - /// Amount of token swap into the bin - pub amount_in_with_fees: u64, - /// Amount of token swap out from the bin - pub amount_out: u64, - /// Swap fee, includes protocol fee - pub fee: u64, - /// Part of fee - pub protocol_fee_after_host_fee: u64, - /// Part of protocol fee - pub host_fee: u64, - /// Indicate whether reached exact out amount - pub is_exact_out_amount: bool, -} - -#[zero_copy] -#[derive(Default, Debug, InitSpace)] -pub struct Bin { - /// Amount of token X in the bin. This already excluded protocol fees. - pub amount_x: u64, - /// Amount of token Y in the bin. This already excluded protocol fees. - pub amount_y: u64, - /// Bin price - pub price: u128, - /// Liquidities of the bin. This is the same as LP mint supply. q-number - pub liquidity_supply: u128, - /// reward_a_per_token_stored - pub reward_per_token_stored: [u128; NUM_REWARDS], - /// Swap fee amount of token X per liquidity deposited. - pub fee_amount_x_per_token_stored: u128, - /// Swap fee amount of token Y per liquidity deposited. - pub fee_amount_y_per_token_stored: u128, - /// Total token X swap into the bin. Only used for tracking purpose. - pub amount_x_in: u128, - /// Total token Y swap into he bin. Only used for tracking purpose. - pub amount_y_in: u128, -} - -impl Bin { - pub fn is_zero_liquidity(&self) -> bool { - self.liquidity_supply == 0 - } - /// Deposit to the bin. - pub fn deposit(&mut self, amount_x: u64, amount_y: u64, liquidity_share: u128) -> Result<()> { - self.amount_x = self.amount_x.safe_add(amount_x)?; - self.amount_y = self.amount_y.safe_add(amount_y)?; - self.liquidity_supply = self.liquidity_supply.safe_add(liquidity_share)?; - - Ok(()) - } - - /// Deposit composition fee - pub fn deposit_composition_fee(&mut self, fee_x: u64, fee_y: u64) -> Result<()> { - self.amount_x = self.amount_x.safe_add(fee_x)?; - self.amount_y = self.amount_y.safe_add(fee_y)?; - - Ok(()) - } - - /// Get or compute and save bin price if not exists - pub fn get_or_store_bin_price(&mut self, id: i32, bin_step: u16) -> Result { - if self.price == 0 { - self.price = get_price_from_id(id, bin_step)?; - } - - Ok(self.price) - } - - /// Update fee per liquidity stored. Used for claiming swap fee later. - pub fn update_fee_per_token_stored(&mut self, fee: u64, swap_for_y: bool) -> Result<()> { - let fee_per_token_stored: u128 = safe_shl_div_cast( - fee.into(), - self.liquidity_supply - .safe_shr(SCALE_OFFSET.into())? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?, - SCALE_OFFSET, - Rounding::Down, - )?; - - // Fee was charged at swap-in side - if swap_for_y { - // Change to wrapping add later - self.fee_amount_x_per_token_stored = self - .fee_amount_x_per_token_stored - .safe_add(fee_per_token_stored)?; - } else { - self.fee_amount_y_per_token_stored = self - .fee_amount_y_per_token_stored - .safe_add(fee_per_token_stored)?; - } - Ok(()) - } - - /// Swap - pub fn swap( - &mut self, - amount_in: u64, - price: u128, - swap_for_y: bool, - lb_pair: &LbPair, - host_fee_bps: Option, - ) -> Result { - // Get maximum out token amount can be swapped out from the bin. - let max_amount_out = self.get_max_amount_out(swap_for_y); - // Get maximum in token amount needed to swap out all of the opposite token from the bin. - let mut max_amount_in = self.get_max_amount_in(price, swap_for_y)?; - - // The fee was deducted from the amount_in if the swap will not move the active bin. So, the amount_in include fees - // When the amount_in > max_amount_in, it will swap finish all the current bin token X/Y based on the swap direction. - // However, max_amount_in is amount that required to swap finish the current bin without fee - // Therefore, we need find max_amount_in_include_fees, where max_amount_in_include_fees - fee = max_amount_in - let max_fee = lb_pair.compute_fee(max_amount_in)?; - max_amount_in = max_amount_in.safe_add(max_fee)?; - - // If the in token amount > maximum token amount needed to swap out all of the opposite token from the bin. - let (amount_in_with_fees, amount_out, fee, protocol_fee) = if amount_in > max_amount_in { - ( - max_amount_in, - max_amount_out, - max_fee, - lb_pair.compute_protocol_fee(max_fee)?, - ) - } else { - // TODO: User possible to bypass fee by swapping small amount ? User do a "normal" swap by just bundling all small swap that bypass fee ? - let fee = lb_pair.compute_fee_from_amount(amount_in)?; - let amount_in_after_fee = amount_in.safe_sub(fee)?; - let amount_out = Bin::get_amount_out(amount_in_after_fee, price, swap_for_y)?; - ( - amount_in, - std::cmp::min(amount_out, max_amount_out), - fee, - lb_pair.compute_protocol_fee(fee)?, - ) - }; - - let host_fee = match host_fee_bps { - Some(bps) => protocol_fee - .safe_mul(bps.into())? - .safe_div(BASIS_POINT_MAX as u64)?, - None => 0, - }; - - let protocol_fee_after_host_fee = protocol_fee.safe_sub(host_fee)?; - - // Exclude fee and protocol fee. Protocol fee already part of fee. User need to claim the fee later. - let amount_into_bin = amount_in_with_fees.safe_sub(fee)?; - - if swap_for_y { - self.amount_x = self.amount_x.safe_add(amount_into_bin)?; - self.amount_y = self.amount_y.safe_sub(amount_out)?; - } else { - self.amount_y = self.amount_y.safe_add(amount_into_bin)?; - self.amount_x = self.amount_x.safe_sub(amount_out)?; - } - - Ok(SwapResult { - amount_in_with_fees, - amount_out, - fee, - protocol_fee_after_host_fee, - host_fee, - is_exact_out_amount: false, - }) - } - - pub fn swap_exact_out( - &mut self, - amount_in: u64, - price: u128, - swap_for_y: bool, - lb_pair: &LbPair, - host_fee_bps: Option, - exact_out_amount: u64, - ) -> Result { - // Get maximum out token amount can be swapped out from the bin. - let max_amount_out = self.get_max_amount_out(swap_for_y); - if exact_out_amount >= max_amount_out { - let mut swap_result = self.swap(amount_in, price, swap_for_y, lb_pair, host_fee_bps)?; - if exact_out_amount == max_amount_out { - swap_result.is_exact_out_amount = true; - } - return Ok(swap_result); - } else { - let exact_amount_in = Bin::get_amount_in(exact_out_amount, price, swap_for_y)?; - let fee = lb_pair.compute_fee(exact_amount_in)?; - let amount_in_with_fees = exact_amount_in.safe_add(fee)?; - let mut swap_result = self.swap( - amount_in_with_fees, - price, - swap_for_y, - lb_pair, - host_fee_bps, - )?; - swap_result.is_exact_out_amount = true; - Ok(swap_result) - } - } - - /// Withdraw token X, and Y from the bin based on liquidity share. - pub fn withdraw(&mut self, liquidity_share: u128) -> Result<(u64, u64)> { - let (out_amount_x, out_amount_y) = self.calculate_out_amount(liquidity_share)?; - - self.amount_x = self.amount_x.safe_sub(out_amount_x)?; - self.amount_y = self.amount_y.safe_sub(out_amount_y)?; - - self.liquidity_supply = self.liquidity_supply.safe_sub(liquidity_share)?; - - Ok((out_amount_x, out_amount_y)) - } - - /// Calcualte out amount based on liquidity share - pub fn calculate_out_amount(&self, liquidity_share: u128) -> Result<(u64, u64)> { - // Math::round_down(liquidity_share_to_withdraw * amount_x / bin_liquidity_supply) - let out_amount_x = safe_mul_div_cast( - liquidity_share, - self.amount_x.into(), - self.liquidity_supply, - Rounding::Down, - )?; - - // Math::round_down(liquidity_share_to_withdraw * amount_y / bin_liquidity_supply) - let out_amount_y = safe_mul_div_cast( - liquidity_share, - self.amount_y.into(), - self.liquidity_supply, - Rounding::Down, - )?; - Ok((out_amount_x, out_amount_y)) - } - - pub fn is_empty(&self, is_x: bool) -> bool { - if is_x { - self.amount_x == 0 - } else { - self.amount_y == 0 - } - } - - /// Get maximum token amount able to be swapped out from the bin. - #[inline] - pub fn get_max_amount_out(&self, swap_for_y: bool) -> u64 { - if swap_for_y { - self.amount_y - } else { - self.amount_x - } - } - - pub fn get_amount_in(amount_out: u64, price: u128, swap_for_y: bool) -> Result { - if swap_for_y { - // (amount_y << SCALE_OFFSET) / price - // Convert amount_y into Q64x0, if not the result will always in 0 as price is in Q64x64 - // Division between same Q number format cancel out, result in integer - // amount_y / price = amount_in_token_x (integer [Rounding::Down]) - safe_shl_div_cast(amount_out.into(), price, SCALE_OFFSET, Rounding::Up) - } else { - // (Q64x64(price) * Q64x0(amount_x)) >> SCALE_OFFSET - // price * amount_x = amount_in_token_y (Q64x64) - // amount_in_token_y >> SCALE_OFFSET (convert it back to integer form [Rounding::Down]) - safe_mul_shr_cast(amount_out.into(), price, SCALE_OFFSET, Rounding::Up) - } - } - - /// Get out token amount from the bin based in amount in. The result is floor-ed. - /// X -> Y: inX * bin_price - /// Y -> X: inY / bin_price - pub fn get_amount_out(amount_in: u64, price: u128, swap_for_y: bool) -> Result { - if swap_for_y { - // (Q64x64(price) * Q64x0(amount_in)) >> SCALE_OFFSET - // price * amount_in = amount_out_token_y (Q64x64) - // amount_out_in_token_y >> SCALE_OFFSET (convert it back to integer form, with some loss of precision [Rounding::Down]) - safe_mul_shr_cast(price, amount_in.into(), SCALE_OFFSET, Rounding::Down) - } else { - // (amount_in << SCALE_OFFSET) / price - // Convert amount_in into Q64x0, if not the result will always in 0 as price is in Q64x64 - // Division between same Q number format cancel out, result in integer - // amount_in / price = amount_out_token_x (integer [Rounding::Down]) - safe_shl_div_cast(amount_in.into(), price, SCALE_OFFSET, Rounding::Down) - } - } - - /// Get maximum token amount needed to deposit into bin, in order to withdraw out all the opposite token from the bin. The result is ceil-ed. - /// X -> Y: reserve_y / bin_price - /// Y -> X: reserve_x * bin_price - pub fn get_max_amount_in(&self, price: u128, swap_for_y: bool) -> Result { - if swap_for_y { - // (amount_y << SCALE_OFFSET) / price - // Convert amount_y into Q64x0, if not the result will always in 0 as price is in Q64x64 - // Division between same Q number format cancel out, result in integer - // amount_y / price = amount_in_token_x (integer [Rounding::Up]) - safe_shl_div_cast(self.amount_y.into(), price, SCALE_OFFSET, Rounding::Up) - } else { - // (Q64x64(price) * Q64x0(amount_x)) >> SCALE_OFFSET - // price * amount_x = amount_in_token_y (Q64x64) - // amount_in_token_y >> SCALE_OFFSET (convert it back to integer form [Rounding::Up]) - safe_mul_shr_cast(self.amount_x.into(), price, SCALE_OFFSET, Rounding::Up) - } - } - - pub fn get_max_amounts_in(&self, price: u128) -> Result<(u64, u64)> { - let max_amount_in_x = self.get_max_amount_in(price, true)?; - let max_amount_in_y = self.get_max_amount_in(price, false)?; - - Ok((max_amount_in_x, max_amount_in_y)) - } - - /// Accumulate amount X and Y swap into the bin for analytic purpose. - pub fn accumulate_amounts_in(&mut self, amount_x_in: u64, amount_y_in: u64) { - self.amount_x_in = self.amount_x_in.wrapping_add(amount_x_in.into()); - self.amount_y_in = self.amount_y_in.wrapping_add(amount_y_in.into()); - } -} - -#[derive(Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[repr(u8)] -/// Layout version -pub enum LayoutVersion { - V0, - V1, -} - -#[account(zero_copy)] -#[derive(Debug, InitSpace)] -/// An account to contain a range of bin. For example: Bin 100 <-> 200. -/// For example: -/// BinArray index: 0 contains bin 0 <-> 599 -/// index: 2 contains bin 600 <-> 1199, ... -pub struct BinArray { - pub index: i64, // Larger size to make bytemuck "safe" (correct alignment) - /// Version of binArray - pub version: u8, - pub _padding: [u8; 7], - pub lb_pair: Pubkey, - pub bins: [Bin; MAX_BIN_PER_ARRAY], -} - -impl BinArray { - pub fn is_zero_liquidity(&self) -> bool { - for bin in self.bins.iter() { - if !bin.is_zero_liquidity() { - return false; - } - } - true - } - - pub fn initialize(&mut self, index: i64, lb_pair: Pubkey) -> Result<()> { - require!(i32::try_from(index).is_ok(), LBError::InvalidStartBinIndex); - BinArray::check_valid_index(index as i32)?; - - self.index = index; - self.lb_pair = lb_pair; - self.version = LayoutVersion::V1.into(); - self.bins = [Bin::default(); MAX_BIN_PER_ARRAY]; - - Ok(()) - } - - pub fn migrate_to_v2(&mut self) -> Result<()> { - let version: LayoutVersion = self - .version - .try_into() - .map_err(|_| LBError::TypeCastFailed)?; - if version == LayoutVersion::V0 { - self.version = LayoutVersion::V1.into(); - for bin in self.bins.iter_mut() { - bin.liquidity_supply = bin.liquidity_supply.safe_shl(SCALE_OFFSET.into())?; - } - } - Ok(()) - } - - fn get_bin_index_in_array(&self, bin_id: i32) -> Result { - self.is_bin_id_within_range(bin_id)?; - - let (lower_bin_id, upper_bin_id) = - BinArray::get_bin_array_lower_upper_bin_id(self.index as i32)?; - - let index = if bin_id.is_positive() { - // When bin id is positive, the index is ascending - bin_id.safe_sub(lower_bin_id)? - } else { - // When bin id is negative, the index is descending. Eg: bin id -1 will be located at last index of the bin array - ((MAX_BIN_PER_ARRAY as i32).safe_sub(upper_bin_id.safe_sub(bin_id)?)?).safe_sub(1)? - }; - - if index >= 0 && index < MAX_BIN_PER_ARRAY as i32 { - Ok(index as usize) - } else { - Err(LBError::InvalidBinId.into()) - } - } - - /// Get bin from bin array - pub fn get_bin_mut<'a>(&'a mut self, bin_id: i32) -> Result<&mut Bin> { - Ok(&mut self.bins[self.get_bin_index_in_array(bin_id)?]) - } - - pub fn get_bin<'a>(&'a self, bin_id: i32) -> Result<&'a Bin> { - Ok(&self.bins[self.get_bin_index_in_array(bin_id)?]) - } - - /// Check whether the bin id is within the bin array range - pub fn is_bin_id_within_range(&self, bin_id: i32) -> Result<()> { - let (lower_bin_id, upper_bin_id) = - BinArray::get_bin_array_lower_upper_bin_id(self.index as i32)?; - - require!( - bin_id >= lower_bin_id && bin_id <= upper_bin_id, - LBError::InvalidBinId - ); - - Ok(()) - } - - /// Get bin array index from bin id - pub fn bin_id_to_bin_array_index(bin_id: i32) -> Result { - let (idx, rem) = bin_id.div_rem(&(MAX_BIN_PER_ARRAY as i32)); - - if bin_id.is_negative() && rem != 0 { - Ok(idx.safe_sub(1)?) - } else { - Ok(idx) - } - } - - /// Get lower and upper bin id of the given bin array index - pub fn get_bin_array_lower_upper_bin_id(index: i32) -> Result<(i32, i32)> { - let lower_bin_id = index.safe_mul(MAX_BIN_PER_ARRAY as i32)?; - let upper_bin_id = lower_bin_id - .safe_add(MAX_BIN_PER_ARRAY as i32)? - .safe_sub(1)?; - - Ok((lower_bin_id, upper_bin_id)) - } - - /// Check that the index within MAX and MIN bin id - pub fn check_valid_index(index: i32) -> Result<()> { - let (lower_bin_id, upper_bin_id) = BinArray::get_bin_array_lower_upper_bin_id(index)?; - - require!( - lower_bin_id >= MIN_BIN_ID && upper_bin_id <= MAX_BIN_ID, - LBError::InvalidStartBinIndex - ); - - Ok(()) - } - - /// Update the bin reward(s) per liquidity share stored for the active bin. - pub fn update_all_rewards( - &mut self, - lb_pair: &mut RefMut<'_, LbPair>, - current_time: u64, - ) -> Result<()> { - for reward_idx in 0..NUM_REWARDS { - let bin = self.get_bin_mut(lb_pair.active_id)?; - let reward_info = &mut lb_pair.reward_infos[reward_idx]; - - if reward_info.initialized() { - if bin.liquidity_supply > 0 { - let reward_per_token_stored_delta = reward_info - .calculate_reward_per_token_stored_since_last_update( - current_time, - bin.liquidity_supply - .safe_shr(SCALE_OFFSET.into())? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?, - )?; - - bin.reward_per_token_stored[reward_idx] = bin.reward_per_token_stored - [reward_idx] - .safe_add(reward_per_token_stored_delta)?; - } else { - // Time period which the reward was distributed to empty bin - let time_period = - reward_info.get_seconds_elapsed_since_last_update(current_time)?; - - // Save the time window of empty bin reward, and reward it in the next time window - reward_info.cumulative_seconds_with_empty_liquidity_reward = reward_info - .cumulative_seconds_with_empty_liquidity_reward - .safe_add(time_period)?; - } - - reward_info.update_last_update_time(current_time); - } - } - Ok(()) - } -} diff --git a/programs/lb_clmm/src/state/bin_array_bitmap_extension.rs b/programs/lb_clmm/src/state/bin_array_bitmap_extension.rs deleted file mode 100644 index 7d2f0319..00000000 --- a/programs/lb_clmm/src/state/bin_array_bitmap_extension.rs +++ /dev/null @@ -1,276 +0,0 @@ -use crate::constants::{BIN_ARRAY_BITMAP_SIZE, EXTENSION_BINARRAY_BITMAP_SIZE}; -use crate::errors::LBError; -use crate::math::safe_math::SafeMath; -use crate::math::utils_math::one; -use anchor_lang::prelude::*; -use ruint::aliases::U512; -use std::ops::BitXor; - -#[account(zero_copy)] -#[derive(Debug, InitSpace)] -pub struct BinArrayBitmapExtension { - pub lb_pair: Pubkey, - /// Packed initialized bin array state for start_bin_index is positive - pub positive_bin_array_bitmap: [[u64; 8]; EXTENSION_BINARRAY_BITMAP_SIZE], - /// Packed initialized bin array state for start_bin_index is negative - pub negative_bin_array_bitmap: [[u64; 8]; EXTENSION_BINARRAY_BITMAP_SIZE], -} - -impl Default for BinArrayBitmapExtension { - #[inline] - fn default() -> BinArrayBitmapExtension { - BinArrayBitmapExtension { - lb_pair: Pubkey::default(), - positive_bin_array_bitmap: [[0; 8]; EXTENSION_BINARRAY_BITMAP_SIZE], - negative_bin_array_bitmap: [[0; 8]; EXTENSION_BINARRAY_BITMAP_SIZE], - } - } -} - -impl BinArrayBitmapExtension { - pub fn initialize(&mut self, lb_pair: Pubkey) { - self.lb_pair = lb_pair; - self.positive_bin_array_bitmap = [[0; 8]; EXTENSION_BINARRAY_BITMAP_SIZE]; - self.negative_bin_array_bitmap = [[0; 8]; EXTENSION_BINARRAY_BITMAP_SIZE]; - } - - fn get_bitmap_offset(bin_array_index: i32) -> Result { - // bin_array_index starts from 512 in positive side and -513 in negative side - let offset = if bin_array_index > 0 { - bin_array_index / BIN_ARRAY_BITMAP_SIZE - 1 - } else { - -(bin_array_index + 1) / BIN_ARRAY_BITMAP_SIZE - 1 - }; - Ok(offset as usize) - } - - /// According to the given bin array index, calculate its corresponding binarray and then find the bitmap it belongs to. - fn get_bitmap(&self, bin_array_index: i32) -> Result<(usize, [u64; 8])> { - let offset = Self::get_bitmap_offset(bin_array_index)?; - if bin_array_index < 0 { - Ok((offset, self.negative_bin_array_bitmap[offset])) - } else { - Ok((offset, self.positive_bin_array_bitmap[offset])) - } - } - - fn bin_array_offset_in_bitmap(bin_array_index: i32) -> Result { - if bin_array_index > 0 { - Ok(bin_array_index.safe_rem(BIN_ARRAY_BITMAP_SIZE)? as usize) - } else { - Ok((-(bin_array_index + 1)).safe_rem(BIN_ARRAY_BITMAP_SIZE)? as usize) - } - } - - fn to_bin_array_index( - offset: usize, - bin_array_offset: usize, - is_positive: bool, - ) -> Result { - let offset = offset as i32; - let bin_array_offset = bin_array_offset as i32; - if is_positive { - Ok((offset + 1) * BIN_ARRAY_BITMAP_SIZE + bin_array_offset) - } else { - Ok(-((offset + 1) * BIN_ARRAY_BITMAP_SIZE + bin_array_offset) - 1) - } - } - - /// Flip the value of bin in the bitmap. - pub fn flip_bin_array_bit(&mut self, bin_array_index: i32) -> Result<()> { - // TODO do we need validate bin_array_index again? - let (offset, bin_array_bitmap) = self.get_bitmap(bin_array_index).unwrap(); - let bin_array_offset_in_bitmap = Self::bin_array_offset_in_bitmap(bin_array_index).unwrap(); - let bin_array_bitmap = U512::from_limbs(bin_array_bitmap); - - let mask = one::<512, 8>() << bin_array_offset_in_bitmap; - if bin_array_index < 0 { - self.negative_bin_array_bitmap[offset as usize] = - bin_array_bitmap.bitxor(mask).into_limbs(); - } else { - self.positive_bin_array_bitmap[offset as usize] = - bin_array_bitmap.bitxor(mask).into_limbs(); - } - Ok(()) - } - - pub fn bit(&self, bin_array_index: i32) -> Result { - let (_, bin_array_bitmap) = self.get_bitmap(bin_array_index)?; - let bin_array_offset_in_bitmap = Self::bin_array_offset_in_bitmap(bin_array_index)?; - let bin_array_bitmap = U512::from_limbs(bin_array_bitmap); - return Ok(bin_array_bitmap.bit(bin_array_offset_in_bitmap as usize)); - } - pub fn bitmap_range() -> (i32, i32) { - return ( - -BIN_ARRAY_BITMAP_SIZE * (EXTENSION_BINARRAY_BITMAP_SIZE as i32 + 1), - BIN_ARRAY_BITMAP_SIZE * (EXTENSION_BINARRAY_BITMAP_SIZE as i32 + 1) - 1, - ); - } - - pub fn iter_bitmap(&self, start_index: i32, end_index: i32) -> Result> { - let offset: usize = Self::get_bitmap_offset(start_index)?; - let bin_array_offset = Self::bin_array_offset_in_bitmap(start_index)?; - if start_index < 0 { - // iter in negative_bin_array_bitmap - if start_index <= end_index { - for i in (0..=offset).rev() { - let mut bin_array_bitmap = U512::from_limbs(self.negative_bin_array_bitmap[i]); - - if i == offset { - bin_array_bitmap = bin_array_bitmap - << BIN_ARRAY_BITMAP_SIZE as usize - bin_array_offset - 1; - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - - let bin_array_offset_in_bitmap = - bin_array_offset - bin_array_bitmap.leading_zeros(); - - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - false, - )?)); - } - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - let bin_array_offset_in_bitmap = - BIN_ARRAY_BITMAP_SIZE as usize - bin_array_bitmap.leading_zeros() - 1; - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - false, - )?)); - } - } else { - for i in offset..EXTENSION_BINARRAY_BITMAP_SIZE { - let mut bin_array_bitmap = U512::from_limbs(self.negative_bin_array_bitmap[i]); - if i == offset { - bin_array_bitmap = bin_array_bitmap >> bin_array_offset; - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - - let bin_array_offset_in_bitmap = - bin_array_offset + bin_array_bitmap.trailing_zeros(); - - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - false, - )?)); - } - - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - let bin_array_offset_in_bitmap = bin_array_bitmap.trailing_zeros(); - - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - false, - )?)); - } - } - } else { - // iter in possitive_bin_array_bitmap - if start_index <= end_index { - for i in offset..EXTENSION_BINARRAY_BITMAP_SIZE { - let mut bin_array_bitmap = U512::from_limbs(self.positive_bin_array_bitmap[i]); - if i == offset { - bin_array_bitmap = bin_array_bitmap >> bin_array_offset; - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - - let bin_array_offset_in_bitmap = - bin_array_offset + bin_array_bitmap.trailing_zeros(); - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - true, - )?)); - } - - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - - let bin_array_offset_in_bitmap = bin_array_bitmap.trailing_zeros(); - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - true, - )?)); - } - } else { - for i in (0..=offset).rev() { - let mut bin_array_bitmap = U512::from_limbs(self.positive_bin_array_bitmap[i]); - - if i == offset { - bin_array_bitmap = bin_array_bitmap - << BIN_ARRAY_BITMAP_SIZE as usize - bin_array_offset - 1; - - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - let bin_array_offset_in_bitmap = - bin_array_offset - bin_array_bitmap.leading_zeros(); - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - true, - )?)); - } - - if bin_array_bitmap.eq(&U512::ZERO) { - continue; - } - let bin_array_offset_in_bitmap = - BIN_ARRAY_BITMAP_SIZE as usize - bin_array_bitmap.leading_zeros() - 1; - return Ok(Some(BinArrayBitmapExtension::to_bin_array_index( - i, - bin_array_offset_in_bitmap, - true, - )?)); - } - } - } - Ok(None) - } - - pub fn next_bin_array_index_with_liquidity( - &self, - swap_for_y: bool, - start_index: i32, - ) -> Result<(i32, bool)> { - let (min_bitmap_id, max_bit_map_id) = BinArrayBitmapExtension::bitmap_range(); - if start_index > 0 { - if swap_for_y { - match self.iter_bitmap(start_index, BIN_ARRAY_BITMAP_SIZE)? { - Some(value) => return Ok((value, true)), - None => return Ok((BIN_ARRAY_BITMAP_SIZE - 1, false)), - } - } else { - match self.iter_bitmap(start_index, max_bit_map_id)? { - Some(value) => return Ok((value, true)), - None => return Err(LBError::CannotFindNonZeroLiquidityBinArrayId.into()), - } - } - } else { - if swap_for_y { - match self.iter_bitmap(start_index, min_bitmap_id)? { - Some(value) => return Ok((value, true)), - None => return Err(LBError::CannotFindNonZeroLiquidityBinArrayId.into()), - } - } else { - match self.iter_bitmap(start_index, -BIN_ARRAY_BITMAP_SIZE - 1)? { - Some(value) => return Ok((value, true)), - None => return Ok((-BIN_ARRAY_BITMAP_SIZE, false)), - } - } - } - } -} diff --git a/programs/lb_clmm/src/state/lb_pair.rs b/programs/lb_clmm/src/state/lb_pair.rs deleted file mode 100644 index 87534e29..00000000 --- a/programs/lb_clmm/src/state/lb_pair.rs +++ /dev/null @@ -1,766 +0,0 @@ -use std::cmp::min; - -use crate::assert_eq_admin; -use crate::constants::{ - BASIS_POINT_MAX, BIN_ARRAY_BITMAP_SIZE, FEE_PRECISION, MAX_BIN_ID, MAX_FEE_RATE, - MAX_FEE_UPDATE_WINDOW, MIN_BIN_ID, -}; -use crate::instructions::admin::update_fee_parameters::FeeParameter; -use crate::math::u128x128_math::Rounding; -use crate::math::u64x64_math::SCALE_OFFSET; -use crate::math::utils_math::{one, safe_mul_div_cast, safe_mul_shr_cast, safe_shl_div_cast}; -use crate::state::bin::BinArray; -use crate::state::bin_array_bitmap_extension::BinArrayBitmapExtension; -use crate::state::parameters::{StaticParameters, VariableParameters}; -use crate::{errors::LBError, math::safe_math::SafeMath}; -use anchor_lang::prelude::*; -use num_enum::{IntoPrimitive, TryFromPrimitive}; -use ruint::aliases::{U1024, U256}; -use std::ops::BitXor; -use std::ops::Shl; -use std::ops::Shr; - -/// Type of the Pair. 0 = Permissionless, 1 = Permission, 2 = CustomizablePermissionless -#[derive(Copy, Clone, Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[repr(u8)] -pub enum PairType { - Permissionless, - Permission, - CustomizablePermissionless, -} - -#[derive( - AnchorSerialize, AnchorDeserialize, Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive, -)] -#[repr(u8)] -/// Pair status. 0 = Enabled, 1 = Disabled. Putting 0 as enabled for backward compatibility. -pub enum PairStatus { - // Fully enabled. - // Condition: - // Permissionless: PairStatus::Enabled - // Permission: PairStatus::Enabled and current_point > activation_point - Enabled, - // Similar as emergency mode. User can only withdraw (Only outflow). Except whitelisted wallet still have full privileges. - Disabled, -} - -#[zero_copy] -#[derive(InitSpace, Default, Debug)] -pub struct ProtocolFee { - pub amount_x: u64, - pub amount_y: u64, -} - -#[account(zero_copy)] -#[derive(InitSpace, Debug)] -pub struct LbPair { - pub parameters: StaticParameters, - pub v_parameters: VariableParameters, - pub bump_seed: [u8; 1], - /// Bin step signer seed - pub bin_step_seed: [u8; 2], - /// Type of the pair - pub pair_type: u8, - /// Active bin id - pub active_id: i32, - /// Bin step. Represent the price increment / decrement. - pub bin_step: u16, - /// Status of the pair. Check PairStatus enum. - pub status: u8, - /// Require base factor seed - pub require_base_factor_seed: u8, - /// Base factor seed - pub base_factor_seed: [u8; 2], - /// Activation type - pub activation_type: u8, - /// padding 0 - pub _padding_0: u8, - /// Token X mint - pub token_x_mint: Pubkey, - /// Token Y mint - pub token_y_mint: Pubkey, - /// LB token X vault - pub reserve_x: Pubkey, - /// LB token Y vault - pub reserve_y: Pubkey, - /// Uncollected protocol fee - pub protocol_fee: ProtocolFee, - /// _padding_1, previous Fee owner, BE CAREFUL FOR TOMBSTONE WHEN REUSE !! - pub _padding_1: [u8; 32], - /// Farming reward information - pub reward_infos: [RewardInfo; 2], // TODO: Bug in anchor IDL parser when using InitSpace macro. Temp hardcode it. https://github.com/coral-xyz/anchor/issues/2556 - /// Oracle pubkey - pub oracle: Pubkey, - /// Packed initialized bin array state - pub bin_array_bitmap: [u64; 16], // store default bin id from -512 to 511 (bin id from -35840 to 35840, price from 2.7e-16 to 3.6e15) - /// Last time the pool fee parameter was updated - pub last_updated_at: i64, - /// _padding_2, previous whitelisted_wallet, BE CAREFUL FOR TOMBSTONE WHEN REUSE !! - pub _padding_2: [u8; 32], - /// Address allowed to swap when the current point is greater than or equal to the pre-activation point. The pre-activation point is calculated as `activation_point - pre_activation_duration`. - pub pre_activation_swap_address: Pubkey, - /// Base keypair. Only required for permission pair - pub base_key: Pubkey, - /// Time point to enable the pair. Only applicable for permission pair. - pub activation_point: u64, - /// Duration before activation point. Used to calculate pre-activation point for pre_activation_swap_address - pub pre_activation_duration: u64, - /// _padding 3 is reclaimed free space from swap_cap_deactivate_point and swap_cap_amount before, BE CAREFUL FOR TOMBSTONE WHEN REUSE !! - pub _padding_3: [u8; 8], - /// _padding_4, previous lock_duration, BE CAREFUL FOR TOMBSTONE WHEN REUSE !! - pub _padding_4: u64, - /// Pool creator - pub creator: Pubkey, - /// Reserved space for future use - pub _reserved: [u8; 24], -} - -impl Default for LbPair { - fn default() -> Self { - Self { - active_id: 0, - parameters: StaticParameters::default(), - v_parameters: VariableParameters::default(), - bump_seed: [0u8; 1], - activation_type: 0, - bin_step: 0, - token_x_mint: Pubkey::default(), - token_y_mint: Pubkey::default(), - bin_step_seed: [0u8; 2], - protocol_fee: ProtocolFee::default(), - reserve_x: Pubkey::default(), - reserve_y: Pubkey::default(), - reward_infos: [RewardInfo::default(); 2], - oracle: Pubkey::default(), - bin_array_bitmap: [0u64; 16], - last_updated_at: 0, - pair_type: PairType::Permissionless.into(), - status: 0, - pre_activation_swap_address: Pubkey::default(), - base_key: Pubkey::default(), - activation_point: 0, - creator: Pubkey::default(), - _padding_4: 0, - require_base_factor_seed: 0, - base_factor_seed: [0u8; 2], - pre_activation_duration: 0, - _padding_0: 0u8, - _padding_1: [0u8; 32], - _padding_2: [0u8; 32], - _padding_3: [0u8; 8], - _reserved: [0u8; 24], - } - } -} - -/// Stores the state relevant for tracking liquidity mining rewards -#[zero_copy] -#[derive(InitSpace, Default, Debug, PartialEq)] -pub struct RewardInfo { - /// Reward token mint. - pub mint: Pubkey, - /// Reward vault token account. - pub vault: Pubkey, - /// Authority account that allows to fund rewards - pub funder: Pubkey, - /// TODO check whether we need to store it in pool - pub reward_duration: u64, // 8 - /// TODO check whether we need to store it in pool - pub reward_duration_end: u64, // 8 - /// TODO check whether we need to store it in pool - pub reward_rate: u128, // 8 - /// The last time reward states were updated. - pub last_update_time: u64, // 8 - /// Accumulated seconds where when farm distribute rewards, but the bin is empty. The reward will be accumulated for next reward time window. - pub cumulative_seconds_with_empty_liquidity_reward: u64, -} - -impl RewardInfo { - /// Returns true if this reward is initialized. - /// Once initialized, a reward cannot transition back to uninitialized. - pub fn initialized(&self) -> bool { - self.mint.ne(&Pubkey::default()) - } - - pub fn is_valid_funder(&self, funder: Pubkey) -> bool { - assert_eq_admin(funder) || funder.eq(&self.funder) - } - - pub fn init_reward( - &mut self, - mint: Pubkey, - vault: Pubkey, - funder: Pubkey, - reward_duration: u64, - ) { - self.mint = mint; - self.vault = vault; - self.funder = funder; - self.reward_duration = reward_duration; - } - - pub fn update_last_update_time(&mut self, current_time: u64) { - self.last_update_time = std::cmp::min(current_time, self.reward_duration_end); - } - - pub fn get_seconds_elapsed_since_last_update(&self, current_time: u64) -> Result { - let last_time_reward_applicable = std::cmp::min(current_time, self.reward_duration_end); - let time_period = last_time_reward_applicable.safe_sub(self.last_update_time.into())?; - - Ok(time_period) - } - - // To make it simple we truncate decimals of liquidity_supply for the calculation - pub fn calculate_reward_per_token_stored_since_last_update( - &self, - current_time: u64, - liquidity_supply: u64, - ) -> Result { - let time_period = self.get_seconds_elapsed_since_last_update(current_time)?; - - safe_mul_div_cast( - time_period.into(), - self.reward_rate, - liquidity_supply.into(), - Rounding::Down, - ) - } - - pub fn calculate_reward_accumulated_since_last_update( - &self, - current_time: u64, - ) -> Result { - let last_time_reward_applicable = std::cmp::min(current_time, self.reward_duration_end); - - let time_period = - U256::from(last_time_reward_applicable.safe_sub(self.last_update_time.into())?); - - Ok(time_period.safe_mul(U256::from(self.reward_rate))?) - } - - /// Farming rate after funding - pub fn update_rate_after_funding( - &mut self, - current_time: u64, - funding_amount: u64, - ) -> Result<()> { - let reward_duration_end = self.reward_duration_end; - let total_amount: u64; - - if current_time >= reward_duration_end { - total_amount = funding_amount - } else { - let remaining_seconds = reward_duration_end.safe_sub(current_time)?; - let leftover: u64 = safe_mul_shr_cast( - self.reward_rate, - remaining_seconds.into(), - SCALE_OFFSET, - Rounding::Down, - )?; - - total_amount = leftover.safe_add(funding_amount)?; - } - - self.reward_rate = safe_shl_div_cast( - total_amount.into(), - self.reward_duration.into(), - SCALE_OFFSET, - Rounding::Down, - )?; - self.last_update_time = current_time; - self.reward_duration_end = current_time.safe_add(self.reward_duration)?; - - Ok(()) - } -} - -impl LbPair { - pub fn initialize( - &mut self, - bump: u8, - active_id: i32, - bin_step: u16, - token_mint_x: Pubkey, - token_mint_y: Pubkey, - reserve_x: Pubkey, - reserve_y: Pubkey, - oracle: Pubkey, - static_parameter: StaticParameters, - pair_type: PairType, - pair_status: u8, - base_key: Pubkey, - creator: Pubkey, - activation_type: u8, - activation_point: u64, - pre_activation_swap_address: Pubkey, - pre_activation_duration: u64, - ) -> Result<()> { - self.parameters = static_parameter; - self.active_id = active_id; - self.bin_step = bin_step; - self.token_x_mint = token_mint_x; - self.token_y_mint = token_mint_y; - self.reserve_x = reserve_x; - self.reserve_y = reserve_y; - self.bump_seed = [bump]; - self.bin_step_seed = bin_step.to_le_bytes(); - self.oracle = oracle; - self.pair_type = pair_type.into(); - self.base_key = base_key; - self.status = pair_status; - self.creator = creator; - self.pre_activation_swap_address = pre_activation_swap_address; - self.pre_activation_duration = pre_activation_duration; - - self.activation_point = activation_point; - - // Old permissionless pools before added base factor as signer seed by default will be false. All the new pools after the patch will be having bse factor as signer seed. - self.require_base_factor_seed = match pair_type { - PairType::Permissionless => true.into(), - // Permissioned pool doesn't have base factor as signer seed - _ => false.into(), - }; - - self.base_factor_seed = self.parameters.base_factor.to_le_bytes(); - self.activation_type = activation_type; - - Ok(()) - } - - pub fn status(&self) -> Result { - let pair_status: PairStatus = self - .status - .try_into() - .map_err(|_| LBError::TypeCastFailed)?; - - Ok(pair_status) - } - - pub fn pair_type(&self) -> Result { - let pair_type: PairType = self - .pair_type - .try_into() - .map_err(|_| LBError::TypeCastFailed)?; - - Ok(pair_type) - } - - pub fn is_permission_pair(&self) -> Result { - let pair_type = self.pair_type()?; - Ok(pair_type.eq(&PairType::Permission)) - } - - pub fn update_fee_parameters(&mut self, parameter: &FeeParameter) -> Result<()> { - let current_timestamp = Clock::get()?.unix_timestamp; - if self.last_updated_at > 0 { - let second_elapsed = current_timestamp.safe_sub(self.last_updated_at)?; - - require!( - second_elapsed > MAX_FEE_UPDATE_WINDOW, - LBError::ExcessiveFeeUpdate - ); - } - - self.parameters.update(parameter)?; - self.last_updated_at = current_timestamp; - - Ok(()) - } - - fn require_base_factor_seed(&self) -> bool { - self.require_base_factor_seed != 0 - } - - pub fn seeds(&self) -> Result> { - let min_key = min(self.token_x_mint, self.token_y_mint); - let (min_key_ref, max_key_ref) = if min_key == self.token_x_mint { - (self.token_x_mint.as_ref(), self.token_y_mint.as_ref()) - } else { - (self.token_y_mint.as_ref(), self.token_x_mint.as_ref()) - }; - - let pair_type = PairType::try_from(self.pair_type).map_err(|_| LBError::InvalidPoolType)?; - match pair_type { - PairType::CustomizablePermissionless => Ok(vec![ - self.base_key.as_ref(), - min_key_ref, - max_key_ref, - &self.bump_seed, - ]), - PairType::Permission => Ok(vec![ - self.base_key.as_ref(), - min_key_ref, - max_key_ref, - &self.bin_step_seed, - &self.bump_seed, - ]), - PairType::Permissionless => { - if self.require_base_factor_seed() { - // Second version permissionless pool - Ok(vec![ - min_key_ref, - max_key_ref, - &self.bin_step_seed, - &self.base_factor_seed, - &self.bump_seed, - ]) - } else { - // First version permissionless pool - Ok(vec![ - min_key_ref, - max_key_ref, - &self.bin_step_seed, - &self.bump_seed, - ]) - } - } - } - } - - #[inline(always)] - pub fn swap_for_y(&self, out_token_mint: Pubkey) -> bool { - out_token_mint.eq(&self.token_y_mint) - } - - /// Plus / Minus 1 to the active bin based on the swap direction - pub fn advance_active_bin(&mut self, swap_for_y: bool) -> Result<()> { - let next_active_bin_id = if swap_for_y { - self.active_id.safe_sub(1)? - } else { - self.active_id.safe_add(1)? - }; - - require!( - next_active_bin_id >= MIN_BIN_ID && next_active_bin_id <= MAX_BIN_ID, - LBError::PairInsufficientLiquidity - ); - - self.active_id = next_active_bin_id; - - Ok(()) - } - - /// Base fee rate = Base fee factor * bin step. This is in 1e9 unit. - pub fn get_base_fee(&self) -> Result { - Ok(u128::from(self.parameters.base_factor) - .safe_mul(self.bin_step.into())? - // Make it to be the same as FEE_PRECISION defined for ceil_div later on. - .safe_mul(10u128)?) - } - - /// Variable fee rate = variable fee factor * (volatility_accumulator * bin_step)^2 - pub fn compute_variable_fee(&self, volatility_accumulator: u32) -> Result { - if self.parameters.variable_fee_control > 0 { - let volatility_accumulator: u128 = volatility_accumulator.into(); - let bin_step: u128 = self.bin_step.into(); - let variable_fee_control: u128 = self.parameters.variable_fee_control.into(); - - let square_vfa_bin = volatility_accumulator - .safe_mul(bin_step)? - .checked_pow(2) - .ok_or(LBError::MathOverflow)?; - - // Variable fee control, volatility accumulator, bin step are in basis point unit (10_000) - // This is 1e20. Which > 1e9. Scale down it to 1e9 unit and ceiling the remaining. - let v_fee = variable_fee_control.safe_mul(square_vfa_bin)?; - - let scaled_v_fee = v_fee.safe_add(99_999_999_999)?.safe_div(100_000_000_000)?; - return Ok(scaled_v_fee); - } - - Ok(0) - } - - /// Variable fee rate = variable_fee_control * (variable_fee_accumulator * bin_step) ^ 2 - pub fn get_variable_fee(&self) -> Result { - self.compute_variable_fee(self.v_parameters.volatility_accumulator) - } - - /// Total fee rate = base_fee_rate + variable_fee_rate - pub fn get_total_fee(&self) -> Result { - let total_fee_rate = self.get_base_fee()?.safe_add(self.get_variable_fee()?)?; - let total_fee_rate_cap = std::cmp::min(total_fee_rate, MAX_FEE_RATE.into()); - Ok(total_fee_rate_cap) - } - - #[cfg(test)] - /// Maximum fee rate - fn get_max_total_fee(&self) -> Result { - let max_total_fee_rate = self - .get_base_fee()? - .safe_add(self.compute_variable_fee(self.parameters.max_volatility_accumulator)?)?; - - let total_fee_rate_cap = std::cmp::min(max_total_fee_rate, MAX_FEE_RATE.into()); - Ok(total_fee_rate_cap) - } - - /// Compute composition fee. Composition_fee = fee_amount * (1 + total fee rate) - pub fn compute_composition_fee(&self, swap_amount: u64) -> Result { - let total_fee_rate = self.get_total_fee()?; - // total_fee_rate 1e9 unit - let fee_amount = u128::from(swap_amount).safe_mul(total_fee_rate)?; - let composition_fee = - fee_amount.safe_mul(u128::from(FEE_PRECISION).safe_add(total_fee_rate)?)?; - // 1e9 unit * 1e9 unit = 1e18, scale back - let scaled_down_fee = composition_fee.safe_div(u128::from(FEE_PRECISION).pow(2))?; - - Ok(scaled_down_fee - .try_into() - .map_err(|_| LBError::TypeCastFailed)?) - } - - /// Compute fee from amount, where fee is part of the amount. The result is ceil-ed. - pub fn compute_fee_from_amount(&self, amount_with_fees: u64) -> Result { - // total_fee_rate 1e9 unit - let total_fee_rate = self.get_total_fee()?; - // Ceil division - let fee_amount = u128::from(amount_with_fees) - .safe_mul(total_fee_rate)? - .safe_add((FEE_PRECISION - 1).into())?; - let scaled_down_fee = fee_amount.safe_div(FEE_PRECISION.into())?; - - Ok(scaled_down_fee - .try_into() - .map_err(|_| LBError::TypeCastFailed)?) - } - - /// Compute fee for the amount. The fee is not part of the amount. This function is used when you do not know the amount_with_fees - /// Solve for fee_amount, equation: (amount + fee_amount) * total_fee_rate / 1e9 = fee_amount - /// fee_amount = (amount * total_fee_rate) / (1e9 - total_fee_rate) - /// The result is ceil-ed. - pub fn compute_fee(&self, amount: u64) -> Result { - let total_fee_rate = self.get_total_fee()?; - let denominator = u128::from(FEE_PRECISION).safe_sub(total_fee_rate)?; - - // Ceil division - let fee = u128::from(amount) - .safe_mul(total_fee_rate)? - .safe_add(denominator)? - .safe_sub(1)?; - - let scaled_down_fee = fee.safe_div(denominator)?; - - Ok(scaled_down_fee - .try_into() - .map_err(|_| LBError::TypeCastFailed)?) - } - - /// Compute protocol fee - pub fn compute_protocol_fee(&self, fee_amount: u64) -> Result { - let protocol_fee = u128::from(fee_amount) - .safe_mul(self.parameters.protocol_share.into())? - .safe_div(BASIS_POINT_MAX as u128)?; - - Ok(protocol_fee - .try_into() - .map_err(|_| LBError::TypeCastFailed)?) - } - - /// Accumulate protocol fee - pub fn accumulate_protocol_fees(&mut self, fee_amount_x: u64, fee_amount_y: u64) -> Result<()> { - self.protocol_fee.amount_x = self.protocol_fee.amount_x.safe_add(fee_amount_x)?; - self.protocol_fee.amount_y = self.protocol_fee.amount_y.safe_add(fee_amount_y)?; - - Ok(()) - } - - /// Update volatility reference and accumulator - pub fn update_volatility_parameters(&mut self, current_timestamp: i64) -> Result<()> { - self.v_parameters.update_volatility_parameter( - self.active_id, - current_timestamp, - &self.parameters, - ) - } - - pub fn update_references(&mut self, current_timestamp: i64) -> Result<()> { - self.v_parameters - .update_references(self.active_id, current_timestamp, &self.parameters) - } - - pub fn update_volatility_accumulator(&mut self) -> Result<()> { - self.v_parameters - .update_volatility_accumulator(self.active_id, &self.parameters) - } - - pub fn withdraw_protocol_fee(&mut self, amount_x: u64, amount_y: u64) -> Result<()> { - self.protocol_fee.amount_x = self.protocol_fee.amount_x.safe_sub(amount_x)?; - self.protocol_fee.amount_y = self.protocol_fee.amount_y.safe_sub(amount_y)?; - - Ok(()) - } - - pub fn oracle_initialized(&self) -> bool { - self.oracle != Pubkey::default() - } - - pub fn flip_bin_array_bit( - &mut self, - bin_array_bitmap_extension: &Option>, - bin_array_index: i32, - ) -> Result<()> { - if self.is_overflow_default_bin_array_bitmap(bin_array_index) { - match bin_array_bitmap_extension { - Some(bitmap_ext) => { - bitmap_ext.load_mut()?.flip_bin_array_bit(bin_array_index)?; - } - None => return Err(LBError::BitmapExtensionAccountIsNotProvided.into()), - } - } else { - self.flip_bin_array_bit_internal(bin_array_index)?; - } - - Ok(()) - } - - pub fn is_overflow_default_bin_array_bitmap(&self, bin_array_index: i32) -> bool { - let (min_bitmap_id, max_bitmap_id) = LbPair::bitmap_range(); - bin_array_index > max_bitmap_id || bin_array_index < min_bitmap_id - } - - pub fn bitmap_range() -> (i32, i32) { - (-BIN_ARRAY_BITMAP_SIZE, BIN_ARRAY_BITMAP_SIZE - 1) - } - - fn get_bin_array_offset(bin_array_index: i32) -> usize { - (bin_array_index + BIN_ARRAY_BITMAP_SIZE) as usize - } - - fn flip_bin_array_bit_internal(&mut self, bin_array_index: i32) -> Result<()> { - let bin_array_offset = Self::get_bin_array_offset(bin_array_index); - let bin_array_bitmap = U1024::from_limbs(self.bin_array_bitmap); - let mask = one::<1024, 16>() << bin_array_offset; - self.bin_array_bitmap = bin_array_bitmap.bitxor(mask).into_limbs(); - Ok(()) - } - - // return bin_array_index that it's liquidity is non-zero - // if cannot find one, return false - pub fn next_bin_array_index_with_liquidity_internal( - &self, - swap_for_y: bool, - start_array_index: i32, - ) -> Result<(i32, bool)> { - let bin_array_bitmap = U1024::from_limbs(self.bin_array_bitmap); - let array_offset: usize = Self::get_bin_array_offset(start_array_index); - let (min_bitmap_id, max_bitmap_id) = LbPair::bitmap_range(); - if swap_for_y { - let binmap_range: usize = max_bitmap_id - .safe_sub(min_bitmap_id)? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?; - let offset_bit_map = bin_array_bitmap.shl(binmap_range.safe_sub(array_offset)?); - - if offset_bit_map.eq(&U1024::ZERO) { - return Ok((min_bitmap_id.safe_sub(1)?, false)); - } else { - let next_bit = offset_bit_map.leading_zeros(); - return Ok((start_array_index.safe_sub(next_bit as i32)?, true)); - } - } else { - let offset_bit_map = bin_array_bitmap.shr(array_offset); - if offset_bit_map.eq(&U1024::ZERO) { - return Ok((max_bitmap_id.safe_add(1)?, false)); - } else { - let next_bit = offset_bit_map.trailing_zeros(); - return Ok(( - start_array_index.checked_add(next_bit as i32).unwrap(), - true, - )); - }; - } - } - - // shift active until non-zero liquidity bin_array_index - fn shift_active_bin(&mut self, swap_for_y: bool, bin_array_index: i32) -> Result<()> { - // update active id - let (lower_bin_id, upper_bin_id) = - BinArray::get_bin_array_lower_upper_bin_id(bin_array_index)?; - - if swap_for_y { - self.active_id = upper_bin_id; - } else { - self.active_id = lower_bin_id; - } - Ok(()) - } - - fn next_bin_array_index_with_liquidity_from_extension( - swap_for_y: bool, - bin_array_index: i32, - bin_array_bitmap_extension: &Option>, - ) -> Result<(i32, bool)> { - match bin_array_bitmap_extension { - Some(bitmap_ext) => { - return Ok(bitmap_ext - .load()? - .next_bin_array_index_with_liquidity(swap_for_y, bin_array_index)?); - } - None => return Err(LBError::BitmapExtensionAccountIsNotProvided.into()), - } - } - - pub fn next_bin_array_index_from_internal_to_extension( - &mut self, - swap_for_y: bool, - current_array_index: i32, - start_array_index: i32, - bin_array_bitmap_extension: &Option>, - ) -> Result<()> { - let (bin_array_index, is_non_zero_liquidity_flag) = - self.next_bin_array_index_with_liquidity_internal(swap_for_y, start_array_index)?; - if is_non_zero_liquidity_flag { - if current_array_index != bin_array_index { - self.shift_active_bin(swap_for_y, bin_array_index)?; - } - } else { - let (bin_array_index, _) = LbPair::next_bin_array_index_with_liquidity_from_extension( - swap_for_y, - bin_array_index, - bin_array_bitmap_extension, - )?; - // no need to check for flag here, because if we cannot find the non-liquidity bin array id in the extension go from lb_pair state, then extension will return error - if current_array_index != bin_array_index { - self.shift_active_bin(swap_for_y, bin_array_index)?; - } - } - Ok(()) - } - - pub fn next_bin_array_index_with_liquidity( - &mut self, - swap_for_y: bool, - bin_array_bitmap_extension: &Option>, - ) -> Result<()> { - let start_array_index = BinArray::bin_id_to_bin_array_index(self.active_id)?; - - if self.is_overflow_default_bin_array_bitmap(start_array_index) { - let (bin_array_index, is_non_zero_liquidity_flag) = - LbPair::next_bin_array_index_with_liquidity_from_extension( - swap_for_y, - start_array_index, - bin_array_bitmap_extension, - )?; - if is_non_zero_liquidity_flag { - if start_array_index != bin_array_index { - self.shift_active_bin(swap_for_y, bin_array_index)?; - } - } else { - self.next_bin_array_index_from_internal_to_extension( - swap_for_y, - start_array_index, - bin_array_index, - bin_array_bitmap_extension, - )?; - } - } else { - self.next_bin_array_index_from_internal_to_extension( - swap_for_y, - start_array_index, - start_array_index, - bin_array_bitmap_extension, - )?; - } - Ok(()) - } -} diff --git a/programs/lb_clmm/src/state/mod.rs b/programs/lb_clmm/src/state/mod.rs deleted file mode 100644 index f1dfd2c9..00000000 --- a/programs/lb_clmm/src/state/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod bin; -pub mod bin_array_bitmap_extension; -pub mod lb_pair; -pub mod oracle; -pub mod parameters; -pub mod position; -pub mod preset_parameters; diff --git a/programs/lb_clmm/src/state/oracle.rs b/programs/lb_clmm/src/state/oracle.rs deleted file mode 100644 index dfe5b49a..00000000 --- a/programs/lb_clmm/src/state/oracle.rs +++ /dev/null @@ -1,256 +0,0 @@ -#[cfg(not(feature = "localnet"))] -use crate::constants::SAMPLE_LIFETIME; -use crate::errors::LBError; -use crate::{constants::DEFAULT_OBSERVATION_LENGTH, math::safe_math::SafeMath}; -use anchor_lang::prelude::*; -use std::cell::RefMut; - -#[cfg(not(feature = "localnet"))] -fn get_sample_lifetime() -> i64 { - SAMPLE_LIFETIME as i64 -} - -#[cfg(feature = "localnet")] -fn get_sample_lifetime() -> i64 { - 5 -} - -/// Extension trait for loading dynamic-sized data in a zero-copy oracle account. -pub trait OracleContentLoader<'info> { - fn load_content_mut<'a>(&'a self) -> Result>; - fn load_content_init<'a>(&'a self) -> Result>; - fn load_content<'a>(&'a self) -> Result>; -} - -#[zero_copy] -#[derive(Default, Debug, PartialEq, Eq)] -pub struct Observation { - /// Cumulative active bin ID - pub cumulative_active_bin_id: i128, - /// Observation sample created timestamp - pub created_at: i64, - /// Observation sample last updated timestamp - pub last_updated_at: i64, -} - -impl Observation { - pub fn initialized(&self) -> bool { - self.created_at > 0 && self.last_updated_at > 0 - } - - pub fn reset(&mut self) { - self.cumulative_active_bin_id = 0; - self.created_at = 0; - self.last_updated_at = 0; - } - - /// Calculate cumulative_active_bin_id += active_id * delta_seconds - pub fn accumulate_active_bin_id(&self, active_id: i32, current_timestamp: i64) -> Result { - if self.initialized() { - let delta = current_timestamp.safe_sub(self.last_updated_at)?; - let cumulative_active_bin_id = Into::::into(active_id).safe_mul(delta.into())?; - - Ok(self - .cumulative_active_bin_id - .safe_add(cumulative_active_bin_id)?) - } else { - Ok(active_id.into()) - } - } - - /// Calculate the timestamp for the next observation sampling - pub fn compute_next_sampling_timestamp(&self) -> Option { - if self.initialized() { - self.created_at.checked_add(get_sample_lifetime()) - } else { - None - } - } - - /// Update the observation sample - pub fn update(&mut self, cumulative_active_bin_id: i128, current_timestamp: i64) { - self.cumulative_active_bin_id = cumulative_active_bin_id; - self.last_updated_at = current_timestamp; - - if !self.initialized() { - self.created_at = current_timestamp; - } - } -} - -#[account(zero_copy)] -#[derive(Default, Debug)] -pub struct Oracle { - /// Index of latest observation - pub idx: u64, - /// Size of active sample. Active sample is initialized observation. - pub active_size: u64, - /// Number of observations - pub length: u64, -} - -impl Oracle { - pub fn init(&mut self) { - self.length = DEFAULT_OBSERVATION_LENGTH; - } - - pub fn increase_length(&mut self, length_to_increase: u64) -> Result<()> { - self.length = self.length.safe_add(length_to_increase)?; - Ok(()) - } - - pub fn space(observation_length: u64) -> usize { - 8 + std::mem::size_of::() - + observation_length as usize * std::mem::size_of::() - } - - pub fn new_space( - length_to_add: u64, - account_loader: &AccountLoader<'_, Oracle>, - ) -> Result { - let oracle = account_loader.load()?; - Ok(Oracle::space(oracle.length + length_to_add)) - } - - pub fn metadata_len() -> usize { - 8 + std::mem::size_of::() - } -} - -/// An oracle struct loaded with dynamic sized data type -#[derive(Debug)] -pub struct DynamicOracle<'a> { - pub metadata: RefMut<'a, Oracle>, - pub observations: RefMut<'a, [Observation]>, -} - -impl<'a> DynamicOracle<'a> { - pub fn new( - metadata: RefMut<'a, Oracle>, - observations: RefMut<'a, [Observation]>, - ) -> DynamicOracle<'a> { - Self { - observations, - metadata, - } - } - - /// Get wrapping next index - fn next_idx(idx: usize, bound: usize) -> Option { - idx.checked_add(1)?.checked_rem(bound) - } - - /// Return indication whether the oracle have any observation samples - fn is_initial_sampling(metadata: &Oracle) -> bool { - metadata.active_size == 0 - } - - /// Return the latest observation sample - pub fn get_latest_sample_mut<'dyo>(&'dyo mut self) -> Option<&'dyo mut Observation> { - if Self::is_initial_sampling(&self.metadata) { - return None; - } - Some(&mut self.observations[self.metadata.idx as usize]) - } - - pub fn get_latest_sample<'dyo>(&'dyo self) -> Option<&'dyo Observation> { - if Self::is_initial_sampling(&self.metadata) { - return None; - } - Some(&self.observations[self.metadata.idx as usize]) - } - - /// Return the earliest observation sample - pub fn get_earliest_sample<'dyo>(&'dyo self) -> Option<&'dyo Observation> { - if Self::is_initial_sampling(&self.metadata) { - return None; - } - let next_idx = Self::next_idx( - self.metadata.idx as usize, - self.metadata.active_size as usize, - )?; - Some(&self.observations[next_idx]) - } - - /// Get next observation and reset to empty value - fn next_reset<'dyo>(&'dyo mut self) -> Option<&'dyo mut Observation> { - let next_idx = Self::next_idx(self.metadata.idx as usize, self.metadata.length as usize)?; - self.metadata.idx = next_idx as u64; - - let next_sample = &mut self.observations[next_idx]; - - if !next_sample.initialized() { - self.metadata.active_size = std::cmp::min( - self.metadata.active_size.checked_add(1)?, - self.metadata.length, - ); - } - - next_sample.reset(); - Some(next_sample) - } - - /// Update existing observation sample / create a new observation sample based on sample lifetime expiration - pub fn update(&mut self, active_id: i32, current_timestamp: i64) -> Result<()> { - if Self::is_initial_sampling(&self.metadata) { - self.metadata.active_size += 1; - } - - let mut latest_sample = self - .get_latest_sample_mut() - .ok_or_else(|| LBError::InsufficientSample)?; // Unreachable ! - - let cumulative_active_bin_id = - latest_sample.accumulate_active_bin_id(active_id, current_timestamp)?; - - if let Some(next_sampling_timestamp) = latest_sample.compute_next_sampling_timestamp() { - if current_timestamp >= next_sampling_timestamp { - latest_sample = self.next_reset().ok_or_else(|| LBError::MathOverflow)?; - } - } - latest_sample.update(cumulative_active_bin_id, current_timestamp); - - Ok(()) - } -} - -fn oracle_account_split<'a, 'info>( - oracle_al: &'a AccountLoader<'info, Oracle>, -) -> Result> { - let data = oracle_al.as_ref().try_borrow_mut_data()?; - - let (oracle_metadata, observations) = RefMut::map_split(data, |data| { - let (oracle_bytes, observations_bytes) = data.split_at_mut(Oracle::metadata_len()); - let oracle = bytemuck::from_bytes_mut::(&mut oracle_bytes[8..]); - let observations = bytemuck::cast_slice_mut::(observations_bytes); - (oracle, observations) - }); - - Ok(DynamicOracle::new(oracle_metadata, observations)) -} - -impl<'info> OracleContentLoader<'info> for AccountLoader<'info, Oracle> { - fn load_content_mut<'a>(&'a self) -> Result> { - { - // Re-use anchor internal validation such as discriminator check - self.load_mut()?; - } - oracle_account_split(&self) - } - - fn load_content_init<'a>(&'a self) -> Result> { - { - // Re-use anchor internal validation and initialization such as insert of discriminator for new zero copy account - self.load_init()?; - } - oracle_account_split(&self) - } - - fn load_content<'a>(&'a self) -> Result> { - { - // Re-use anchor internal validation and initialization such as insert of discriminator for new zero copy account - self.load()?; - } - oracle_account_split(&self) - } -} diff --git a/programs/lb_clmm/src/state/parameters.rs b/programs/lb_clmm/src/state/parameters.rs deleted file mode 100644 index e1dd2574..00000000 --- a/programs/lb_clmm/src/state/parameters.rs +++ /dev/null @@ -1,193 +0,0 @@ -use crate::constants::{BASIS_POINT_MAX, MAX_BASE_FACTOR_STEP, MAX_PROTOCOL_SHARE}; -use crate::instructions::admin::update_fee_parameters::FeeParameter; -use crate::{errors::LBError, math::safe_math::SafeMath}; -use anchor_lang::prelude::*; - -#[zero_copy] -#[derive(InitSpace, Debug)] -/// Parameter that set by the protocol -pub struct StaticParameters { - /// Used for base fee calculation. base_fee_rate = base_factor * bin_step - pub base_factor: u16, - /// Filter period determine high frequency trading time window. - pub filter_period: u16, - /// Decay period determine when the volatile fee start decay / decrease. - pub decay_period: u16, - /// Reduction factor controls the volatile fee rate decrement rate. - pub reduction_factor: u16, - /// Used to scale the variable fee component depending on the dynamic of the market - pub variable_fee_control: u32, - /// Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate. - pub max_volatility_accumulator: u32, - /// Min bin id supported by the pool based on the configured bin step. - pub min_bin_id: i32, - /// Max bin id supported by the pool based on the configured bin step. - pub max_bin_id: i32, - /// Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee - pub protocol_share: u16, - /// Padding for bytemuck safe alignment - pub _padding: [u8; 6], -} - -impl StaticParameters { - pub fn update(&mut self, parameter: &FeeParameter) -> Result<()> { - let base_factor_delta = if parameter.base_factor > self.base_factor { - parameter.base_factor.safe_sub(self.base_factor)? - } else { - self.base_factor.safe_sub(parameter.base_factor)? - }; - - // Fee increment / decrement must <= 100% of the current fee rate - require!( - base_factor_delta <= self.base_factor, - LBError::ExcessiveFeeUpdate - ); - - // Fee increment / decrement must <= 100 bps, 1% - require!( - base_factor_delta <= MAX_BASE_FACTOR_STEP, - LBError::ExcessiveFeeUpdate - ); - - // During quote it already capped. Extra safety check. - require!( - parameter.protocol_share <= MAX_PROTOCOL_SHARE, - LBError::ExcessiveFeeUpdate - ); - - self.protocol_share = parameter.protocol_share; - self.base_factor = parameter.base_factor; - - Ok(()) - } - - #[inline(always)] - #[cfg(not(feature = "localnet"))] - pub fn get_filter_period(&self) -> u16 { - self.filter_period - } - - #[inline(always)] - #[cfg(feature = "localnet")] - pub fn get_filter_period(&self) -> u16 { - 5 - } - - #[inline(always)] - #[cfg(not(feature = "localnet"))] - pub fn get_decay_period(&self) -> u16 { - self.decay_period - } - - #[inline(always)] - #[cfg(feature = "localnet")] - pub fn get_decay_period(&self) -> u16 { - 10 - } -} - -impl Default for StaticParameters { - /// These value are references from Trader Joe - fn default() -> Self { - Self { - base_factor: 10_000, - filter_period: 30, - decay_period: 600, - reduction_factor: 500, - variable_fee_control: 40_000, - protocol_share: 1_000, - max_volatility_accumulator: 350_000, // Capped at 35 bin crossed. 350_000 / 10_000 (bps unit) = 35 delta bin - _padding: [0u8; 6], - max_bin_id: i32::MAX, - min_bin_id: i32::MIN, - } - } -} - -#[zero_copy] -#[derive(InitSpace, Default, Debug)] -/// Parameters that changes based on dynamic of the market -pub struct VariableParameters { - /// Volatility accumulator measure the number of bin crossed since reference bin ID. Normally (without filter period taken into consideration), reference bin ID is the active bin of last swap. - /// It affects the variable fee rate - pub volatility_accumulator: u32, - /// Volatility reference is decayed volatility accumulator. It is always <= volatility_accumulator - pub volatility_reference: u32, - /// Active bin id of last swap. - pub index_reference: i32, - /// Padding for bytemuck safe alignment - pub _padding: [u8; 4], - /// Last timestamp the variable parameters was updated - pub last_update_timestamp: i64, - /// Padding for bytemuck safe alignment - pub _padding_1: [u8; 8], -} - -impl VariableParameters { - /// volatility_accumulator = min(volatility_reference + num_of_bin_crossed, max_volatility_accumulator) - pub fn update_volatility_accumulator( - &mut self, - active_id: i32, - static_params: &StaticParameters, - ) -> Result<()> { - // Upscale to prevent overflow caused by swapping from left most bin to right most bin. - let delta_id = i64::from(self.index_reference) - .safe_sub(active_id.into())? - .unsigned_abs(); - - let volatility_accumulator = u64::from(self.volatility_reference) - .safe_add(delta_id.safe_mul(BASIS_POINT_MAX as u64)?)?; - - self.volatility_accumulator = std::cmp::min( - volatility_accumulator, - static_params.max_volatility_accumulator.into(), - ) - .try_into() - .map_err(|_| LBError::TypeCastFailed)?; - - Ok(()) - } - - /// Update id, and volatility reference - pub fn update_references( - &mut self, - active_id: i32, - current_timestamp: i64, - static_params: &StaticParameters, - ) -> Result<()> { - let elapsed = current_timestamp.safe_sub(self.last_update_timestamp)?; - - // Not high frequency trade - if elapsed >= static_params.get_filter_period() as i64 { - // Update active id of last transaction - self.index_reference = active_id; - // filter period < t < decay_period. Decay time window. - if elapsed < static_params.get_decay_period() as i64 { - let volatility_reference = self - .volatility_accumulator - .safe_mul(static_params.reduction_factor as u32)? - .safe_div(BASIS_POINT_MAX as u32)?; - - self.volatility_reference = volatility_reference; - } - // Out of decay time window - else { - self.volatility_reference = 0; - } - } - - // self.last_update_timestamp = current_timestamp; - - Ok(()) - } - - pub fn update_volatility_parameter( - &mut self, - active_id: i32, - current_timestamp: i64, - static_params: &StaticParameters, - ) -> Result<()> { - self.update_references(active_id, current_timestamp, static_params)?; - self.update_volatility_accumulator(active_id, static_params) - } -} diff --git a/programs/lb_clmm/src/state/position.rs b/programs/lb_clmm/src/state/position.rs deleted file mode 100644 index 12090fc5..00000000 --- a/programs/lb_clmm/src/state/position.rs +++ /dev/null @@ -1,366 +0,0 @@ -use super::bin::Bin; -use crate::{ - constants::{MAX_BIN_PER_POSITION, NUM_REWARDS}, - errors::LBError, - manager::bin_array_manager::BinArrayManager, - math::{ - safe_math::SafeMath, u128x128_math::Rounding, u64x64_math::SCALE_OFFSET, - utils_math::safe_mul_shr_cast, - }, -}; -use anchor_lang::prelude::*; -use num_traits::Zero; -use std::cell::Ref; - -#[account(zero_copy)] -#[derive(InitSpace, Debug)] -pub struct Position { - /// The LB pair of this position - pub lb_pair: Pubkey, - /// Owner of the position. Client rely on this to to fetch their positions. - pub owner: Pubkey, - /// Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept. - pub liquidity_shares: [u64; MAX_BIN_PER_POSITION], - /// Farming reward information - pub reward_infos: [UserRewardInfo; MAX_BIN_PER_POSITION], - /// Swap fee to claim information - pub fee_infos: [FeeInfo; MAX_BIN_PER_POSITION], - /// Lower bin ID - pub lower_bin_id: i32, - /// Upper bin ID - pub upper_bin_id: i32, - /// Last updated timestamp - pub last_updated_at: i64, - /// Total claimed token fee X - pub total_claimed_fee_x_amount: u64, - /// Total claimed token fee Y - pub total_claimed_fee_y_amount: u64, - /// Total claimed rewards - pub total_claimed_rewards: [u64; 2], - /// Reserved space for future use - pub _reserved: [u8; 160], -} - -#[account(zero_copy)] -#[derive(InitSpace, Debug)] -pub struct PositionV2 { - /// The LB pair of this position - pub lb_pair: Pubkey, - /// Owner of the position. Client rely on this to to fetch their positions. - pub owner: Pubkey, - /// Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept. - pub liquidity_shares: [u128; MAX_BIN_PER_POSITION], - /// Farming reward information - pub reward_infos: [UserRewardInfo; MAX_BIN_PER_POSITION], - /// Swap fee to claim information - pub fee_infos: [FeeInfo; MAX_BIN_PER_POSITION], - /// Lower bin ID - pub lower_bin_id: i32, - /// Upper bin ID - pub upper_bin_id: i32, - /// Last updated timestamp - pub last_updated_at: i64, - /// Total claimed token fee X - pub total_claimed_fee_x_amount: u64, - /// Total claimed token fee Y - pub total_claimed_fee_y_amount: u64, - /// Total claimed rewards - pub total_claimed_rewards: [u64; 2], - /// Operator of position - pub operator: Pubkey, - /// Time point which the locked liquidity can be withdraw - pub lock_release_point: u64, - /// _padding_0, previous subjected_to_bootstrap_liquidity_locking, BE CAREFUL FOR TOMBSTONE WHEN REUSE !! - pub _padding_0: u8, - /// Address is able to claim fee in this position, only valid for bootstrap_liquidity_position - pub fee_owner: Pubkey, - /// Reserved space for future use - pub _reserved: [u8; 87], -} - -impl Default for PositionV2 { - fn default() -> Self { - Self { - lb_pair: Pubkey::default(), - owner: Pubkey::default(), - lower_bin_id: 0, - upper_bin_id: 0, - last_updated_at: 0, - liquidity_shares: [0u128; MAX_BIN_PER_POSITION], - reward_infos: [UserRewardInfo::default(); MAX_BIN_PER_POSITION], - fee_infos: [FeeInfo::default(); MAX_BIN_PER_POSITION], - total_claimed_fee_x_amount: 0, - total_claimed_fee_y_amount: 0, - total_claimed_rewards: [0u64; 2], - operator: Pubkey::default(), - lock_release_point: 0, - fee_owner: Pubkey::default(), - _padding_0: 0, - _reserved: [0u8; 87], - } - } -} - -#[zero_copy] -#[derive(Default, Debug, AnchorDeserialize, AnchorSerialize, InitSpace, PartialEq)] -pub struct FeeInfo { - pub fee_x_per_token_complete: u128, - pub fee_y_per_token_complete: u128, - pub fee_x_pending: u64, - pub fee_y_pending: u64, -} - -#[zero_copy] -#[derive(Default, Debug, AnchorDeserialize, AnchorSerialize, InitSpace, PartialEq)] -pub struct UserRewardInfo { - pub reward_per_token_completes: [u128; NUM_REWARDS], - pub reward_pendings: [u64; NUM_REWARDS], -} - -impl PositionV2 { - pub fn init( - &mut self, - lb_pair: Pubkey, - owner: Pubkey, - operator: Pubkey, - lower_bin_id: i32, - upper_bin_id: i32, - current_time: i64, - lock_release_point: u64, - fee_owner: Pubkey, - ) -> Result<()> { - self.lb_pair = lb_pair; - self.owner = owner; - self.operator = operator; - - self.lower_bin_id = lower_bin_id; - self.upper_bin_id = upper_bin_id; - - self.liquidity_shares = [0u128; MAX_BIN_PER_POSITION]; - self.reward_infos = [UserRewardInfo::default(); MAX_BIN_PER_POSITION]; - - self.last_updated_at = current_time; - self.lock_release_point = lock_release_point; - - self.fee_owner = fee_owner; - - Ok(()) - } - - pub fn migrate_from_v1(&mut self, position: Ref<'_, Position>) -> Result<()> { - self.lb_pair = position.lb_pair; - self.owner = position.owner; - self.reward_infos = position.reward_infos; - self.fee_infos = position.fee_infos; - self.lower_bin_id = position.lower_bin_id; - self.upper_bin_id = position.upper_bin_id; - self.total_claimed_fee_x_amount = position.total_claimed_fee_x_amount; - self.total_claimed_fee_y_amount = position.total_claimed_fee_y_amount; - self.total_claimed_rewards = position.total_claimed_rewards; - self.last_updated_at = position.last_updated_at; - - for (i, &liquidity_share) in position.liquidity_shares.iter().enumerate() { - self.liquidity_shares[i] = u128::from(liquidity_share).safe_shl(SCALE_OFFSET.into())?; - } - Ok(()) - } - - pub fn id_within_position(&self, id: i32) -> Result<()> { - require!( - id >= self.lower_bin_id && id <= self.upper_bin_id, - LBError::InvalidPosition - ); - Ok(()) - } - - /// Return the width of the position. The width is 1 when the position have the same value for upper_bin_id, and lower_bin_id. - pub fn width(&self) -> Result { - Ok(self.upper_bin_id.safe_sub(self.lower_bin_id)?.safe_add(1)?) - } - - pub fn get_idx(&self, bin_id: i32) -> Result { - self.id_within_position(bin_id)?; - Ok(bin_id.safe_sub(self.lower_bin_id)? as usize) - } - - pub fn from_idx_to_bin_id(&self, i: usize) -> Result { - Ok(self.lower_bin_id.safe_add(i as i32)?) - } - - pub fn withdraw(&mut self, bin_id: i32, liquidity_share: u128) -> Result<()> { - let idx = self.get_idx(bin_id)?; - self.liquidity_shares[idx] = self.liquidity_shares[idx].safe_sub(liquidity_share)?; - - Ok(()) - } - - pub fn deposit(&mut self, bin_id: i32, liquidity_share: u128) -> Result<()> { - let idx = self.get_idx(bin_id)?; - self.liquidity_shares[idx] = self.liquidity_shares[idx].safe_add(liquidity_share)?; - - Ok(()) - } - - pub fn get_liquidity_share_in_bin(&self, bin_id: i32) -> Result { - let idx = self.get_idx(bin_id)?; - Ok(self.liquidity_shares[idx]) - } - - pub fn accumulate_total_claimed_rewards(&mut self, reward_index: usize, reward: u64) { - let total_claimed_reward = self.total_claimed_rewards[reward_index]; - self.total_claimed_rewards[reward_index] = total_claimed_reward.wrapping_add(reward); - } - - pub fn accumulate_total_claimed_fees(&mut self, fee_x: u64, fee_y: u64) { - self.total_claimed_fee_x_amount = self.total_claimed_fee_x_amount.wrapping_add(fee_x); - self.total_claimed_fee_y_amount = self.total_claimed_fee_y_amount.wrapping_add(fee_y); - } - - /// Update reward + fee earning - pub fn update_earning_per_token_stored( - &mut self, - bin_array_manager: &BinArrayManager, - ) -> Result<()> { - let (bin_arrays_lower_bin_id, bin_arrays_upper_bin_id) = - bin_array_manager.get_lower_upper_bin_id()?; - - // Make sure that the bin arrays cover all the bins of the position. - // TODO: Should we? Maybe we shall update only the bins the user are interacting with, and allow chunk for claim reward. - require!( - self.lower_bin_id >= bin_arrays_lower_bin_id - && self.upper_bin_id <= bin_arrays_upper_bin_id, - LBError::InvalidBinArray - ); - - for bin_id in self.lower_bin_id..=self.upper_bin_id { - let bin = bin_array_manager.get_bin(bin_id)?; - self.update_reward_per_token_stored(bin_id, &bin)?; - self.update_fee_per_token_stored(bin_id, &bin)?; - } - - Ok(()) - } - - pub fn update_fee_per_token_stored(&mut self, bin_id: i32, bin: &Bin) -> Result<()> { - let idx = self.get_idx(bin_id)?; - - let fee_infos = &mut self.fee_infos[idx]; - - let fee_x_per_token_stored = bin.fee_amount_x_per_token_stored; - - let new_fee_x: u64 = safe_mul_shr_cast( - self.liquidity_shares[idx] - .safe_shr(SCALE_OFFSET.into())? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?, - fee_x_per_token_stored.safe_sub(fee_infos.fee_x_per_token_complete)?, - SCALE_OFFSET, - Rounding::Down, - )?; - - fee_infos.fee_x_pending = new_fee_x.safe_add(fee_infos.fee_x_pending)?; - fee_infos.fee_x_per_token_complete = fee_x_per_token_stored; - - let fee_y_per_token_stored = bin.fee_amount_y_per_token_stored; - - let new_fee_y: u64 = safe_mul_shr_cast( - self.liquidity_shares[idx] - .safe_shr(SCALE_OFFSET.into())? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?, - fee_y_per_token_stored.safe_sub(fee_infos.fee_y_per_token_complete)?, - SCALE_OFFSET, - Rounding::Down, - )?; - - fee_infos.fee_y_pending = new_fee_y.safe_add(fee_infos.fee_y_pending)?; - fee_infos.fee_y_per_token_complete = fee_y_per_token_stored; - - Ok(()) - } - - pub fn update_reward_per_token_stored(&mut self, bin_id: i32, bin: &Bin) -> Result<()> { - let idx = self.get_idx(bin_id)?; - - let reward_info = &mut self.reward_infos[idx]; - for reward_idx in 0..NUM_REWARDS { - let reward_per_token_stored = bin.reward_per_token_stored[reward_idx]; - - let new_reward: u64 = safe_mul_shr_cast( - self.liquidity_shares[idx] - .safe_shr(SCALE_OFFSET.into())? - .try_into() - .map_err(|_| LBError::TypeCastFailed)?, - reward_per_token_stored - .safe_sub(reward_info.reward_per_token_completes[reward_idx])?, - SCALE_OFFSET, - Rounding::Down, - )?; - - reward_info.reward_pendings[reward_idx] = - new_reward.safe_add(reward_info.reward_pendings[reward_idx])?; - reward_info.reward_per_token_completes[reward_idx] = reward_per_token_stored; - } - - Ok(()) - } - - pub fn get_total_reward(&self, reward_index: usize) -> Result { - let mut total_reward = 0; - for val in self.reward_infos.iter() { - total_reward = total_reward.safe_add(val.reward_pendings[reward_index])?; - } - Ok(total_reward) - } - - pub fn reset_all_pending_reward(&mut self, reward_index: usize) { - for val in self.reward_infos.iter_mut() { - val.reward_pendings[reward_index] = 0; - } - } - - pub fn claim_fee(&mut self) -> Result<(u64, u64)> { - let mut fee_x = 0; - let mut fee_y = 0; - - for fee_info in self.fee_infos.iter_mut() { - fee_x = fee_x.safe_add(fee_info.fee_x_pending)?; - fee_info.fee_x_pending = 0; - - fee_y = fee_y.safe_add(fee_info.fee_y_pending)?; - fee_info.fee_y_pending = 0; - } - - Ok((fee_x, fee_y)) - } - - pub fn set_last_updated_at(&mut self, current_time: i64) { - self.last_updated_at = current_time; - } - - /// Position is empty when rewards is 0, fees is 0, and liquidity share is 0. - pub fn is_empty(&self) -> bool { - for (idx, liquidity_share) in self.liquidity_shares.iter().enumerate() { - if !liquidity_share.is_zero() { - return false; - } - let reward_infos = &self.reward_infos[idx]; - - for reward_pending in reward_infos.reward_pendings { - if !reward_pending.is_zero() { - return false; - } - } - - let fee_infos = &self.fee_infos[idx]; - if !fee_infos.fee_x_pending.is_zero() || !fee_infos.fee_y_pending.is_zero() { - return false; - } - } - true - } - - pub fn is_liquidity_locked(&self, current_point: u64) -> bool { - current_point < self.lock_release_point - } -} diff --git a/programs/lb_clmm/src/state/preset_parameters.rs b/programs/lb_clmm/src/state/preset_parameters.rs deleted file mode 100644 index 688b057b..00000000 --- a/programs/lb_clmm/src/state/preset_parameters.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::constants::{BASIS_POINT_MAX, MAX_PROTOCOL_SHARE, U24_MAX}; -use crate::errors::LBError; -use crate::math::price_math::get_price_from_id; -use anchor_lang::prelude::*; - -use super::parameters::StaticParameters; - -#[account] -#[derive(InitSpace, Debug)] -pub struct PresetParameter { - /// Bin step. Represent the price increment / decrement. - pub bin_step: u16, - /// Used for base fee calculation. base_fee_rate = base_factor * bin_step - pub base_factor: u16, - /// Filter period determine high frequency trading time window. - pub filter_period: u16, - /// Decay period determine when the volatile fee start decay / decrease. - pub decay_period: u16, - /// Reduction factor controls the volatile fee rate decrement rate. - pub reduction_factor: u16, - /// Used to scale the variable fee component depending on the dynamic of the market - pub variable_fee_control: u32, - /// Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate. - pub max_volatility_accumulator: u32, - /// Min bin id supported by the pool based on the configured bin step. - pub min_bin_id: i32, - /// Max bin id supported by the pool based on the configured bin step. - pub max_bin_id: i32, - /// Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee - pub protocol_share: u16, -} - -impl PresetParameter { - pub fn init( - &mut self, - bin_step: u16, - base_factor: u16, - filter_period: u16, - decay_period: u16, - reduction_factor: u16, - variable_fee_control: u32, - max_volatility_accumulator: u32, - min_bin_id: i32, - max_bin_id: i32, - protocol_share: u16, - ) { - self.bin_step = bin_step; - self.base_factor = base_factor; - self.filter_period = filter_period; - self.decay_period = decay_period; - self.reduction_factor = reduction_factor; - self.variable_fee_control = variable_fee_control; - self.max_volatility_accumulator = max_volatility_accumulator; - self.min_bin_id = min_bin_id; - self.max_bin_id = max_bin_id; - self.protocol_share = protocol_share; - } - - pub fn update( - &mut self, - base_factor: u16, - filter_period: u16, - decay_period: u16, - reduction_factor: u16, - variable_fee_control: u32, - max_volatility_accumulator: u32, - protocol_share: u16, - ) { - self.init( - self.bin_step, - base_factor, - filter_period, - decay_period, - reduction_factor, - variable_fee_control, - max_volatility_accumulator, - self.min_bin_id, - self.max_bin_id, - protocol_share, - ); - } - - pub fn validate(&self) -> Result<()> { - require!( - self.bin_step <= BASIS_POINT_MAX as u16, - LBError::InvalidInput - ); - - // we don't rug - require!( - self.protocol_share <= MAX_PROTOCOL_SHARE, - LBError::InvalidInput - ); - - // filter period < t < decay period - require!( - self.filter_period < self.decay_period, - LBError::InvalidInput - ); - - // reduction factor decide the decay rate of variable fee, max reduction_factor is BASIS_POINT_MAX = 100% reduction - require!( - self.reduction_factor <= BASIS_POINT_MAX as u16, - LBError::InvalidInput - ); - - // prevent program overflow - require!(self.variable_fee_control <= U24_MAX, LBError::InvalidInput); - require!( - self.max_volatility_accumulator <= U24_MAX, - LBError::InvalidInput - ); - - let max_price = get_price_from_id(self.max_bin_id, self.bin_step); - let min_price = get_price_from_id(self.min_bin_id, self.bin_step); - - require!(max_price.is_ok(), LBError::InvalidInput); - require!(min_price.is_ok(), LBError::InvalidInput); - - // Bin is not swap-able when the price is u128::MAX, and 1. Make sure the min and max price bound is 2**127 - 1, 2 - if let Ok(max_price) = max_price { - require!( - max_price == 170141183460469231731687303715884105727, - LBError::InvalidInput - ); - } - - if let Ok(min_price) = min_price { - require!(min_price == 2, LBError::InvalidInput); - } - - Ok(()) - } - - pub fn to_static_parameters(&self) -> StaticParameters { - StaticParameters { - base_factor: self.base_factor, - decay_period: self.decay_period, - filter_period: self.filter_period, - max_bin_id: self.max_bin_id, - min_bin_id: self.min_bin_id, - variable_fee_control: self.variable_fee_control, - reduction_factor: self.reduction_factor, - protocol_share: self.protocol_share, - max_volatility_accumulator: self.max_volatility_accumulator, - _padding: [0u8; 6], - } - } -} diff --git a/programs/lb_clmm/src/utils/mod.rs b/programs/lb_clmm/src/utils/mod.rs deleted file mode 100644 index f577dc79..00000000 --- a/programs/lb_clmm/src/utils/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod pda; -pub mod seeds; diff --git a/programs/lb_clmm/src/utils/pda.rs b/programs/lb_clmm/src/utils/pda.rs deleted file mode 100644 index d4ea1f2f..00000000 --- a/programs/lb_clmm/src/utils/pda.rs +++ /dev/null @@ -1,134 +0,0 @@ -use super::seeds::{ - self, BIN_ARRAY, BIN_ARRAY_BITMAP_SEED, ILM_BASE_KEY, ORACLE, PRESET_PARAMETER, -}; -use anchor_lang::prelude::Pubkey; -use num_traits::ToBytes; -use std::{cmp::max, cmp::min}; - -pub fn derive_lb_pair_pda2( - token_x_mint: Pubkey, - token_y_mint: Pubkey, - bin_step: u16, - base_factor: u16, -) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[ - min(token_x_mint, token_y_mint).as_ref(), - max(token_x_mint, token_y_mint).as_ref(), - &bin_step.to_le_bytes(), - &base_factor.to_le_bytes(), - ], - &crate::ID, - ) -} - -pub fn derive_customizable_permissionless_lb_pair( - token_x_mint: Pubkey, - token_y_mint: Pubkey, -) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[ - ILM_BASE_KEY.as_ref(), - min(token_x_mint, token_y_mint).as_ref(), - max(token_x_mint, token_y_mint).as_ref(), - ], - &crate::ID, - ) -} - -pub fn derive_permission_lb_pair_pda( - base: Pubkey, - token_x_mint: Pubkey, - token_y_mint: Pubkey, - bin_step: u16, -) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[ - base.as_ref(), - min(token_x_mint, token_y_mint).as_ref(), - max(token_x_mint, token_y_mint).as_ref(), - &bin_step.to_le_bytes(), - ], - &crate::ID, - ) -} - -#[deprecated] -pub fn derive_lb_pair_pda( - token_x_mint: Pubkey, - token_y_mint: Pubkey, - bin_step: u16, -) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[ - min(token_x_mint, token_y_mint).as_ref(), - max(token_x_mint, token_y_mint).as_ref(), - &bin_step.to_le_bytes(), - ], - &crate::ID, - ) -} - -pub fn derive_position_pda( - lb_pair: Pubkey, - base: Pubkey, - lower_bin_id: i32, - width: i32, -) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[ - seeds::POSITION.as_ref(), - lb_pair.as_ref(), - base.as_ref(), - lower_bin_id.to_le_bytes().as_ref(), - width.to_le_bytes().as_ref(), - ], - &crate::ID, - ) -} - -pub fn derive_oracle_pda(lb_pair: Pubkey) -> (Pubkey, u8) { - Pubkey::find_program_address(&[ORACLE, lb_pair.as_ref()], &crate::ID) -} - -pub fn derive_bin_array_pda(lb_pair: Pubkey, bin_array_index: i64) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[BIN_ARRAY, lb_pair.as_ref(), &bin_array_index.to_le_bytes()], - &crate::ID, - ) -} - -pub fn derive_bin_array_bitmap_extension(lb_pair: Pubkey) -> (Pubkey, u8) { - Pubkey::find_program_address(&[BIN_ARRAY_BITMAP_SEED, lb_pair.as_ref()], &crate::ID) -} - -pub fn derive_reserve_pda(token_mint: Pubkey, lb_pair: Pubkey) -> (Pubkey, u8) { - Pubkey::find_program_address(&[lb_pair.as_ref(), token_mint.as_ref()], &crate::ID) -} - -pub fn derive_reward_vault_pda(lb_pair: Pubkey, reward_index: u64) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[lb_pair.as_ref(), reward_index.to_le_bytes().as_ref()], - &crate::ID, - ) -} - -pub fn derive_event_authority_pda() -> (Pubkey, u8) { - Pubkey::find_program_address(&[b"__event_authority"], &crate::ID) -} - -#[deprecated] -pub fn derive_preset_parameter_pda(bin_step: u16) -> (Pubkey, u8) { - Pubkey::find_program_address(&[PRESET_PARAMETER, &bin_step.to_le_bytes()], &crate::ID) -} - -pub fn derive_preset_parameter_pda2(bin_step: u16, base_factor: u16) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[ - PRESET_PARAMETER, - &bin_step.to_le_bytes(), - &base_factor.to_le_bytes(), - ], - &crate::ID, - ) -} diff --git a/programs/lb_clmm/src/utils/seeds.rs b/programs/lb_clmm/src/utils/seeds.rs deleted file mode 100644 index 5dc8cf5c..00000000 --- a/programs/lb_clmm/src/utils/seeds.rs +++ /dev/null @@ -1,19 +0,0 @@ -use anchor_lang::prelude::*; -use anchor_lang::solana_program::pubkey; - -#[constant] -pub const BIN_ARRAY: &[u8] = b"bin_array"; - -#[constant] -pub const ORACLE: &[u8] = b"oracle"; - -#[constant] -pub const BIN_ARRAY_BITMAP_SEED: &[u8] = b"bitmap"; - -#[constant] -pub const PRESET_PARAMETER: &[u8] = b"preset_parameter"; - -#[constant] -pub const POSITION: &[u8] = b"position"; - -pub const ILM_BASE_KEY: Pubkey = pubkey!("MFGQxwAmB91SwuYX36okv2Qmdc9aMuHTwWGUrp4AtB1"); diff --git a/target/idl/lb_clmm.json b/target/idl/lb_clmm.json deleted file mode 100644 index 4ec85702..00000000 --- a/target/idl/lb_clmm.json +++ /dev/null @@ -1,5097 +0,0 @@ -{ - "version": "0.8.2", - "name": "lb_clmm", - "constants": [ - { - "name": "BASIS_POINT_MAX", - "type": "i32", - "value": "10000" - }, - { - "name": "MAX_BIN_PER_ARRAY", - "type": { - "defined": "usize" - }, - "value": "70" - }, - { - "name": "MAX_BIN_PER_POSITION", - "type": { - "defined": "usize" - }, - "value": "70" - }, - { - "name": "MIN_BIN_ID", - "type": "i32", - "value": "- 443636" - }, - { - "name": "MAX_BIN_ID", - "type": "i32", - "value": "443636" - }, - { - "name": "MAX_FEE_RATE", - "type": "u64", - "value": "100_000_000" - }, - { - "name": "FEE_PRECISION", - "type": "u64", - "value": "1_000_000_000" - }, - { - "name": "MAX_PROTOCOL_SHARE", - "type": "u16", - "value": "2_500" - }, - { - "name": "HOST_FEE_BPS", - "type": "u16", - "value": "2_000" - }, - { - "name": "NUM_REWARDS", - "type": { - "defined": "usize" - }, - "value": "2" - }, - { - "name": "MIN_REWARD_DURATION", - "type": "u64", - "value": "1" - }, - { - "name": "MAX_REWARD_DURATION", - "type": "u64", - "value": "31536000" - }, - { - "name": "EXTENSION_BINARRAY_BITMAP_SIZE", - "type": { - "defined": "usize" - }, - "value": "12" - }, - { - "name": "BIN_ARRAY_BITMAP_SIZE", - "type": "i32", - "value": "512" - }, - { - "name": "MAX_REWARD_BIN_SPLIT", - "type": { - "defined": "usize" - }, - "value": "15" - }, - { - "name": "MAX_BIN_STEP", - "type": "u16", - "value": "400" - }, - { - "name": "MAX_BASE_FEE", - "type": "u128", - "value": "100_000_000" - }, - { - "name": "MIN_BASE_FEE", - "type": "u128", - "value": "100_000" - }, - { - "name": "BIN_ARRAY", - "type": "bytes", - "value": "[98, 105, 110, 95, 97, 114, 114, 97, 121]" - }, - { - "name": "ORACLE", - "type": "bytes", - "value": "[111, 114, 97, 99, 108, 101]" - }, - { - "name": "BIN_ARRAY_BITMAP_SEED", - "type": "bytes", - "value": "[98, 105, 116, 109, 97, 112]" - }, - { - "name": "PRESET_PARAMETER", - "type": "bytes", - "value": "[112, 114, 101, 115, 101, 116, 95, 112, 97, 114, 97, 109, 101, 116, 101, 114]" - }, - { - "name": "POSITION", - "type": "bytes", - "value": "[112, 111, 115, 105, 116, 105, 111, 110]" - } - ], - "instructions": [ - { - "name": "initializeLbPair", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "presetParameter", - "isMut": false, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "activeId", - "type": "i32" - }, - { - "name": "binStep", - "type": "u16" - } - ] - }, - { - "name": "initializeCustomizablePermissionlessLbPair", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "params", - "type": { - "defined": "CustomizableParams" - } - } - ] - }, - { - "name": "initializePermissionLbPair", - "accounts": [ - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ixData", - "type": { - "defined": "InitPermissionPairIx" - } - } - ] - }, - { - "name": "initializeBinArrayBitmapExtension", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "docs": [ - "Initialize an account to store if a bin array is initialized." - ] - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "initializeBinArray", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "index", - "type": "i64" - } - ] - }, - { - "name": "addLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameter" - } - } - ] - }, - { - "name": "addLiquidityByWeight", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByWeight" - } - } - ] - }, - { - "name": "addLiquidityByStrategy", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByStrategy" - } - } - ] - }, - { - "name": "addLiquidityByStrategyOneSide", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByStrategyOneSide" - } - } - ] - }, - { - "name": "addLiquidityOneSide", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityOneSideParameter" - } - } - ] - }, - { - "name": "removeLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "binLiquidityRemoval", - "type": { - "vec": { - "defined": "BinLiquidityReduction" - } - } - } - ] - }, - { - "name": "initializePosition", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": true - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - } - ] - }, - { - "name": "initializePositionPda", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true, - "docs": [ - "owner" - ] - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - } - ] - }, - { - "name": "initializePositionByOperator", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": false - }, - { - "name": "operator", - "isMut": false, - "isSigner": true, - "docs": [ - "operator" - ] - }, - { - "name": "operatorTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "ownerTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - }, - { - "name": "feeOwner", - "type": "publicKey" - }, - { - "name": "lockReleasePoint", - "type": "u64" - } - ] - }, - { - "name": "updatePositionOperator", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "operator", - "type": "publicKey" - } - ] - }, - { - "name": "swap", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountIn", - "type": "u64" - }, - { - "name": "minAmountOut", - "type": "u64" - } - ] - }, - { - "name": "withdrawProtocolFee", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "receiverTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "receiverTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "feeOwner", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountX", - "type": "u64" - }, - { - "name": "amountY", - "type": "u64" - } - ] - }, - { - "name": "initializeReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "rewardDuration", - "type": "u64" - }, - { - "name": "funder", - "type": "publicKey" - } - ] - }, - { - "name": "fundReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "funderTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "amount", - "type": "u64" - }, - { - "name": "carryForward", - "type": "bool" - } - ] - }, - { - "name": "updateRewardFunder", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "newFunder", - "type": "publicKey" - } - ] - }, - { - "name": "updateRewardDuration", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "newDuration", - "type": "u64" - } - ] - }, - { - "name": "claimReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - } - ] - }, - { - "name": "claimFee", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "closePosition", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "updateFeeParameters", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "feeParameter", - "type": { - "defined": "FeeParameter" - } - } - ] - }, - { - "name": "increaseOracleLength", - "accounts": [ - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lengthToAdd", - "type": "u64" - } - ] - }, - { - "name": "initializePresetParameter", - "accounts": [ - { - "name": "presetParameter", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ix", - "type": { - "defined": "InitPresetParametersIx" - } - } - ] - }, - { - "name": "closePresetParameter", - "accounts": [ - { - "name": "presetParameter", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "removeAllLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "togglePairStatus", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "migratePosition", - "accounts": [ - { - "name": "positionV2", - "isMut": true, - "isSigner": true - }, - { - "name": "positionV1", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "migrateBinArray", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "updateFeesAndRewards", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "withdrawIneligibleReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "funderTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - } - ] - }, - { - "name": "setActivationPoint", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - } - ], - "args": [ - { - "name": "activationPoint", - "type": "u64" - } - ] - }, - { - "name": "addLiquidityOneSidePrecise", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "parameter", - "type": { - "defined": "AddLiquiditySingleSidePreciseParameter" - } - } - ] - }, - { - "name": "setPreActivationDuration", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "creator", - "isMut": false, - "isSigner": true - } - ], - "args": [ - { - "name": "preActivationDuration", - "type": "u16" - } - ] - }, - { - "name": "setPreActivationSwapAddress", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "creator", - "isMut": false, - "isSigner": true - } - ], - "args": [ - { - "name": "preActivationSwapAddress", - "type": "publicKey" - } - ] - }, - { - "name": "swapExactOut", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "maxInAmount", - "type": "u64" - }, - { - "name": "outAmount", - "type": "u64" - } - ] - }, - { - "name": "swapWithPriceImpact", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountIn", - "type": "u64" - }, - { - "name": "activeId", - "type": { - "option": "i32" - } - }, - { - "name": "maxPriceImpactBps", - "type": "u16" - } - ] - } - ], - "accounts": [ - { - "name": "BinArrayBitmapExtension", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "type": "publicKey" - }, - { - "name": "positiveBinArrayBitmap", - "docs": [ - "Packed initialized bin array state for start_bin_index is positive" - ], - "type": { - "array": [ - { - "array": [ - "u64", - 8 - ] - }, - 12 - ] - } - }, - { - "name": "negativeBinArrayBitmap", - "docs": [ - "Packed initialized bin array state for start_bin_index is negative" - ], - "type": { - "array": [ - { - "array": [ - "u64", - 8 - ] - }, - 12 - ] - } - } - ] - } - }, - { - "name": "BinArray", - "docs": [ - "An account to contain a range of bin. For example: Bin 100 <-> 200.", - "For example:", - "BinArray index: 0 contains bin 0 <-> 599", - "index: 2 contains bin 600 <-> 1199, ..." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "index", - "type": "i64" - }, - { - "name": "version", - "docs": [ - "Version of binArray" - ], - "type": "u8" - }, - { - "name": "padding", - "type": { - "array": [ - "u8", - 7 - ] - } - }, - { - "name": "lbPair", - "type": "publicKey" - }, - { - "name": "bins", - "type": { - "array": [ - { - "defined": "Bin" - }, - 70 - ] - } - } - ] - } - }, - { - "name": "LbPair", - "type": { - "kind": "struct", - "fields": [ - { - "name": "parameters", - "type": { - "defined": "StaticParameters" - } - }, - { - "name": "vParameters", - "type": { - "defined": "VariableParameters" - } - }, - { - "name": "bumpSeed", - "type": { - "array": [ - "u8", - 1 - ] - } - }, - { - "name": "binStepSeed", - "docs": [ - "Bin step signer seed" - ], - "type": { - "array": [ - "u8", - 2 - ] - } - }, - { - "name": "pairType", - "docs": [ - "Type of the pair" - ], - "type": "u8" - }, - { - "name": "activeId", - "docs": [ - "Active bin id" - ], - "type": "i32" - }, - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "status", - "docs": [ - "Status of the pair. Check PairStatus enum." - ], - "type": "u8" - }, - { - "name": "requireBaseFactorSeed", - "docs": [ - "Require base factor seed" - ], - "type": "u8" - }, - { - "name": "baseFactorSeed", - "docs": [ - "Base factor seed" - ], - "type": { - "array": [ - "u8", - 2 - ] - } - }, - { - "name": "activationType", - "docs": [ - "Activation type" - ], - "type": "u8" - }, - { - "name": "padding0", - "docs": [ - "padding 0" - ], - "type": "u8" - }, - { - "name": "tokenXMint", - "docs": [ - "Token X mint" - ], - "type": "publicKey" - }, - { - "name": "tokenYMint", - "docs": [ - "Token Y mint" - ], - "type": "publicKey" - }, - { - "name": "reserveX", - "docs": [ - "LB token X vault" - ], - "type": "publicKey" - }, - { - "name": "reserveY", - "docs": [ - "LB token Y vault" - ], - "type": "publicKey" - }, - { - "name": "protocolFee", - "docs": [ - "Uncollected protocol fee" - ], - "type": { - "defined": "ProtocolFee" - } - }, - { - "name": "padding1", - "docs": [ - "_padding_1, previous Fee owner, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "RewardInfo" - }, - 2 - ] - } - }, - { - "name": "oracle", - "docs": [ - "Oracle pubkey" - ], - "type": "publicKey" - }, - { - "name": "binArrayBitmap", - "docs": [ - "Packed initialized bin array state" - ], - "type": { - "array": [ - "u64", - 16 - ] - } - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last time the pool fee parameter was updated" - ], - "type": "i64" - }, - { - "name": "padding2", - "docs": [ - "_padding_2, previous whitelisted_wallet, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "preActivationSwapAddress", - "docs": [ - "Address allowed to swap when the current point is greater than or equal to the pre-activation point. The pre-activation point is calculated as `activation_point - pre_activation_duration`." - ], - "type": "publicKey" - }, - { - "name": "baseKey", - "docs": [ - "Base keypair. Only required for permission pair" - ], - "type": "publicKey" - }, - { - "name": "activationPoint", - "docs": [ - "Time point to enable the pair. Only applicable for permission pair." - ], - "type": "u64" - }, - { - "name": "preActivationDuration", - "docs": [ - "Duration before activation point. Used to calculate pre-activation point for pre_activation_swap_address" - ], - "type": "u64" - }, - { - "name": "padding3", - "docs": [ - "_padding 3 is reclaimed free space from swap_cap_deactivate_point and swap_cap_amount before, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 8 - ] - } - }, - { - "name": "padding4", - "docs": [ - "_padding_4, previous lock_duration, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": "u64" - }, - { - "name": "creator", - "docs": [ - "Pool creator" - ], - "type": "publicKey" - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 24 - ] - } - } - ] - } - }, - { - "name": "Oracle", - "type": { - "kind": "struct", - "fields": [ - { - "name": "idx", - "docs": [ - "Index of latest observation" - ], - "type": "u64" - }, - { - "name": "activeSize", - "docs": [ - "Size of active sample. Active sample is initialized observation." - ], - "type": "u64" - }, - { - "name": "length", - "docs": [ - "Number of observations" - ], - "type": "u64" - } - ] - } - }, - { - "name": "Position", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "docs": [ - "The LB pair of this position" - ], - "type": "publicKey" - }, - { - "name": "owner", - "docs": [ - "Owner of the position. Client rely on this to to fetch their positions." - ], - "type": "publicKey" - }, - { - "name": "liquidityShares", - "docs": [ - "Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept." - ], - "type": { - "array": [ - "u64", - 70 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "UserRewardInfo" - }, - 70 - ] - } - }, - { - "name": "feeInfos", - "docs": [ - "Swap fee to claim information" - ], - "type": { - "array": [ - { - "defined": "FeeInfo" - }, - 70 - ] - } - }, - { - "name": "lowerBinId", - "docs": [ - "Lower bin ID" - ], - "type": "i32" - }, - { - "name": "upperBinId", - "docs": [ - "Upper bin ID" - ], - "type": "i32" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last updated timestamp" - ], - "type": "i64" - }, - { - "name": "totalClaimedFeeXAmount", - "docs": [ - "Total claimed token fee X" - ], - "type": "u64" - }, - { - "name": "totalClaimedFeeYAmount", - "docs": [ - "Total claimed token fee Y" - ], - "type": "u64" - }, - { - "name": "totalClaimedRewards", - "docs": [ - "Total claimed rewards" - ], - "type": { - "array": [ - "u64", - 2 - ] - } - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 160 - ] - } - } - ] - } - }, - { - "name": "PositionV2", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "docs": [ - "The LB pair of this position" - ], - "type": "publicKey" - }, - { - "name": "owner", - "docs": [ - "Owner of the position. Client rely on this to to fetch their positions." - ], - "type": "publicKey" - }, - { - "name": "liquidityShares", - "docs": [ - "Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept." - ], - "type": { - "array": [ - "u128", - 70 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "UserRewardInfo" - }, - 70 - ] - } - }, - { - "name": "feeInfos", - "docs": [ - "Swap fee to claim information" - ], - "type": { - "array": [ - { - "defined": "FeeInfo" - }, - 70 - ] - } - }, - { - "name": "lowerBinId", - "docs": [ - "Lower bin ID" - ], - "type": "i32" - }, - { - "name": "upperBinId", - "docs": [ - "Upper bin ID" - ], - "type": "i32" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last updated timestamp" - ], - "type": "i64" - }, - { - "name": "totalClaimedFeeXAmount", - "docs": [ - "Total claimed token fee X" - ], - "type": "u64" - }, - { - "name": "totalClaimedFeeYAmount", - "docs": [ - "Total claimed token fee Y" - ], - "type": "u64" - }, - { - "name": "totalClaimedRewards", - "docs": [ - "Total claimed rewards" - ], - "type": { - "array": [ - "u64", - 2 - ] - } - }, - { - "name": "operator", - "docs": [ - "Operator of position" - ], - "type": "publicKey" - }, - { - "name": "lockReleasePoint", - "docs": [ - "Time point which the locked liquidity can be withdraw" - ], - "type": "u64" - }, - { - "name": "padding0", - "docs": [ - "_padding_0, previous subjected_to_bootstrap_liquidity_locking, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": "u8" - }, - { - "name": "feeOwner", - "docs": [ - "Address is able to claim fee in this position, only valid for bootstrap_liquidity_position" - ], - "type": "publicKey" - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 87 - ] - } - } - ] - } - }, - { - "name": "PresetParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - } - ] - } - } - ], - "types": [ - { - "name": "InitPresetParametersIx", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - } - ] - } - }, - { - "name": "FeeParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Base factor for base fee rate" - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameterByStrategyOneSide", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amount", - "docs": [ - "Amount of X token or Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "strategyParameters", - "docs": [ - "strategy parameters" - ], - "type": { - "defined": "StrategyParameters" - } - } - ] - } - }, - { - "name": "LiquidityParameterByStrategy", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "strategyParameters", - "docs": [ - "strategy parameters" - ], - "type": { - "defined": "StrategyParameters" - } - } - ] - } - }, - { - "name": "StrategyParameters", - "type": { - "kind": "struct", - "fields": [ - { - "name": "minBinId", - "docs": [ - "min bin id" - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "max bin id" - ], - "type": "i32" - }, - { - "name": "strategyType", - "docs": [ - "strategy type" - ], - "type": { - "defined": "StrategyType" - } - }, - { - "name": "parameteres", - "docs": [ - "parameters" - ], - "type": { - "array": [ - "u8", - 64 - ] - } - } - ] - } - }, - { - "name": "LiquidityOneSideParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amount", - "docs": [ - "Amount of X token or Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistributionByWeight" - } - } - } - ] - } - }, - { - "name": "BinLiquidityDistributionByWeight", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "docs": [ - "Define the bin ID wish to deposit to." - ], - "type": "i32" - }, - { - "name": "weight", - "docs": [ - "weight of liquidity distributed for this bin id" - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameterByWeight", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistributionByWeight" - } - } - } - ] - } - }, - { - "name": "AddLiquiditySingleSidePreciseParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bins", - "type": { - "vec": { - "defined": "CompressedBinDepositAmount" - } - } - }, - { - "name": "decompressMultiplier", - "type": "u64" - } - ] - } - }, - { - "name": "CompressedBinDepositAmount", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "type": "i32" - }, - { - "name": "amount", - "type": "u32" - } - ] - } - }, - { - "name": "BinLiquidityDistribution", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "docs": [ - "Define the bin ID wish to deposit to." - ], - "type": "i32" - }, - { - "name": "distributionX", - "docs": [ - "DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin." - ], - "type": "u16" - }, - { - "name": "distributionY", - "docs": [ - "DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin." - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistribution" - } - } - } - ] - } - }, - { - "name": "CustomizableParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activeId", - "docs": [ - "Pool price" - ], - "type": "i32" - }, - { - "name": "binStep", - "docs": [ - "Bin step" - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Base factor" - ], - "type": "u16" - }, - { - "name": "activationType", - "docs": [ - "Activation type. 0 = Slot, 1 = Time. Check ActivationType enum" - ], - "type": "u8" - }, - { - "name": "hasAlphaVault", - "docs": [ - "Whether the pool has an alpha vault" - ], - "type": "bool" - }, - { - "name": "activationPoint", - "docs": [ - "Decide when does the pool start trade. None = Now" - ], - "type": { - "option": "u64" - } - }, - { - "name": "padding", - "docs": [ - "Padding, for future use" - ], - "type": { - "array": [ - "u8", - 64 - ] - } - } - ] - } - }, - { - "name": "InitPermissionPairIx", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activeId", - "type": "i32" - }, - { - "name": "binStep", - "type": "u16" - }, - { - "name": "baseFactor", - "type": "u16" - }, - { - "name": "minBinId", - "type": "i32" - }, - { - "name": "maxBinId", - "type": "i32" - }, - { - "name": "lockDuration", - "type": "u64" - }, - { - "name": "activationType", - "type": "u8" - } - ] - } - }, - { - "name": "BinLiquidityReduction", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "type": "i32" - }, - { - "name": "bpsToRemove", - "type": "u16" - } - ] - } - }, - { - "name": "Bin", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of token X in the bin. This already excluded protocol fees." - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of token Y in the bin. This already excluded protocol fees." - ], - "type": "u64" - }, - { - "name": "price", - "docs": [ - "Bin price" - ], - "type": "u128" - }, - { - "name": "liquiditySupply", - "docs": [ - "Liquidities of the bin. This is the same as LP mint supply. q-number" - ], - "type": "u128" - }, - { - "name": "rewardPerTokenStored", - "docs": [ - "reward_a_per_token_stored" - ], - "type": { - "array": [ - "u128", - 2 - ] - } - }, - { - "name": "feeAmountXPerTokenStored", - "docs": [ - "Swap fee amount of token X per liquidity deposited." - ], - "type": "u128" - }, - { - "name": "feeAmountYPerTokenStored", - "docs": [ - "Swap fee amount of token Y per liquidity deposited." - ], - "type": "u128" - }, - { - "name": "amountXIn", - "docs": [ - "Total token X swap into the bin. Only used for tracking purpose." - ], - "type": "u128" - }, - { - "name": "amountYIn", - "docs": [ - "Total token Y swap into he bin. Only used for tracking purpose." - ], - "type": "u128" - } - ] - } - }, - { - "name": "ProtocolFee", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "type": "u64" - }, - { - "name": "amountY", - "type": "u64" - } - ] - } - }, - { - "name": "RewardInfo", - "docs": [ - "Stores the state relevant for tracking liquidity mining rewards" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "mint", - "docs": [ - "Reward token mint." - ], - "type": "publicKey" - }, - { - "name": "vault", - "docs": [ - "Reward vault token account." - ], - "type": "publicKey" - }, - { - "name": "funder", - "docs": [ - "Authority account that allows to fund rewards" - ], - "type": "publicKey" - }, - { - "name": "rewardDuration", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u64" - }, - { - "name": "rewardDurationEnd", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u64" - }, - { - "name": "rewardRate", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u128" - }, - { - "name": "lastUpdateTime", - "docs": [ - "The last time reward states were updated." - ], - "type": "u64" - }, - { - "name": "cumulativeSecondsWithEmptyLiquidityReward", - "docs": [ - "Accumulated seconds where when farm distribute rewards, but the bin is empty. The reward will be accumulated for next reward time window." - ], - "type": "u64" - } - ] - } - }, - { - "name": "Observation", - "type": { - "kind": "struct", - "fields": [ - { - "name": "cumulativeActiveBinId", - "docs": [ - "Cumulative active bin ID" - ], - "type": "i128" - }, - { - "name": "createdAt", - "docs": [ - "Observation sample created timestamp" - ], - "type": "i64" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Observation sample last updated timestamp" - ], - "type": "i64" - } - ] - } - }, - { - "name": "StaticParameters", - "docs": [ - "Parameter that set by the protocol" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - }, - { - "name": "padding", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 6 - ] - } - } - ] - } - }, - { - "name": "VariableParameters", - "docs": [ - "Parameters that changes based on dynamic of the market" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "volatilityAccumulator", - "docs": [ - "Volatility accumulator measure the number of bin crossed since reference bin ID. Normally (without filter period taken into consideration), reference bin ID is the active bin of last swap.", - "It affects the variable fee rate" - ], - "type": "u32" - }, - { - "name": "volatilityReference", - "docs": [ - "Volatility reference is decayed volatility accumulator. It is always <= volatility_accumulator" - ], - "type": "u32" - }, - { - "name": "indexReference", - "docs": [ - "Active bin id of last swap." - ], - "type": "i32" - }, - { - "name": "padding", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 4 - ] - } - }, - { - "name": "lastUpdateTimestamp", - "docs": [ - "Last timestamp the variable parameters was updated" - ], - "type": "i64" - }, - { - "name": "padding1", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 8 - ] - } - } - ] - } - }, - { - "name": "FeeInfo", - "type": { - "kind": "struct", - "fields": [ - { - "name": "feeXPerTokenComplete", - "type": "u128" - }, - { - "name": "feeYPerTokenComplete", - "type": "u128" - }, - { - "name": "feeXPending", - "type": "u64" - }, - { - "name": "feeYPending", - "type": "u64" - } - ] - } - }, - { - "name": "UserRewardInfo", - "type": { - "kind": "struct", - "fields": [ - { - "name": "rewardPerTokenCompletes", - "type": { - "array": [ - "u128", - 2 - ] - } - }, - { - "name": "rewardPendings", - "type": { - "array": [ - "u64", - 2 - ] - } - } - ] - } - }, - { - "name": "StrategyType", - "type": { - "kind": "enum", - "variants": [ - { - "name": "SpotOneSide" - }, - { - "name": "CurveOneSide" - }, - { - "name": "BidAskOneSide" - }, - { - "name": "SpotBalanced" - }, - { - "name": "CurveBalanced" - }, - { - "name": "BidAskBalanced" - }, - { - "name": "SpotImBalanced" - }, - { - "name": "CurveImBalanced" - }, - { - "name": "BidAskImBalanced" - } - ] - } - }, - { - "name": "Rounding", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Up" - }, - { - "name": "Down" - } - ] - } - }, - { - "name": "ActivationType", - "docs": [ - "Type of the activation" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Slot" - }, - { - "name": "Timestamp" - } - ] - } - }, - { - "name": "LayoutVersion", - "docs": [ - "Layout version" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "V0" - }, - { - "name": "V1" - } - ] - } - }, - { - "name": "PairType", - "docs": [ - "Type of the Pair. 0 = Permissionless, 1 = Permission, 2 = CustomizablePermissionless" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Permissionless" - }, - { - "name": "Permission" - }, - { - "name": "CustomizablePermissionless" - } - ] - } - }, - { - "name": "PairStatus", - "docs": [ - "Pair status. 0 = Enabled, 1 = Disabled. Putting 0 as enabled for backward compatibility." - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Enabled" - }, - { - "name": "Disabled" - } - ] - } - } - ], - "events": [ - { - "name": "CompositionFee", - "fields": [ - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "binId", - "type": "i16", - "index": false - }, - { - "name": "tokenXFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "tokenYFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "protocolTokenXFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "protocolTokenYFeeAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "AddLiquidity", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "amounts", - "type": { - "array": [ - "u64", - 2 - ] - }, - "index": false - }, - { - "name": "activeBinId", - "type": "i32", - "index": false - } - ] - }, - { - "name": "RemoveLiquidity", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "amounts", - "type": { - "array": [ - "u64", - 2 - ] - }, - "index": false - }, - { - "name": "activeBinId", - "type": "i32", - "index": false - } - ] - }, - { - "name": "Swap", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "startBinId", - "type": "i32", - "index": false - }, - { - "name": "endBinId", - "type": "i32", - "index": false - }, - { - "name": "amountIn", - "type": "u64", - "index": false - }, - { - "name": "amountOut", - "type": "u64", - "index": false - }, - { - "name": "swapForY", - "type": "bool", - "index": false - }, - { - "name": "fee", - "type": "u64", - "index": false - }, - { - "name": "protocolFee", - "type": "u64", - "index": false - }, - { - "name": "feeBps", - "type": "u128", - "index": false - }, - { - "name": "hostFee", - "type": "u64", - "index": false - } - ] - }, - { - "name": "ClaimReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "totalReward", - "type": "u64", - "index": false - } - ] - }, - { - "name": "FundReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "funder", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "amount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "InitializeReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardMint", - "type": "publicKey", - "index": false - }, - { - "name": "funder", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "rewardDuration", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdateRewardDuration", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "oldRewardDuration", - "type": "u64", - "index": false - }, - { - "name": "newRewardDuration", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdateRewardFunder", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "oldFunder", - "type": "publicKey", - "index": false - }, - { - "name": "newFunder", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "PositionClose", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "ClaimFee", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - }, - { - "name": "feeX", - "type": "u64", - "index": false - }, - { - "name": "feeY", - "type": "u64", - "index": false - } - ] - }, - { - "name": "LbPairCreate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "binStep", - "type": "u16", - "index": false - }, - { - "name": "tokenX", - "type": "publicKey", - "index": false - }, - { - "name": "tokenY", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "PositionCreate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "FeeParameterUpdate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "protocolShare", - "type": "u16", - "index": false - }, - { - "name": "baseFactor", - "type": "u16", - "index": false - } - ] - }, - { - "name": "IncreaseObservation", - "fields": [ - { - "name": "oracle", - "type": "publicKey", - "index": false - }, - { - "name": "newObservationLength", - "type": "u64", - "index": false - } - ] - }, - { - "name": "WithdrawIneligibleReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardMint", - "type": "publicKey", - "index": false - }, - { - "name": "amount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdatePositionOperator", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "oldOperator", - "type": "publicKey", - "index": false - }, - { - "name": "newOperator", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "UpdatePositionLockReleasePoint", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "currentPoint", - "type": "u64", - "index": false - }, - { - "name": "newLockReleasePoint", - "type": "u64", - "index": false - }, - { - "name": "oldLockReleasePoint", - "type": "u64", - "index": false - }, - { - "name": "sender", - "type": "publicKey", - "index": false - } - ] - } - ], - "errors": [ - { - "code": 6000, - "name": "InvalidStartBinIndex", - "msg": "Invalid start bin index" - }, - { - "code": 6001, - "name": "InvalidBinId", - "msg": "Invalid bin id" - }, - { - "code": 6002, - "name": "InvalidInput", - "msg": "Invalid input data" - }, - { - "code": 6003, - "name": "ExceededAmountSlippageTolerance", - "msg": "Exceeded amount slippage tolerance" - }, - { - "code": 6004, - "name": "ExceededBinSlippageTolerance", - "msg": "Exceeded bin slippage tolerance" - }, - { - "code": 6005, - "name": "CompositionFactorFlawed", - "msg": "Composition factor flawed" - }, - { - "code": 6006, - "name": "NonPresetBinStep", - "msg": "Non preset bin step" - }, - { - "code": 6007, - "name": "ZeroLiquidity", - "msg": "Zero liquidity" - }, - { - "code": 6008, - "name": "InvalidPosition", - "msg": "Invalid position" - }, - { - "code": 6009, - "name": "BinArrayNotFound", - "msg": "Bin array not found" - }, - { - "code": 6010, - "name": "InvalidTokenMint", - "msg": "Invalid token mint" - }, - { - "code": 6011, - "name": "InvalidAccountForSingleDeposit", - "msg": "Invalid account for single deposit" - }, - { - "code": 6012, - "name": "PairInsufficientLiquidity", - "msg": "Pair insufficient liquidity" - }, - { - "code": 6013, - "name": "InvalidFeeOwner", - "msg": "Invalid fee owner" - }, - { - "code": 6014, - "name": "InvalidFeeWithdrawAmount", - "msg": "Invalid fee withdraw amount" - }, - { - "code": 6015, - "name": "InvalidAdmin", - "msg": "Invalid admin" - }, - { - "code": 6016, - "name": "IdenticalFeeOwner", - "msg": "Identical fee owner" - }, - { - "code": 6017, - "name": "InvalidBps", - "msg": "Invalid basis point" - }, - { - "code": 6018, - "name": "MathOverflow", - "msg": "Math operation overflow" - }, - { - "code": 6019, - "name": "TypeCastFailed", - "msg": "Type cast error" - }, - { - "code": 6020, - "name": "InvalidRewardIndex", - "msg": "Invalid reward index" - }, - { - "code": 6021, - "name": "InvalidRewardDuration", - "msg": "Invalid reward duration" - }, - { - "code": 6022, - "name": "RewardInitialized", - "msg": "Reward already initialized" - }, - { - "code": 6023, - "name": "RewardUninitialized", - "msg": "Reward not initialized" - }, - { - "code": 6024, - "name": "IdenticalFunder", - "msg": "Identical funder" - }, - { - "code": 6025, - "name": "RewardCampaignInProgress", - "msg": "Reward campaign in progress" - }, - { - "code": 6026, - "name": "IdenticalRewardDuration", - "msg": "Reward duration is the same" - }, - { - "code": 6027, - "name": "InvalidBinArray", - "msg": "Invalid bin array" - }, - { - "code": 6028, - "name": "NonContinuousBinArrays", - "msg": "Bin arrays must be continuous" - }, - { - "code": 6029, - "name": "InvalidRewardVault", - "msg": "Invalid reward vault" - }, - { - "code": 6030, - "name": "NonEmptyPosition", - "msg": "Position is not empty" - }, - { - "code": 6031, - "name": "UnauthorizedAccess", - "msg": "Unauthorized access" - }, - { - "code": 6032, - "name": "InvalidFeeParameter", - "msg": "Invalid fee parameter" - }, - { - "code": 6033, - "name": "MissingOracle", - "msg": "Missing oracle account" - }, - { - "code": 6034, - "name": "InsufficientSample", - "msg": "Insufficient observation sample" - }, - { - "code": 6035, - "name": "InvalidLookupTimestamp", - "msg": "Invalid lookup timestamp" - }, - { - "code": 6036, - "name": "BitmapExtensionAccountIsNotProvided", - "msg": "Bitmap extension account is not provided" - }, - { - "code": 6037, - "name": "CannotFindNonZeroLiquidityBinArrayId", - "msg": "Cannot find non-zero liquidity binArrayId" - }, - { - "code": 6038, - "name": "BinIdOutOfBound", - "msg": "Bin id out of bound" - }, - { - "code": 6039, - "name": "InsufficientOutAmount", - "msg": "Insufficient amount in for minimum out" - }, - { - "code": 6040, - "name": "InvalidPositionWidth", - "msg": "Invalid position width" - }, - { - "code": 6041, - "name": "ExcessiveFeeUpdate", - "msg": "Excessive fee update" - }, - { - "code": 6042, - "name": "PoolDisabled", - "msg": "Pool disabled" - }, - { - "code": 6043, - "name": "InvalidPoolType", - "msg": "Invalid pool type" - }, - { - "code": 6044, - "name": "ExceedMaxWhitelist", - "msg": "Whitelist for wallet is full" - }, - { - "code": 6045, - "name": "InvalidIndex", - "msg": "Invalid index" - }, - { - "code": 6046, - "name": "RewardNotEnded", - "msg": "Reward not ended" - }, - { - "code": 6047, - "name": "MustWithdrawnIneligibleReward", - "msg": "Must withdraw ineligible reward" - }, - { - "code": 6048, - "name": "UnauthorizedAddress", - "msg": "Unauthorized address" - }, - { - "code": 6049, - "name": "OperatorsAreTheSame", - "msg": "Cannot update because operators are the same" - }, - { - "code": 6050, - "name": "WithdrawToWrongTokenAccount", - "msg": "Withdraw to wrong token account" - }, - { - "code": 6051, - "name": "WrongRentReceiver", - "msg": "Wrong rent receiver" - }, - { - "code": 6052, - "name": "AlreadyPassActivationPoint", - "msg": "Already activated" - }, - { - "code": 6053, - "name": "ExceedMaxSwappedAmount", - "msg": "Swapped amount is exceeded max swapped amount" - }, - { - "code": 6054, - "name": "InvalidStrategyParameters", - "msg": "Invalid strategy parameters" - }, - { - "code": 6055, - "name": "LiquidityLocked", - "msg": "Liquidity locked" - }, - { - "code": 6056, - "name": "BinRangeIsNotEmpty", - "msg": "Bin range is not empty" - }, - { - "code": 6057, - "name": "NotExactAmountOut", - "msg": "Amount out is not matched with exact amount out" - }, - { - "code": 6058, - "name": "InvalidActivationType", - "msg": "Invalid activation type" - }, - { - "code": 6059, - "name": "InvalidActivationDuration", - "msg": "Invalid activation duration" - }, - { - "code": 6060, - "name": "MissingTokenAmountAsTokenLaunchProof", - "msg": "Missing token amount as token launch owner proof" - }, - { - "code": 6061, - "name": "InvalidQuoteToken", - "msg": "Quote token must be SOL or USDC" - }, - { - "code": 6062, - "name": "InvalidBinStep", - "msg": "Invalid bin step" - }, - { - "code": 6063, - "name": "InvalidBaseFee", - "msg": "Invalid base fee" - }, - { - "code": 6064, - "name": "InvalidPreActivationDuration", - "msg": "Invalid pre-activation duration" - }, - { - "code": 6065, - "name": "AlreadyPassPreActivationSwapPoint", - "msg": "Already pass pre-activation swap point" - } - ], - "metadata": { - "address": "GrAkKfEpTKQuVHG2Y97Y2FF4i7y7Q5AHLK94JBy7Y5yv" - } -} \ No newline at end of file diff --git a/target/types/lb_clmm.ts b/target/types/lb_clmm.ts deleted file mode 100644 index 90ddeb7c..00000000 --- a/target/types/lb_clmm.ts +++ /dev/null @@ -1,10189 +0,0 @@ -export type LbClmm = { - "version": "0.8.2", - "name": "lb_clmm", - "constants": [ - { - "name": "BASIS_POINT_MAX", - "type": "i32", - "value": "10000" - }, - { - "name": "MAX_BIN_PER_ARRAY", - "type": { - "defined": "usize" - }, - "value": "70" - }, - { - "name": "MAX_BIN_PER_POSITION", - "type": { - "defined": "usize" - }, - "value": "70" - }, - { - "name": "MIN_BIN_ID", - "type": "i32", - "value": "- 443636" - }, - { - "name": "MAX_BIN_ID", - "type": "i32", - "value": "443636" - }, - { - "name": "MAX_FEE_RATE", - "type": "u64", - "value": "100_000_000" - }, - { - "name": "FEE_PRECISION", - "type": "u64", - "value": "1_000_000_000" - }, - { - "name": "MAX_PROTOCOL_SHARE", - "type": "u16", - "value": "2_500" - }, - { - "name": "HOST_FEE_BPS", - "type": "u16", - "value": "2_000" - }, - { - "name": "NUM_REWARDS", - "type": { - "defined": "usize" - }, - "value": "2" - }, - { - "name": "MIN_REWARD_DURATION", - "type": "u64", - "value": "1" - }, - { - "name": "MAX_REWARD_DURATION", - "type": "u64", - "value": "31536000" - }, - { - "name": "EXTENSION_BINARRAY_BITMAP_SIZE", - "type": { - "defined": "usize" - }, - "value": "12" - }, - { - "name": "BIN_ARRAY_BITMAP_SIZE", - "type": "i32", - "value": "512" - }, - { - "name": "MAX_REWARD_BIN_SPLIT", - "type": { - "defined": "usize" - }, - "value": "15" - }, - { - "name": "MAX_BIN_STEP", - "type": "u16", - "value": "400" - }, - { - "name": "MAX_BASE_FEE", - "type": "u128", - "value": "100_000_000" - }, - { - "name": "MIN_BASE_FEE", - "type": "u128", - "value": "100_000" - }, - { - "name": "BIN_ARRAY", - "type": "bytes", - "value": "[98, 105, 110, 95, 97, 114, 114, 97, 121]" - }, - { - "name": "ORACLE", - "type": "bytes", - "value": "[111, 114, 97, 99, 108, 101]" - }, - { - "name": "BIN_ARRAY_BITMAP_SEED", - "type": "bytes", - "value": "[98, 105, 116, 109, 97, 112]" - }, - { - "name": "PRESET_PARAMETER", - "type": "bytes", - "value": "[112, 114, 101, 115, 101, 116, 95, 112, 97, 114, 97, 109, 101, 116, 101, 114]" - }, - { - "name": "POSITION", - "type": "bytes", - "value": "[112, 111, 115, 105, 116, 105, 111, 110]" - } - ], - "instructions": [ - { - "name": "initializeLbPair", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "presetParameter", - "isMut": false, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "activeId", - "type": "i32" - }, - { - "name": "binStep", - "type": "u16" - } - ] - }, - { - "name": "initializeCustomizablePermissionlessLbPair", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "params", - "type": { - "defined": "CustomizableParams" - } - } - ] - }, - { - "name": "initializePermissionLbPair", - "accounts": [ - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ixData", - "type": { - "defined": "InitPermissionPairIx" - } - } - ] - }, - { - "name": "initializeBinArrayBitmapExtension", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "docs": [ - "Initialize an account to store if a bin array is initialized." - ] - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "initializeBinArray", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "index", - "type": "i64" - } - ] - }, - { - "name": "addLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameter" - } - } - ] - }, - { - "name": "addLiquidityByWeight", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByWeight" - } - } - ] - }, - { - "name": "addLiquidityByStrategy", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByStrategy" - } - } - ] - }, - { - "name": "addLiquidityByStrategyOneSide", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByStrategyOneSide" - } - } - ] - }, - { - "name": "addLiquidityOneSide", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityOneSideParameter" - } - } - ] - }, - { - "name": "removeLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "binLiquidityRemoval", - "type": { - "vec": { - "defined": "BinLiquidityReduction" - } - } - } - ] - }, - { - "name": "initializePosition", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": true - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - } - ] - }, - { - "name": "initializePositionPda", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true, - "docs": [ - "owner" - ] - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - } - ] - }, - { - "name": "initializePositionByOperator", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": false - }, - { - "name": "operator", - "isMut": false, - "isSigner": true, - "docs": [ - "operator" - ] - }, - { - "name": "operatorTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "ownerTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - }, - { - "name": "feeOwner", - "type": "publicKey" - }, - { - "name": "lockReleasePoint", - "type": "u64" - } - ] - }, - { - "name": "updatePositionOperator", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "operator", - "type": "publicKey" - } - ] - }, - { - "name": "swap", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountIn", - "type": "u64" - }, - { - "name": "minAmountOut", - "type": "u64" - } - ] - }, - { - "name": "withdrawProtocolFee", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "receiverTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "receiverTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "feeOwner", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountX", - "type": "u64" - }, - { - "name": "amountY", - "type": "u64" - } - ] - }, - { - "name": "initializeReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "rewardDuration", - "type": "u64" - }, - { - "name": "funder", - "type": "publicKey" - } - ] - }, - { - "name": "fundReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "funderTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "amount", - "type": "u64" - }, - { - "name": "carryForward", - "type": "bool" - } - ] - }, - { - "name": "updateRewardFunder", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "newFunder", - "type": "publicKey" - } - ] - }, - { - "name": "updateRewardDuration", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "newDuration", - "type": "u64" - } - ] - }, - { - "name": "claimReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - } - ] - }, - { - "name": "claimFee", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "closePosition", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "updateFeeParameters", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "feeParameter", - "type": { - "defined": "FeeParameter" - } - } - ] - }, - { - "name": "increaseOracleLength", - "accounts": [ - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lengthToAdd", - "type": "u64" - } - ] - }, - { - "name": "initializePresetParameter", - "accounts": [ - { - "name": "presetParameter", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ix", - "type": { - "defined": "InitPresetParametersIx" - } - } - ] - }, - { - "name": "closePresetParameter", - "accounts": [ - { - "name": "presetParameter", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "removeAllLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "togglePairStatus", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "migratePosition", - "accounts": [ - { - "name": "positionV2", - "isMut": true, - "isSigner": true - }, - { - "name": "positionV1", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "migrateBinArray", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "updateFeesAndRewards", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "withdrawIneligibleReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "funderTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - } - ] - }, - { - "name": "setActivationPoint", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - } - ], - "args": [ - { - "name": "activationPoint", - "type": "u64" - } - ] - }, - { - "name": "addLiquidityOneSidePrecise", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "parameter", - "type": { - "defined": "AddLiquiditySingleSidePreciseParameter" - } - } - ] - }, - { - "name": "setPreActivationDuration", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "creator", - "isMut": false, - "isSigner": true - } - ], - "args": [ - { - "name": "preActivationDuration", - "type": "u16" - } - ] - }, - { - "name": "setPreActivationSwapAddress", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "creator", - "isMut": false, - "isSigner": true - } - ], - "args": [ - { - "name": "preActivationSwapAddress", - "type": "publicKey" - } - ] - }, - { - "name": "swapExactOut", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "maxInAmount", - "type": "u64" - }, - { - "name": "outAmount", - "type": "u64" - } - ] - }, - { - "name": "swapWithPriceImpact", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountIn", - "type": "u64" - }, - { - "name": "activeId", - "type": { - "option": "i32" - } - }, - { - "name": "maxPriceImpactBps", - "type": "u16" - } - ] - } - ], - "accounts": [ - { - "name": "binArrayBitmapExtension", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "type": "publicKey" - }, - { - "name": "positiveBinArrayBitmap", - "docs": [ - "Packed initialized bin array state for start_bin_index is positive" - ], - "type": { - "array": [ - { - "array": [ - "u64", - 8 - ] - }, - 12 - ] - } - }, - { - "name": "negativeBinArrayBitmap", - "docs": [ - "Packed initialized bin array state for start_bin_index is negative" - ], - "type": { - "array": [ - { - "array": [ - "u64", - 8 - ] - }, - 12 - ] - } - } - ] - } - }, - { - "name": "binArray", - "docs": [ - "An account to contain a range of bin. For example: Bin 100 <-> 200.", - "For example:", - "BinArray index: 0 contains bin 0 <-> 599", - "index: 2 contains bin 600 <-> 1199, ..." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "index", - "type": "i64" - }, - { - "name": "version", - "docs": [ - "Version of binArray" - ], - "type": "u8" - }, - { - "name": "padding", - "type": { - "array": [ - "u8", - 7 - ] - } - }, - { - "name": "lbPair", - "type": "publicKey" - }, - { - "name": "bins", - "type": { - "array": [ - { - "defined": "Bin" - }, - 70 - ] - } - } - ] - } - }, - { - "name": "lbPair", - "type": { - "kind": "struct", - "fields": [ - { - "name": "parameters", - "type": { - "defined": "StaticParameters" - } - }, - { - "name": "vParameters", - "type": { - "defined": "VariableParameters" - } - }, - { - "name": "bumpSeed", - "type": { - "array": [ - "u8", - 1 - ] - } - }, - { - "name": "binStepSeed", - "docs": [ - "Bin step signer seed" - ], - "type": { - "array": [ - "u8", - 2 - ] - } - }, - { - "name": "pairType", - "docs": [ - "Type of the pair" - ], - "type": "u8" - }, - { - "name": "activeId", - "docs": [ - "Active bin id" - ], - "type": "i32" - }, - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "status", - "docs": [ - "Status of the pair. Check PairStatus enum." - ], - "type": "u8" - }, - { - "name": "requireBaseFactorSeed", - "docs": [ - "Require base factor seed" - ], - "type": "u8" - }, - { - "name": "baseFactorSeed", - "docs": [ - "Base factor seed" - ], - "type": { - "array": [ - "u8", - 2 - ] - } - }, - { - "name": "activationType", - "docs": [ - "Activation type" - ], - "type": "u8" - }, - { - "name": "padding0", - "docs": [ - "padding 0" - ], - "type": "u8" - }, - { - "name": "tokenXMint", - "docs": [ - "Token X mint" - ], - "type": "publicKey" - }, - { - "name": "tokenYMint", - "docs": [ - "Token Y mint" - ], - "type": "publicKey" - }, - { - "name": "reserveX", - "docs": [ - "LB token X vault" - ], - "type": "publicKey" - }, - { - "name": "reserveY", - "docs": [ - "LB token Y vault" - ], - "type": "publicKey" - }, - { - "name": "protocolFee", - "docs": [ - "Uncollected protocol fee" - ], - "type": { - "defined": "ProtocolFee" - } - }, - { - "name": "padding1", - "docs": [ - "_padding_1, previous Fee owner, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "RewardInfo" - }, - 2 - ] - } - }, - { - "name": "oracle", - "docs": [ - "Oracle pubkey" - ], - "type": "publicKey" - }, - { - "name": "binArrayBitmap", - "docs": [ - "Packed initialized bin array state" - ], - "type": { - "array": [ - "u64", - 16 - ] - } - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last time the pool fee parameter was updated" - ], - "type": "i64" - }, - { - "name": "padding2", - "docs": [ - "_padding_2, previous whitelisted_wallet, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "preActivationSwapAddress", - "docs": [ - "Address allowed to swap when the current point is greater than or equal to the pre-activation point. The pre-activation point is calculated as `activation_point - pre_activation_duration`." - ], - "type": "publicKey" - }, - { - "name": "baseKey", - "docs": [ - "Base keypair. Only required for permission pair" - ], - "type": "publicKey" - }, - { - "name": "activationPoint", - "docs": [ - "Time point to enable the pair. Only applicable for permission pair." - ], - "type": "u64" - }, - { - "name": "preActivationDuration", - "docs": [ - "Duration before activation point. Used to calculate pre-activation point for pre_activation_swap_address" - ], - "type": "u64" - }, - { - "name": "padding3", - "docs": [ - "_padding 3 is reclaimed free space from swap_cap_deactivate_point and swap_cap_amount before, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 8 - ] - } - }, - { - "name": "padding4", - "docs": [ - "_padding_4, previous lock_duration, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": "u64" - }, - { - "name": "creator", - "docs": [ - "Pool creator" - ], - "type": "publicKey" - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 24 - ] - } - } - ] - } - }, - { - "name": "oracle", - "type": { - "kind": "struct", - "fields": [ - { - "name": "idx", - "docs": [ - "Index of latest observation" - ], - "type": "u64" - }, - { - "name": "activeSize", - "docs": [ - "Size of active sample. Active sample is initialized observation." - ], - "type": "u64" - }, - { - "name": "length", - "docs": [ - "Number of observations" - ], - "type": "u64" - } - ] - } - }, - { - "name": "position", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "docs": [ - "The LB pair of this position" - ], - "type": "publicKey" - }, - { - "name": "owner", - "docs": [ - "Owner of the position. Client rely on this to to fetch their positions." - ], - "type": "publicKey" - }, - { - "name": "liquidityShares", - "docs": [ - "Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept." - ], - "type": { - "array": [ - "u64", - 70 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "UserRewardInfo" - }, - 70 - ] - } - }, - { - "name": "feeInfos", - "docs": [ - "Swap fee to claim information" - ], - "type": { - "array": [ - { - "defined": "FeeInfo" - }, - 70 - ] - } - }, - { - "name": "lowerBinId", - "docs": [ - "Lower bin ID" - ], - "type": "i32" - }, - { - "name": "upperBinId", - "docs": [ - "Upper bin ID" - ], - "type": "i32" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last updated timestamp" - ], - "type": "i64" - }, - { - "name": "totalClaimedFeeXAmount", - "docs": [ - "Total claimed token fee X" - ], - "type": "u64" - }, - { - "name": "totalClaimedFeeYAmount", - "docs": [ - "Total claimed token fee Y" - ], - "type": "u64" - }, - { - "name": "totalClaimedRewards", - "docs": [ - "Total claimed rewards" - ], - "type": { - "array": [ - "u64", - 2 - ] - } - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 160 - ] - } - } - ] - } - }, - { - "name": "positionV2", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "docs": [ - "The LB pair of this position" - ], - "type": "publicKey" - }, - { - "name": "owner", - "docs": [ - "Owner of the position. Client rely on this to to fetch their positions." - ], - "type": "publicKey" - }, - { - "name": "liquidityShares", - "docs": [ - "Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept." - ], - "type": { - "array": [ - "u128", - 70 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "UserRewardInfo" - }, - 70 - ] - } - }, - { - "name": "feeInfos", - "docs": [ - "Swap fee to claim information" - ], - "type": { - "array": [ - { - "defined": "FeeInfo" - }, - 70 - ] - } - }, - { - "name": "lowerBinId", - "docs": [ - "Lower bin ID" - ], - "type": "i32" - }, - { - "name": "upperBinId", - "docs": [ - "Upper bin ID" - ], - "type": "i32" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last updated timestamp" - ], - "type": "i64" - }, - { - "name": "totalClaimedFeeXAmount", - "docs": [ - "Total claimed token fee X" - ], - "type": "u64" - }, - { - "name": "totalClaimedFeeYAmount", - "docs": [ - "Total claimed token fee Y" - ], - "type": "u64" - }, - { - "name": "totalClaimedRewards", - "docs": [ - "Total claimed rewards" - ], - "type": { - "array": [ - "u64", - 2 - ] - } - }, - { - "name": "operator", - "docs": [ - "Operator of position" - ], - "type": "publicKey" - }, - { - "name": "lockReleasePoint", - "docs": [ - "Time point which the locked liquidity can be withdraw" - ], - "type": "u64" - }, - { - "name": "padding0", - "docs": [ - "_padding_0, previous subjected_to_bootstrap_liquidity_locking, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": "u8" - }, - { - "name": "feeOwner", - "docs": [ - "Address is able to claim fee in this position, only valid for bootstrap_liquidity_position" - ], - "type": "publicKey" - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 87 - ] - } - } - ] - } - }, - { - "name": "presetParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - } - ] - } - } - ], - "types": [ - { - "name": "InitPresetParametersIx", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - } - ] - } - }, - { - "name": "FeeParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Base factor for base fee rate" - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameterByStrategyOneSide", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amount", - "docs": [ - "Amount of X token or Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "strategyParameters", - "docs": [ - "strategy parameters" - ], - "type": { - "defined": "StrategyParameters" - } - } - ] - } - }, - { - "name": "LiquidityParameterByStrategy", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "strategyParameters", - "docs": [ - "strategy parameters" - ], - "type": { - "defined": "StrategyParameters" - } - } - ] - } - }, - { - "name": "StrategyParameters", - "type": { - "kind": "struct", - "fields": [ - { - "name": "minBinId", - "docs": [ - "min bin id" - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "max bin id" - ], - "type": "i32" - }, - { - "name": "strategyType", - "docs": [ - "strategy type" - ], - "type": { - "defined": "StrategyType" - } - }, - { - "name": "parameteres", - "docs": [ - "parameters" - ], - "type": { - "array": [ - "u8", - 64 - ] - } - } - ] - } - }, - { - "name": "LiquidityOneSideParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amount", - "docs": [ - "Amount of X token or Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistributionByWeight" - } - } - } - ] - } - }, - { - "name": "BinLiquidityDistributionByWeight", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "docs": [ - "Define the bin ID wish to deposit to." - ], - "type": "i32" - }, - { - "name": "weight", - "docs": [ - "weight of liquidity distributed for this bin id" - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameterByWeight", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistributionByWeight" - } - } - } - ] - } - }, - { - "name": "AddLiquiditySingleSidePreciseParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bins", - "type": { - "vec": { - "defined": "CompressedBinDepositAmount" - } - } - }, - { - "name": "decompressMultiplier", - "type": "u64" - } - ] - } - }, - { - "name": "CompressedBinDepositAmount", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "type": "i32" - }, - { - "name": "amount", - "type": "u32" - } - ] - } - }, - { - "name": "BinLiquidityDistribution", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "docs": [ - "Define the bin ID wish to deposit to." - ], - "type": "i32" - }, - { - "name": "distributionX", - "docs": [ - "DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin." - ], - "type": "u16" - }, - { - "name": "distributionY", - "docs": [ - "DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin." - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistribution" - } - } - } - ] - } - }, - { - "name": "CustomizableParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activeId", - "docs": [ - "Pool price" - ], - "type": "i32" - }, - { - "name": "binStep", - "docs": [ - "Bin step" - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Base factor" - ], - "type": "u16" - }, - { - "name": "activationType", - "docs": [ - "Activation type. 0 = Slot, 1 = Time. Check ActivationType enum" - ], - "type": "u8" - }, - { - "name": "hasAlphaVault", - "docs": [ - "Whether the pool has an alpha vault" - ], - "type": "bool" - }, - { - "name": "activationPoint", - "docs": [ - "Decide when does the pool start trade. None = Now" - ], - "type": { - "option": "u64" - } - }, - { - "name": "padding", - "docs": [ - "Padding, for future use" - ], - "type": { - "array": [ - "u8", - 64 - ] - } - } - ] - } - }, - { - "name": "InitPermissionPairIx", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activeId", - "type": "i32" - }, - { - "name": "binStep", - "type": "u16" - }, - { - "name": "baseFactor", - "type": "u16" - }, - { - "name": "minBinId", - "type": "i32" - }, - { - "name": "maxBinId", - "type": "i32" - }, - { - "name": "lockDuration", - "type": "u64" - }, - { - "name": "activationType", - "type": "u8" - } - ] - } - }, - { - "name": "BinLiquidityReduction", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "type": "i32" - }, - { - "name": "bpsToRemove", - "type": "u16" - } - ] - } - }, - { - "name": "Bin", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of token X in the bin. This already excluded protocol fees." - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of token Y in the bin. This already excluded protocol fees." - ], - "type": "u64" - }, - { - "name": "price", - "docs": [ - "Bin price" - ], - "type": "u128" - }, - { - "name": "liquiditySupply", - "docs": [ - "Liquidities of the bin. This is the same as LP mint supply. q-number" - ], - "type": "u128" - }, - { - "name": "rewardPerTokenStored", - "docs": [ - "reward_a_per_token_stored" - ], - "type": { - "array": [ - "u128", - 2 - ] - } - }, - { - "name": "feeAmountXPerTokenStored", - "docs": [ - "Swap fee amount of token X per liquidity deposited." - ], - "type": "u128" - }, - { - "name": "feeAmountYPerTokenStored", - "docs": [ - "Swap fee amount of token Y per liquidity deposited." - ], - "type": "u128" - }, - { - "name": "amountXIn", - "docs": [ - "Total token X swap into the bin. Only used for tracking purpose." - ], - "type": "u128" - }, - { - "name": "amountYIn", - "docs": [ - "Total token Y swap into he bin. Only used for tracking purpose." - ], - "type": "u128" - } - ] - } - }, - { - "name": "ProtocolFee", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "type": "u64" - }, - { - "name": "amountY", - "type": "u64" - } - ] - } - }, - { - "name": "RewardInfo", - "docs": [ - "Stores the state relevant for tracking liquidity mining rewards" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "mint", - "docs": [ - "Reward token mint." - ], - "type": "publicKey" - }, - { - "name": "vault", - "docs": [ - "Reward vault token account." - ], - "type": "publicKey" - }, - { - "name": "funder", - "docs": [ - "Authority account that allows to fund rewards" - ], - "type": "publicKey" - }, - { - "name": "rewardDuration", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u64" - }, - { - "name": "rewardDurationEnd", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u64" - }, - { - "name": "rewardRate", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u128" - }, - { - "name": "lastUpdateTime", - "docs": [ - "The last time reward states were updated." - ], - "type": "u64" - }, - { - "name": "cumulativeSecondsWithEmptyLiquidityReward", - "docs": [ - "Accumulated seconds where when farm distribute rewards, but the bin is empty. The reward will be accumulated for next reward time window." - ], - "type": "u64" - } - ] - } - }, - { - "name": "Observation", - "type": { - "kind": "struct", - "fields": [ - { - "name": "cumulativeActiveBinId", - "docs": [ - "Cumulative active bin ID" - ], - "type": "i128" - }, - { - "name": "createdAt", - "docs": [ - "Observation sample created timestamp" - ], - "type": "i64" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Observation sample last updated timestamp" - ], - "type": "i64" - } - ] - } - }, - { - "name": "StaticParameters", - "docs": [ - "Parameter that set by the protocol" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - }, - { - "name": "padding", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 6 - ] - } - } - ] - } - }, - { - "name": "VariableParameters", - "docs": [ - "Parameters that changes based on dynamic of the market" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "volatilityAccumulator", - "docs": [ - "Volatility accumulator measure the number of bin crossed since reference bin ID. Normally (without filter period taken into consideration), reference bin ID is the active bin of last swap.", - "It affects the variable fee rate" - ], - "type": "u32" - }, - { - "name": "volatilityReference", - "docs": [ - "Volatility reference is decayed volatility accumulator. It is always <= volatility_accumulator" - ], - "type": "u32" - }, - { - "name": "indexReference", - "docs": [ - "Active bin id of last swap." - ], - "type": "i32" - }, - { - "name": "padding", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 4 - ] - } - }, - { - "name": "lastUpdateTimestamp", - "docs": [ - "Last timestamp the variable parameters was updated" - ], - "type": "i64" - }, - { - "name": "padding1", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 8 - ] - } - } - ] - } - }, - { - "name": "FeeInfo", - "type": { - "kind": "struct", - "fields": [ - { - "name": "feeXPerTokenComplete", - "type": "u128" - }, - { - "name": "feeYPerTokenComplete", - "type": "u128" - }, - { - "name": "feeXPending", - "type": "u64" - }, - { - "name": "feeYPending", - "type": "u64" - } - ] - } - }, - { - "name": "UserRewardInfo", - "type": { - "kind": "struct", - "fields": [ - { - "name": "rewardPerTokenCompletes", - "type": { - "array": [ - "u128", - 2 - ] - } - }, - { - "name": "rewardPendings", - "type": { - "array": [ - "u64", - 2 - ] - } - } - ] - } - }, - { - "name": "StrategyType", - "type": { - "kind": "enum", - "variants": [ - { - "name": "SpotOneSide" - }, - { - "name": "CurveOneSide" - }, - { - "name": "BidAskOneSide" - }, - { - "name": "SpotBalanced" - }, - { - "name": "CurveBalanced" - }, - { - "name": "BidAskBalanced" - }, - { - "name": "SpotImBalanced" - }, - { - "name": "CurveImBalanced" - }, - { - "name": "BidAskImBalanced" - } - ] - } - }, - { - "name": "Rounding", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Up" - }, - { - "name": "Down" - } - ] - } - }, - { - "name": "ActivationType", - "docs": [ - "Type of the activation" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Slot" - }, - { - "name": "Timestamp" - } - ] - } - }, - { - "name": "LayoutVersion", - "docs": [ - "Layout version" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "V0" - }, - { - "name": "V1" - } - ] - } - }, - { - "name": "PairType", - "docs": [ - "Type of the Pair. 0 = Permissionless, 1 = Permission, 2 = CustomizablePermissionless" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Permissionless" - }, - { - "name": "Permission" - }, - { - "name": "CustomizablePermissionless" - } - ] - } - }, - { - "name": "PairStatus", - "docs": [ - "Pair status. 0 = Enabled, 1 = Disabled. Putting 0 as enabled for backward compatibility." - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Enabled" - }, - { - "name": "Disabled" - } - ] - } - } - ], - "events": [ - { - "name": "CompositionFee", - "fields": [ - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "binId", - "type": "i16", - "index": false - }, - { - "name": "tokenXFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "tokenYFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "protocolTokenXFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "protocolTokenYFeeAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "AddLiquidity", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "amounts", - "type": { - "array": [ - "u64", - 2 - ] - }, - "index": false - }, - { - "name": "activeBinId", - "type": "i32", - "index": false - } - ] - }, - { - "name": "RemoveLiquidity", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "amounts", - "type": { - "array": [ - "u64", - 2 - ] - }, - "index": false - }, - { - "name": "activeBinId", - "type": "i32", - "index": false - } - ] - }, - { - "name": "Swap", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "startBinId", - "type": "i32", - "index": false - }, - { - "name": "endBinId", - "type": "i32", - "index": false - }, - { - "name": "amountIn", - "type": "u64", - "index": false - }, - { - "name": "amountOut", - "type": "u64", - "index": false - }, - { - "name": "swapForY", - "type": "bool", - "index": false - }, - { - "name": "fee", - "type": "u64", - "index": false - }, - { - "name": "protocolFee", - "type": "u64", - "index": false - }, - { - "name": "feeBps", - "type": "u128", - "index": false - }, - { - "name": "hostFee", - "type": "u64", - "index": false - } - ] - }, - { - "name": "ClaimReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "totalReward", - "type": "u64", - "index": false - } - ] - }, - { - "name": "FundReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "funder", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "amount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "InitializeReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardMint", - "type": "publicKey", - "index": false - }, - { - "name": "funder", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "rewardDuration", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdateRewardDuration", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "oldRewardDuration", - "type": "u64", - "index": false - }, - { - "name": "newRewardDuration", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdateRewardFunder", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "oldFunder", - "type": "publicKey", - "index": false - }, - { - "name": "newFunder", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "PositionClose", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "ClaimFee", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - }, - { - "name": "feeX", - "type": "u64", - "index": false - }, - { - "name": "feeY", - "type": "u64", - "index": false - } - ] - }, - { - "name": "LbPairCreate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "binStep", - "type": "u16", - "index": false - }, - { - "name": "tokenX", - "type": "publicKey", - "index": false - }, - { - "name": "tokenY", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "PositionCreate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "FeeParameterUpdate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "protocolShare", - "type": "u16", - "index": false - }, - { - "name": "baseFactor", - "type": "u16", - "index": false - } - ] - }, - { - "name": "IncreaseObservation", - "fields": [ - { - "name": "oracle", - "type": "publicKey", - "index": false - }, - { - "name": "newObservationLength", - "type": "u64", - "index": false - } - ] - }, - { - "name": "WithdrawIneligibleReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardMint", - "type": "publicKey", - "index": false - }, - { - "name": "amount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdatePositionOperator", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "oldOperator", - "type": "publicKey", - "index": false - }, - { - "name": "newOperator", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "UpdatePositionLockReleasePoint", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "currentPoint", - "type": "u64", - "index": false - }, - { - "name": "newLockReleasePoint", - "type": "u64", - "index": false - }, - { - "name": "oldLockReleasePoint", - "type": "u64", - "index": false - }, - { - "name": "sender", - "type": "publicKey", - "index": false - } - ] - } - ], - "errors": [ - { - "code": 6000, - "name": "InvalidStartBinIndex", - "msg": "Invalid start bin index" - }, - { - "code": 6001, - "name": "InvalidBinId", - "msg": "Invalid bin id" - }, - { - "code": 6002, - "name": "InvalidInput", - "msg": "Invalid input data" - }, - { - "code": 6003, - "name": "ExceededAmountSlippageTolerance", - "msg": "Exceeded amount slippage tolerance" - }, - { - "code": 6004, - "name": "ExceededBinSlippageTolerance", - "msg": "Exceeded bin slippage tolerance" - }, - { - "code": 6005, - "name": "CompositionFactorFlawed", - "msg": "Composition factor flawed" - }, - { - "code": 6006, - "name": "NonPresetBinStep", - "msg": "Non preset bin step" - }, - { - "code": 6007, - "name": "ZeroLiquidity", - "msg": "Zero liquidity" - }, - { - "code": 6008, - "name": "InvalidPosition", - "msg": "Invalid position" - }, - { - "code": 6009, - "name": "BinArrayNotFound", - "msg": "Bin array not found" - }, - { - "code": 6010, - "name": "InvalidTokenMint", - "msg": "Invalid token mint" - }, - { - "code": 6011, - "name": "InvalidAccountForSingleDeposit", - "msg": "Invalid account for single deposit" - }, - { - "code": 6012, - "name": "PairInsufficientLiquidity", - "msg": "Pair insufficient liquidity" - }, - { - "code": 6013, - "name": "InvalidFeeOwner", - "msg": "Invalid fee owner" - }, - { - "code": 6014, - "name": "InvalidFeeWithdrawAmount", - "msg": "Invalid fee withdraw amount" - }, - { - "code": 6015, - "name": "InvalidAdmin", - "msg": "Invalid admin" - }, - { - "code": 6016, - "name": "IdenticalFeeOwner", - "msg": "Identical fee owner" - }, - { - "code": 6017, - "name": "InvalidBps", - "msg": "Invalid basis point" - }, - { - "code": 6018, - "name": "MathOverflow", - "msg": "Math operation overflow" - }, - { - "code": 6019, - "name": "TypeCastFailed", - "msg": "Type cast error" - }, - { - "code": 6020, - "name": "InvalidRewardIndex", - "msg": "Invalid reward index" - }, - { - "code": 6021, - "name": "InvalidRewardDuration", - "msg": "Invalid reward duration" - }, - { - "code": 6022, - "name": "RewardInitialized", - "msg": "Reward already initialized" - }, - { - "code": 6023, - "name": "RewardUninitialized", - "msg": "Reward not initialized" - }, - { - "code": 6024, - "name": "IdenticalFunder", - "msg": "Identical funder" - }, - { - "code": 6025, - "name": "RewardCampaignInProgress", - "msg": "Reward campaign in progress" - }, - { - "code": 6026, - "name": "IdenticalRewardDuration", - "msg": "Reward duration is the same" - }, - { - "code": 6027, - "name": "InvalidBinArray", - "msg": "Invalid bin array" - }, - { - "code": 6028, - "name": "NonContinuousBinArrays", - "msg": "Bin arrays must be continuous" - }, - { - "code": 6029, - "name": "InvalidRewardVault", - "msg": "Invalid reward vault" - }, - { - "code": 6030, - "name": "NonEmptyPosition", - "msg": "Position is not empty" - }, - { - "code": 6031, - "name": "UnauthorizedAccess", - "msg": "Unauthorized access" - }, - { - "code": 6032, - "name": "InvalidFeeParameter", - "msg": "Invalid fee parameter" - }, - { - "code": 6033, - "name": "MissingOracle", - "msg": "Missing oracle account" - }, - { - "code": 6034, - "name": "InsufficientSample", - "msg": "Insufficient observation sample" - }, - { - "code": 6035, - "name": "InvalidLookupTimestamp", - "msg": "Invalid lookup timestamp" - }, - { - "code": 6036, - "name": "BitmapExtensionAccountIsNotProvided", - "msg": "Bitmap extension account is not provided" - }, - { - "code": 6037, - "name": "CannotFindNonZeroLiquidityBinArrayId", - "msg": "Cannot find non-zero liquidity binArrayId" - }, - { - "code": 6038, - "name": "BinIdOutOfBound", - "msg": "Bin id out of bound" - }, - { - "code": 6039, - "name": "InsufficientOutAmount", - "msg": "Insufficient amount in for minimum out" - }, - { - "code": 6040, - "name": "InvalidPositionWidth", - "msg": "Invalid position width" - }, - { - "code": 6041, - "name": "ExcessiveFeeUpdate", - "msg": "Excessive fee update" - }, - { - "code": 6042, - "name": "PoolDisabled", - "msg": "Pool disabled" - }, - { - "code": 6043, - "name": "InvalidPoolType", - "msg": "Invalid pool type" - }, - { - "code": 6044, - "name": "ExceedMaxWhitelist", - "msg": "Whitelist for wallet is full" - }, - { - "code": 6045, - "name": "InvalidIndex", - "msg": "Invalid index" - }, - { - "code": 6046, - "name": "RewardNotEnded", - "msg": "Reward not ended" - }, - { - "code": 6047, - "name": "MustWithdrawnIneligibleReward", - "msg": "Must withdraw ineligible reward" - }, - { - "code": 6048, - "name": "UnauthorizedAddress", - "msg": "Unauthorized address" - }, - { - "code": 6049, - "name": "OperatorsAreTheSame", - "msg": "Cannot update because operators are the same" - }, - { - "code": 6050, - "name": "WithdrawToWrongTokenAccount", - "msg": "Withdraw to wrong token account" - }, - { - "code": 6051, - "name": "WrongRentReceiver", - "msg": "Wrong rent receiver" - }, - { - "code": 6052, - "name": "AlreadyPassActivationPoint", - "msg": "Already activated" - }, - { - "code": 6053, - "name": "ExceedMaxSwappedAmount", - "msg": "Swapped amount is exceeded max swapped amount" - }, - { - "code": 6054, - "name": "InvalidStrategyParameters", - "msg": "Invalid strategy parameters" - }, - { - "code": 6055, - "name": "LiquidityLocked", - "msg": "Liquidity locked" - }, - { - "code": 6056, - "name": "BinRangeIsNotEmpty", - "msg": "Bin range is not empty" - }, - { - "code": 6057, - "name": "NotExactAmountOut", - "msg": "Amount out is not matched with exact amount out" - }, - { - "code": 6058, - "name": "InvalidActivationType", - "msg": "Invalid activation type" - }, - { - "code": 6059, - "name": "InvalidActivationDuration", - "msg": "Invalid activation duration" - }, - { - "code": 6060, - "name": "MissingTokenAmountAsTokenLaunchProof", - "msg": "Missing token amount as token launch owner proof" - }, - { - "code": 6061, - "name": "InvalidQuoteToken", - "msg": "Quote token must be SOL or USDC" - }, - { - "code": 6062, - "name": "InvalidBinStep", - "msg": "Invalid bin step" - }, - { - "code": 6063, - "name": "InvalidBaseFee", - "msg": "Invalid base fee" - }, - { - "code": 6064, - "name": "InvalidPreActivationDuration", - "msg": "Invalid pre-activation duration" - }, - { - "code": 6065, - "name": "AlreadyPassPreActivationSwapPoint", - "msg": "Already pass pre-activation swap point" - } - ] -}; - -export const IDL: LbClmm = { - "version": "0.8.2", - "name": "lb_clmm", - "constants": [ - { - "name": "BASIS_POINT_MAX", - "type": "i32", - "value": "10000" - }, - { - "name": "MAX_BIN_PER_ARRAY", - "type": { - "defined": "usize" - }, - "value": "70" - }, - { - "name": "MAX_BIN_PER_POSITION", - "type": { - "defined": "usize" - }, - "value": "70" - }, - { - "name": "MIN_BIN_ID", - "type": "i32", - "value": "- 443636" - }, - { - "name": "MAX_BIN_ID", - "type": "i32", - "value": "443636" - }, - { - "name": "MAX_FEE_RATE", - "type": "u64", - "value": "100_000_000" - }, - { - "name": "FEE_PRECISION", - "type": "u64", - "value": "1_000_000_000" - }, - { - "name": "MAX_PROTOCOL_SHARE", - "type": "u16", - "value": "2_500" - }, - { - "name": "HOST_FEE_BPS", - "type": "u16", - "value": "2_000" - }, - { - "name": "NUM_REWARDS", - "type": { - "defined": "usize" - }, - "value": "2" - }, - { - "name": "MIN_REWARD_DURATION", - "type": "u64", - "value": "1" - }, - { - "name": "MAX_REWARD_DURATION", - "type": "u64", - "value": "31536000" - }, - { - "name": "EXTENSION_BINARRAY_BITMAP_SIZE", - "type": { - "defined": "usize" - }, - "value": "12" - }, - { - "name": "BIN_ARRAY_BITMAP_SIZE", - "type": "i32", - "value": "512" - }, - { - "name": "MAX_REWARD_BIN_SPLIT", - "type": { - "defined": "usize" - }, - "value": "15" - }, - { - "name": "MAX_BIN_STEP", - "type": "u16", - "value": "400" - }, - { - "name": "MAX_BASE_FEE", - "type": "u128", - "value": "100_000_000" - }, - { - "name": "MIN_BASE_FEE", - "type": "u128", - "value": "100_000" - }, - { - "name": "BIN_ARRAY", - "type": "bytes", - "value": "[98, 105, 110, 95, 97, 114, 114, 97, 121]" - }, - { - "name": "ORACLE", - "type": "bytes", - "value": "[111, 114, 97, 99, 108, 101]" - }, - { - "name": "BIN_ARRAY_BITMAP_SEED", - "type": "bytes", - "value": "[98, 105, 116, 109, 97, 112]" - }, - { - "name": "PRESET_PARAMETER", - "type": "bytes", - "value": "[112, 114, 101, 115, 101, 116, 95, 112, 97, 114, 97, 109, 101, 116, 101, 114]" - }, - { - "name": "POSITION", - "type": "bytes", - "value": "[112, 111, 115, 105, 116, 105, 111, 110]" - } - ], - "instructions": [ - { - "name": "initializeLbPair", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "presetParameter", - "isMut": false, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "activeId", - "type": "i32" - }, - { - "name": "binStep", - "type": "u16" - } - ] - }, - { - "name": "initializeCustomizablePermissionlessLbPair", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "params", - "type": { - "defined": "CustomizableParams" - } - } - ] - }, - { - "name": "initializePermissionLbPair", - "accounts": [ - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "tokenMintX", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenMintY", - "isMut": false, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ixData", - "type": { - "defined": "InitPermissionPairIx" - } - } - ] - }, - { - "name": "initializeBinArrayBitmapExtension", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "docs": [ - "Initialize an account to store if a bin array is initialized." - ] - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "initializeBinArray", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "index", - "type": "i64" - } - ] - }, - { - "name": "addLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameter" - } - } - ] - }, - { - "name": "addLiquidityByWeight", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByWeight" - } - } - ] - }, - { - "name": "addLiquidityByStrategy", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByStrategy" - } - } - ] - }, - { - "name": "addLiquidityByStrategyOneSide", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityParameterByStrategyOneSide" - } - } - ] - }, - { - "name": "addLiquidityOneSide", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "liquidityParameter", - "type": { - "defined": "LiquidityOneSideParameter" - } - } - ] - }, - { - "name": "removeLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "binLiquidityRemoval", - "type": { - "vec": { - "defined": "BinLiquidityReduction" - } - } - } - ] - }, - { - "name": "initializePosition", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": true - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - } - ] - }, - { - "name": "initializePositionPda", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true, - "docs": [ - "owner" - ] - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - } - ] - }, - { - "name": "initializePositionByOperator", - "accounts": [ - { - "name": "payer", - "isMut": true, - "isSigner": true - }, - { - "name": "base", - "isMut": false, - "isSigner": true - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": false - }, - { - "name": "operator", - "isMut": false, - "isSigner": true, - "docs": [ - "operator" - ] - }, - { - "name": "operatorTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "ownerTokenX", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lowerBinId", - "type": "i32" - }, - { - "name": "width", - "type": "i32" - }, - { - "name": "feeOwner", - "type": "publicKey" - }, - { - "name": "lockReleasePoint", - "type": "u64" - } - ] - }, - { - "name": "updatePositionOperator", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "operator", - "type": "publicKey" - } - ] - }, - { - "name": "swap", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountIn", - "type": "u64" - }, - { - "name": "minAmountOut", - "type": "u64" - } - ] - }, - { - "name": "withdrawProtocolFee", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "receiverTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "receiverTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "feeOwner", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountX", - "type": "u64" - }, - { - "name": "amountY", - "type": "u64" - } - ] - }, - { - "name": "initializeReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "rewardDuration", - "type": "u64" - }, - { - "name": "funder", - "type": "publicKey" - } - ] - }, - { - "name": "fundReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "funderTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "amount", - "type": "u64" - }, - { - "name": "carryForward", - "type": "bool" - } - ] - }, - { - "name": "updateRewardFunder", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "newFunder", - "type": "publicKey" - } - ] - }, - { - "name": "updateRewardDuration", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - }, - { - "name": "newDuration", - "type": "u64" - } - ] - }, - { - "name": "claimReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "userTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - } - ] - }, - { - "name": "claimFee", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "closePosition", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "updateFeeParameters", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "feeParameter", - "type": { - "defined": "FeeParameter" - } - } - ] - }, - { - "name": "increaseOracleLength", - "accounts": [ - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "lengthToAdd", - "type": "u64" - } - ] - }, - { - "name": "initializePresetParameter", - "accounts": [ - { - "name": "presetParameter", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rent", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "ix", - "type": { - "defined": "InitPresetParametersIx" - } - } - ] - }, - { - "name": "closePresetParameter", - "accounts": [ - { - "name": "presetParameter", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "removeAllLiquidity", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userTokenX", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenY", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "togglePairStatus", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": false, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "migratePosition", - "accounts": [ - { - "name": "positionV2", - "isMut": true, - "isSigner": true - }, - { - "name": "positionV1", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": true, - "isSigner": true - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "rentReceiver", - "isMut": true, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "migrateBinArray", - "accounts": [ - { - "name": "lbPair", - "isMut": false, - "isSigner": false - } - ], - "args": [] - }, - { - "name": "updateFeesAndRewards", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "owner", - "isMut": false, - "isSigner": true - } - ], - "args": [] - }, - { - "name": "withdrawIneligibleReward", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardVault", - "isMut": true, - "isSigner": false - }, - { - "name": "rewardMint", - "isMut": false, - "isSigner": false - }, - { - "name": "funderTokenAccount", - "isMut": true, - "isSigner": false - }, - { - "name": "funder", - "isMut": false, - "isSigner": true - }, - { - "name": "binArray", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "rewardIndex", - "type": "u64" - } - ] - }, - { - "name": "setActivationPoint", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "admin", - "isMut": true, - "isSigner": true - } - ], - "args": [ - { - "name": "activationPoint", - "type": "u64" - } - ] - }, - { - "name": "addLiquidityOneSidePrecise", - "accounts": [ - { - "name": "position", - "isMut": true, - "isSigner": false - }, - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "userToken", - "isMut": true, - "isSigner": false - }, - { - "name": "reserve", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenMint", - "isMut": false, - "isSigner": false - }, - { - "name": "binArrayLower", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayUpper", - "isMut": true, - "isSigner": false - }, - { - "name": "sender", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "parameter", - "type": { - "defined": "AddLiquiditySingleSidePreciseParameter" - } - } - ] - }, - { - "name": "setPreActivationDuration", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "creator", - "isMut": false, - "isSigner": true - } - ], - "args": [ - { - "name": "preActivationDuration", - "type": "u16" - } - ] - }, - { - "name": "setPreActivationSwapAddress", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "creator", - "isMut": false, - "isSigner": true - } - ], - "args": [ - { - "name": "preActivationSwapAddress", - "type": "publicKey" - } - ] - }, - { - "name": "swapExactOut", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "maxInAmount", - "type": "u64" - }, - { - "name": "outAmount", - "type": "u64" - } - ] - }, - { - "name": "swapWithPriceImpact", - "accounts": [ - { - "name": "lbPair", - "isMut": true, - "isSigner": false - }, - { - "name": "binArrayBitmapExtension", - "isMut": false, - "isSigner": false, - "isOptional": true - }, - { - "name": "reserveX", - "isMut": true, - "isSigner": false - }, - { - "name": "reserveY", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenIn", - "isMut": true, - "isSigner": false - }, - { - "name": "userTokenOut", - "isMut": true, - "isSigner": false - }, - { - "name": "tokenXMint", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYMint", - "isMut": false, - "isSigner": false - }, - { - "name": "oracle", - "isMut": true, - "isSigner": false - }, - { - "name": "hostFeeIn", - "isMut": true, - "isSigner": false, - "isOptional": true - }, - { - "name": "user", - "isMut": false, - "isSigner": true - }, - { - "name": "tokenXProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "tokenYProgram", - "isMut": false, - "isSigner": false - }, - { - "name": "eventAuthority", - "isMut": false, - "isSigner": false - }, - { - "name": "program", - "isMut": false, - "isSigner": false - } - ], - "args": [ - { - "name": "amountIn", - "type": "u64" - }, - { - "name": "activeId", - "type": { - "option": "i32" - } - }, - { - "name": "maxPriceImpactBps", - "type": "u16" - } - ] - } - ], - "accounts": [ - { - "name": "binArrayBitmapExtension", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "type": "publicKey" - }, - { - "name": "positiveBinArrayBitmap", - "docs": [ - "Packed initialized bin array state for start_bin_index is positive" - ], - "type": { - "array": [ - { - "array": [ - "u64", - 8 - ] - }, - 12 - ] - } - }, - { - "name": "negativeBinArrayBitmap", - "docs": [ - "Packed initialized bin array state for start_bin_index is negative" - ], - "type": { - "array": [ - { - "array": [ - "u64", - 8 - ] - }, - 12 - ] - } - } - ] - } - }, - { - "name": "binArray", - "docs": [ - "An account to contain a range of bin. For example: Bin 100 <-> 200.", - "For example:", - "BinArray index: 0 contains bin 0 <-> 599", - "index: 2 contains bin 600 <-> 1199, ..." - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "index", - "type": "i64" - }, - { - "name": "version", - "docs": [ - "Version of binArray" - ], - "type": "u8" - }, - { - "name": "padding", - "type": { - "array": [ - "u8", - 7 - ] - } - }, - { - "name": "lbPair", - "type": "publicKey" - }, - { - "name": "bins", - "type": { - "array": [ - { - "defined": "Bin" - }, - 70 - ] - } - } - ] - } - }, - { - "name": "lbPair", - "type": { - "kind": "struct", - "fields": [ - { - "name": "parameters", - "type": { - "defined": "StaticParameters" - } - }, - { - "name": "vParameters", - "type": { - "defined": "VariableParameters" - } - }, - { - "name": "bumpSeed", - "type": { - "array": [ - "u8", - 1 - ] - } - }, - { - "name": "binStepSeed", - "docs": [ - "Bin step signer seed" - ], - "type": { - "array": [ - "u8", - 2 - ] - } - }, - { - "name": "pairType", - "docs": [ - "Type of the pair" - ], - "type": "u8" - }, - { - "name": "activeId", - "docs": [ - "Active bin id" - ], - "type": "i32" - }, - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "status", - "docs": [ - "Status of the pair. Check PairStatus enum." - ], - "type": "u8" - }, - { - "name": "requireBaseFactorSeed", - "docs": [ - "Require base factor seed" - ], - "type": "u8" - }, - { - "name": "baseFactorSeed", - "docs": [ - "Base factor seed" - ], - "type": { - "array": [ - "u8", - 2 - ] - } - }, - { - "name": "activationType", - "docs": [ - "Activation type" - ], - "type": "u8" - }, - { - "name": "padding0", - "docs": [ - "padding 0" - ], - "type": "u8" - }, - { - "name": "tokenXMint", - "docs": [ - "Token X mint" - ], - "type": "publicKey" - }, - { - "name": "tokenYMint", - "docs": [ - "Token Y mint" - ], - "type": "publicKey" - }, - { - "name": "reserveX", - "docs": [ - "LB token X vault" - ], - "type": "publicKey" - }, - { - "name": "reserveY", - "docs": [ - "LB token Y vault" - ], - "type": "publicKey" - }, - { - "name": "protocolFee", - "docs": [ - "Uncollected protocol fee" - ], - "type": { - "defined": "ProtocolFee" - } - }, - { - "name": "padding1", - "docs": [ - "_padding_1, previous Fee owner, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "RewardInfo" - }, - 2 - ] - } - }, - { - "name": "oracle", - "docs": [ - "Oracle pubkey" - ], - "type": "publicKey" - }, - { - "name": "binArrayBitmap", - "docs": [ - "Packed initialized bin array state" - ], - "type": { - "array": [ - "u64", - 16 - ] - } - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last time the pool fee parameter was updated" - ], - "type": "i64" - }, - { - "name": "padding2", - "docs": [ - "_padding_2, previous whitelisted_wallet, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 32 - ] - } - }, - { - "name": "preActivationSwapAddress", - "docs": [ - "Address allowed to swap when the current point is greater than or equal to the pre-activation point. The pre-activation point is calculated as `activation_point - pre_activation_duration`." - ], - "type": "publicKey" - }, - { - "name": "baseKey", - "docs": [ - "Base keypair. Only required for permission pair" - ], - "type": "publicKey" - }, - { - "name": "activationPoint", - "docs": [ - "Time point to enable the pair. Only applicable for permission pair." - ], - "type": "u64" - }, - { - "name": "preActivationDuration", - "docs": [ - "Duration before activation point. Used to calculate pre-activation point for pre_activation_swap_address" - ], - "type": "u64" - }, - { - "name": "padding3", - "docs": [ - "_padding 3 is reclaimed free space from swap_cap_deactivate_point and swap_cap_amount before, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": { - "array": [ - "u8", - 8 - ] - } - }, - { - "name": "padding4", - "docs": [ - "_padding_4, previous lock_duration, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": "u64" - }, - { - "name": "creator", - "docs": [ - "Pool creator" - ], - "type": "publicKey" - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 24 - ] - } - } - ] - } - }, - { - "name": "oracle", - "type": { - "kind": "struct", - "fields": [ - { - "name": "idx", - "docs": [ - "Index of latest observation" - ], - "type": "u64" - }, - { - "name": "activeSize", - "docs": [ - "Size of active sample. Active sample is initialized observation." - ], - "type": "u64" - }, - { - "name": "length", - "docs": [ - "Number of observations" - ], - "type": "u64" - } - ] - } - }, - { - "name": "position", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "docs": [ - "The LB pair of this position" - ], - "type": "publicKey" - }, - { - "name": "owner", - "docs": [ - "Owner of the position. Client rely on this to to fetch their positions." - ], - "type": "publicKey" - }, - { - "name": "liquidityShares", - "docs": [ - "Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept." - ], - "type": { - "array": [ - "u64", - 70 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "UserRewardInfo" - }, - 70 - ] - } - }, - { - "name": "feeInfos", - "docs": [ - "Swap fee to claim information" - ], - "type": { - "array": [ - { - "defined": "FeeInfo" - }, - 70 - ] - } - }, - { - "name": "lowerBinId", - "docs": [ - "Lower bin ID" - ], - "type": "i32" - }, - { - "name": "upperBinId", - "docs": [ - "Upper bin ID" - ], - "type": "i32" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last updated timestamp" - ], - "type": "i64" - }, - { - "name": "totalClaimedFeeXAmount", - "docs": [ - "Total claimed token fee X" - ], - "type": "u64" - }, - { - "name": "totalClaimedFeeYAmount", - "docs": [ - "Total claimed token fee Y" - ], - "type": "u64" - }, - { - "name": "totalClaimedRewards", - "docs": [ - "Total claimed rewards" - ], - "type": { - "array": [ - "u64", - 2 - ] - } - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 160 - ] - } - } - ] - } - }, - { - "name": "positionV2", - "type": { - "kind": "struct", - "fields": [ - { - "name": "lbPair", - "docs": [ - "The LB pair of this position" - ], - "type": "publicKey" - }, - { - "name": "owner", - "docs": [ - "Owner of the position. Client rely on this to to fetch their positions." - ], - "type": "publicKey" - }, - { - "name": "liquidityShares", - "docs": [ - "Liquidity shares of this position in bins (lower_bin_id <-> upper_bin_id). This is the same as LP concept." - ], - "type": { - "array": [ - "u128", - 70 - ] - } - }, - { - "name": "rewardInfos", - "docs": [ - "Farming reward information" - ], - "type": { - "array": [ - { - "defined": "UserRewardInfo" - }, - 70 - ] - } - }, - { - "name": "feeInfos", - "docs": [ - "Swap fee to claim information" - ], - "type": { - "array": [ - { - "defined": "FeeInfo" - }, - 70 - ] - } - }, - { - "name": "lowerBinId", - "docs": [ - "Lower bin ID" - ], - "type": "i32" - }, - { - "name": "upperBinId", - "docs": [ - "Upper bin ID" - ], - "type": "i32" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Last updated timestamp" - ], - "type": "i64" - }, - { - "name": "totalClaimedFeeXAmount", - "docs": [ - "Total claimed token fee X" - ], - "type": "u64" - }, - { - "name": "totalClaimedFeeYAmount", - "docs": [ - "Total claimed token fee Y" - ], - "type": "u64" - }, - { - "name": "totalClaimedRewards", - "docs": [ - "Total claimed rewards" - ], - "type": { - "array": [ - "u64", - 2 - ] - } - }, - { - "name": "operator", - "docs": [ - "Operator of position" - ], - "type": "publicKey" - }, - { - "name": "lockReleasePoint", - "docs": [ - "Time point which the locked liquidity can be withdraw" - ], - "type": "u64" - }, - { - "name": "padding0", - "docs": [ - "_padding_0, previous subjected_to_bootstrap_liquidity_locking, BE CAREFUL FOR TOMBSTONE WHEN REUSE !!" - ], - "type": "u8" - }, - { - "name": "feeOwner", - "docs": [ - "Address is able to claim fee in this position, only valid for bootstrap_liquidity_position" - ], - "type": "publicKey" - }, - { - "name": "reserved", - "docs": [ - "Reserved space for future use" - ], - "type": { - "array": [ - "u8", - 87 - ] - } - } - ] - } - }, - { - "name": "presetParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - } - ] - } - } - ], - "types": [ - { - "name": "InitPresetParametersIx", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binStep", - "docs": [ - "Bin step. Represent the price increment / decrement." - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - } - ] - } - }, - { - "name": "FeeParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Base factor for base fee rate" - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameterByStrategyOneSide", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amount", - "docs": [ - "Amount of X token or Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "strategyParameters", - "docs": [ - "strategy parameters" - ], - "type": { - "defined": "StrategyParameters" - } - } - ] - } - }, - { - "name": "LiquidityParameterByStrategy", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "strategyParameters", - "docs": [ - "strategy parameters" - ], - "type": { - "defined": "StrategyParameters" - } - } - ] - } - }, - { - "name": "StrategyParameters", - "type": { - "kind": "struct", - "fields": [ - { - "name": "minBinId", - "docs": [ - "min bin id" - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "max bin id" - ], - "type": "i32" - }, - { - "name": "strategyType", - "docs": [ - "strategy type" - ], - "type": { - "defined": "StrategyType" - } - }, - { - "name": "parameteres", - "docs": [ - "parameters" - ], - "type": { - "array": [ - "u8", - 64 - ] - } - } - ] - } - }, - { - "name": "LiquidityOneSideParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amount", - "docs": [ - "Amount of X token or Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistributionByWeight" - } - } - } - ] - } - }, - { - "name": "BinLiquidityDistributionByWeight", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "docs": [ - "Define the bin ID wish to deposit to." - ], - "type": "i32" - }, - { - "name": "weight", - "docs": [ - "weight of liquidity distributed for this bin id" - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameterByWeight", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "activeId", - "docs": [ - "Active bin that integrator observe off-chain" - ], - "type": "i32" - }, - { - "name": "maxActiveBinSlippage", - "docs": [ - "max active bin slippage allowed" - ], - "type": "i32" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistributionByWeight" - } - } - } - ] - } - }, - { - "name": "AddLiquiditySingleSidePreciseParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "bins", - "type": { - "vec": { - "defined": "CompressedBinDepositAmount" - } - } - }, - { - "name": "decompressMultiplier", - "type": "u64" - } - ] - } - }, - { - "name": "CompressedBinDepositAmount", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "type": "i32" - }, - { - "name": "amount", - "type": "u32" - } - ] - } - }, - { - "name": "BinLiquidityDistribution", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "docs": [ - "Define the bin ID wish to deposit to." - ], - "type": "i32" - }, - { - "name": "distributionX", - "docs": [ - "DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin." - ], - "type": "u16" - }, - { - "name": "distributionY", - "docs": [ - "DistributionX (or distributionY) is the percentages of amountX (or amountY) you want to add to each bin." - ], - "type": "u16" - } - ] - } - }, - { - "name": "LiquidityParameter", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of X token to deposit" - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of Y token to deposit" - ], - "type": "u64" - }, - { - "name": "binLiquidityDist", - "docs": [ - "Liquidity distribution to each bins" - ], - "type": { - "vec": { - "defined": "BinLiquidityDistribution" - } - } - } - ] - } - }, - { - "name": "CustomizableParams", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activeId", - "docs": [ - "Pool price" - ], - "type": "i32" - }, - { - "name": "binStep", - "docs": [ - "Bin step" - ], - "type": "u16" - }, - { - "name": "baseFactor", - "docs": [ - "Base factor" - ], - "type": "u16" - }, - { - "name": "activationType", - "docs": [ - "Activation type. 0 = Slot, 1 = Time. Check ActivationType enum" - ], - "type": "u8" - }, - { - "name": "hasAlphaVault", - "docs": [ - "Whether the pool has an alpha vault" - ], - "type": "bool" - }, - { - "name": "activationPoint", - "docs": [ - "Decide when does the pool start trade. None = Now" - ], - "type": { - "option": "u64" - } - }, - { - "name": "padding", - "docs": [ - "Padding, for future use" - ], - "type": { - "array": [ - "u8", - 64 - ] - } - } - ] - } - }, - { - "name": "InitPermissionPairIx", - "type": { - "kind": "struct", - "fields": [ - { - "name": "activeId", - "type": "i32" - }, - { - "name": "binStep", - "type": "u16" - }, - { - "name": "baseFactor", - "type": "u16" - }, - { - "name": "minBinId", - "type": "i32" - }, - { - "name": "maxBinId", - "type": "i32" - }, - { - "name": "lockDuration", - "type": "u64" - }, - { - "name": "activationType", - "type": "u8" - } - ] - } - }, - { - "name": "BinLiquidityReduction", - "type": { - "kind": "struct", - "fields": [ - { - "name": "binId", - "type": "i32" - }, - { - "name": "bpsToRemove", - "type": "u16" - } - ] - } - }, - { - "name": "Bin", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "docs": [ - "Amount of token X in the bin. This already excluded protocol fees." - ], - "type": "u64" - }, - { - "name": "amountY", - "docs": [ - "Amount of token Y in the bin. This already excluded protocol fees." - ], - "type": "u64" - }, - { - "name": "price", - "docs": [ - "Bin price" - ], - "type": "u128" - }, - { - "name": "liquiditySupply", - "docs": [ - "Liquidities of the bin. This is the same as LP mint supply. q-number" - ], - "type": "u128" - }, - { - "name": "rewardPerTokenStored", - "docs": [ - "reward_a_per_token_stored" - ], - "type": { - "array": [ - "u128", - 2 - ] - } - }, - { - "name": "feeAmountXPerTokenStored", - "docs": [ - "Swap fee amount of token X per liquidity deposited." - ], - "type": "u128" - }, - { - "name": "feeAmountYPerTokenStored", - "docs": [ - "Swap fee amount of token Y per liquidity deposited." - ], - "type": "u128" - }, - { - "name": "amountXIn", - "docs": [ - "Total token X swap into the bin. Only used for tracking purpose." - ], - "type": "u128" - }, - { - "name": "amountYIn", - "docs": [ - "Total token Y swap into he bin. Only used for tracking purpose." - ], - "type": "u128" - } - ] - } - }, - { - "name": "ProtocolFee", - "type": { - "kind": "struct", - "fields": [ - { - "name": "amountX", - "type": "u64" - }, - { - "name": "amountY", - "type": "u64" - } - ] - } - }, - { - "name": "RewardInfo", - "docs": [ - "Stores the state relevant for tracking liquidity mining rewards" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "mint", - "docs": [ - "Reward token mint." - ], - "type": "publicKey" - }, - { - "name": "vault", - "docs": [ - "Reward vault token account." - ], - "type": "publicKey" - }, - { - "name": "funder", - "docs": [ - "Authority account that allows to fund rewards" - ], - "type": "publicKey" - }, - { - "name": "rewardDuration", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u64" - }, - { - "name": "rewardDurationEnd", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u64" - }, - { - "name": "rewardRate", - "docs": [ - "TODO check whether we need to store it in pool" - ], - "type": "u128" - }, - { - "name": "lastUpdateTime", - "docs": [ - "The last time reward states were updated." - ], - "type": "u64" - }, - { - "name": "cumulativeSecondsWithEmptyLiquidityReward", - "docs": [ - "Accumulated seconds where when farm distribute rewards, but the bin is empty. The reward will be accumulated for next reward time window." - ], - "type": "u64" - } - ] - } - }, - { - "name": "Observation", - "type": { - "kind": "struct", - "fields": [ - { - "name": "cumulativeActiveBinId", - "docs": [ - "Cumulative active bin ID" - ], - "type": "i128" - }, - { - "name": "createdAt", - "docs": [ - "Observation sample created timestamp" - ], - "type": "i64" - }, - { - "name": "lastUpdatedAt", - "docs": [ - "Observation sample last updated timestamp" - ], - "type": "i64" - } - ] - } - }, - { - "name": "StaticParameters", - "docs": [ - "Parameter that set by the protocol" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "baseFactor", - "docs": [ - "Used for base fee calculation. base_fee_rate = base_factor * bin_step" - ], - "type": "u16" - }, - { - "name": "filterPeriod", - "docs": [ - "Filter period determine high frequency trading time window." - ], - "type": "u16" - }, - { - "name": "decayPeriod", - "docs": [ - "Decay period determine when the volatile fee start decay / decrease." - ], - "type": "u16" - }, - { - "name": "reductionFactor", - "docs": [ - "Reduction factor controls the volatile fee rate decrement rate." - ], - "type": "u16" - }, - { - "name": "variableFeeControl", - "docs": [ - "Used to scale the variable fee component depending on the dynamic of the market" - ], - "type": "u32" - }, - { - "name": "maxVolatilityAccumulator", - "docs": [ - "Maximum number of bin crossed can be accumulated. Used to cap volatile fee rate." - ], - "type": "u32" - }, - { - "name": "minBinId", - "docs": [ - "Min bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "maxBinId", - "docs": [ - "Max bin id supported by the pool based on the configured bin step." - ], - "type": "i32" - }, - { - "name": "protocolShare", - "docs": [ - "Portion of swap fees retained by the protocol by controlling protocol_share parameter. protocol_swap_fee = protocol_share * total_swap_fee" - ], - "type": "u16" - }, - { - "name": "padding", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 6 - ] - } - } - ] - } - }, - { - "name": "VariableParameters", - "docs": [ - "Parameters that changes based on dynamic of the market" - ], - "type": { - "kind": "struct", - "fields": [ - { - "name": "volatilityAccumulator", - "docs": [ - "Volatility accumulator measure the number of bin crossed since reference bin ID. Normally (without filter period taken into consideration), reference bin ID is the active bin of last swap.", - "It affects the variable fee rate" - ], - "type": "u32" - }, - { - "name": "volatilityReference", - "docs": [ - "Volatility reference is decayed volatility accumulator. It is always <= volatility_accumulator" - ], - "type": "u32" - }, - { - "name": "indexReference", - "docs": [ - "Active bin id of last swap." - ], - "type": "i32" - }, - { - "name": "padding", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 4 - ] - } - }, - { - "name": "lastUpdateTimestamp", - "docs": [ - "Last timestamp the variable parameters was updated" - ], - "type": "i64" - }, - { - "name": "padding1", - "docs": [ - "Padding for bytemuck safe alignment" - ], - "type": { - "array": [ - "u8", - 8 - ] - } - } - ] - } - }, - { - "name": "FeeInfo", - "type": { - "kind": "struct", - "fields": [ - { - "name": "feeXPerTokenComplete", - "type": "u128" - }, - { - "name": "feeYPerTokenComplete", - "type": "u128" - }, - { - "name": "feeXPending", - "type": "u64" - }, - { - "name": "feeYPending", - "type": "u64" - } - ] - } - }, - { - "name": "UserRewardInfo", - "type": { - "kind": "struct", - "fields": [ - { - "name": "rewardPerTokenCompletes", - "type": { - "array": [ - "u128", - 2 - ] - } - }, - { - "name": "rewardPendings", - "type": { - "array": [ - "u64", - 2 - ] - } - } - ] - } - }, - { - "name": "StrategyType", - "type": { - "kind": "enum", - "variants": [ - { - "name": "SpotOneSide" - }, - { - "name": "CurveOneSide" - }, - { - "name": "BidAskOneSide" - }, - { - "name": "SpotBalanced" - }, - { - "name": "CurveBalanced" - }, - { - "name": "BidAskBalanced" - }, - { - "name": "SpotImBalanced" - }, - { - "name": "CurveImBalanced" - }, - { - "name": "BidAskImBalanced" - } - ] - } - }, - { - "name": "Rounding", - "type": { - "kind": "enum", - "variants": [ - { - "name": "Up" - }, - { - "name": "Down" - } - ] - } - }, - { - "name": "ActivationType", - "docs": [ - "Type of the activation" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Slot" - }, - { - "name": "Timestamp" - } - ] - } - }, - { - "name": "LayoutVersion", - "docs": [ - "Layout version" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "V0" - }, - { - "name": "V1" - } - ] - } - }, - { - "name": "PairType", - "docs": [ - "Type of the Pair. 0 = Permissionless, 1 = Permission, 2 = CustomizablePermissionless" - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Permissionless" - }, - { - "name": "Permission" - }, - { - "name": "CustomizablePermissionless" - } - ] - } - }, - { - "name": "PairStatus", - "docs": [ - "Pair status. 0 = Enabled, 1 = Disabled. Putting 0 as enabled for backward compatibility." - ], - "type": { - "kind": "enum", - "variants": [ - { - "name": "Enabled" - }, - { - "name": "Disabled" - } - ] - } - } - ], - "events": [ - { - "name": "CompositionFee", - "fields": [ - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "binId", - "type": "i16", - "index": false - }, - { - "name": "tokenXFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "tokenYFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "protocolTokenXFeeAmount", - "type": "u64", - "index": false - }, - { - "name": "protocolTokenYFeeAmount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "AddLiquidity", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "amounts", - "type": { - "array": [ - "u64", - 2 - ] - }, - "index": false - }, - { - "name": "activeBinId", - "type": "i32", - "index": false - } - ] - }, - { - "name": "RemoveLiquidity", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "amounts", - "type": { - "array": [ - "u64", - 2 - ] - }, - "index": false - }, - { - "name": "activeBinId", - "type": "i32", - "index": false - } - ] - }, - { - "name": "Swap", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "from", - "type": "publicKey", - "index": false - }, - { - "name": "startBinId", - "type": "i32", - "index": false - }, - { - "name": "endBinId", - "type": "i32", - "index": false - }, - { - "name": "amountIn", - "type": "u64", - "index": false - }, - { - "name": "amountOut", - "type": "u64", - "index": false - }, - { - "name": "swapForY", - "type": "bool", - "index": false - }, - { - "name": "fee", - "type": "u64", - "index": false - }, - { - "name": "protocolFee", - "type": "u64", - "index": false - }, - { - "name": "feeBps", - "type": "u128", - "index": false - }, - { - "name": "hostFee", - "type": "u64", - "index": false - } - ] - }, - { - "name": "ClaimReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "totalReward", - "type": "u64", - "index": false - } - ] - }, - { - "name": "FundReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "funder", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "amount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "InitializeReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardMint", - "type": "publicKey", - "index": false - }, - { - "name": "funder", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "rewardDuration", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdateRewardDuration", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "oldRewardDuration", - "type": "u64", - "index": false - }, - { - "name": "newRewardDuration", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdateRewardFunder", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardIndex", - "type": "u64", - "index": false - }, - { - "name": "oldFunder", - "type": "publicKey", - "index": false - }, - { - "name": "newFunder", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "PositionClose", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "ClaimFee", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - }, - { - "name": "feeX", - "type": "u64", - "index": false - }, - { - "name": "feeY", - "type": "u64", - "index": false - } - ] - }, - { - "name": "LbPairCreate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "binStep", - "type": "u16", - "index": false - }, - { - "name": "tokenX", - "type": "publicKey", - "index": false - }, - { - "name": "tokenY", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "PositionCreate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "owner", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "FeeParameterUpdate", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "protocolShare", - "type": "u16", - "index": false - }, - { - "name": "baseFactor", - "type": "u16", - "index": false - } - ] - }, - { - "name": "IncreaseObservation", - "fields": [ - { - "name": "oracle", - "type": "publicKey", - "index": false - }, - { - "name": "newObservationLength", - "type": "u64", - "index": false - } - ] - }, - { - "name": "WithdrawIneligibleReward", - "fields": [ - { - "name": "lbPair", - "type": "publicKey", - "index": false - }, - { - "name": "rewardMint", - "type": "publicKey", - "index": false - }, - { - "name": "amount", - "type": "u64", - "index": false - } - ] - }, - { - "name": "UpdatePositionOperator", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "oldOperator", - "type": "publicKey", - "index": false - }, - { - "name": "newOperator", - "type": "publicKey", - "index": false - } - ] - }, - { - "name": "UpdatePositionLockReleasePoint", - "fields": [ - { - "name": "position", - "type": "publicKey", - "index": false - }, - { - "name": "currentPoint", - "type": "u64", - "index": false - }, - { - "name": "newLockReleasePoint", - "type": "u64", - "index": false - }, - { - "name": "oldLockReleasePoint", - "type": "u64", - "index": false - }, - { - "name": "sender", - "type": "publicKey", - "index": false - } - ] - } - ], - "errors": [ - { - "code": 6000, - "name": "InvalidStartBinIndex", - "msg": "Invalid start bin index" - }, - { - "code": 6001, - "name": "InvalidBinId", - "msg": "Invalid bin id" - }, - { - "code": 6002, - "name": "InvalidInput", - "msg": "Invalid input data" - }, - { - "code": 6003, - "name": "ExceededAmountSlippageTolerance", - "msg": "Exceeded amount slippage tolerance" - }, - { - "code": 6004, - "name": "ExceededBinSlippageTolerance", - "msg": "Exceeded bin slippage tolerance" - }, - { - "code": 6005, - "name": "CompositionFactorFlawed", - "msg": "Composition factor flawed" - }, - { - "code": 6006, - "name": "NonPresetBinStep", - "msg": "Non preset bin step" - }, - { - "code": 6007, - "name": "ZeroLiquidity", - "msg": "Zero liquidity" - }, - { - "code": 6008, - "name": "InvalidPosition", - "msg": "Invalid position" - }, - { - "code": 6009, - "name": "BinArrayNotFound", - "msg": "Bin array not found" - }, - { - "code": 6010, - "name": "InvalidTokenMint", - "msg": "Invalid token mint" - }, - { - "code": 6011, - "name": "InvalidAccountForSingleDeposit", - "msg": "Invalid account for single deposit" - }, - { - "code": 6012, - "name": "PairInsufficientLiquidity", - "msg": "Pair insufficient liquidity" - }, - { - "code": 6013, - "name": "InvalidFeeOwner", - "msg": "Invalid fee owner" - }, - { - "code": 6014, - "name": "InvalidFeeWithdrawAmount", - "msg": "Invalid fee withdraw amount" - }, - { - "code": 6015, - "name": "InvalidAdmin", - "msg": "Invalid admin" - }, - { - "code": 6016, - "name": "IdenticalFeeOwner", - "msg": "Identical fee owner" - }, - { - "code": 6017, - "name": "InvalidBps", - "msg": "Invalid basis point" - }, - { - "code": 6018, - "name": "MathOverflow", - "msg": "Math operation overflow" - }, - { - "code": 6019, - "name": "TypeCastFailed", - "msg": "Type cast error" - }, - { - "code": 6020, - "name": "InvalidRewardIndex", - "msg": "Invalid reward index" - }, - { - "code": 6021, - "name": "InvalidRewardDuration", - "msg": "Invalid reward duration" - }, - { - "code": 6022, - "name": "RewardInitialized", - "msg": "Reward already initialized" - }, - { - "code": 6023, - "name": "RewardUninitialized", - "msg": "Reward not initialized" - }, - { - "code": 6024, - "name": "IdenticalFunder", - "msg": "Identical funder" - }, - { - "code": 6025, - "name": "RewardCampaignInProgress", - "msg": "Reward campaign in progress" - }, - { - "code": 6026, - "name": "IdenticalRewardDuration", - "msg": "Reward duration is the same" - }, - { - "code": 6027, - "name": "InvalidBinArray", - "msg": "Invalid bin array" - }, - { - "code": 6028, - "name": "NonContinuousBinArrays", - "msg": "Bin arrays must be continuous" - }, - { - "code": 6029, - "name": "InvalidRewardVault", - "msg": "Invalid reward vault" - }, - { - "code": 6030, - "name": "NonEmptyPosition", - "msg": "Position is not empty" - }, - { - "code": 6031, - "name": "UnauthorizedAccess", - "msg": "Unauthorized access" - }, - { - "code": 6032, - "name": "InvalidFeeParameter", - "msg": "Invalid fee parameter" - }, - { - "code": 6033, - "name": "MissingOracle", - "msg": "Missing oracle account" - }, - { - "code": 6034, - "name": "InsufficientSample", - "msg": "Insufficient observation sample" - }, - { - "code": 6035, - "name": "InvalidLookupTimestamp", - "msg": "Invalid lookup timestamp" - }, - { - "code": 6036, - "name": "BitmapExtensionAccountIsNotProvided", - "msg": "Bitmap extension account is not provided" - }, - { - "code": 6037, - "name": "CannotFindNonZeroLiquidityBinArrayId", - "msg": "Cannot find non-zero liquidity binArrayId" - }, - { - "code": 6038, - "name": "BinIdOutOfBound", - "msg": "Bin id out of bound" - }, - { - "code": 6039, - "name": "InsufficientOutAmount", - "msg": "Insufficient amount in for minimum out" - }, - { - "code": 6040, - "name": "InvalidPositionWidth", - "msg": "Invalid position width" - }, - { - "code": 6041, - "name": "ExcessiveFeeUpdate", - "msg": "Excessive fee update" - }, - { - "code": 6042, - "name": "PoolDisabled", - "msg": "Pool disabled" - }, - { - "code": 6043, - "name": "InvalidPoolType", - "msg": "Invalid pool type" - }, - { - "code": 6044, - "name": "ExceedMaxWhitelist", - "msg": "Whitelist for wallet is full" - }, - { - "code": 6045, - "name": "InvalidIndex", - "msg": "Invalid index" - }, - { - "code": 6046, - "name": "RewardNotEnded", - "msg": "Reward not ended" - }, - { - "code": 6047, - "name": "MustWithdrawnIneligibleReward", - "msg": "Must withdraw ineligible reward" - }, - { - "code": 6048, - "name": "UnauthorizedAddress", - "msg": "Unauthorized address" - }, - { - "code": 6049, - "name": "OperatorsAreTheSame", - "msg": "Cannot update because operators are the same" - }, - { - "code": 6050, - "name": "WithdrawToWrongTokenAccount", - "msg": "Withdraw to wrong token account" - }, - { - "code": 6051, - "name": "WrongRentReceiver", - "msg": "Wrong rent receiver" - }, - { - "code": 6052, - "name": "AlreadyPassActivationPoint", - "msg": "Already activated" - }, - { - "code": 6053, - "name": "ExceedMaxSwappedAmount", - "msg": "Swapped amount is exceeded max swapped amount" - }, - { - "code": 6054, - "name": "InvalidStrategyParameters", - "msg": "Invalid strategy parameters" - }, - { - "code": 6055, - "name": "LiquidityLocked", - "msg": "Liquidity locked" - }, - { - "code": 6056, - "name": "BinRangeIsNotEmpty", - "msg": "Bin range is not empty" - }, - { - "code": 6057, - "name": "NotExactAmountOut", - "msg": "Amount out is not matched with exact amount out" - }, - { - "code": 6058, - "name": "InvalidActivationType", - "msg": "Invalid activation type" - }, - { - "code": 6059, - "name": "InvalidActivationDuration", - "msg": "Invalid activation duration" - }, - { - "code": 6060, - "name": "MissingTokenAmountAsTokenLaunchProof", - "msg": "Missing token amount as token launch owner proof" - }, - { - "code": 6061, - "name": "InvalidQuoteToken", - "msg": "Quote token must be SOL or USDC" - }, - { - "code": 6062, - "name": "InvalidBinStep", - "msg": "Invalid bin step" - }, - { - "code": 6063, - "name": "InvalidBaseFee", - "msg": "Invalid base fee" - }, - { - "code": 6064, - "name": "InvalidPreActivationDuration", - "msg": "Invalid pre-activation duration" - }, - { - "code": 6065, - "name": "AlreadyPassPreActivationSwapPoint", - "msg": "Already pass pre-activation swap point" - } - ] -};