# redeemToken can fail for certain tokens

SwappableYieldSource.redeemToken used ERC20.transferFrom from the contract to itself, reverting on tokens that enforce allowance checks and locking user deposits.

- Payout: Audit contest
- Severity: high
- Program: PoolTogether
- Found by: cmichel
- Disclosed: 2021-09-15
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-07-pooltogether-findings/issues/61
- Library page: https://bugbountylibrary.com/r/c4%3A2021-07-pooltogether%3AH-02
- Tags: area:web3 domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic

**Target:** SwappableYieldSource Solidity contract (redeemToken)
**Root cause:** redeemToken calls ERC20.transferFrom(address(this), msg.sender, redeemableBalance) instead of transfer; some token implementations check the allowance of the from address (the contract) rather than skipping it when from == msg.sender, so the call reverts.
**Steps:**
1. User deposits tokens into SwappableYieldSource.
2. User calls redeemToken to withdraw redeemableBalance.
3. Contract executes `ERC20.transferFrom(address(this), msg.sender, redeemableBalance)`.
4. Token enforces allowance check on address(this) which never approved itself, so the transfer reverts.
5. Deposited funds remain stuck in the contract, unrecoverable for the user.
**How found:** Code review of the redeem path noticing transferFrom used where transfer semantics were intended, and reasoning about token implementations that enforce allowance on the from address.
**Exploitation:** Not an attack; a functional bug. Any user of an affected token cannot redeem, permanently locking their deposit in the contract.
**Insight:** When a contract moves its own token balance out, transferFrom(address(this),...) is unsafe: some ERC20s check allowance even when from is the caller. Grep redeem/withdraw paths for transferFrom with address(this) as from.

