solidity/test/formal/checked_uint_mul_16.py

38 lines
873 B
Python
Raw Normal View History

from opcodes import AND, ISZERO, GT, DIV
from rule import Rule
from util import BVUnsignedUpCast, BVUnsignedMax
from z3 import BitVec, Not, BVMulNoOverflow
"""
Overflow checked unsigned integer multiplication.
"""
# Approximation with 16-bit base types.
n_bits = 16
type_bits = 8
while type_bits <= n_bits:
rule = Rule()
# Input vars
X_short = BitVec('X', type_bits)
Y_short = BitVec('Y', type_bits)
# Z3's overflow condition
actual_overflow = Not(BVMulNoOverflow(X_short, Y_short, False))
# cast to full n_bits values
X = BVUnsignedUpCast(X_short, n_bits)
Y = BVUnsignedUpCast(Y_short, n_bits)
# Constants
maxValue = BVUnsignedMax(type_bits, n_bits)
# Overflow check in YulUtilFunction::overflowCheckedIntMulFunction
overflow_check = AND(ISZERO(ISZERO(X)), GT(Y, DIV(maxValue, X)))
rule.check(overflow_check != 0, actual_overflow)
type_bits *= 2