# Malicious minters can repeatedly penalize their undercollateralized accounts in a short peroid of time, which can result in disfunctioning of critical protocol functions, such as `mintM`.

Mzero's updateCollateral() compounds an undercollateralization penalty on every call, letting a minter push principalOfTotalActiveOwedM to uint112.max and brick mintM.

- Payout: Contest reward
- Severity: medium
- Program: Mzero
- Credited: pkqs90
- Disclosed: 2023-10-27
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-10-mzero-judging/issues/45
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-10-mzero%3AM-2
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:dos

**Target:** MinterGateway.updateCollateral() / mintM()
**Root cause:** The undercollateralization penalty is applied on every updateCollateral() call rather than once per update interval, and it compounds into principalOfActiveOwedM, which is bounded only by uint112.max.
**Steps:**
1. Deposit 100000e6 collateral and mint 90000e6 M (mintRatio 90%, penaltyRate 1%, interval 2000s).
2. Wait 4 intervals so the account becomes undercollateralized; first updateCollateral() applies 4*90000e6*1% = 36e8 penalty.
3. Collect many validator signatures with incrementing timestamps (e.g. one per minute).
4. Call `updateCollateral(100000e6, [], bytes32(0), [validator1], [ts_i], [sig_i])` repeatedly; each call compounds the penalty by 1%.
5. After ~5590 calls principalOfTotalActiveOwedM reaches uint112.max; subsequent `mintM` reverts with OverflowsPrincipalOfTotalOwedM.
**How found:** Code review of updateCollateral() penalty logic: noticed the undercollateralization penalty is charged per call, not per interval, and that principalOfActiveOwedM compounds unboundedly toward the uint112 cap checked in mintM.
**Exploitation:** A malicious minter gathers high-frequency validator attestations of unchanged off-chain collateral, then spams updateCollateral() with each fresh timestamp. Each call re-applies the undercollateralization penalty, compounding principalOfTotalActiveOwedM until it saturates uint112.max, disabling mintM and related functions protocol-wide before validators can deactivate the minter.
**Escalation:** Single minter's repeated calls escalate to protocol-wide DoS of mintM and any function gated on principalOfTotalActiveOwedM.
**Insight:** When a penalty or interest accrual is charged per-call rather than per-elapsed-interval, check whether repeated calls with fresh oracle/validator timestamps can compound a state variable into a hard type bound that gates other functions.
