Skip to content

Commit 54c5a15

Browse files
authored
Generates a more sensible symbolic default for constructor arguments (#1414)
* Fix #1412 * Add basic test * CC
1 parent 2a1c341 commit 54c5a15

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

manticore/ethereum/manticore.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,42 @@ def make_symbolic_arguments(self, types):
577577
"""
578578
Make a reasonable serialization of the symbolic argument types
579579
"""
580-
# FIXME this is more naive than reasonable.
581-
return ABI.deserialize(types, self.make_symbolic_buffer(32, name='INITARGS', avoid_collisions=True))
580+
from . import abitypes
581+
return self._make_symbolic_arguments(abitypes.parse(types))
582+
583+
def _make_symbolic_arguments(self, ty):
584+
''' This makes a tuple of symbols to be used as arguments of type ty'''
585+
586+
# If the types describe an string or an array this will produce strings
587+
# or arrays of a default size.
588+
#TODO: add a configuration constant for these two
589+
default_string_size = 32
590+
default_array_size = 32
591+
if ty[0] in ('int', 'uint'):
592+
result = self.make_symbolic_value()
593+
elif ty[0] == 'bytesM':
594+
result = self.make_symbolic_buffer(size=ty[1])
595+
elif ty[0] == 'function':
596+
address = self.make_symbolic_value()
597+
func_id = self.make_symbolic_buffer(size=4)
598+
result = (address, func_id)
599+
elif ty[0] in ('bytes', 'string'):
600+
result = self.make_symbolic_buffer(size=default_string_size)
601+
elif ty[0] == 'tuple':
602+
result = ()
603+
for ty_i in ty[1]:
604+
result += (self._make_symbolic_arguments(ty_i), )
605+
elif ty[0] == 'array':
606+
result = []
607+
rep = ty[1]
608+
if rep is None:
609+
rep = default_array_size
610+
for _ in range(rep):
611+
result.append(self._make_symbolic_arguments(ty[2]))
612+
else:
613+
raise NotImplemented
614+
615+
return result
582616

583617
def json_create_contract(self, jfile, owner=None, name=None, contract_name=None, balance=0, gas=None, network_id=None, args=()):
584618
""" Creates a solidity contract based on a truffle json artifact.

tests/ethereum/test_general.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,15 @@ def test_create_contract_with_too_much_args(self):
473473

474474
self.assertEqual(str(e.exception), 'The number of values to serialize is greater than the number of types')
475475

476+
def test_create_contract_with_string_args(self):
477+
source_code = 'contract DontWork1{ string s; constructor(string memory s_) public{ s = s_;} }'
478+
owner = self.mevm.create_account()
479+
480+
sym_args = self.mevm.make_symbolic_arguments('(string)')
481+
contract = self.mevm.solidity_create_contract(source_code, owner=owner, args=sym_args)
482+
self.assertIsNotNone(contract)
483+
self.assertEqual(self.mevm.count_states(), 1)
484+
476485
def test_create_contract_two_instances(self):
477486
source_code = 'contract A { constructor(uint32 arg) {} }'
478487
owner = self.mevm.create_account()

0 commit comments

Comments
 (0)