Skip to main content
本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
自 2026-07 程序升级以来,AMM v4 的 OpenBook / Serum 依赖已被移除。旧版 v1 的 SwapBaseIn / SwapBaseOutDepositWithdraw 指令保持原有的账户布局以保证向后兼容:市场账户仍在原位置被接受,但不再被验证或使用(不发起 CPI)。新的集成应使用 V2 交换入口点,它们完全省略了市场账户。多条指令已被移除并现在会回滚——见 changelog 条目。下面的账户列表使用 Raydium SDK 中的字段名;底层 IDL 有时使用 serum_* 前缀。2026-09 程序升级添加了一条管理员指令 WithdrawExcessLamports(标签 18),并从 CreateConfigAccount 中移除了 rent sysvar。交易者或 LP 调用的所有内容都保持不变。见 2026-09-09 changelog 条目

指令清单

SDK 仅为面向用户的指令公开构建器。维护指令通常由 Raydium keeper 调用。 已移除 / 不再可调用(其客户端构建器已删除):Initialize(标签 0,使用 Initialize2)、MonitorStep(2)、MigrateToOpenBook(5)、WithdrawSrm(8)、PreInitialize(10,使用 Initialize2)、SimulateInfo(12)、AdminCancelOrders(13)。 携带这些标签之一的交易会失败;程序永远不会执行该指令。将这七条都视为已删除,而不是要处理的错误路径。

Initialize2

引导一个新的 AMM v4 池,绑定到现有的 OpenBook 市场。 参数
账户(可写 W、签名者 S
两种被接受的布局。 上面 19 个账户的列表是推荐的那一种。为了向后兼容,程序也会读取一个 21 个账户的旧版布局,它在位置 7 插入一个被忽略的 amm_open_orders,在位置 16 插入一个被忽略的 market_program —— 这正是仓库内的 initialize2 指令构建器仍在生成的形式。其他任何长度都会按 旧版布局按位置解析,并且会失败。
后置条件
  • 铸造给创建者的 LP = sqrt(init_coin_amount × init_pc_amount) − 10^coin_mint.decimals。LP 小数位等于 coin_mint.decimals,因此被减去的数量恰好是整整一个 LP 代币;它从未被铸造,永久退出流通。如果 sqrt(...) 低于该值,指令会以 InitLpAmountTooLess 回滚。
  • AmmInfo.lp_amount 存储完整的 sqrt(...)不是已铸造的数量 —— 因此 lp_mint.supply 永久比 amm.lp_amount 低整整一个 LP 代币。所有按比例的计算都使用 amm.lp_amount
  • 不发布 OpenBook 订单(订单簿网格已被移除)。AmmInfo.market 记录在槽位 15 传入的账户,但 AmmInfo.open_ordersAmmInfo.market_program 都被写为 Pubkey::default(),而 coin_lot_size / pc_lot_size / min_size 被初始化为 0。在旧版的 21 账户布局上,额外的 amm_open_ordersmarket_program 账户会被读取后丢弃。
常见错误InvalidCoinMint(coin 与 pc 铸币相同)、InvalidConfigAccountamm_config PDA 错误)、InvalidFee(创建池费用目标错误)、InvalidProgramAddressamm_authority 错误或 nonce 错误)、RepeatCreateAmm(该市场已存在池)、InitLpAmountTooLessInvalidSupply(某个初始数量为 0,或 LP 铸币已有供应量)、AlreadyInUse

Deposit

添加流动性。 参数
账户(简化)
被接受的账户数量只有 11、14 或 15 —— 没有别的。 旧版布局是 14 个账户(或带一个被忽略的 尾部账户时为 15 个):与上面相同的列表,但在位置 4 插入一个被忽略的 amm_open_orders,在位置 9 插入一个被忽略的 market,并在位置 14 追加一个被忽略的 market_event_queue。其他任何数量都会以 WrongAccountsNumber 回滚。
数学 — 标准按比例分配。使用池的有效储备(金库 + 账面上),SDK 计算产生给定 LP 数量的 coin/pc 对,并根据 max_* 检查。如果任一方超过上限,则以 ExceededSlippage 回滚。

Withdraw

销毁 LP,接收两种代币。 参数
账户 — 推荐的 11 账户布局
Withdraw 不是把 Deposit 反过来。 被接受的数量是 11,或 20 到 23。旧版的 20 账户布局把用户的 LP 账户放在两个接收 ATA 之前,并交错插入五个被忽略的市场账户: token_program, amm(W), amm_authority, amm_open_orders(W), amm_target_orders(W), lp_mint(W), pool_coin_token_account(W), pool_pc_token_account(W), market_program, market(W), market_coin_vault(W), market_pc_vault(W), market_vault_signer, user_lp_token_account(W), user_coin_token_account(W), user_pc_token_account(W), user_owner(S), market_event_queue(W), market_bids(W), market_asks(W)。 22 和 23 账户的形式会在位置 8 之后插入两个被忽略的填充账户。其他任何数量都会以 WrongAccountsNumber 回滚。
不再有从 OpenBook 结算的步骤 —— 按比例分配的数学直接使用金库余额。

SwapBaseIn

精确输入交换。始终是AMM 路径交换(不通过 OpenBook 匹配路由)。
为新代码使用 V2 变体。 由于 AMM v4 的 OpenBook 依赖已被移除,V1 入口点(SwapBaseInSwapBaseOut)仍然期望完整的 17 账户列表(或 18 个带可选 target-orders 账户),但 OpenBook/市场账户现在按位置被接受并被忽略——它们不被验证,不发起 CPI。传递错误的账户数量仍会以 WrongAccountsNumber 回滚,但市场账户内容不再被检查。新的集成应使用 SwapBaseInV2 / SwapBaseOutV2,它们采用更小的账户列表,代表当今的规范执行路径。V1 形式在此记录以供完整性和阅读现有链上交易。
参数
账户(简化) 数学 — 见 products/amm-v4/math 前置条件
  • AmmStatus::from_u64(amm.status).swap_permission() 为真 —— 也就是 status1Initialized)、6SwapOnly)或 7WaitingTrade)。status 是枚举值,不是位掩码;见 products/amm-v4/accounts
  • amm.state_data.pool_open_time <= now
  • amount_in > 0
  • user_source_token_account 至少持有 amount_in
后置条件
  • 用户失去 amount_in 的源代币,获得 amount_out ≥ minimum_amount_out 的目标代币。
  • 交易费留在金库中,提高不变式 kneed_take_pnl_* 计数器不会被交换触及 —— 协议 PnL 会在下一次 DepositWithdrawWithdrawPnl 时根据 k 的增量重新计算(Processor::calc_take_pnl)。
  • 注意:state_data.swap_*_in_amount / swap_*_out_amount 分析计数器不再更新——其值被冻结。使用交易日志进行交易量分析。
常见错误ExceededSlippageInvalidInputInvalidStatusNotAllowed(coin/pc mint 相同)。

SwapBaseOut

精确输出,SwapBaseIn 的反向。账户相同。 参数

SwapBaseInV2 / SwapBaseOutV2

变体交换入口点(标签 16 / 17),完全跳过 OpenBook 账户。数学与 V1 路径相同,但账户列表缩小到仅 AMM 端和用户——8 个账户,amm_open_orders 不被传递 池储备现在是金库余额(减去待处理 PnL),所以报价数学直接且与 v1 路径相同。使用 V2 来节省计算并避免传递(现在被忽略的)市场账户。Raydium 路由器在通过 AMM v4 路由时始终使用 V2 形式。 参数与 V1 形式相同(SwapBaseInV2amount_in / minimum_amount_outSwapBaseOutV2max_amount_in / amount_out)。

MonitorStep 和其他已移除的指令

已移除——不再可调用。 自 2026-07 升级以来,MonitorStep(标签 2)已从程序中移除,如果被调用现在会回滚unimplemented!)。其客户端构建器也被删除了。同样适用于 MigrateToOpenBook(5)、WithdrawSrm(8)、SimulateInfo(12)、AdminCancelOrders(13)以及旧版 Initialize(0)/ PreInitialize(10)池创建入口点——改用 Initialize2
历史上,MonitorStep 驱动池的 OpenBook 交互:它结算已成交的订单(通过 OpenBook CPI 将收益从市场金库移到池金库),取消陈旧订单,并发布新订单以缩小 target_ordersamm_open_orders 之间的差距。随着 OpenBook 依赖的移除,没有什么可驱动的,指令已消失。任何仍调用它的 keeper 或集成必须移除该调用。

WithdrawPnl / TakePnl

管理员清扫累积的协议费。 参数
  • WithdrawPnl 不接受参数;它读取 need_take_pnl_* 并移动这些确切的数量。
破坏性更改(仅限管理员)。 账户列表从 17(+1 可选)下降到 10——amm_open_orders 和所有六个市场账户被移除——没有兼容性解析。旧布局错位(旧 #5 是 amm_open_orders,现在是 pool_coin_token_account)并以 InvalidCoinVault 等错误失败。管理员工具必须更新。
账户(新 10 账户布局) 效果
  • pool_coin_token_account 转移 need_take_pnl_coinpnl_coin_token_account
  • pc 相同。
  • need_take_pnl_coinneed_take_pnl_pc 置零。
  • 逻辑更改:如果金库余额不足以覆盖累积的 PnL,指令直接返回 TakePnlError(它不再操纵订单簿状态)。
由于累积的 PnL 已从不变量中排除,储备没有变化。

SetParams

管理员参数更改,由 Raydium 多签调用。参数是 param: u8 标签 + 有效负载。
破坏性更改(仅限管理员)。 账户列表被减少到仅 [amm (W), admin (S)](权限、open-orders、target-orders、金库和所有市场账户被移除)。param 枚举被重新编号和修剪Status = 0、State = 1、Fees = 2(曾是 9)、SetOpenTime = 3(曾是 11)。所有订单簿网格参数和 AmmOwnerLastOrderDistanceUpdateOpenOrder 被移除,SetParamsInstruction 结构体删除了 new_pubkeylast_order_distance。管理员工具必须更新。

CreateConfigAccount / UpdateConfigAccount

程序级 AmmConfig PDA(seed ["amm_config_account_seed"])的管理员管理。该账户只持有三个有意义的字段 —— pnl_ownercancel_ownercreate_pool_fee —— 外加两个保留的填充区域;没有池创建标志。UpdateConfigAccountparam = 0 设置 pnl_owner,用 param = 1 设置 cancel_owner,用 param = 2 设置 create_pool_fee
在 2026-09 中更改,向后兼容。 CreateConfigAccount 不再读取 rent sysvar。其账户列表现在是 4 个账户,从 5 个下降:程序从 Rent::get() 读取 rent 参数,而不是反序列化传入的 sysvar 账户——这是 Solana 3.0 依赖升级使其自然的做法。被移除的账户是列表中的最后一个,处理程序通过 next_account_info 按位置读取其账户,没有长度检查。因此,仍传递旧 5 账户列表的现有管理员工具继续工作:尾部 rent 账户根本不被读取。在方便时更新它,不是紧急的。UpdateConfigAccount 不变。
Initialize2 在位置 3 保留 rent sysvar,并仍然使用它:程序停止在其上调用 Rent::from_account_info,但它仍被转发到创建池金库和 LP mint 的 spl_token::initialize_accountinitialize_mint CPI 中。不要从账户列表中删除它。

WithdrawExcessLamports

管理员清扫坐在程序控制的账户上 rent-exempt 最小值之上的 lamport。在 2026-09 升级中添加,以恢复 SIMD-0437 rent 减少 在每个步骤之前创建的账户上留下的过度资金。 它仅移动超额部分。代币余额、账户数据、所有者和池状态保持不变,指令在已处于最小值的账户上是无操作的——所以重复触发和在每次推出步骤后再次触发是安全的。 参数 — 无。有效负载是单个标签字节 18 账户 每个源账户的处理方式 程序根据源账户的 owner 分派: 常见错误InvalidSignAccount(错误的签名者)、InvalidSplTokenProgram(槽 3 中的错误程序)、InvalidProgramAddress(错误的 amm_authority)、LamportsCalculateError(自定义代码 60;wSOL 往返没有净为零)和来自程序所有路径的 InsufficientFunds,当账户持有少于其自身 rent 最小值时。 无 SDK 构建器。 @raydium-io/raydium-sdk-v2 不为此指令提供构建器,raydium-sdk-V2-demo 仓库也不提供——这是管理员路径。手动编码,就像 solana-fundamentals/rent-and-reclaimable-rent 中的钱包端清扫对 token-program 指令所做的那样。

状态变化矩阵

OpenBook 列已消失——没有指令再触及订单簿。

接下来去哪里

来源: