# Rogue pool in Shelter

Shelter client can re-call activate to reset the grace timer, blocking user withdrawals while enabling deactivate to drain all donated tokens.

- Payout: Audit contest
- Severity: medium
- Program: Concur Finance
- Found by: 0x1f8b
- Disclosed: 2022-05-24
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-02-concur-findings/issues/74
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-concur%3AM-19
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** Shelter.sol token shelter contract (activate/deactivate/donate/withdraw)
**Root cause:** activate() lacks a guard against re-activation, so the client can reset activated[_token] at will; withdraw requires activated+GRACE_PERIOD < now while deactivate requires activated+GRACE_PERIOD > now, so resetting the timer flips which path is open.
**Steps:**
1. client calls `activate(tokenA)`
2. users deposit tokenA via `donate`
3. client calls `activate(tokenA)` again near end of GRACE_PERIOD to reset start time
4. more users `donate`
5. client calls `deactivate(tokenA)` while activated+GRACE_PERIOD > block.timestamp and receives all tokens; users cannot `withdraw` since activated+GRACE_PERIOD < block.timestamp is false
**How found:** Code reading of Shelter.sol L38-42: noticed activate has no already-activated check and that the withdraw/deactivate conditions are complementary on the same timestamp, so resetting it locks users out while unlocking the client.
**Exploitation:** Malicious client repeatedly re-activates the token to keep the grace window perpetually open, preventing user withdrawals, then calls deactivate to sweep all donated funds.
**Insight:** When two functions gate on opposite comparisons of the same mutable timestamp, check whether an unguarded setter can flip which side of the boundary you're on; re-callable init/activate functions are a classic lever.
