# Malicious user can abuse UpdateCommitment to create commitments for other users

updateCommitment only checks the original lender is msg.sender, not the new lender, letting an attacker reassign a commitment to a victim and drain their approved funds.

- Payout: Contest reward
- Severity: high
- Program: Teller
- Credited: 0x52
- Disclosed: 2023-03-20
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-03-teller-judging/issues/260
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-03-teller%3AH-5
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** LenderCommitmentForwarder.updateCommitment (Solidity contract)
**Root cause:** updateCommitment enforces the caller is the existing commitment's lender via the commitmentLender modifier but never validates that the new _commitment.lender equals msg.sender, so the stored lender can be overwritten to any address.
**Steps:**
1. Attacker calls createCommitment to make a commitment they own (passes commitmentLender check).
2. Attacker calls `updateCommitment(_commitmentId, _commitment)` with a crafted Commitment struct whose `lender` is set to the victim address and with malicious loan parameters (principal, interest, etc.).
3. Only principalTokenAddress and marketId are constrained; the new lender field is written unchecked into `commitments[_commitmentId]`.
4. validateCommitment passes, so the commitment now belongs to the victim.
5. Attacker accepts/borrows against the commitment so the victim's tokens previously approved to the contract are pulled and stolen.
**How found:** Manual code review of updateCommitment: noticed the commitmentLender modifier only checks the original lender is msg.sender, and that the assignment `commitments[_commitmentId] = _commitment` never re-validates the new lender field, unlike the constrained principalTokenAddress and marketId.
**Exploitation:** Attacker first creates a legitimate commitment to satisfy the commitmentLender modifier, then updates it with a Commitment struct pointing lender at a victim who has approved tokens to LenderCommitmentForwarder. The overwritten commitment uses attacker-favorable loan terms; attacker then borrows against it, causing the contract to transfer the victim's approved tokens to the attacker.
**Insight:** When a function both authorizes the caller against stored state and then overwrites that state from calldata, check every field that grants authority (owner/lender/beneficiary) is re-validated against msg.sender after the write, not just before it.
