# Lava Post-Mortem: March 28, 2024 **PREFACE** Lava is a lending protocol that focuses on enabling the collateralization of AMM liquidity positions. This comes with different challenges and risks that the protocol has various controls for and aims to continuously mitigate in order to unlock an important and unique asset type. This report is divided into two sections: an operational response review and a technical incident report that details which controls and how those controls were circumvented in the USDC-USDC.e LP contract and what mitigations have been introduced in order to prevent future incidents. **OPERATIONAL RESPONSE** The incident was reported by PeckShield Alert to the protocol on March 28, 2024. Within 15 minutes of reviewing the report, all lending markets on the protocol were paused to prevent any further exploits. Lava community members reached out to contacts at major exchanges to identify the exploit address and prevent potential off-ramping of assets. Within an hour and with coordination of major exchanges, law enforcement incidents were filed. The address has also been listed as a malicious address on the blockchain explorer Arbiscan (Etherscan). All affected addresses were identified and a contingency plan was enacted for compensation by the Insurance Fund, not dependent on the successful return of funds by the attacker. An on-chain message was delivered to the attack address and the final recipient address of exploited funds in accordance to the protocol's exploit response procedures stipulating ongoing investigations will be halted if the attacker returns 90% of user funds. Attack Address: 0x851aa754c39bf23cdaac2025367514dfd7530418 Final Attacker Recipient Address: 0xFBcDB6CECA13b0e2ca51e86C94D78fAaB10A6428 Lava has redeployed new contracts and will redeploy an updated LP contract. Affected addresses will be compensated according to the compensation plan discussed in the community chat. **TECHNICAL INCIDENT REPORT** USDC-USDC.e address: [0x10bdA01aC4E644fD84a04Dab01E15A5eDcEE46dD ](https://arbiscan.io/address/0x10bdA01aC4E644fD84a04Dab01E15A5eDcEE46dD) **State before the attack (block no. 195240642):** * LPT price as per oracle: 28310.525317659138287544 ETH per token unit * Total supply: 999,764,088,549,219 * Balance: 100959.807705 USDC 4.684079 USDC.e * Liquidity: 1108080214664 * Pool Composition: 100% USDC, out of range * aUSDC-USDC.e supply: 1008780764418363 (100.9% of supply) * debtUSDC-USDC.e supply: 10113813004947 (1% of supply) **Attack:** Date: Mar-28-2024 10:57:33 PM +UTC Block No: 195240643 Transaction: [0xcb1a2f5eeb1a767ea5ccbc3665351fadc1af135d12a38c504f8f6eb997e9e603](https://arbiscan.io/tx/0xcb1a2f5eeb1a767ea5ccbc3665351fadc1af135d12a38c504f8f6eb997e9e603) Events: 1. Flash loan: 1. Flash loan 2332.91 ETH from Balancer 1. Flash loan 2.09m USDC from Balancer 1. Flash loan 2.78m USDC.e from Balancer 1. Flash loan 1 unit of USDC from Uniswap (ETH-USDC) 1. Flash loan 1.84m USDC from Aave 1. Flash loan 1 unit of USDC.e from Aave 1. Flash loan 2.7m USDC.e from Uniswap (ETH-USDC.e) 1. Deposit into USDC-USDC.e with 1000 USDC 1. Compound fees (11 USDC, 4 usdc.e) 1. Swap USDC.e for USDC 1. add 175882126453 liquidity (+0.017%) 1. Add liquidity 1. liquidityAdded: 10000999999999 (+0.99%) 1. sharesMinted: 9902135598300 (+0.99%) 1. Transfer 35.7 WETH to account B 1. Deposit 25.7 WETH to VEGA ($125k) 1. Borrow 988680292585834 USDC-USDC.e (98.8% of supply) and transfer to account A 1. Swap USDC.e for USDC 1. Swap 840k USDC.e for USDC ($80 swap fee) 1. Pool's price is now 1.0001 (LP range is equally balanced 50:50) 1. Remove USDC-USDC.e liquidity 998582428184134 shares (98.8% of supply) 1. Compounding fees are skipped since last compound time == block.timestamp 1. Receive 50421 of USDC and 50431 of USDC.e (1008552424386387) liquidity 1. Add USDC-USDC.e liquidity 1. Add 3.2m USDC and 3.2m USDC.e liquidity (64016491927282568) 1. Mint 63383659993147186 shares (+6300% from start) 1. Add 64k USDC and 64k USDC.e liquidity (1280329838527140) 1. Mint an additional 1267673199844615 shares 1. Add Lava deposits 1. Deposit 2297 WETH 1. Deposit 63383659993147186 LPT tokens to VEGA (97% of attackers balance) 1. Transfer aUSDC-USDC.e tokens to account C 1. Borrow out USDC-USDC.e 63,393,646,662,769,266 tokens 1. Remove 65306908143833814 liquidity 1. 64,661,319,862,613,881 shares burned The wrapper now has 1097126341300 shares and 1108080214664 liquidity. This amount of liquidity corresponds to roughly 55 USDC and 55 USDC.e. So far all of the logic was executed correctly. The wrapper also has $81 worth of pending USDC fees (and no USDC.e fees). The wrapper now mistakenly includes the $81 worth of fees as its legitimate assets. Since the underlying liquidity value is just $110, the addition of $81 worth of fees increases the LPT price by 72%. *This gives the account with the LPT token as collateral enough borrow power to borrow out all of Lava's assets.* Donating assets to the wrapper via trading fees was identified as an attack vector. The wrapper tries to prevent this problem by limiting trading fees to a maximum APR value but only if both token0 and token1 trading fees breach the limit. In this case only token0 generated fees were over the limit, but token1 fees were not and the check was not triggered. ![safety](https://hackmd.io/_uploads/SytPELY1C.png) *If the check was implemented with a logical "or" operator instead of "and" the attack would fail.* **Summary:** 1. Create one account with the LPT token as collateral. 1. Generate one-sided trading fees for the LPT. 1. With a different account, borrow and unwind out the LPT tokens. 1. The wrapper mistakenly includes the fees as its assets. Since the actual liquidity is low this greatly increases the LPT token price. 1. First account's borrow power is increased to a point where it can borrow out all of the lending market assets. **Mitigation:** 1. Update the _limitFees function to correctly limit fees even if they are generated only with one token. 1. When the compound function is called for a second time in one block, claim any pending fees as protocol fees.