# Malicious user can steal native tokens of MoneyMarketHook caller

MoneyMarketHook multicall lacks reentrancy guard; an ERC777 token callback during a second withdraw lets an attacker re-enter execute and drain the contract's wrapped-native balance owed to the victim.

- Payout: Contest reward
- Severity: medium
- Program: INIT Capital
- Credited: rvierdiiev
- Disclosed: 2024-01-16
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-12-initcapital-findings/issues/19
- Library page: https://bugbountylibrary.com/r/c4%3A2023-12-initcapital%3AM-07
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:reentrancy

**Target:** MoneyMarketHook.execute multicall / wrapped native token unwrap
**Root cause:** execute() unwraps the entire WETH balance and sends it to msg.sender with no reentrancy guard; an ERC777 hook during a later withdraw in the same multicall re-enters execute and claims the balance.
**Steps:**
1. Victim calls `execute` with multiple withdraws: first a wrapped-native withdraw (WETH lands on MoneyMarketHook balance), then a withdraw of an ERC777 token with `to` set to attacker contract.
2. During the second withdraw, `IInitCore.burnTo` transfers pool tokens to the attacker's `to` address, triggering the ERC777 `tokensToSend`/`tokensReceived` hook.
3. Attacker re-enters `MoneyMarketHook.execute` with any valid params and `_params.returnNative = true`.
4. Re-entrant call unwraps the full WETH balance and sends native tokens to the attacker.
5. Control returns to the victim's multicall, which unwraps/sends 0 to the victim.
**How found:** Code reading of MoneyMarketHook: noticed the final unwrap sends the entire contract WETH balance to msg.sender (succeeds even at 0), that execute lacks a reentrancy check, and that withdraw supports arbitrary `to` recipients which can trigger ERC777 hooks mid-multicall.
**Exploitation:** Attacker must be the `to` recipient of an ERC777 withdraw within the victim's multicall; on the token hook they re-enter execute with returnNative=true to sweep the WETH balance the victim's earlier withdraw left on the hook contract.
**Insight:** In multicall-style hooks, look for a final step that sweeps the contract's whole token balance to msg.sender combined with any callback-capable token transfer (ERC777/ERC677) to an attacker-chosen recipient earlier in the same call; the sweep becomes reentrancy-stealable.
