OpenZeppelin / OpenZeppelin/stellar-contracts
🐞 [Bug]: Vault: a mint can leave total_supply + 10^offset unrepresentable, freezing all conversions
@ozgunozerk is already working on this.
Since Sep 15, 2026.
- Dominant language
- Rust
- Stars
- 95
- Forks
- 68
- Avg merge
- 4d 42m
- Merged PRs (30d)
- 20
Description
What happened?
Every vault conversion computes total_supply + 10^offset (the real shares plus the virtual shares) with a checked add and panics with MathOverflow if the sum does not fit in i128. The mint path, however, only checks that total_supply + shares fits. So a deposit or mint can succeed and leave the stored supply less than 10^offset below i128::MAX. From then on every deposit, mint, withdraw, redeem and preview fails on that addition. Since both exit paths convert before burning or transferring, deposited assets cannot leave through the vault interface.
The state is only reachable at the numeric ceiling: it requires a single vault, at the maximum offset of 10, to hold about i128::MAX / 10^10 base units of the underlying, roughly 17 billion whole tokens of an 18-decimal asset. The poisoning deposit is the last base unit of remaining capacity, so this is a robustness gap rather than a practical attack, and we classify it as Low. Fix: check total_supply + shares + 10^offset in deposit_internal before the asset transfer, which covers both deposit and mint. Reported through the bug bounty program.
Expected behavior
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.