high

Business Logic Error: How It Works, Real Exploits & Automated Detection

April 1, 2026
Chainsethereumarbitrumbaseoptimismpolygon
Detected byslithermythrilechidnahound-ai

Business logic errors are flaws in the protocol's core assumptions, order of operations, or state management that enable unintended exploitation. Unlike code-level vulnerabilities, logic errors emerge from incorrect algorithmic design. Protocols exploited due to logic errors have lost over $100M. Firepan's HOUND AI detects business logic errors automatically during development and post-deployment monitoring, covering continuous analysis across the full contract lifecycle.

What Is Business Logic Error?

Business logic errors differ from code vulnerabilities in that the code executes as written, but the written logic doesn't match the intended protocol behavior. Examples:

  1. Incorrect order of operations: Interest accrued before collateral check, allowing borrowing against accrued (not paid) interest
  2. Missing state transitions: Functions don't update necessary state; subsequent calls operate on stale data
  3. Double-counting: Asset counted twice in different contexts (collateral and reserve)
  4. Improper fee allocation: Fees not properly distributed; collected and lost
  5. Calculation errors: Interest, liquidation threshold, or collateral ratios computed incorrectly
  6. Race condition logic: Protocol doesn't account for concurrent operations on same state
  7. Invariant violations: Core protocol invariants (e.g., totalSupply == sum of balances) not maintained

How Business Logic Error Works

Logic error exploitation typically involves:

  1. Identify assumption: Find protocol assumption (e.g., "interest credited last")
  2. Violate assumption: Exploit order of operations to violate assumption
  3. Extract value: Call functions assuming assumption holds, breaking protocol
// VULNERABLE — example only
// Demonstrates: Business Logic Error
// Do NOT use in production

pragma solidity ^0.8.0;

contract VulnerableLending {
    mapping(address => uint256) public balances;
    mapping(address => uint256) public interest;
    uint256 public totalBorrowed;

    // VULNERABLE: Order of operations error
    function borrowWithInterest(uint256 amount) public {
        // MISTAKE: Check collateral BEFORE accruing interest
        // This allows borrowing against unaccrued interest

        require(balances[msg.sender] >= amount * 120 / 100);  // 120% collateral

        // Borrow proceeds...
        totalBorrowed += amount;

        // Interest accrued AFTER borrow allowed
        // Interest not yet in balance, so next borrow will count it
        interest[msg.sender] += amount / 10;
    }

    // VULNERABLE: Double-counting in collateral calculation
    function getCollateralValue(address user) public view returns (uint256) {
        // MISTAKE: Counts both balance and interest as collateral
        return balances[user] + interest[user];
    }

    // VULNERABLE: Missing state update
    function claimRewards(address token) public {
        uint256 reward = calculateReward(token);

        // MISTAKE: Doesn't reset reward clock
        // Next call calculates same reward again
        (bool success, ) = msg.sender.call{value: reward}("");
        require(success);

        // Should have: lastClaimTime[msg.sender] = block.timestamp;
    }

    // VULNERABLE: Invariant violation not detected
    function transferAndBurn(address to, uint256 amount) public {
        balances[msg.sender] -= amount;
        balances[to] += amount;

        // MISTAKE: Doesn't update totalSupply
        // Invariant broken: totalSupply != sum(balances)
    }

    // VULNERABLE: Race condition on shared state
    function liquidateAndSwap(address borrower, address token) public {
        // Liquidate collateral
        uint256 collateral = balances[borrower];
        balances[borrower] = 0;
        totalBorrowed -= debt[borrower];

        // RACE: Between liquidation and swap, balances are inconsistent
        // Another transaction reading balance would see 0 but borrow still active

        // Swap collateral for repayment
        uint256 repayment = IDex(DEX).swap(token, USDC, collateral);
        require(repayment >= debt[borrower]);
    }
}

contract LogicErrorExploiter {
    VulnerableLending public target;

    function exploitInterestAccrual() public {
        // STEP 1: Deposit collateral
        IERC20(collateral).transferFrom(msg.sender, address(target), 100 ether);

        // STEP 2: Borrow 80 ether (80% LTV)
        target.borrowWithInterest(80 ether);

        // Interest accrued but not in balance, so collateral value is overstated

        // STEP 3: Borrow again against accrued interest
        target.borrowWithInterest(10 ether);  // Should fail, but doesn't

        // Extracted 10 extra ether due to double-counted interest
    }

    function exploitDoubleRewardClaim() public {
        // Claim rewards without reset
        target.claimRewards(address(this));  // Get reward
        target.claimRewards(address(this));  // Get same reward again!

        // No state was reset, so same reward claimed twice
    }
}

Real-World Business Logic Exploits

| Protocol | Date | Loss | Root Cause | |----------|------|------|-----------| | Curve Finance | 2020 | $20M | Calculation error in stable swap formula | | Yearn Finance | 2021 | $11M | Logic error in strategy switching | | Bancor | 2020 | $500K | Oracle logic allowed borrowing against reserves | | Lido (stake rate) | 2021 | $100M+ | Interest accrual logic error |

How to Detect Business Logic Error

Manual detection requires protocol understanding:

  • Protocol assumptions: Document core assumptions (invariants, order of operations)
  • State consistency: Verify state changes maintain invariants
  • Order verification: Confirm operations occur in correct order
  • Double-check: Look for variables used twice in different contexts
  • Fee flow: Trace all fees from collection to distribution
  • Edge cases: Test boundary conditions and concurrent operations
  • Calculation verification: Hand-check interest, liquidation, and fee calculations

Red flags:

  • State updates not immediately after use (deferred updates)
  • Variables used in multiple calculations (double-counting risk)
  • Missing state resets after operations
  • Rewards/fees calculated but not distributed
  • Operations on stale state in concurrent scenarios
  • Calculations that don't match documented formulas

How Firepan Detects Business Logic Error Automatically

Firepan's HOUND AI performs invariant and state analysis:

  1. Invariant identification: Identifies protocol invariants from code patterns
  2. Invariant verification: Checks whether invariants are maintained through all code paths
  3. State consistency mapping: Traces state updates and identifies stale state usage
  4. Order verification: Confirms operations occur in correct logical sequence
  5. Double-usage detection: Flags variables used in multiple calculations
  6. Fee flow tracking: Traces fees from collection to distribution
  7. Concurrent operation simulation: Tests behavior under concurrent state access

Firepan's HOUND AI engine identifies logic errors across all monitored contracts.

Prevention Best Practices

1. Document Protocol Invariants

Explicitly state invariants for all critical state:

// INVARIANT: totalSupply == sum(balances[*])
// INVARIANT: totalBorrowed == sum(debt[*])
// INVARIANT: collateralValue[user] >= debt[user] * LTV

// These should be verified by assertions or tests

2. Use Checks-Effects-Interactions (CEI) Pattern

Always update state BEFORE external calls:

// CORRECT order
function withdraw(uint256 amount) public {
    require(balances[msg.sender] >= amount);

    balances[msg.sender] -= amount;  // Update state first
    totalSupply -= amount;

    (bool success, ) = msg.sender.call{value: amount}("");  // Then call
    require(success);
}

3. Verify Invariants with Assertions

Add assertions to catch invariant violations:

function transfer(address to, uint256 amount) public {
    balances[msg.sender] -= amount;
    balances[to] += amount;

    // Verify invariant
    assert(getTotalSupply() == totalSupplyVariable);
}

function getTotalSupply() private view returns (uint256) {
    // Sum all balances
}

4. Test Concurrent Operations

Use property-based testing to find concurrent state issues:

// Property: liquidation + swap should be atomic
// Property: borrowing should respect LTV after interest accrual
// Property: reward claims should not allow double-claiming

// Use Echidna to test these properties

5. Formal Verification

For critical logic, use formal verification:

// Prove that invariants hold in all execution paths
// Example: Prove totalSupply is never negative

Frequently Asked Questions

Q: What is business logic error in smart contracts?

A: Business logic error is a flaw in the protocol's core algorithm or assumptions, allowing exploitation even though the code executes as written. Examples include interest accrued after collateral checks or variables double-counted in different calculations.


Q: Which protocols have been exploited via logic errors?

A: Curve Finance ($20M, 2020) had stable swap calculation errors. Yearn Finance ($11M, 2021) suffered strategy switching logic bugs. Bancor ($500K, 2020) had oracle logic allowing borrowing against reserves. Lido ($100M+ risk) had interest accrual logic errors.


Q: How does Firepan detect business logic error?

A: Firepan identifies protocol invariants, verifies they're maintained through all code paths, traces state consistency, confirms operation order, detects double-usage of variables, tracks fee flows, and simulates concurrent operations.


Q: Can business logic error be exploited after deployment?

A: Yes, logic errors are immediately exploitable post-deployment. They exploit the algorithm itself, not implementation bugs. As soon as protocol is live, attackers can execute exploitation paths.


Q: How do I prevent business logic error?

A: Document invariants explicitly. Use Checks-Effects-Interactions (CEI) pattern. Add invariant assertions. Test concurrent operations with property-based testing (Echidna). Consider formal verification for critical logic paths.

Conclusion

Business logic errors have cost protocols over $100M. Unlike code vulnerabilities, logic errors exploit the algorithm itself—fixing requires rethinking design. Curve's stable swap error, Yearn's strategy bugs, and Lido's interest calculations demonstrate the category. Careful invariant documentation, assertion checks, and property-based testing prevent logic errors. Firepan's HOUND AI detects invariant violations and state consistency issues across all monitored contracts.

Start securing your smart contracts at https://app.firepan.com/

Firepan

Scan Your Contracts Now

12,453 contracts secured. 2,851 vulnerabilities blocked. 236 exploits prevented. Run a free surface scan — results in minutes, no credit card required.

Run Free Scan →