sherlock-audit / 2024-08-woofi-solana-deployment-judging

0 stars 0 forks source link

Helpful Jetblack Snake - A malicious user can create multiple `rebate_manager` in advance #58

Open sherlock-admin3 opened 13 hours ago

sherlock-admin3 commented 13 hours ago

Helpful Jetblack Snake

High

A malicious user can create multiple rebate_manager in advance

Summary

A malicious user can create rebate_manager in advance, steal funds from the protocol, or prevent rebate_manager from being created.

Vulnerability Detail

rebate_manager uses the address of quote_token_mint as seeds to generate a new address:

    #[account(
        init,
        payer = authority,
        space = 8 + RebateManager::INIT_SPACE,
        seeds = [
          REBATEMANAGER_SEED.as_bytes(),
@>        quote_token_mint.key().as_ref()
        ],
        bump)]
    pub rebate_manager: Box<Account<'info, RebateManager>>,

So there will be multiple rebate_manager in the protocol, if there are multiple quote_token_mint.

When we add a new quote_token_mint, we need to initialize the new rebate_manager,

Initialize rebate_manager needs to call CreateRebateManager.handler function:

pub fn handler(ctx: Context<CreateRebateManager>) -> Result<()> {
    let authority = ctx.accounts.authority.key();
    let quote_token_mint = ctx.accounts.quote_token_mint.key();
    let token_vault = ctx.accounts.token_vault.key();

    let rebate_manager = &mut ctx.accounts.rebate_manager;

    rebate_manager.initialize(authority, quote_token_mint, token_vault)
}

This function can be called by anyone, and if an attacker calls the function rebate_manager.authority is set to the attacker's address.

If the administrator deposit money in token_vault(quote token), need to verify rebate_manager.authority:

    #[account(mut,
@>      constraint = rebate_manager.authority == authority.key() || rebate_manager.admin_authority.contains(authority.key),
        constraint = rebate_manager.quote_token_mint == quote_token_mint.key()
    )]
    pub rebate_manager: Box<Account<'info, RebateManager>>,

    #[account(mut,
        address = rebate_manager.token_vault,
@>      constraint = token_vault.mint == quote_token_mint.key()
      )]
    pub token_vault: Box<Account<'info, TokenAccount>>,

    pub fn deposit(ctx: Context<DepositWithdraw>, amount: u128) -> Result<()> {
        let token_owner_account = &ctx.accounts.token_owner_account;
        let token_vault = &ctx.accounts.token_vault;

        require!(
            token_owner_account.amount as u128 >= amount,
            ErrorCode::NotEnoughBalance
        );

        transfer_from_owner_to_vault(
            &ctx.accounts.authority,
            token_owner_account,
@>            token_vault,
            &ctx.accounts.token_program,
            amount as u64,
        )?;

        Ok(())
    }

If rebate_manager is created by an attacker, rebate_Manager.authority is the attacker's address and the administrator cannot deposit, However, an attacker could add the administrator account to admin_authority, which would deposit funds into rebate_manager created by the attacker.

An attacker can withdraw funds from rebate_manager.

The administrator query the address of rebate_manager by the program id. The administrator may not know that rebate_manager was created by the attacker if the administrator does not check the address of rebate_Manager.authority.

In another case, the administrator checks the address of rebate_manager.authority, finds out that rebate_manager is fake, and wants to recreate rebate_manager, The problem is that rebate_manager uses the init keyword, and rebate_manager cannot be recreated:

    #[account(init,....],bump)]
    pub rebate_manager: Box<Account<'info, RebateManager>>,

Since there can be multiple rebate_manager, an attacker can create all possible rebate_manager in advance (against the mainstream quote_token_mint).

Impact

steal funds from the protocol, or prevent rebate_manager from being created.

Code Snippet

https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/1c4c9c622e8c44ae2f8cd4219c7c2a0181f25ca0/WOOFi_Solana/programs/rebate_manager/src/instructions/admin/create_rebate_manager.rs#L14-L23

https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/1c4c9c622e8c44ae2f8cd4219c7c2a0181f25ca0/WOOFi_Solana/programs/rebate_manager/src/instructions/admin/deposit_withdraw.rs#L19-L54

Tool used

Manual Review

Recommendation

Only allows administrators to call CreateRebateManager.handle

toprince commented 10 hours ago

Not valid. Same with https://github.com/sherlock-audit/2024-08-woofi-solana-deployment-judging/issues/14