# Imprecise management of users’ allowance allows the admin of the upgradeable proxy contract to rug users

Aave Lens FeeFollowModule pulls fees via transferFrom on an arbitrary follower address, so an upgradeable proxy admin could swap logic and drain users' unlimited approvals.

- Payout: Audit contest
- Severity: medium
- Program: Aave Lens
- Found by: WatchPug
- Disclosed: 2022-06-13
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-02-aave-lens#m-06
- Library page: http://bugbountylibrary.com/r/c4%3A2022-02-aave-lens%3AM-06
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Upgradeable LensHub proxy and FeeFollowModule/collect modules
**Root cause:** FeeFollowModule.processFollow calls safeTransferFrom(follower, ...) where follower is an arbitrary caller-supplied parameter, and the Hub is an upgradeable proxy, so a malicious admin can replace logic to invoke processFollow against any user who granted unlimited allowance.
**Steps:**
1. Alice approves type(uint256).max to FeeCollectModule and follows profileId 1 paying 1e18 WETH.
2. Malicious/compromised proxy admin calls `upgradeToAndCall()` setting a malicious implementation adding `rugFollow(address follower, address followModule, uint256 profileId, bytes calldata data)`.
3. Attacker creates profileId 2 with FeeCollectModule, currency WETH, amount 1,000,000.
4. Attacker calls `rugFollow()` with follower = Alice, profileId = 2, pulling 1,000,000 WETH from Alice via processFollow's transferFrom.
**How found:** Observed that processFollow's transferFrom source is the input parameter follower rather than msg.sender, combined with the fact that LensHub is an upgradeable proxy and users grant unlimited approvals to modules.
**Exploitation:** Proxy admin upgrades LensHub to malicious implementation exposing a function that calls IFollowModule.processFollow(follower, profileIds, data) with an attacker-chosen follower; the module's safeTransferFrom(follower, recipient/treasury, amount) then moves the victim's approved tokens to the attacker-controlled recipient.
**Insight:** When auditing fee/collect modules, check whether transferFrom's `from` is msg.sender or a caller-supplied parameter; if it's the latter and the calling hub is upgradeable, unlimited approvals become drainable by the proxy admin.

