convex-testing-interface
Safe HaskellSafe-Inferred
LanguageHaskell2010

Convex.ThreatModel.TokenForgery

Description

Threat model for detecting Token Forgery vulnerabilities.

A Token Forgery Attack exploits minting policies that are too permissive. If a minting policy allows tokens to be minted under weak conditions (e.g., just requiring any signature), an attacker can mint unauthorized tokens.

Vulnerability Pattern ==

A vulnerable minting policy might only check:

MintValidation -> {
  // VULNERABLE: Anyone who signs can mint!
  list.length(self.extra_signatories) > 0
}

This is trivially satisfied by ANY signed transaction, allowing anyone to forge tokens that should be restricted.

Consequences ==

  1. Validation token bypass: If a validator requires a "validation token" to prove authorization, attackers can mint their own tokens.
  2. Asset theft: Forged tokens can be used to satisfy validator checks, potentially draining funds.
  3. Protocol manipulation: In DeFi protocols, forged governance or utility tokens can manipulate voting, rewards, or access control.

Mitigation ==

A secure minting policy should:

  • Require specific authorized signers (not just "any signature")
  • Check that minting is authorized by a governance mechanism
  • Verify minting is part of a valid protocol operation
  • Use one-shot minting for unique tokens (NFTs, thread tokens)

This threat model tests if additional tokens can be minted using the same minting policy that the transaction already uses. If the transaction still validates with extra minted tokens, the minting policy may be too permissive.

Synopsis

Threat models

tokenForgeryAttack Source #

Arguments

:: IsPlutusScriptInEra lang 
=> PlutusScript lang

The minting policy to test

-> AssetName

The asset name to mint

-> ThreatModel () 

Check for Token Forgery vulnerabilities with a Plutus V2 minting policy.

Given a minting policy and asset name, this threat model attempts to mint additional tokens with that policy. If the transaction still validates, the minting policy is too permissive.

Usage: threatPrecondition $ tokenForgeryAttack mintingPolicy assetName

The redeemer used is Constr 0 [] (unit), which is common for simple minting policies. Use tokenForgeryAttackWith for custom redeemers.

tokenForgeryAttackWith Source #

Arguments

:: IsPlutusScriptInEra lang 
=> ScriptData

Redeemer for the minting policy

-> PlutusScript lang

The minting policy to test

-> AssetName

The asset name to mint

-> ThreatModel () 

Check for Token Forgery vulnerabilities with a custom redeemer.

This variant allows specifying the redeemer to use when attempting to mint additional tokens. This is useful when the minting policy expects a specific redeemer format.

  -- Test with MintValidation redeemer (Constr 0 [])
  tokenForgeryAttackWith (ScriptDataConstructor 0 []) mintingPolicy assetName

  -- Test with custom redeemer
  tokenForgeryAttackWith myRedeemer mintingPolicy assetName

Helpers

simpleAlwaysSucceedsMintingPolicyV2 :: PlutusScript PlutusScriptV2 Source #

A simple Plutus minting policy that always validates (for testing).

This provides a reusable always-succeeds minting policy suitable for testing token forgery vulnerabilities. It's commonly used to create throwaway minting policies when testing spending validators.

Usage: threatModels = [ tokenForgeryAttack simpleAlwaysSucceedsMintingPolicyV3 simpleTestAssetName ]

simpleTestAssetName :: AssetName Source #

A simple asset name for testing (empty string).

This provides a basic asset name for use with token forgery attacks and other threat model testing where the asset name is not critical.

The empty asset name is a common convention for test tokens.