# There is no price conversion between vault token and provider underlying token amounts in withdrawFromProtocol

Vault.withdrawFromProtocol passes vaultCurrency amount to provider calcShares without FX conversion, so withdrawing from a differently-priced underlying token mis-sizes shares and misbalances the vault.

- Payout: Contest reward
- Severity: medium
- Program: Derby
- Credited: Bobface
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/135
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-31
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:oracle-manipulation

**Target:** Vault.withdrawFromProtocol / Provider.calcShares (Aave, Compound)
**Root cause:** withdrawFromProtocol treats the vaultCurrency-denominated _amount as if it were the provider's underlying token amount, calling calcShares without converting between the two currencies' prices.
**Steps:**
1. Vault currency is USDC; provider underlying is USDT (AaveProvider).
2. USDT trades at 0.8 USD while vaultCurrency USDC is 1 USD.
3. Call `withdrawFromProtocol(protocolNum, 10^12)` intending to withdraw 10^6 USDC.
4. Code rebases decimals then calls `calcShares(_amount, LPToken)` treating 10^12 as USDT amount.
5. Shares computed correspond to ~0.8x the intended value; withdrawal returns ~20% less USDC than requested.
**How found:** Code reading: noticed withdrawFromProtocol's _amount is documented as vaultCurrency but calcShares expects provider underlying token, and no price conversion exists between them; reasoned that stablecoin depeg makes the assumption of equal price invalid.
**Insight:** When a vault abstracts over multiple providers with different underlying tokens, audit every internal call that crosses the vaultCurrency/provider-token boundary for missing FX conversion—especially share/amount math that silently assumes 1:1 price.
