# Calling `requestRedeem` with `_msgSender() != owner`  will lead to user's shares being locked in the vault forever

requestRedeem on behalf of another owner records lastRedeemRequestId against owner not receiver, permanently locking shares unclaimable by either party.

- Payout: Contest reward
- Severity: high
- Program: Amphor
- Credited: Afriaudit
- Disclosed: 2024-03-04
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-03-amphor-judging/issues/85
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-03-amphor%3AH-2
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** AsyncSynthVault.sol requestRedeem/_createRedeemRequest
**Root cause:** _createRedeemRequest increments redeemRequestBalance[receiver] but sets lastRedeemRequestId[owner] instead of the receiver, so claimRedeem for the receiver finds lastRequestId zero and mints nothing.
**Steps:**
1. Owner deposits 20 tokens, receives vault shares, approves user2 for full share balance.
2. Vault owner calls close(); epoch=1.
3. user2 calls `requestRedeem(balanceOf(user1), user2, user1, "")`; pendingRedeemRequest(user2)==20 but lastRedeemRequestId[user1]=1.
4. Owner calls settle(23); epoch=2.
5. user2 calls `claimRedeem(user2)`; lastRedeemRequestId[user2]==0 so no assets minted.
6. user1 calls `claimRedeem(user1)`; also receives nothing; shares locked.
**How found:** Code reading of _createRedeemRequest revealed the mismatch between the receiver-indexed balance update and the owner-indexed lastRedeemRequestId write, then confirmed via Foundry PoC.
**Exploitation:** Any approved spender triggers requestRedeem with receiver=self and owner=victim; the redeem balance is credited to receiver but the request id is written to owner, so neither party can claim, permanently stranding the shares.
**Insight:** In async vault redeem flows, audit that every state write in the request path is keyed by the same address (receiver vs owner); delegated requestRedeem with receiver != owner is the classic trigger for index mismatch.
