# Lenders can escape the blacklisting of their accounts because they can move their MarketTokens to different accounts and gain the WithdrawOnly Role on any account they want

Permissionless updateLenderAuthorization grants WithdrawOnly to any unregistered account, letting sanctioned lenders move MarketTokens to fresh accounts and withdraw.

- Payout: Contest reward
- Severity: high
- Program: Wildcat Protocol
- Credited: 0xStalin
- Disclosed: 2023-12-11
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-10-wildcat-findings/issues/266
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-05
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:auth-bypass vuln:business-logic

**Target:** WildcatMarketController / WildcatMarketConfig (Solidity market contracts)
**Root cause:** updateLenderAuthorization is callable by anyone and passes _authorizedLenders.contains(lender); for any account not in the set this is false, and updateAccountAuthorization maps false to AuthRole.WithdrawOnly instead of Null.
**Steps:**
1. Sanctioned lender calls WildcatMarketToken.transfer() to move MarketTokens to fresh accounts with no prior market interaction.
2. Anyone (or the lender) calls WildcatMarketController.updateLenderAuthorization(freshAccount, [market]).
3. _authorizedLenders.contains(freshAccount) returns false, so updateAccountAuthorization(freshAccount, false) is invoked.
4. WildcatMarketConfig.updateAccountAuthorization sets account.approval = AuthRole.WithdrawOnly for the fresh account.
5. Lender queues and executes withdrawals from each fresh account holding MarketTokens, exiting the market despite sanctions.
**How found:** Code reading of Sentinel.isSanctioned showed sanctioning requires the oracle flag; tracing the withdrawal/authorization path revealed updateLenderAuthorization is unpermissioned and that contains() returning false maps to WithdrawOnly rather than Null.
**Exploitation:** A lender flagged by the Chainalysis oracle pre-empts nukeFromOrbit/executeWithdrawal sanctioning by transferring MarketTokens to unregistered accounts, then permissionlessly self-grants WithdrawOnly via updateLenderAuthorization and withdraws from each account.
**Insight:** When a boolean 'isAuthorized' flag is derived from set membership, check what the false branch does—here false silently grants a privileged role instead of no role, turning a permissionless sync function into a role-granting primitive.
