# Lack of access control allow attacker to mintFungible() and mintSynth() with other user's wallet balance

VaderPoolV2.mintFungible/mintSynth take arbitrary from/to addresses, letting anyone drain approved users' token balances into their own LP position.

- Payout: Audit contest
- Severity: high
- Program: Vader Protocol
- Found by: WatchPug
- Disclosed: 2022-02-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-11-vader-findings/issues/204
- Library page: https://bugbountylibrary.com/r/c4%3A2021-11-vader%3AH-21
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** VaderPoolV2 DEX pool contract (mintFungible/mintSynth)
**Root cause:** mintFungible() and mintSynth() pull funds via safeTransferFrom(from,...) and mint LP/synth to `to`, both caller-supplied, with no check that from == msg.sender or that the caller is authorized to spend on behalf of `from`.
**Steps:**
1. Victim approves VaderPoolV2 for native/foreign tokens (normal LP usage).
2. Attacker calls `mintFungible(foreignAsset, nativeDeposit, foreignDeposit, victim, attacker)` with deposits up to the victim's allowance.
3. Contract executes `nativeAsset.safeTransferFrom(victim, pool, nativeDeposit)` and `foreignAsset.safeTransferFrom(victim, pool, foreignDeposit)`.
4. LP tokens are minted to `to = attacker`, capturing the victim's funds as attacker-owned liquidity.
5. Repeat for mintSynth() to convert victim balances into synth tokens owned by attacker.
**How found:** Code review of mintFungible: noticed `from` and `to` are independent caller-supplied parameters and that safeTransferFrom uses `from` without verifying msg.sender == from.
**Exploitation:** Attacker needs only a victim address with an outstanding allowance to the pool; no capital required. By setting `from` to the victim and `to` to themselves, the attacker mints LP/synth backed entirely by the victim's approved tokens, then can redeem/withdraw to realize the value.
**Escalation:** Applies to every user who ever approved the pool, so a single attacker can sweep all outstanding approvals in one loop.
**Insight:** In AMM/pool contracts, any function taking both `from` and `to` as parameters must enforce `from == msg.sender` (or an explicit allowance/operator check); grep for safeTransferFrom(from,...) patterns where `from` is not msg.sender.
