# Replay attack to suddenly offboard the re-onboarded lending term

Stale canOffboard flag in LendingTermOffboarding lets anyone force-offboard a re-onboarded lending term, bypassing DAO vote and slashing stakers.

- Payout: Contest reward
- Severity: medium
- Program: Ethereum Credit Guild
- Credited: serial-coder
- Disclosed: 2024-02-22
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-12-ethereumcreditguild-findings/issues/1147
- Library page: https://bugbountylibrary.com/r/c4%3A2023-12-ethereumcreditguild%3AM-05
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic vuln:governance

**Target:** LendingTermOffboarding governance contract
**Root cause:** canOffboard[term] is only reset in cleanup(), which requires all loans closed; a term can be re-onboarded before cleanup runs, leaving the flag set.
**Steps:**
1. `proposeOffboard(term)` and gather quorum via `supportOffboard(snapshotBlock, term)` to set `canOffboard[term]=true`
2. Call `offboard(term)`; loans remain open so `cleanup()` reverts on `issuance()!=0`
3. While loans are being closed, term is re-onboarded via `proposeOnboard()` + timelock; `canOffboard[term]` still true
4. After any delay, attacker (no GUILD needed) calls `offboard(term)` again, force-offboarding the active term
**How found:** Code reading of offboard/cleanup lifecycle: noticed cleanup() is the only place resetting canOffboard, and it is gated on loan closure, creating a window where re-onboarding leaves the flag stale.
**Exploitation:** Attacker waits for a term to be offboarded but not yet cleaned up, lets it be re-onboarded, then calls offboard() to force it down; loans get called and stakers in SurplusGuildMinter can be slashed.
**Escalation:** Timing the attack after re-onboarding and new loan issuance maximizes borrower/staker losses and breaks governance decision.
**Insight:** When a state flag gates a privileged action, check every path that re-activates the guarded object without clearing the flag; lifecycle gaps between offboard and cleanup are replay windows.
