Skip to content
high Logic / State No SWC entry CWE-837

msg.value Reused Across a Loop / Multicall

SAFE-0146 Logic / State Checked automatically by the scanner
1

What goes wrong

msg.value is read multiple times inside a loop or a payable multicall, so a single ETH payment is counted once per iteration. The caller pays for one but is credited for many — minting/buying N times while sending value for one.

2

The vulnerable pattern

proof of concept — how it is exploited
// payable multicall([buy(), buy(), buy()]) with msg.value = 1 price.
// each buy() checks require(msg.value == price) -> passes 3x.
// attacker gets 3 items for the price of 1.
3

How to fix it

the pattern that is safe
// track consumed value, or forbid payable multicall
uint256 remaining = msg.value;
for (uint i; i < n; i++) { require(remaining >= price); remaining -= price; ... }
Opyn / multi-mint bugs. Never trust msg.value inside a loop.
Check your own contract for this

The SaferICO scanner runs 201 detectors over your Solidity source, SAFE-0146 among them. Paste an address or the source itself — a small per-scan fee, shown before you sign, or unlimited on any plan.

Run the scanner See how it is attacked Read the docs