# Maximal approvals remain for the AssetManager's adapters and tokens after removal

AssetManager's removeAdapter/removeToken never revoke unlimited ERC20 approvals, so a removed malicious adapter or token can still drain the contract's residual balance.

- Payout: Contest reward
- Severity: medium
- Program: Union Finance
- Credited: hyh
- Disclosed: 2022-11-04
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-10-union-finance-judging/issues/36
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-10-union-finance%3AM-15
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** AssetManager.sol removeAdapter/removeToken (Solidity lending vault)
**Root cause:** removeAdapter() and removeToken() only pop entries from moneyMarkets/supportedTokensList without zeroing the unlimited safeApprove allowances previously granted to adapters and markets.
**Steps:**
1. Admin adds adapter/token; approveAllMarketsMax()/approveAllTokensMax() grant type(uint256).max allowances to each market/adapter.
2. Admin later calls `removeAdapter(adapterAddress)` or `removeToken(tokenAddress)`; only array entry is popped, allowance stays max.
3. Deposits leave residual tokens on AssetManager balance until next rebalance().
4. Removed adapter/token (or later-discovered vuln in it) calls `transferFrom(assetManager, attacker, balance)` using the still-live infinite allowance.
**How found:** Code review of removeAdapter/removeToken against the approveAllMarketsMax/approveAllTokensMax grant path, noticing approvals are never revoked on removal while deposit() leaves funds on the contract.
**Exploitation:** A malicious or later-compromised adapter/token retains an unlimited allowance; a bot watches AssetManager's token balance and pulls it via transferFrom whenever residual funds sit on the contract before rebalance.
**Insight:** When auditing vaults that grant max approvals to pluggable adapters/markets, check the removal/deregistration path revokes allowances — stale infinite approvals outlive the trust decision and become a latent drain vector.
