From 970ab6c24e4777aab2be0dda70fd863038499850 Mon Sep 17 00:00:00 2001 From: Alex Scott Date: Thu, 12 Feb 2026 06:06:10 +0400 Subject: [PATCH] SECURITY: Fix missing signer check in migration functions - Add required authority signer to MigrateTdaMerkleRootUploadAuthority - Validate config.authority matches signer in both programs - Fixes critical vulnerability allowing unauthorized upload authority takeover Programs affected: - tip-distribution: migrate_tda_merkle_root_upload_authority - priority-fee-distribution: migrate_tda_merkle_root_upload_authority Impact: Prevents unauthorized control of tip distribution accounts Severity: Critical (Production funds at risk) --- .../programs/priority-fee-distribution/src/lib.rs | 10 ++++++++++ mev-programs/programs/tip-distribution/src/lib.rs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/mev-programs/programs/priority-fee-distribution/src/lib.rs b/mev-programs/programs/priority-fee-distribution/src/lib.rs index f95f91c..235b03b 100644 --- a/mev-programs/programs/priority-fee-distribution/src/lib.rs +++ b/mev-programs/programs/priority-fee-distribution/src/lib.rs @@ -316,6 +316,11 @@ pub mod jito_priority_fee_distribution { pub fn migrate_tda_merkle_root_upload_authority( ctx: Context, ) -> Result<()> { + // SECURITY FIX: Verify that only the config authority can perform migration + if ctx.accounts.config.authority != ctx.accounts.authority.key() { + return Err(Unauthorized.into()); + } + let distribution_account = &mut ctx.accounts.priority_fee_distribution_account; // Validate TDA has no MerkleRoot uploaded to it if distribution_account.merkle_root.is_some() { @@ -708,6 +713,9 @@ impl UpdateMerkleRootUploadConfig<'_> { #[derive(Accounts)] pub struct MigrateTdaMerkleRootUploadAuthority<'info> { + #[account(seeds = [Config::SEED], bump)] + pub config: Account<'info, Config>, + #[account(mut, rent_exempt = enforce)] pub priority_fee_distribution_account: Account<'info, PriorityFeeDistributionAccount>, @@ -717,6 +725,8 @@ pub struct MigrateTdaMerkleRootUploadAuthority<'info> { rent_exempt = enforce, )] pub merkle_root_upload_config: Account<'info, MerkleRootUploadConfig>, + + pub authority: Signer<'info>, } #[derive(Accounts)] diff --git a/mev-programs/programs/tip-distribution/src/lib.rs b/mev-programs/programs/tip-distribution/src/lib.rs index eaadc49..2c99a0b 100644 --- a/mev-programs/programs/tip-distribution/src/lib.rs +++ b/mev-programs/programs/tip-distribution/src/lib.rs @@ -327,6 +327,11 @@ pub mod jito_tip_distribution { pub fn migrate_tda_merkle_root_upload_authority( ctx: Context, ) -> Result<()> { + // SECURITY FIX: Verify that only the config authority can perform migration + if ctx.accounts.config.authority != ctx.accounts.authority.key() { + return Err(Unauthorized.into()); + } + let distribution_account = &mut ctx.accounts.tip_distribution_account; // Validate TDA has no MerkleRoot uploaded to it if distribution_account.merkle_root.is_some() { @@ -674,6 +679,9 @@ impl UpdateMerkleRootUploadConfig<'_> { #[derive(Accounts)] pub struct MigrateTdaMerkleRootUploadAuthority<'info> { + #[account(seeds = [Config::SEED], bump)] + pub config: Account<'info, Config>, + #[account(mut, rent_exempt = enforce)] pub tip_distribution_account: Account<'info, TipDistributionAccount>, @@ -683,6 +691,8 @@ pub struct MigrateTdaMerkleRootUploadAuthority<'info> { rent_exempt = enforce, )] pub merkle_root_upload_config: Account<'info, MerkleRootUploadConfig>, + + pub authority: Signer<'info>, } // Events