Skip to main content

Overview

The Flash-Loan Router implements a multi-layered security model ensuring that only authorized solvers can execute settlements, settlement data remains immutable throughout execution, and no funds can be extracted outside the settlement flow.

Core Security Properties

1. Solver Authentication

Only registered CoW Protocol solvers can call flashLoanAndSettle(). Authentication is verified through the same authentication contract used by the CoW Settlement contract.
modifier onlySolver() {
    require(
        settlementAuthentication.isSolver(msg.sender),
        "Not a solver"
    );
    _;
}
The solver registry is managed by CoW Protocol governance, ensuring that only trusted entities can initiate flash loan settlements.

2. Data Integrity

Settlement call data is hashed and verified at each borrower callback stage. Any attempt to modify the data between callbacks will cause the transaction to revert.
function borrowerCallBack(bytes memory loansWithSettlement) external onlyPendingBorrower {
    require(
        loansWithSettlement.hash() == pendingDataHash,
        "Data from borrower not matching"
    );
    borrowNextLoan(loansWithSettlement);
}

3. Execution Guarantees

Each call to flashLoanAndSettle results in exactly one call to settle(). The state machine transitions ensure this property:
  • READY -> Borrower addresses -> SETTLING -> READY
  • No state can be skipped or repeated

4. Reentrancy Protection

The pendingBorrower transient storage variable prevents nested or concurrent settlement execution. When the state is not READY, new settlements cannot begin.

Borrower Security

Borrower adapters restrict fund access through two mechanisms:
  • onlyRouter modifier: Only the registered router can trigger flash loans
  • onlySettlementContract modifier: Only the settlement contract can set ERC-20 approvals
The only way to move funds out of a borrower is through ERC-20 approvals set during settlement execution. This ensures borrowed funds can only be accessed within the settlement context.

Threat Model

Protected Against

ThreatProtection
Unauthorized settlement executionSolver authentication via CoW Protocol’s authenticator
Settlement data tamperingHash verification at each callback step
Reentrancy attackspendingBorrower state check prevents nesting
Out-of-order loan executiononlyPendingBorrower validates expected caller
Unauthorized fund accessonlySettlementContract restricts approvals
Multiple settlements per callState machine enforces single settlement

Risk Factors

While user funds in CoW Protocol remain safe, solvers should be aware that malicious tokens, lenders, or borrowers can modify chain state before the settle() call. This could cause settlements to revert or execute at unfavorable prices, affecting solver profitability but not user fund security.
Specific risks include:
  • Malicious tokens: Non-standard ERC-20 implementations may behave unpredictably
  • Malicious lenders: Could manipulate state during flash loan callbacks
  • Malicious borrowers: Could attempt to alter execution flow (mitigated by hash verification)

Trust Assumptions

The Flash-Loan Router security model relies on the following trusted components:

Trusted (CoW Protocol)

  • Settlement Contract: Correctly executes settlements
  • Authentication Contract: Correctly identifies authorized solvers
  • Solver Registry: Managed by governance with appropriate access controls

Requires Verification (External)

  • Flash Loan Providers: Solvers should verify lender legitimacy through reputable sources
  • ERC-20 Tokens: Token contracts should be audited and well-known
  • Borrower Adapters: Each adapter should be reviewed for correct implementation

Function-Level Security

flashLoanAndSettle()

  • Restricted to registered solvers
  • Validates no concurrent settlement
  • Hashes and stores settlement data
  • Emits event for transparency

borrowerCallBack()

  • Only callable by the expected pending borrower
  • Validates data integrity via hash comparison
  • Continues sequential loan processing

settle()

  • Validates only settle() function selector
  • Executes settlement and requires success
  • Sets state to SETTLING

Borrower approve()

  • Only callable by the settlement contract
  • Sets ERC-20 approvals for fund management
  • Cannot be called outside settlement context

Next Steps

Last modified on March 4, 2026