<!-- canonical: https://0xsimao.com/findings/m-0-total-principal-invariant-broken -->

# MToken's total principal invariant can be broken

Crit/High · Three Sigma · Stablecoin framework · 8th January, 2024

Finding 3S-M^0-M01 of the M^0 Minter Gateway security review.

- Protocol: https://www.m0.org/
- Report: /reports/m-0
- Codebase: https://github.com/0xsimao/ttg/tree/a8127901fa1f24a2e821cf4d9854a1aa6ac8088c
- Source: https://cdn.sanity.io/files/qoqld077/production/1cdafafad874aba76e062ad8c216c98338c096db.pdf

---

### Description

Because there's an unchecked total earning principal addition in
[MToken._addEarningAmount](https://github.com/MZero-Labs/protocol/blob/3499f50ff3382729f3e59565b19386ba61ef8e36/src/MToken.sol#L176-L181), the MToken contract would be subject to a potential silent
overflow of principalOfTotalEarningSupply. However, there's a check in the
[MinterGateway.mintM](https://github.com/MZero-Labs/protocol/blob/3499f50ff3382729f3e59565b19386ba61ef8e36/src/MinterGateway.sol#L261-L275) function that's supposed to prevent this from ever happening.
But because minterRate and earnerRate can be different, it is possible that a silent
overflow happening in MToken doesn't get caught by the check in MinterGateway. The
transaction will not be reverted, and principalOfTotalEarningSupply will silently
overflow, reaching a broken state. Because a silent overflow in MToken will lead to an
additional mint of MinterGateway.excessOwedM, the function can still revert in a safe
uint112 cast within MToken.mint. But there's still possible mint amount values which will
lead to a successful transaction.
Close to the point of overflow, a malicious minter could mint the appropriate amount to
make MToken reach the broken state. The overflowed principalOfTotalEarningSupply
might still be used to drive further impact to the protocol.

### Recommendation

Use checked addition in _addEarningAmount.

```solidity
function _addEarningAmount(address account_, uint112 principalAmount_)
internal {
    unchecked {
        _balances[account_].rawBalance += principalAmount_;

    }
    principalOfTotalEarningSupply += principalAmount_;
}
```

### Status

Addressed in [#74523a8](https://github.com/MZero-Labs/protocol/commit/74523a8e77be8654b902baaca41201d135c72190).
