# Rico BankDiamond: arbitrary call in flash drains tokens

Rico BankDiamond's flash function executed arbitrary calldata, letting an attacker transfer all tokens and drain owner allowances, netting 36K.

- Payout: Real-world hack
- Severity: high
- Program: Rico
- Analysis by: DeFiHackLabs
- Disclosed: 2024-04-20
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2024-04/Rico_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20240420-rico
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** BankDiamond contract on Arbitrum
**Root cause:** The flash function accepted arbitrary calldata and executed it without validating the target or operation, allowing any caller to invoke token transfer/transferFrom on behalf of the contract.
**Steps:**
1. Fork Arbitrum at block 202973712.
2. Call `IBankDiamond(BankDiamond).flash(token, abi.encodeWithSelector(IERC20.transfer.selector, address(this), tokenBalance))` for each token held by BankDiamond to transfer entire balance to attacker.
3. For owners with allowances to BankDiamond, call `flash(token, abi.encodeWithSelector(IERC20.transferFrom.selector, owner, address(this), tokenBalance))` to pull tokens up to allowance.
4. Swap all received tokens to USDC via UniV3Router `exactInputSingle`.
**Exploitation:** Attacker called flash with crafted calldata to make BankDiamond execute token transfers to the attacker, then transferredFrom owners' allowances, and swapped all tokens to USDC.
**Insight:** When a contract exposes a flash-loan-like function that takes arbitrary calldata, check if it executes that calldata directly on any token or contract without restricting the target or operation; this allows draining all token balances and allowances held by the contract.
