# BaseTOFT.sol: retrieveFromStrategy can be used to manipulate other user's positions due to absent approval check

retrieveFromStrategy lacks an approval check on the `from` parameter, letting anyone force-withdraw a victim's YieldBox position cross-chain without consent.

- Payout: Contest reward
- Severity: high
- Program: Tapioca DAO
- Credited: carrotsmuggler
- Disclosed: 2023-11-16
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-07-tapioca-findings/issues/1032
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-tapioca%3AH-34
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** BaseTOFT / BaseTOFTStrategyModule cross-chain strategy withdrawal
**Root cause:** retrieveFromStrategy accepts an arbitrary `from` address and forwards it through LayerZero; on the destination chain the msg.sender is the lzEndpoint, so the strategyWithdraw path never verifies the original caller was authorized for `from`.
**Steps:**
1. Victim approves TOFT contract on YieldBox and deposits into strategy via sendToStrategy.
2. Attacker calls `tapiocaOFT10.retrieveFromStrategy(victim, amount, share, assetId, dstChainId, ...)` with victim as `from`.
3. BaseTOFTStrategyModule packs `from` into lzPayload and lzSend to source chain.
4. lzEndpoint delivers message; TOFT decodes `from` and calls `_retrieveFromYieldBox(assetId, amount, share, from, address(this))`.
5. YieldBox sees msg.sender = TOFT (approved) and withdraws victim's shares; tokens are bridged back to `from`.
**How found:** Code reading of the cross-chain message flow: noticed `from` is attacker-controlled and that after LayerZero delivery msg.sender becomes the endpoint, so no approval check on the original caller exists.
**Exploitation:** Attacker pays gas on both chains to trigger a cross-chain withdrawal of the victim's YieldBox position; no allowance from victim to attacker is required because the TOFT contract itself is the approved spender.
**Insight:** In LayerZero/OFT-style cross-chain handlers, the destination-side msg.sender is always the endpoint, not the user — audit whether the packed `from`/`to` fields are ever authenticated against the original caller before acting on their behalf.
