Security Audit
Comprehensive security analysis and testing results
✅ PRODUCTION READY
All critical security tests passed. Contract audited and verified for mainnet deployment.
Key Security Features
Funds Stay in Your Wallet
Your WETH never leaves your wallet. The router only pulls funds during active flash loans and returns them immediately with your fee share.
Full Provider Control
Pause your commitment at ANY time. Set expiry dates and adjust limits. Your funds, your rules.
Owner Cannot Steal Funds
No withdrawal functions exist for provider funds. Owner can only withdraw legitimately earned fees (capped at 1% of loans).
Fee Limits Enforced
Fees hardcoded between 0.01% - 1%. Owner fee capped at 100% of the fee. No excessive fees possible.
Ownership & Rescue Hardening
transferOwnership and renounceOwnership are disabled. Ownership transfers and ERC-20/ETH rescue flows now follow the same dual-signature path as fee changes.
Flexible Token Wrapper
The wrapper address is only used when loans must be paid in native ETH (e.g. WETH unwrap for toNative demos). Future tokens (LINK, wstETH, etc.) can set wrapper = 0 to be loaned as themselves.
Reentrancy Protection
OpenZeppelin's ReentrancyGuard prevents reentrancy attacks on flash loan execution.
Overflow Protection
Solidity 0.8.24 built-in overflow protection plus OpenZeppelin SafeMath for critical calculations.
Attack Resistance
Admin Privilege Analysis
Owner Cannot Steal Funds
Finding: Owner has NO ability to withdraw provider funds.
Evidence:
- No
withdraw()oremergencyWithdraw()functions - Only
withdrawOwnerProfits()exists for legitimate fees - Providers' funds stay in their own wallets
- Router only has approval to pull during active loans
Fee Limits Are Enforced
Hardcoded Limits:
- Minimum Fee: 0.01% (1 bps)
- Maximum Fee: 1% (100 bps)
- Owner Fee: 0-100% of the fee (max 1% of loan)
- Cannot be bypassed or changed beyond these limits
Dual-Signature Control (2-of-2 Multi-Sig)
Security Design: Critical operations require TWO independent signatures.
How It Works:
- Step 1: Owner (deployer) proposes change
- Step 2: Admin (Vultisig vault) approves and executes
- Both must agree for config changes or profit withdrawals
- Single compromised key cannot modify the protocol
Protected Operations:
- Fee configuration changes
- Pool limit adjustments
- Owner profit withdrawals
- Token enable/disable
- Ownership transfer (propose + execute)
- ERC-20 / ETH rescue transactions
Admin Address: 0xC021...319e7 (Vultisig vault)
Testnets can override via TESTNET_ADMIN_ADDRESS. Current Sepolia admin is 0x3CD6...c191 for compatibility with wallets that do not support Sepolia.
How to Approve Changes (via Etherscan)
Vultisig uses TSS, so there is no single private key to paste into a CLI. Everything can be performed directly from the Write Contract tab on Etherscan:
1. Owner (deployer device) proposes
- Open router contract on Etherscan → Contract → Write Contract
- Connect deployer wallet
- Call
proposeTokenConfigorproposeProfitWithdrawal - Copy the emitted
ChangeProposedhash (optional)
2. Admin (Vultisig vault) executes
- Open the same contract on Etherscan from the Vultisig wallet
- Call
executeTokenConfigorexecuteProfitWithdrawalwith identical parameters - Vultisig automatically co-signs the transaction across devices
- Transaction emits
ChangeExecutedfor audit trail
Need a refresher? See the dual-control runbook for screenshots and detailed instructions.
Owner Can Disable Token (Emergency)
Impact: Owner can set enabled = false to prevent new flash loans.
Mitigation:
- Existing commitments remain intact
- Providers can still pause/withdraw
- No funds are locked
- Only prevents NEW flash loans
Verdict: This is a safety feature for emergency shutdown, not a vulnerability.
Concurrent Flash Loan Test Results
Two concurrent flash loans executed successfully in block 9704215 on Sepolia testnet, proving the system handles simultaneous borrowing without interference.
- ✅ Providers' WETH stayed in their wallets
- ✅ Router pulled liquidity on-demand
- ✅ No interference between concurrent loans
- ✅ Owner accumulated 0.000000084 WETH in profits (2% of fees)
- ✅ Borrowers only needed fees, not full loan amounts
Known Limitations & Mitigations
Balance Tracking (Low Risk)
Issue: If a provider receives or sends WETH externally, the totalCommitted value doesn't automatically update.
Impact:
- ✅ No fund loss possible (router checks actual balance)
- ⚠️ UI might show misleading "Total Committed" value
- ⚠️ Loans might fail if provider sent WETH away
Mitigation:
- Router checks actual balance at pull time
- Never over-pulls from providers
- Website uses
getActualAvailableLiquidity()for accurate display - Commitments shown as intent, not guarantee
No Forced Withdrawal During Loan
Behavior: Providers cannot force-withdraw WETH while it's actively in use for a flash loan.
Rationale:
- Flash loans are atomic (single transaction)
- Funds return immediately after loan completes
- This ensures borrowers can repay
- Providers can pause to prevent NEW loans
Edge Cases Handled
Critical Code Paths
struct TokenConfig {
bool enabled;
bool supportsPermit;
uint16 feeBps; // 0.01% – 1%
uint256 maxFlashLoan; // absolute cap
address wrapper; // WETH or native bridge
uint16 maxBorrowBps; // % of pool borrowable
uint16 ownerFeeBps; // owner's cut of fee
}uint256 maxBorrow = Math.mulDiv( totalCommitted[token], config.maxBorrowBps, FEE_DENOMINATOR ); if (amount > maxBorrow) revert ExceedsMaxBorrowLimit();
Unlimited commitments previously risked overflowing totalCommitted * maxBorrowBps. We now calculate borrow caps with Math.mulDiv, ensuring the percentage guard holds for any pool size.
Testing & Verification
Automated Coverage
- ✓ 62+ Hardhat/Foundry tests
- ✓ Dedicated failure-path tests (FlashLoanFailed, paused router)
- ✓ Demo borrower integration tests
- ✓ Concurrent loan tests (same block)
- ✓ Owner privilege tests
- ✓ Provider control tests
Manual Review Checklist
- ✓ Verified bytecode on Etherscan
- ✓ Checked owner cannot drain WETH
- ✓ Ensured Math.mulDiv guards unlimited commitments
- ✓ Confirmed fee limits enforced
- ✓ Verified reentrancy protection
- ✓ Tested balance tracking
Contract Information
Bug Bounty & Responsible Disclosure
Found something concerning? Please disclose responsibly.
Critical issues are rewarded. Provide reproduction steps, impact analysis, and recommended fixes. We take security seriously and will respond promptly to all reports.
Security Verdict
The FlashBankRouter contract has passed comprehensive security testing and demonstrates:
- Strong security properties with no critical vulnerabilities
- Provider fund safety with non-custodial architecture
- Strict admin privilege limitations
- Comprehensive attack resistance
- Proper accounting and overflow protection
Contract verified on Etherscan. All source code is open source and available for independent review.