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.
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:
Logic error exploitation typically involves:
// 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
}
}
| 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 |
Manual detection requires protocol understanding:
Red flags:
Firepan's HOUND AI performs invariant and state analysis:
Firepan's HOUND AI engine identifies logic errors across all monitored contracts.
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
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.
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
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 →