Back to P2P Loans

An honest audit

Both FlashBank features, reviewed candidly: what they do, who you have to trust, what can go wrong, and exactly what is and isn't tested. We would rather under-claim than oversell — so this page leads with the limitations, not the badges.

No external audit. Neither contract has been reviewed by a professional auditing firm. Everything below is our own reading of our own code. The severities are our judgement, not an independent rating.

The P2P loans are a Sepolia playground. They run on a testnet with play-money only — no real value. Never send real assets to the playground contracts.

Open by default. Source for both contracts is verified on Etherscan and public on GitHub. Please read it, and tell us what we missed.

Flash-loan router

Custody
Non-custodial (allowance-based)
Liquidity
Stays in provider wallets
Tests
57 passing · 21 pending
Admin model
Dual-sig + single-sig emergencies
External audit
None
Upgradeable
No (immutable)

P2P term loans

Custody
Escrow between create & settle
Pricing
No oracle · time-based only
Tests
45 passing
Owner powers
Interface fee only (≤ 1%)
External audit
None
Network
Sepolia playground

How to read this

StrengthBy designTrust assumptionLowMedium

Strength is something we think we got right. By design is a deliberate trade-off you should understand before using it. Trust assumption means there is a person or counterparty you are relying on. Low / Medium are issues ranked by our own estimate of impact and likelihood.

Flash-loan router

FlashBankRouter lets anyone borrow a token within a single transaction, provided they return it plus a fee before the transaction ends. Liquidity is never pooled in the contract — it stays in provider wallets and is pulled, used and returned inside one atomic call.

Custody & settlement

Providers approve the router as a spender; the router pulls only at loan time and returns funds in the same transaction. Repayment is checked by comparing balances before and after — if the borrowed amount plus fee has not come back, the whole transaction reverts. There are no price oracles and no liquidations.

Trust assumptions & findings

Strength

Non-custodial, immutable, reentrancy-guarded

Provider funds never sit in the contract. flashLoan() is nonReentrant, repayment is balance-verified, the borrower callback runs inside a try/catch, and there is no upgrade proxy — the deployed bytecode is what runs forever.

Trust assumption

A live allowance is a standing exposure

To earn fees you grant the router an ERC-20 allowance. While that allowance is live, a bug in the (immutable) router could in principle move up to the approved amount. Mitigations: the code is small and reentrancy-guarded, every loan must round-trip in one transaction, and you can pause or set your allowance to zero at any time.

Medium

The owner can take up to 100% of the fee

ownerFeeBps is capped at 100% of the fee (not of the loan). A misconfiguration or hostile owner could route the entire fee to the protocol, leaving providers with their principal back but no reward. Providers can pause if they dislike the split. The loan fee itself is hard-capped at 0.01%–1%.

Medium

Single-signature emergency paths exist

Most sensitive actions use a propose/execute dual-signature flow, but setTokenConfig andwithdrawOwnerProfits are callable by the owner or admin alone. A single compromised key can therefore change fees/limits/enabled-status and sweep accrued protocol fees (not provider funds).

Trust assumption

Admin rescue can move the contract's own balance

proposeRescueToken/RescueETH (dual-sig) can send any token or ETH the contract holds to any address. The router is normally near-empty, but this covers transient loan funds and accrued fees, so it is a real operator capability worth knowing about.

By design

Owner can disable a token / fee-on-transfer unsupported

Disabling a token only blocks new loans; existing commitments and balances are untouched. Rebasing and fee-on-transfer tokens are unsupported by design because settlement relies on exact balance deltas.

Low

Committed total can drift from real balances

If a provider moves funds out of their wallet, totalCommitted can overstate availability. No funds are at risk (pulls re-check the real balance at loan time); the UI reads getActualAvailableLiquidity() for an accurate figure.

Tested: 57 passing tests with 21 pending (skipped) — covering reentrancy, failed-repayment reverts, max-borrow guards, overflow on unlimited commitments, and the dual-control flows. The pending tests are a coverage gap we are honest about. Deeper router-specific analysis lives on the security deep-dive.

P2P term loans

FlashBankP2PLoan is a neutral escrow for fixed-term, collateral-backed loans between two people. One side posts terms, the other takes them. Repay principal + a flat fee before the deadline to redeem the collateral; miss it and the lender claims it. No pools, no shared liquidity, no oracle.

Custody & settlement

The contract holds the escrowed side only between creation and settlement. Default is decided purely by the clock: after maturity + grace, an unpaid loan can be claimed. Optionally, an agreed rate(settlementValue, frozen at origination) returns any over-pledged surplus to the borrower on default — still without ever reading a price.

Trust assumptions & findings

Strength

The owner cannot touch escrowed funds

There is no rescue, no admin pull and no upgrade proxy. The owner can only set the optional interface fee (hard-capped at 1%) and where it is sent. Escrowed principal and collateral can leave only via the loan's own repay / claim / cancel paths. A conservation assert backs the disbursement maths, and it is fuzz-tested.

Trust assumption

You must vet the counterparty's tokens

Either side picks the principal and collateral tokens. A malicious offer could name a honeypot or rug token. The contract cannot know a token is “real” — always check both token addresses before you take an offer.

By design

No early liquidation — the lender carries price risk

Because nothing is priced on-chain, a lender cannot act early if collateral falls in value mid-term; they wait for the deadline. That is the deliberate cost of having no oracle. Lenders should size the fee and (optional) agreed rate accordingly.

By design

The agreed rate is a handshake, not a market price

settlementValue is whatever the two parties agree and is frozen forever. Set it high and a defaulting borrower keeps more surplus (the lender can under-recover); leave it at 0 and the lender keeps the whole pledge (the borrower can lose more than they borrowed). Both outcomes are intended and shown up front.

Strength

Offers are editable in place; the featured boost is non-refundable on cancel

You can re-price or amend an open offer's non-escrow terms with updateOffer (the agreed rate, flat fee, duration, grace and service fee) and top up placement with boostOffer — both keep your existing featured spend. Each edit bumps a version, and takeChecked pins it so a taker can't be front-run by a last-second re-price. Cancelling still refunds the escrow and listing fee but not the featured boost(an advertising spend) — which is exactly why in-place editing exists.

By design

All-or-nothing repayment; no fee-on-transfer tokens

There is no partial repayment — you redeem the whole collateral or none of it. As with the router, rebasing and fee-on-transfer tokens are rejected because terms are enforced to the exact unit.

Tested: 45 passing tests covering the full lifecycle (create/take/repay/default/cancel), the optional surplus split (including rounding in the borrower's favour), in-place offer amendments with the version-pinned take (so a re-price can't be front-run), a live re-entrancy attack via a malicious token, fee edge cases, and a conservation fuzz test. See how the mechanics work on the loans page and Lorrow compatibility.

What “tested” means here

Tests are automated checks we wrote. They catch the bugs we thought of — not the ones we didn't. They are not a guarantee of correctness, and they are not an audit. Treat a green suite as necessary, never sufficient.

Responsible disclosure

Found something we missed? Please tell us before telling the world. Open an issue or PR on GitHub, or email security@flashbank.net. We read the code with you.