def test_external_contract_calls_with_public_globals():
    contract_1 = """
lucky: public(num)

@public
def __init__(_lucky: num):
    self.lucky = _lucky
    """

    lucky_number = 7
    c = get_contract(contract_1, args=[lucky_number])

    contract_2 = """
class Foo():
    def get_lucky() -> num: pass

@public
def bar(arg1: address) -> num:
    return Foo(arg1).get_lucky()
    """
    c2 = get_contract(contract_2)

    assert c2.bar(c.address) == lucky_number
    print(
        'Successfully executed an external contract call with public globals')
Exemple #2
0
def test_address_can_returned_from_contract_type(t):
    contract_1 = """
@public
def bar() -> num:
    return 1
"""
    contract_2 = """
class Bar():
    def bar() -> num: pass

bar_contract: public(Bar)

@public
def foo(contract_address: contract(Bar)) -> num:
    self.bar_contract = contract_address

@public
def get_bar() -> num:
    return self.bar_contract.bar()
"""
    c1 = get_contract(contract_1)
    c2 = get_contract(contract_2)
    c2.foo(c1.address)
    assert u.remove_0x_head(c2.get_bar_contract()) == c1.address.hex()
    assert c2.get_bar() == 1
def test_invalid_external_contract_call_to_the_same_contract(assert_tx_failed):
    contract_1 = """
@public
def bar() -> num:
    return 1
    """

    contract_2 = """
class Bar():
    def bar() -> num: pass

@public
def bar() -> num:
    return 1

@public
def _stmt(x: address):
    Bar(x).bar()

@public
def _expr(x: address) -> num:
    return Bar(x).bar()
    """

    c1 = get_contract(contract_1)
    c2 = get_contract(contract_2)

    c2._stmt(c1.address)
    c2._expr(c1.address)
    assert_tx_failed(lambda: c2._stmt(c2.address))
    assert_tx_failed(lambda: c2._expr(c2.address))
Exemple #4
0
def test_external_contract_calls_with_multiple_contracts():
    contract_1 = """
lucky: public(num)

def __init__(_lucky: num):
    self.lucky = _lucky
    """

    lucky_number = 7
    c = get_contract(contract_1, args=[lucky_number])

    contract_2 = """
class Foo():
    def get_lucky() -> num: pass

magic_number: public(num)

def __init__(arg1: address):
    self.magic_number = Foo(arg1).get_lucky()
    """

    c2 = get_contract(contract_2, args=[c.address])
    contract_3 = """
class Bar():
    def get_magic_number() -> num: pass

best_number: public(num)

def __init__(arg1: address):
    self.best_number = Bar(arg1).get_magic_number()
    """

    c3 = get_contract(contract_3, args=[c2.address])
    assert c3.get_best_number() == lucky_number
    print('Successfully executed a multiple external contract calls')
Exemple #5
0
def test_complicated_external_contract_calls():
    contract_1 = """
lucky: public(num)

def __init__(_lucky: num):
    self.lucky = _lucky

def foo() -> num:
    return self.lucky

def array() -> bytes <= 3:
    return 'dog'
    """

    lucky_number = 7
    c = get_contract(contract_1, args=[lucky_number])

    contract_2 = """
class Foo():
    def foo() -> num: pass
    def array() -> bytes <= 3: pass

def bar(arg1: address) -> num:
    return Foo(arg1).foo()
    """
    c2 = get_contract(contract_2)

    assert c2.bar(c.address) == lucky_number
    print('Successfully executed a complicated external contract call')
Exemple #6
0
def test_external_contract_can_be_changed_based_on_address():
    contract_1 = """
lucky: public(num)

def set_lucky(_lucky: num):
    self.lucky = _lucky
    """

    lucky_number_1 = 7
    c = get_contract(contract_1)

    contract_2 =  """
lucky: public(num)

def set_lucky(_lucky: num):
    self.lucky = _lucky
    """

    lucky_number_2 = 3
    c2 = get_contract(contract_1)

    contract_3 = """
class Foo():
    def set_lucky(_lucky: num): pass

def set_lucky(arg1: address, arg2: num):
    Foo(arg1).set_lucky(arg2)
    """
    c3 = get_contract(contract_3)

    c3.set_lucky(c.address, lucky_number_1)
    c3.set_lucky(c2.address, lucky_number_2)
    assert c.get_lucky() == lucky_number_1
    assert c2.get_lucky() == lucky_number_2
    print('Successfully executed multiple external contract calls to different contracts based on address')
def test_external_contract_call_state_change():
    contract_1 = """
lucky: public(num)

@public
def set_lucky(_lucky: num):
    self.lucky = _lucky
    """

    lucky_number = 7
    c = get_contract(contract_1)

    contract_2 = """
class Foo():
    def set_lucky(_lucky: num): pass

@public
def set_lucky(arg1: address, arg2: num):
    Foo(arg1).set_lucky(arg2)
    """
    c2 = get_contract(contract_2)

    assert c.get_lucky() == 0
    c2.set_lucky(c.address, lucky_number)
    assert c.get_lucky() == lucky_number
    print('Successfully executed an external contract call state change')
Exemple #8
0
def test_event_logging_cannot_have_more_than_three_topics():
    loggy_code = """
MyLog: __log__({arg1: indexed(bytes <= 3), arg2: indexed(bytes <= 4), arg3: indexed(address), arg4: indexed(num)})

def foo():
    log.MyLog('bar', 'home', self)
    """

    with pytest.raises(VariableDeclarationException):
        get_contract(loggy_code)
Exemple #9
0
def test_mismatched_byte_length():
    code = """
mapped_bytes: num[bytes <= 34]

@public
def set(k: bytes <= 35, v: num):
    self.mapped_bytes[k] = v
    """

    with pytest.raises(TypeMismatchException):
        get_contract(code)
Exemple #10
0
def test_altering_list_within_for_loop():
    code = """
def data() -> num:
    s = [1, 2, 3, 4, 5, 6]
    count = 0
    for i in s:
        s[count] = 1  # this should not be allowed.
        if i >= 3:
            return i
        count += 1
    return -1
    """

    with pytest.raises(StructureException):
        get_contract(code)
Exemple #11
0
def test_logging_the_same_event_multiple_times_with_topics():
    loggy_code = """
MyLog: __log__({arg1: indexed(num), arg2: indexed(address)})

def foo():
    log.MyLog(1, self)
    log.MyLog(1, self)

def bar():
    log.MyLog(1, self)
    log.MyLog(1, self)
    """

    c = get_contract(loggy_code)
    c.foo()
    c.bar()
    logs = s.head_state.receipts[-1].logs[-1]
    event_id = u.bytes_to_int(u.sha3(bytes('MyLog(int128,address)', 'utf-8')))
    # Event id is always the first topic
    assert logs.topics[0] == event_id
    # Event id is calculated correctly
    assert c.translator.event_data[event_id]
    # Event abi is created correctly
    assert c.translator.event_data[event_id] == {'types': ['int128','address'], 'name': 'MyLog', 'names': ['arg1','arg2'], 'indexed': [True,True], 'anonymous': False}
    # Event is decoded correctly
    assert c.translator.decode_event(logs.topics, logs.data) == {'_event_type': b'MyLog', 'arg1': 1, 'arg2': '0x' + c.address.hex()}
Exemple #12
0
def test_basic_for_list_storage_address():
    code = """
addresses: address[3]

def set(i: num, val: address):
    self.addresses[i] = val

def ret(i: num) -> address:
    return self.addresses[i]

def iterate_return_second() -> address:
    count = 0
    for i in self.addresses:
        count += 1
        if count == 2:
            return i
    """

    c = get_contract(code)

    c.set(0, '0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1')
    c.set(1, '0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e')
    c.set(2, '0xDCEceAF3fc5C0a63d195d69b1A90011B7B19650D')

    assert c.ret(1) == c.iterate_return_second(
    ) == "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e"
Exemple #13
0
def test_selfcall_code_4():
    selfcall_code_4 = """
def summy(x: num, y: num) -> num:
    return x + y

def catty(x: bytes <= 5, y: bytes <= 5) -> bytes <= 10:
    return concat(x, y)

def slicey1(x: bytes <= 10, y: num) -> bytes <= 10:
    return slice(x, start=0, len=y)

def slicey2(y: num, x: bytes <= 10) -> bytes <= 10:
    return slice(x, start=0, len=y)

def returnten() -> num:
    return self.summy(3, 7)

def return_mongoose() -> bytes <= 10:
    return self.catty("mon", "goose")

def return_goose() -> bytes <= 10:
    return self.slicey1("goosedog", 5)

def return_goose2() -> bytes <= 10:
    return self.slicey2(5, "goosedog")
    """

    c = get_contract(selfcall_code_4)
    assert c.returnten() == 10
    assert c.return_mongoose() == b"mongoose"
    assert c.return_goose() == b"goose"
    assert c.return_goose2() == b"goose"

    print("Passed multi-argument self-call test")
Exemple #14
0
def test_event_logging_with_multiple_logs_topics_and_data():
    loggy_code = """
MyLog: __log__({arg1: indexed(num), arg2: bytes <= 3})
YourLog: __log__({arg1: indexed(address), arg2: bytes <= 5})

def foo():
    log.MyLog(1, 'bar')
    log.YourLog(self, 'house')
    """

    c = get_contract(loggy_code)
    c.foo()
    logs1 = s.head_state.receipts[-1].logs[-2]
    logs2 = s.head_state.receipts[-1].logs[-1]
    event_id1 = u.bytes_to_int(u.sha3(bytes('MyLog(int128,bytes3)', 'utf-8')))
    event_id2 = u.bytes_to_int(u.sha3(bytes('YourLog(address,bytes5)', 'utf-8')))
    # Event id is always the first topic
    assert logs1.topics[0] == event_id1
    assert logs2.topics[0] == event_id2
    # Event ids are calculated correctly
    assert c.translator.event_data[event_id1]
    assert c.translator.event_data[event_id2]
    # Event abi is created correctly
    assert c.translator.event_data[event_id1] == {'types': ['int128','bytes3'], 'name': 'MyLog', 'names': ['arg1','arg2'], 'indexed': [True, False], 'anonymous': False}
    assert c.translator.event_data[event_id2] == {'types': ['address','bytes5'], 'name': 'YourLog', 'names': ['arg1','arg2'], 'indexed': [True, False], 'anonymous': False}
    # Event is decoded correctly
    assert c.translator.decode_event(logs1.topics, logs1.data) == {'arg1': 1, 'arg2': b'bar', '_event_type': b'MyLog'}
    assert c.translator.decode_event(logs2.topics, logs2.data) == {'arg1': '0x' + c.address.hex(), 'arg2': b'house', '_event_type': b'YourLog'}
Exemple #15
0
def erc20_caller(erc20):
    erc20_caller_code = """
token_address: address(ERC20)

@public
def __init__(token_addr: address):
    self.token_address = token_addr

@public
def symbol() -> bytes32:
    return self.token_address.symbol()

@public
def balanceOf(_owner: address) -> num256:
    return self.token_address.balanceOf(_owner)

@public
def totalSupply() -> num256:
    return self.token_address.totalSupply()

@public
def transfer(_to: address, _value: num256) -> bool:
    return self.token_address.transfer(_to, _value)

@public
def transferFrom(_from: address, _to: address, _value: num(num256)) -> bool:
    return self.token_address.transferFrom(_from, _to, _value)

@public
def allowance(_owner: address, _spender: address) -> num256:
    return self.token_address.allowance(_owner, _spender)
    """
    return get_contract(erc20_caller_code, args=[erc20.address])
Exemple #16
0
def test_logging_with_input_bytes(bytes_helper):
    loggy_code = """
MyLog: __log__({arg1: indexed(bytes <= 4), arg2: indexed(bytes <= 29), arg3: bytes<=31})

def foo(arg1: bytes <= 29, arg2: bytes <= 31):
    log.MyLog('bar', arg1, arg2)
"""
    c = get_contract(loggy_code)
    c.foo('bar', 'foo')
    logs = s.head_state.receipts[-1].logs[-1]
    event_id = u.bytes_to_int(
        u.sha3(bytes('MyLog(bytes4,bytes29,bytes31)', 'utf-8')))
    # # Event id is always the first topic
    assert logs.topics[0] == event_id
    # # Event id is calculated correctly
    assert c.translator.event_data[event_id]
    # # Event abi is created correctly
    assert c.translator.event_data[event_id] == {
        'types': ['bytes4', 'bytes29', 'bytes31'],
        'name': 'MyLog',
        'names': ['arg1', 'arg2', 'arg3'],
        'indexed': [True, True, False],
        'anonymous': False
    }
    # Event is decoded correctly
    assert c.translator.decode_event(logs.topics, logs.data) == {
        'arg1': b'bar\x00',
        'arg2': bytes_helper('bar', 29),
        'arg3': bytes_helper('foo', 31),
        '_event_type': b'MyLog'
    }
Exemple #17
0
def test_invalid_contract_reference_call(assert_tx_failed):
    contract = """
def bar(arg1: address, arg2: num) -> num:
    return Foo(arg1).foo(arg2)
"""
    t.s = t.Chain()
    assert_tx_failed(t, lambda: get_contract(contract), exception = VariableDeclarationException)
Exemple #18
0
def test_string_literal_code():
    string_literal_code = """
def foo() -> bytes <= 5:
    return "horse"

def bar() -> bytes <= 10:
    return concat("b", "a", "d", "m", "i", "", "nton")

def baz() -> bytes <= 40:
    return concat("0123456789012345678901234567890", "12")

def baz2() -> bytes <= 40:
    return concat("01234567890123456789012345678901", "12")

def baz3() -> bytes <= 40:
    return concat("0123456789012345678901234567890", "1")

def baz4() -> bytes <= 100:
    return concat("01234567890123456789012345678901234567890123456789",
                  "01234567890123456789012345678901234567890123456789")
    """

    c = get_contract(string_literal_code)
    assert c.foo() == b"horse"
    assert c.bar() == b"badminton"
    assert c.baz() == b"012345678901234567890123456789012"
    assert c.baz2() == b"0123456789012345678901234567890112"
    assert c.baz3() == b"01234567890123456789012345678901"
    assert c.baz4() == b"0123456789" * 10

    print("Passed string literal test")
Exemple #19
0
def test_loggy_code():
    loggy_code = """
s: bytes <= 100

def foo():
    raw_log([], "moo")

def goo():
    raw_log([0x1234567812345678123456781234567812345678123456781234567812345678], "moo2")

def hoo():
    self.s = "moo3"
    raw_log([], self.s)

def ioo(inp: bytes <= 100):
    raw_log([], inp)
    """

    c = get_contract(loggy_code)
    c.foo()
    assert s.head_state.receipts[-1].logs[0].data == b'moo'
    c.goo()
    assert s.head_state.receipts[-1].logs[0].data == b'moo2'
    assert s.head_state.receipts[-1].logs[0].topics == [0x1234567812345678123456781234567812345678123456781234567812345678]
    c.hoo()
    assert s.head_state.receipts[-1].logs[0].data == b'moo3'
    c.ioo(b"moo4")
    assert s.head_state.receipts[-1].logs[0].data == b'moo4'
    print("Passed raw log tests")
Exemple #20
0
def test_bytes_to_num_code():
    bytes_to_num_code = """
def foo(x: bytes <= 32) -> num:
    return bytes_to_num(x)
    """

    c = get_contract(bytes_to_num_code)
    assert c.foo(b"") == 0
    try:
        c.foo(b"\x00")
        success = True
    except:
        success = False
    assert not success
    assert c.foo(b"\x01") == 1
    try:
        c.foo(b"\x00\x01")
        success = True
    except:
        success = False
    assert not success
    assert c.foo(b"\x01\x00") == 256
    assert c.foo(b"\x01\x00\x00\x00\x01") == 4294967297
    assert c.foo(b"\xff" * 32) == -1
    try:
        c.foo(b"\x80" + b"\xff" * 31)
        success = True
    except:
        success = False
    try:
        c.foo(b"\x01" * 33)
        success = True
    except:
        success = False
    print('Passed bytes_to_num tests')
Exemple #21
0
def test_logging_fails_after_a_global_declaration(assert_tx_failed):
    loggy_code = """
age: num
MyLog: __log__({arg1: bytes <= 3})
    """
    t.s = s
    assert_tx_failed(t, lambda: get_contract(loggy_code), StructureException)
Exemple #22
0
def test_basic_for_list_storage_decimal():
    code = """
readings: decimal[3]

def set(i: num, val: decimal):
    self.readings[i] = val

def ret(i: num) -> decimal:
    return self.readings[i]

def i_return(break_count: num) -> decimal:
    count = 0
    for i in self.readings:
        if count == break_count:
            return i
        count += 1
    """

    c = get_contract(code)

    c.set(0, 0.0001)
    c.set(1, 1.1)
    c.set(2, 2.2)

    assert c.ret(2) == c.i_return(2) == 2.2
    assert c.ret(1) == c.i_return(1) == 1.1
    assert c.ret(0) == c.i_return(0) == 0.0001
Exemple #23
0
def test_logging_fails_with_when_log_is_undeclared(assert_tx_failed):
    loggy_code = """
def foo():
    log.MyLog()
    """
    t.s = s
    assert_tx_failed(t, lambda: get_contract(loggy_code), VariableDeclarationException)
Exemple #24
0
def test_num256_mod(assert_tx_failed):
    num256_code = """
def _num256_mod(x: num256, y: num256) -> num256:
    return num256_mod(x, y)

def _num256_addmod(x: num256, y: num256, z: num256) -> num256:
    return num256_addmod(x, y, z)

def _num256_mulmod(x: num256, y: num256, z: num256) -> num256:
    return num256_mulmod(x, y, z)
    """

    c = get_contract(num256_code)
    t.s = s

    assert c._num256_mod(3, 2) == 1
    assert c._num256_mod(34, 32) == 2
    assert c._num256_addmod(1, 2, 2) == 1
    assert c._num256_addmod(32, 2, 32) == 2
    assert c._num256_addmod((2**256) - 1, 0, 2) == 1
    assert_tx_failed(t, lambda: c._num256_addmod((2**256) - 1, 1, 1))
    assert c._num256_mulmod(3, 1, 2) == 1
    assert c._num256_mulmod(200, 3, 601) == 600
    assert c._num256_mulmod(2**255, 1, 3) == 2
    assert_tx_failed(t, lambda: c._num256_mulmod(2**255, 2, 1))
Exemple #25
0
def test_num256_to_num_casting(assert_tx_failed):
    code = """
def _num256_to_num(x: num(num256)) -> num:
    return x

def _num256_to_num_call(x: num256) -> num:
    return self._num256_to_num(x)

def built_in_conversion(x: num256) -> num:
    return as_num128(x)
    """

    c = get_contract(code)

    # Ensure uint256 function signature.
    assert c.translator.function_data['_num256_to_num']['encode_types'] == [
        'uint256'
    ]

    assert c._num256_to_num(1) == 1
    assert c._num256_to_num((2**127) - 1) == 2**127 - 1
    t.s = s
    assert_tx_failed(t, lambda: c._num256_to_num((2**128)) == 0)
    assert c._num256_to_num_call(1) == 1

    # Check that casting matches manual conversion
    assert c._num256_to_num_call(2**127 - 1) == c.built_in_conversion(2**127 -
                                                                      1)

    # Pass in negative int.
    assert_tx_failed(t, lambda: c._num256_to_num(-1) != -1, ValueOutOfBounds)
    # Make sure it can't be coherced into a negative number.
    assert_tx_failed(t, lambda: c._num256_to_num_call(2**127))
Exemple #26
0
def test_composite_setter_test():
    composite_setter_test = """
mom: {a: {c: num}[3], b:num}
qoq: {c: num}
def foo() -> num:
    self.mom = {a: [{c: 1}, {c: 2}, {c: 3}], b: 4}
    non = {c: 5}
    self.mom.a[0] = non
    non = {c: 6}
    self.mom.a[2] = non
    return self.mom.a[0].c + self.mom.a[1].c * 10 + self.mom.a[2].c * 100 + self.mom.b * 1000

def fop() -> num:
    popp = {a: [{c: 1}, {c: 2}, {c: 3}], b: 4}
    self.qoq = {c: 5}
    popp.a[0] = self.qoq
    self.qoq = {c: 6}
    popp.a[2] = self.qoq
    return popp.a[0].c + popp.a[1].c * 10 + popp.a[2].c * 100 + popp.b * 1000

def foq() -> num:
    popp = {a: [{c: 1}, {c: 2}, {c: 3}], b: 4}
    popp.a[0] = None
    popp.a[2] = None
    return popp.a[0].c + popp.a[1].c * 10 + popp.a[2].c * 100 + popp.b * 1000
    """

    c = get_contract(composite_setter_test)
    assert c.foo() == 4625
    assert c.fop() == 4625
    assert c.foq() == 4020
    print('Passed composite struct test')
Exemple #27
0
def test_logging_fails_with_over_three_topics(assert_tx_failed):
    loggy_code = """
MyLog: __log__({arg1: indexed(num), arg2: indexed(num), arg3: indexed(num), arg4: indexed(num)})
def __init__():
    log.MyLog(1, 2, 3, 4)
    """
    t.s = s
    assert_tx_failed(t, lambda: get_contract(loggy_code), VariableDeclarationException)
Exemple #28
0
def test_list_output_tester_code():
    list_output_tester_code = """
z: num[2]

def foo() -> num[2]:
    return [3, 5]

def goo() -> num[2]:
    x = [3, 5]
    return x

def hoo() -> num[2]:
    self.z = [3, 5]
    return self.z

def joo() -> num[2]:
    self.z = [3, 5]
    x = self.z
    return x

def koo() -> num[2][2]:
    return [[1,2],[3,4]]

def loo() -> num[2][2]:
    x = [[1,2],[3,4]]
    return x

def moo() -> num[2][2]:
    x = [1,2]
    return [x,[3,4]]

def noo(inp: num[2]) -> num[2]:
    return inp

def poo(inp: num[2][2]) -> num[2][2]:
    return inp

def qoo(inp: num[2]) -> num[2][2]:
    return [inp,[3,4]]

def roo(inp: num[2]) -> decimal[2][2]:
    return [inp,[3,4]]
    """

    c = get_contract(list_output_tester_code)
    assert c.foo() == [3, 5]
    assert c.goo() == [3, 5]
    assert c.hoo() == [3, 5]
    assert c.joo() == [3, 5]
    assert c.koo() == [[1, 2], [3, 4]]
    assert c.loo() == [[1, 2], [3, 4]]
    assert c.moo() == [[1, 2], [3, 4]]
    assert c.noo([3, 5]) == [3, 5]
    assert c.poo([[1, 2], [3, 4]]) == [[1, 2], [3, 4]]
    assert c.qoo([1, 2]) == [[1, 2], [3, 4]]
    assert c.roo([1, 2]) == [[1.0, 2.0], [3.0, 4.0]]

    print("Passed list output tests")
Exemple #29
0
def test_external_contract_calls_with_bytes():
    contract_1 = """
def array() -> bytes <= 3:
    return 'dog'
    """

    c = get_contract(contract_1)

    contract_2 = """
class Foo():
    def array() -> bytes <= 3: pass

def get_array(arg1: address) -> bytes <= 3:
    return Foo(arg1).array()
"""

    c2 = get_contract(contract_2)
    assert c2.get_array(c.address) == b'dog'
Exemple #30
0
def test_logging_fails_after_a_function_declaration(assert_tx_failed):
    loggy_code = """
def foo():
    pass

MyLog: __log__({arg1: bytes <= 3})
    """
    t.s = s
    assert_tx_failed(t, lambda: get_contract(loggy_code), StructureException)