# Deposit allows for stealing underlying tokens from TruefiProvider, IdleProvider, YearnProvider, BetaProvider, CompoundProvider and AaveProvider balances

Provider deposit() trusts caller-supplied _uToken, letting an attacker mint real yield tokens against the provider's own underlying balance and receive the proceeds.

- Payout: Contest reward
- Severity: high
- Program: Derby
- Credited: hyh
- Disclosed: 2022-10-17
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/411
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Yield-optimiser Provider contracts (Truefi/Idle/Yearn/Beta/Compound/Aave deposit())
**Root cause:** deposit() accepts arbitrary _uToken and _tToken addresses from the caller and only checks the fake token's self-reported balance delta, then mints real yield tokens using the provider's own underlying balance.
**Steps:**
1. Deploy fake ERC20 that reports balanceOf(address(this)) == _amount and returns true on transferFrom without moving funds.
2. Call `deposit(_amount, real_tToken, fake_uToken)` where `_amount = IERC20(real_uToken).balanceOf(provider)`.
3. Provider's balanceBefore/balanceAfter check passes because fake token reports exactly _amount increase.
4. Provider calls join/mint/deposit on real protocol with _amount, consuming its own real underlying balance.
5. Provider transfers minted real yield tokens to msg.sender.
**How found:** Code review of deposit() across providers: noticed _uToken/_tToken are caller-controlled and the only validation is a self-reported balance delta on the attacker-supplied token.
**Exploitation:** Attacker supplies a pre-cooked fake underlying token and the real yield-bearing token address; the provider mints real yield tokens against its own underlying balance and forwards them to the attacker, who redeems them for the stolen underlying.
**Escalation:** Applies to all six providers; in Beta Finance the BETA reward tokens accumulate on the provider and have a market, so the entire vault's reward yield can be stolen.
**Insight:** When a function takes both token addresses as parameters, the balance-delta check on the caller-supplied token is meaningless; check the real token's balance before/after instead, as CompoundProvider.withdraw() does.
