fix(amm)!: restrict UpdateConfig to authority transfer only

UpdateConfig let the admin rewrite token_program_id and
twap_oracle_program_id in place. Both are immutable deployment
parameters — twap_oracle_program_id derives the current-tick PDA and
every price-observation/price account PDA, and token_program_id is the
program the AMM issues its vault transfers to — so changing either
after any pool exists would orphan every derived account and vault. A
genuine change requires redeploying the AMM, never an in-place edit.

- Instruction::UpdateConfig now carries a single required field,
  new_authority; the two program-id fields are removed.
- update_config assigns the new authority directly (no Option/if-let);
  PDA + admin + signature preconditions unchanged.
- Guest handler and IDL updated to match.
- Drop the integration test that mutated token_program_id (it
  exercised the vulnerability); keep reject-non-admin and
  authority-handoff, and assert program ids survive a transfer.

BREAKING CHANGE: the UpdateConfig instruction ABI changed — the
token_program_id and twap_oracle_program_id fields are removed and
new_authority is now required (was Option). Any client constructing
UpdateConfig must be updated. The instruction enum change also alters
the program ImageID: redeploy and update every ImageID-derived value
(deployed program ids, client/config files, PDA-derived addresses,
AMM/ATA program-id inputs) before submitting
This commit is contained in:
r4bbit
2026-08-05 18:08:43 +02:00
parent 200f429ec6
commit de9a3d5320
5 changed files with 58 additions and 191 deletions
+13 -13
View File
@@ -21,7 +21,7 @@ pub enum Instruction {
/// The configuration account is a PDA derived from the constant `"CONFIG"` seed
/// (`compute_config_pda(self_program_id)`). It stores the program IDs the AMM issues chained
/// calls to (the Token Program and the TWAP oracle program), plus the admin `authority`
/// allowed to change configuration later via `UpdateConfig`. The Program must be initialized
/// allowed to transfer admin control later via `UpdateConfig`. The Program must be initialized
/// via this instruction before any pool can be created or interacted with — the other
/// instructions read these program IDs from this account and reject calls when it does not
/// yet exist.
@@ -33,26 +33,26 @@ pub enum Instruction {
token_program_id: ProgramId,
/// Program ID of the TWAP oracle program the AMM will issue chained calls to.
twap_oracle_program_id: ProgramId,
/// Admin authority allowed to change configuration via `UpdateConfig`.
/// Admin authority allowed to transfer admin control via `UpdateConfig`.
authority: AccountId,
},
/// Updates the AMM Program's configuration. Only the configured admin `authority` may call
/// this; the authority account must be passed authorized (signed).
/// Transfers the AMM Program's admin authority to a new account. Only the configured admin
/// `authority` may call this; the authority account must be passed authorized (signed).
///
/// Each field is optional — `None` leaves the corresponding value unchanged. Setting
/// `new_authority` transfers admin control to a different account.
/// The Token Program and TWAP oracle program IDs are **immutable deployment parameters** set
/// once at `Initialize`: they are baked into every derived PDA (vaults, current-tick,
/// price-observation / price accounts) and into the AMM's chained calls, so changing them
/// after any pool exists would orphan every derived account and vault. They therefore cannot
/// be reconfigured in place — a genuine change requires redeploying the AMM. This instruction
/// only moves the admin authority.
///
/// Required accounts:
/// - AMM Config Account (initialized)
/// - Authority Account — must equal the config's current `authority`, passed authorized.
UpdateConfig {
/// New Token Program ID for chained calls, or `None` to keep the current one.
token_program_id: Option<ProgramId>,
/// New TWAP oracle program ID for chained calls, or `None` to keep the current one.
twap_oracle_program_id: Option<ProgramId>,
/// New admin authority (transfers control), or `None` to keep the current admin.
new_authority: Option<AccountId>,
/// New admin authority (transfers admin control to this account).
new_authority: AccountId,
},
/// Creates a TWAP price-observations account for a pool over a time window, on behalf of the
@@ -382,7 +382,7 @@ pub struct AmmConfig {
pub token_program_id: ProgramId,
/// Program ID of the TWAP oracle program the AMM issues chained calls to.
pub twap_oracle_program_id: ProgramId,
/// Admin authority allowed to change this configuration via `UpdateConfig`.
/// Admin authority allowed to transfer admin control via `UpdateConfig`.
pub authority: AccountId,
}