# Mutual consent cannot be revoked and stays valid forever

MutualConsent stores consent per function selector without args or expiry, so a stale consent lets one party later call setRates/addCredit/increaseCredit unilaterally.

- Payout: Contest reward
- Severity: medium
- Program: Debt DAO
- Credited: aphak5010
- Disclosed: 2023-02-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-debtdao-findings/issues/33
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AM-02
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:access-control vuln:business-logic

**Target:** Solidity MutualConsent modifier / LineOfCredit contract
**Root cause:** MutualConsent records consent keyed only by function selector and never clears or expires it, so a prior consent remains valid for any future call with different arguments.
**Steps:**
1. Lender and borrower agree on rates 5% and both call `setRates(5%,5%)`; consent for selector is stored.
2. Borrower proposes 5.1% and both call `setRates(5.1%,5.1%)`, storing another consent.
3. Borrower later calls `setRates(5%,5%)` alone; the stale consent from step 1 satisfies the modifier.
4. Same pattern applies to `addCredit()` and `increaseCredit()`.
**How found:** Code review of MutualConsent modifier: noticed consent mapping keyed by selector with no revocation, expiry, or argument binding.
**Exploitation:** Borrower socially engineers the lender into consenting to multiple setRates calls, then replays an old consent to unilaterally change rates later without lender approval.
**Insight:** When auditing two-party consent modifiers, check whether consent is bound to the exact call arguments and whether it can be revoked or expires; selector-only consent enables replay of stale approvals.
