February 19, 2026

Capitalizations Index – B ∞/21M

Solidity’s SMTChecker can automatically find real bugs

Solidity’s SMTChecker can automatically find real bugs

In my previous post (https://medium.com/@leonardoalt/formal-verification-in-solidity-5cbff7b7ff8) I wrote about the SMTChecker, a formal verification module embedded in Solidity’s compiler that is under development. The goal of the SMTChecker is to be a compile-time automated prover and bug finder, where properties are specified using Solidity’s require/assert.

While developing the SMTChecker we often try examples from other more stable/established formal verification tools, which we use as benchmarks for what should be supported and proved. After reading https://medium.com/ethworks/formal-verification-for-n00bs-part-3-an-attempt-to-prevent-classic-hack-with-klab-8e8d13318086, we were curious to see how the SMTChecker would perform on that example after our recent work on supporting arrays and reporting fewer false positives when SafeMath is used.

The bug analyzed here is the batch overflow vulnerability. The following code snippet is a reduced version of the full contract which contains the original function:

pragma solidity ^0.5.0;
pragma experimental SMTChecker;
import "./SafeMath.sol";
contract Bug
function batchTransfer(
address[] memory _receivers,
uint256 _value
) public whenNotPaused returns (bool)
return true;
}
}

Briefly, the bug is an overflow in the operation uint256(cnt) * _value . An attacker can choose specific _receivers and a huge _value such that cnt > 0 && cnt <= 20 is true and amount is small, such that they have enough funds. Notice that the gain is in balances[_receivers[i]].add(_value) , where _value might be much higher than it should be.

If we simply run the compiler on the example, the output (among some false positives) contains:

bug.sol:18:20: Warning: Overflow (resulting value larger than 2**256 - 1) happens here
uint256 amount = uint256(cnt) * _value;
^-------------------^
for:
<result> = 2**256
_value = 0x80 * 2**248
amount = 0
balances[msg.sender] = 0
cnt = 2
msg.sender = 2997

The run took 10.24s with 2 backend SMT solvers on my laptop. It basically tells us how to exploit the bug: call batchTransfer(_receivers, 0x80 * 2**248) , where _receivers is an array with two addresses. After the overflow, amount = 0 which satisfies balances[msg.sender] >= amount . The addresses will then receive 0x80 * 2**248 tokens each.

This example shows that the SMTChecker can be used at compile-time to quickly find real bugs, even though it still lacks support to parts of Solidity. We are constantly increasing the power of the SMTChecker, hopefully eventually making it able to fully analyze complex smart contracts automatically.

If you have any questions/ideas please reach out! You can comment here, talk to us on our Gitter channel or start a thread in the Solidity repository.

Published at Tue, 26 Feb 2019 16:12:14 +0000

Previous Article

Chinese Stock Market’s 18% Surge Should Ignite Massive Dow Comeback

Next Article

CBDC: Ukrainische Notenbank forscht an digitaler Währung

You might be interested in …

Греф вангует: глава Сбербанка высказался о будущем криптовалют и блокчейна

ForkLog Греф вангует: глава Сбербанка высказался о будущем криптовалют и блокчейна Президент Сбербанка РФ Герман Греф в очередной раз высказал свою точку зрения о перспективах криптовалют. На форуме инновационных финансовых технологий Finopolis он заявил, что […]

digital_world

digital_worldBy keep_bitcoin_real on 2011-07-06 07:46:34