Skip to main content
Sigvex

Wrapped Token Parity Remediation

How to fix missing wrapped token supply vs collateral parity validation.

Wrapped Token Parity Remediation

Overview

Related Detector: Wrapped Token Parity

Broken parity between wrapped token supply and collateral enables infinite minting attacks. The fix is to enforce supply == collateral invariant checks after every mint, burn, and collateral operation.

Before (Vulnerable)

token::mint_to(ctx.into_mint_ctx(), amount)?;
// No parity check

After (Fixed)

// Deposit collateral first
token::transfer(ctx.into_deposit_ctx(), amount)?;
// Then mint wrapped tokens
token::mint_to(ctx.into_mint_ctx(), amount)?;
// Verify parity
let supply = ctx.accounts.wrapped_mint.supply;
let collateral = ctx.accounts.collateral_vault.amount;
require!(supply == collateral, ErrorCode::ParityViolation);

Alternative Mitigations

Mint Authority PDA

Use a PDA as the mint authority so only the program can mint, and enforce parity within the program:

#[derive(Accounts)]
pub struct Wrap<'info> {
    #[account(mut, mint::authority = mint_authority)]
    pub wrapped_mint: Account<'info, Mint>,
    /// CHECK: PDA authority
    #[account(seeds = [b"mint-authority"], bump)]
    pub mint_authority: AccountInfo<'info>,
}

Common Mistakes

Mistake: Checking Parity Before Operations

// WRONG: checks parity before the mint, not after
require!(supply == collateral, ParityViolation);
token::mint_to(ctx, amount)?;  // Parity now broken

Always check the invariant after all state-changing operations complete.

References