class TestPassHash(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.c.raw_driver.set_contract(name='submission', code=contract,)

        self.c.raw_driver.commit()

        submission = self.c.get_contract('submission')

        # submit erc20 clone
        with open('./test_contracts/pass_hash.s.py') as f:
            code = f.read()
            self.c.submit(code, name='pass_hash')

        with open('./test_contracts/test_pass_hash.s.py') as f:
            code = f.read()
            self.c.submit(code, name='test_pass_hash')

        self.pass_hash = self.c.get_contract('pass_hash')
        self.test_pass_hash = self.c.get_contract('test_pass_hash')

    def test_store_value(self):
        self.test_pass_hash.store(k='thing', v='value')
        output = self.test_pass_hash.get(k='thing')

        self.assertEqual(output, 'value')
Exemple #2
0
def setup_member_contracts(initial_masternodes,
                           initial_delegates,
                           client: ContractingClient,
                           root=DEFAULT_PATH):
    members = root + '/genesis/members.s.py'

    with open(members) as f:
        code = f.read()

    if client.get_contract('masternodes') is None:
        client.submit(code,
                      name='masternodes',
                      owner='election_house',
                      constructor_args={
                          'initial_members': initial_masternodes,
                          'candidate': 'elect_masternodes'
                      })

    if client.get_contract('delegates') is None:
        client.submit(code,
                      name='delegates',
                      owner='election_house',
                      constructor_args={
                          'initial_members': initial_delegates,
                          'candidate': 'elect_delegates'
                      })
class TestDeveloperSubmission(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.c.raw_driver.set_contract(
            name='submission',
            code=contract,
        )

        self.c.raw_driver.commit()

    def test_submit_sets_developer(self):
        self.c.submit(test)

        dev = self.c.get_var('test', '__developer__')

        self.assertEqual(dev, 'stu')

    def test_change_developer_if_developer_works(self):
        self.c.submit(test)

        submission = self.c.get_contract('submission')

        submission.change_developer(contract='test', new_developer='not_stu')

        dev = self.c.get_var('test', '__developer__')

        self.assertEqual(dev, 'not_stu')

    def test_change_developer_prevents_new_change(self):
        self.c.submit(test)

        submission = self.c.get_contract('submission')

        submission.change_developer(contract='test', new_developer='not_stu')

        with self.assertRaises(AssertionError):
            submission.change_developer(contract='test',
                                        new_developer='woohoo')

    def test_cannot_import_submission(self):
        self.c.submit(import_submission)

        imp_con = self.c.get_contract('import_submission')

        with self.assertRaises(AssertionError):
            imp_con.haha()
Exemple #4
0
class TestMiscContracts(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.c.raw_driver.set_contract(name='submission', code=contract,)

        self.c.raw_driver.commit()

        submission = self.c.get_contract('submission')

        # submit erc20 clone
        with open('./test_contracts/thing.s.py') as f:
            code = f.read()
            self.c.submit(code, name='thing')

        with open('./test_contracts/foreign_thing.s.py') as f:
            code = f.read()
            self.c.submit(code, name='foreign_thing')

        self.thing = self.c.get_contract('thing')
        self.foreign_thing = self.c.get_contract('foreign_thing')

    def test_H_values_return(self):
        output = self.foreign_thing.read_H_hello()
        self.assertEqual(output, 'there')

        output = self.foreign_thing.read_H_something()
        self.assertEqual(output, 'else')

    def test_cant_modify_H(self):
        with self.assertRaises(ReferenceError):
            self.foreign_thing.set_H(k='hello', v='not_there')

    def test_cant_add_H(self):
        with self.assertRaises(ReferenceError):
            self.foreign_thing.set_H(k='asdf', v='123')

    def test_cant_set_V(self):
        with self.assertRaises(ReferenceError):
            self.foreign_thing.set_V(v=123)

    def test_V_returns(self):
        output = self.foreign_thing.read_V()
        self.assertEqual(output, 'hi')
class OracleTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()
        with open('oracle.py') as file:
            code = file.read()
        self.client.submit(code, name='oracle')
        self.oracle = self.client.get_contract('oracle')

        self.oracle.set_price(number=0, new_price=1.0)

    def tearDown(self):
        self.client.flush()

    def test_proper_test_setup(self):
        self.assertAlmostEqual(self.oracle.current_price[0], 1)

    def test_oracle_price_negative(self):
        with self.assertRaisesRegex(AssertionError, 'negative'):
            self.oracle.set_price(number=1, new_price=-1)

    def test_oracle_price_normal(self):
        self.assertAlmostEqual(self.oracle.get_price(number=1), 0)
        self.oracle.set_price(number=1, new_price=1)
        self.assertAlmostEqual(self.oracle.get_price(number=1), 1)
Exemple #6
0
class TestSenecaClientReplacesExecutor(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.c.raw_driver.set_contract(name='submission', code=contract)

        self.c.raw_driver.commit()

        # submit erc20 clone
        with open('./test_contracts/constructor_args_contract.s.py') as f:
            self.code = f.read()

    def test_custom_args_works(self):
        self.c.submit(self.code, name='constructor_args_contract', constructor_args={'a': 123, 'b': 321})

        contract = self.c.get_contract('constructor_args_contract')
        a, b = contract.get()

        self.assertEqual(a, 123)
        self.assertEqual(b, 321)

    def test_custom_args_overloading(self):
        with self.assertRaises(TypeError):
            self.c.submit(self.code, name='constructor_args_contract', constructor_args={'a': 123, 'x': 321})

    def test_custom_args_not_enough_args(self):
        with self.assertRaises(TypeError):
            self.c.submit(self.code, name='constructor_args_contract', constructor_args={'a': 123})
Exemple #7
0
def submit_vkbook(vkbook_args: dict, overwrite=False):
    if not overwrite:
        c = ContractingClient()
        contract = c.get_contract('vkbook')
        if contract is not None:
            return

    submit_contract_with_construction_args('vkbook', args=vkbook_args)
class TestPixelGame(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.flush()

        self.c.submit(coin)
        self.c.submit(pixel_game)
        self.pixel = self.c.get_contract('pixel_game')

    def tearDown(self):
        self.c.flush()
class TestRandomsContract(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.flush()

        self.c.submit(module1)

        self.c.submit(all_in_one)
        self.c.submit(dynamic_import)

    def test_ctx2(self):
        module = self.c.get_contract('module1')
        print(module.get_context2())

    def test_multi_call(self):
        aio = self.c.get_contract('all_in_one')
        print(aio.call_me())

    def test_dynamic_call(self):
        dy = self.c.get_contract('dynamic_import')
        dy.called_from_a_far()
class TestMembers(TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        f = open('./contracts/currency.s.py')
        self.client.submit(f.read(), 'currency')
        f.close()

        f = open('./contracts/foundation.s.py')
        self.client.submit(f.read(), 'foundation', constructor_args={
            'vk': 'test'
        })
        f.close()

        self.foundation = self.client.get_contract('foundation')
        self.currency = self.client.get_contract('currency')

    def test_withdraw(self):
        # Send money to foundation
        self.currency.transfer(amount=10000, to='foundation')

        self.foundation.withdraw(amount=123, signer='test')

        self.assertEqual(self.currency.balances['test'], 123)

    def test_change_owner(self):
        self.currency.transfer(amount=10000, to='foundation')

        self.foundation.change_owner(vk='xxx', signer='test')

        with self.assertRaises(AssertionError):
            self.foundation.withdraw(amount=123, signer='test')

        self.foundation.withdraw(amount=123, signer='xxx')
        self.assertEqual(self.currency.balances['xxx'], 123)

    def test_change_owner_fails_if_not_owner(self):
        with self.assertRaises(AssertionError):
            self.foundation.change_owner(vk='xxx', signer='yyy')
Exemple #11
0
def register_policies(client: ContractingClient):
    # add to election house
    election_house = client.get_contract('election_house')

    policies_to_register = [
        'masternodes', 'delegates', 'rewards', 'stamp_cost'
    ]

    for policy in policies_to_register:
        if client.get_var(contract='election_house',
                          variable='policies',
                          arguments=[policy]) is None:
            election_house.register_policy(contract=policy)
Exemple #12
0
class TestFloatIssue(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')

    def tearDown(self):
        self.c.raw_driver.flush()

    def test_if_builtin_can_be_submitted(self):
        with open('./test_contracts/float_issue.s.py') as f:
            contract = f.read()
            self.c.submit(contract, name='float_issue')

        float_issue = self.c.get_contract('float_issue')

        float_issue.get(x=0.1, y=0.1)
Exemple #13
0
class TestDynamicImport(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')

    def tearDown(self):
        self.c.raw_driver.flush()

    def test_if_builtin_can_be_submitted(self):
        with open('./test_contracts/dynamic_import.s.py') as f:
            contract = f.read()
            self.c.submit(contract, name='dynamic_import')

        dynamic_import = self.c.get_contract('dynamic_import')

        with self.assertRaises(ImportError):
            dynamic_import.import_thing(name='math')
class TestRunPrivateFunction(TestCase):
    def setUp(self):
        self.client = ContractingClient()

        with open('./test_contracts/private_methods.s.py') as f:
            code = f.read()

        self.client.submit(code, name='private_methods')
        self.private_methods = self.client.get_contract('private_methods')

    def tearDown(self):
        self.client.flush()

    def test_can_call_public_func(self):
        self.assertEqual(self.private_methods.call_private(), 'abc')

    def test_cannot_call_private_func(self):
        with self.assertRaises(Exception):
            self.private_methods.private()

    def test_cannot_execute_private_func(self):
        with self.assertRaises(AssertionError):
            self.private_methods.executor.execute(
                sender='sys',
                contract_name='private_methods',
                function_name='__private',
                kwargs={})

    def test_can_call_private_func_if_run_private_function_called(self):
        self.assertEqual(
            self.private_methods.run_private_function('__private'), 'abc')

    def test_can_call_private_func_if_run_private_function_called_and_no_prefix(
            self):
        self.assertEqual(self.private_methods.run_private_function('private'),
                         'abc')

    def test_can_call_private_but_then_not(self):
        self.assertEqual(self.private_methods.run_private_function('private'),
                         'abc')

        with self.assertRaises(AssertionError):
            self.private_methods.executor.execute(
                sender='sys',
                contract_name='private_methods',
                function_name='__private',
                kwargs={})
class TestFloatThing(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.c.raw_driver.set_contract(name='submission', code=contract,)

        self.c.raw_driver.commit()

    def test_can_add(self):
        self.c.submit(float_thing)

        ft_con = self.c.get_contract('float_thing')

        ft_con.test(currency_reserve=50000.125, token_reserve=52.45, currency_amount=100.25)
Exemple #16
0
class TestComplexStorage(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.flush()

        self.c.submit(contract)
        self.contract = self.c.get_contract('contract')

    def tearDown(self):
        self.c.flush()

    def test_storage(self):
        self.contract.create(x=1, y=2, color='howdy')
        self.assertEqual(self.contract.storage[1, 2]['color'], 'howdy')

    def test_modify(self):
        self.contract.create(x=1, y=2, color='howdy')
        self.contract.update(x=1, y=2, color='yoyoyo')
Exemple #17
0
class TestProcessor(TestCase):
    def setUp(self):
        self.wallet = Wallet()
        self.client = ContractingClient()
        sync.submit_from_genesis_json_file(cilantro_ee.contracts.__path__[0] +
                                           '/genesis.json',
                                           client=ContractingClient())

        processor.mint(self.wallet.vk.encode().hex(), 1000000000)
        self.currency = self.client.get_contract('currency')

        bal = self.currency.quick_read(variable='balances',
                                       key=self.wallet.vk.encode().hex())
        self.assertEqual(bal, 1000000000)

    def tearDown(self):
        self.client.flush()

    def test_process_good_tx(self):
        txb = TransactionBuilder(self.wallet.verifying_key(),
                                 contract='currency',
                                 function='transfer',
                                 kwargs={
                                     'to': 'jeff',
                                     'amount': 10000
                                 },
                                 stamps=100000,
                                 processor=b'\x00' * 32,
                                 nonce=0)

        txb.sign(self.wallet.signing_key())
        tx_bytes = txb.serialize()

        tx = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes)
        print(tx)

        results = processor.process_transaction(tx)

        balance_from = results['state_changes']['currency.balances:{}'.format(
            self.wallet.vk.encode().hex())]
        balance_jeff = results['state_changes']['currency.balances:jeff']

        self.assertEqual(float(balance_from), 1000000000 - 10000)
        self.assertEqual(float(balance_jeff), 10000)
Exemple #18
0
    def test_submit_contract_with_specific_construction_args(self):
        driver = ContractDriver()
        driver.flush()

        sync.submit_contract_with_construction_args('vkbook',
                                                    args={
                                                        'masternodes':
                                                        ['stu', 'raghu'],
                                                        'delegates':
                                                        ['tejas', 'monica'],
                                                        'num_boot_mns':
                                                        1,
                                                        'num_boot_del':
                                                        1
                                                    })

        client = ContractingClient()
        vkbook = client.get_contract('vkbook')

        self.assertEqual(vkbook.get_masternodes(), ['stu', 'raghu'])
        self.assertEqual(vkbook.get_delegates(), ['tejas', 'monica'])
Exemple #19
0
def submit_from_genesis_json_file(client: ContractingClient,
                                  filename=DEFAULT_GENESIS_PATH,
                                  root=DEFAULT_PATH):
    with open(filename) as f:
        genesis = json.load(f)

    for contract in genesis['contracts']:
        c_filepath = root + '/genesis/' + contract['name'] + '.s.py'

        with open(c_filepath) as f:
            code = f.read()

        contract_name = contract['name']
        if contract.get('submit_as') is not None:
            contract_name = contract['submit_as']

        if client.get_contract(contract_name) is None:
            client.submit(code,
                          name=contract_name,
                          owner=contract['owner'],
                          constructor_args=contract['constructor_args'])
Exemple #20
0
class TestSenecaClientReplacesExecutor(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.flush()

        with open('test_contracts/dater.py') as f:
            self.c.submit(f=f.read(), name='dater')

        self.dater = self.c.get_contract('dater')

    def tearDown(self):
        self.c.flush()

    def test_datetime_passed_argument_and_now_are_correctly_compared(self):
        self.dater.replicate(d=Datetime(year=3000, month=1, day=1))

    def test_datetime_passed_argument_and_now_are_correctly_compared_json(self):
        with self.assertRaises(TypeError):
            self.dater.replicate(d={'__time__':[3000, 12, 15, 12, 12, 12, 0]})

        with self.assertRaises(TypeError):
            self.dater.replicate(d=[2025, 11, 15, 21, 47, 14, 0])
class BuySellTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        with open('tad.py') as file:
            tad = file.read()

        with open('vault.py') as file:
            vault = file.read()

        with open('test_currency.py') as file:
            currency = file.read()

        with open('oracle.py') as file:
            oracle = file.read()

        with open('test_amm.py') as file:
            amm = file.read()

        with open('../keeper-examples/buy_and_sell.py') as file:
            buysell = file.read()

        self.client.submit(tad,
                           name='tad_contract',
                           constructor_args={'owner': 'vault_contract'})
        self.client.submit(vault, name='vault_contract')
        self.client.submit(currency, name='currency')
        self.client.submit(oracle, name='oracle')
        self.client.submit(amm, name='amm')
        self.client.submit(buysell, name='buysell')

        self.tad = self.client.get_contract('tad_contract')
        self.vault = self.client.get_contract('vault_contract')
        self.currency = self.client.get_contract('currency')
        self.oracle = self.client.get_contract('oracle')
        self.amm = self.client.get_contract('amm')
        self.buysell = self.client.get_contract('buysell')

    def tearDown(self):
        self.client.flush()

    def test_buysell_main(self):
        # self.buysell.main() # foreignhash documentation is unclear, todo fix
        pass
class BuySellTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        with open('dai.py') as file:
            dai = file.read()

        with open('vault.py') as file:
            vault = file.read()

        with open('test_currency.py') as file:
            currency = file.read()

        with open('oracle.py') as file:
            oracle = file.read()

        with open('test_amm.py') as file:
            amm = file.read()

        with open('../keeper-examples/buy_and_sell.py') as file:
            buysell = file.read()

        self.client.submit(dai,
                           name='dai_contract',
                           constructor_args={'owner': 'vault_contract'})
        self.client.submit(vault, name='vault_contract')
        self.client.submit(currency, name='currency')
        self.client.submit(oracle, name='oracle')
        self.client.submit(amm, name='amm')
        self.client.submit(buysell, name='buysell')

        self.dai = self.client.get_contract('dai_contract')
        self.vault = self.client.get_contract('vault_contract')
        self.currency = self.client.get_contract('currency')
        self.oracle = self.client.get_contract('oracle')
        self.amm = self.client.get_contract('amm')
        self.buysell = self.client.get_contract('buysell')

    def tearDown(self):
        self.client.flush()

    def test_buysell_main(self):
        self.buysell.main()
Exemple #23
0
class TestMembers(TestCase):
    def setUp(self):
        self.client = ContractingClient()

        f = open('./contracts/currency.s.py')
        self.client.submit(f.read(), 'currency')
        f.close()

        with open('./contracts/election_house.s.py') as f:
            contract = f.read()

        self.client.submit(contract, name='election_house')

        f = open('./contracts/elect_members.s.py')
        self.client.submit(f.read(),
                           'elect_members',
                           constructor_args={'policy': 'masternodes'})
        f.close()

        f = open('./contracts/stamp_cost.s.py')
        self.client.submit(f.read(),
                           'stamp_cost',
                           owner='election_house',
                           constructor_args={'initial_rate': 20_000})
        f.close()

        self.election_house = self.client.get_contract('election_house')
        self.stamp_cost = self.client.get_contract(name='stamp_cost')
        self.election_house.register_policy(contract='stamp_cost')
        self.elect_members = self.client.get_contract('elect_members')
        self.currency = self.client.get_contract('currency')

    def tearDown(self):
        self.client.flush()

    def submit_members(self, constructor_args, owner=None):
        f = open('./contracts/members.s.py')
        self.client.submit(f.read(),
                           name='masternodes',
                           owner=owner,
                           constructor_args=constructor_args)
        f.close()

    def test_init(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        self.assertEqual(mn_contract.current_value(signer='election_house'),
                         [1, 2, 3])

        self.assertEqual(mn_contract.S['yays'], 0)
        self.assertEqual(mn_contract.S['nays'], 0)
        self.assertEqual(mn_contract.S['current_motion'], 0)

    def test_voter_not_masternode_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(
                f='assert_vote_is_valid',
                vk='sys',
                action='introduce_motion',
                position=1,
            )

    def test_vote_invalid_action_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(
                f='assert_vote_is_valid',
                vk=1,
                action='xxx',
                position=1,
            )

    def test_vote_on_motion_bool_succeeds(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.run_private_function(
            f='assert_vote_is_valid',
            vk=1,
            action='vote_on_motion',
            position=True,
        )

    def test_action_introduce_motion_current_motion_not_no_motion_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write(variable='S', key='current_motion', value=1)

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1)

    def test_action_introduce_motion_out_of_range_motion_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=10)

    def test_action_introduce_motion_no_arg_provided_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1)

    def test_action_introduce_motion_vk_not_str_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1,
                                             arg=True)

    def test_action_introduce_motion_vk_not_64_chars_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1,
                                             arg='a')

    def test_action_introduce_motion_not_valid_hex_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(ValueError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1,
                                             arg='x' * 64,
                                             signer='x' * 64)

    def test_action_vote_on_motion_fails_if_not_bool(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(
                f='assert_vote_is_valid',
                vk=1,
                action='vote_on_motion',
                position=1,
            )

    def test_vote_not_tuple_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 'sys'],
        })

        mn_contract = self.client.get_contract('masternodes')
        with self.assertRaises(AssertionError):
            mn_contract.vote(vk='sys', obj={'hanky': 'panky'})

    def test_vote_1_elem_tuple_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 'sys'],
        })

        mn_contract = self.client.get_contract('masternodes')
        with self.assertRaises(ValueError):
            mn_contract.vote(vk='sys', obj=[1])

    def test_vote_4_elem_tuple_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 'sys'],
        })

        mn_contract = self.client.get_contract('masternodes')
        with self.assertRaises(ValueError):
            mn_contract.vote(vk='sys', obj=[1, 2, 3, 4])

    # ADD_MASTER = 1
    # REMOVE_MASTER = 2
    # ADD_SEAT = 3
    # REMOVE_SEAT = 4

    def test_introduce_motion_remove_seat_fails_if_position_out_of_index(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='introduce_motion',
                                             position=4,
                                             arg=None)

    def test_introduce_motion_remove_seat_works_and_sets_position_and_motion_opened(
            self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'open_seats', 1)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        mn_contract.run_private_function(f='introduce_motion',
                                         position=3,
                                         arg=None,
                                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 3)
        self.assertEqual(mn_contract.quick_read('S', 'motion_opened'),
                         env['now'])

    def test_add_master_or_remove_master_adds_arg(self):
        self.submit_members(constructor_args={
            'initial_members': ['abc', 'bcd', 'cde'],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'open_seats', 1)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        mn_contract.run_private_function(f='introduce_motion',
                                         position=1,
                                         arg='abc',
                                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 1)
        self.assertEqual(mn_contract.quick_read('S', 'motion_opened'),
                         env['now'])
        self.assertEqual(mn_contract.quick_read('S', 'member_in_question'),
                         'abc')

    def test_remove_master_that_does_not_exist_fails(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(
                f='introduce_motion',
                position=1,
                arg='abc',
            )

    def test_remove_master_that_exists_passes(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.run_private_function(
            f='introduce_motion',
            position=2,
            arg=1,
        )

    def test_pass_current_motion_add_master_appends_and_removes_seat(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe', amount=100_000, to='elect_members')

        self.elect_members.register(signer='joe')

        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'current_motion', 2)

        mn_contract.run_private_function(f='pass_current_motion', )

        self.assertEqual(mn_contract.quick_read('S', 'members'),
                         [1, 2, 3, 'joe'])

    def test_pass_current_motion_remove_master_adds_new_seat_and_removes_master(
            self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'member_in_question', 1)
        mn_contract.quick_write('S', 'current_motion', 1)

        mn_contract.run_private_function(f='pass_current_motion', )

        self.assertEqual(mn_contract.quick_read('S', 'members'), [2, 3])

    def test_pass_remove_seat_removes_least_popular(self):
        self.submit_members(constructor_args={
            'initial_members': ['abc', 'bcd', 'def'],
        },
                            owner='election_house')

        self.election_house.register_policy(contract='masternodes')
        self.currency.approve(signer='stu', amount=100_000, to='elect_members')

        self.elect_members.vote_no_confidence(signer='stu', address='bcd')

        self.election_house.vote(signer='abc',
                                 policy='masternodes',
                                 value=['introduce_motion', 3])
        self.election_house.vote(signer='bcd',
                                 policy='masternodes',
                                 value=['vote_on_motion', True])
        self.election_house.vote(signer='def',
                                 policy='masternodes',
                                 value=['vote_on_motion', True])

        self.assertListEqual(
            self.election_house.current_value_for_policy(policy='masternodes'),
            ['abc', 'def'])

    def test_pass_remove_seat_removes_relinquished_first(self):
        self.submit_members(constructor_args={
            'initial_members': ['abc', 'bcd', 'def'],
        },
                            owner='election_house')
        self.election_house.register_policy(contract='masternodes')

        self.elect_members.relinquish(signer='abc')

        self.election_house.vote(signer='abc',
                                 policy='masternodes',
                                 value=['introduce_motion', 3])

        self.election_house.vote(signer='bcd',
                                 policy='masternodes',
                                 value=['vote_on_motion', True])
        self.election_house.vote(signer='def',
                                 policy='masternodes',
                                 value=['vote_on_motion', True])

        self.assertListEqual(
            self.election_house.current_value_for_policy(policy='masternodes'),
            ['bcd', 'def'])

    def test_remove_seat_not_current_masternode_fails(self):
        self.submit_members(constructor_args={
            'initial_members': ['abc', 'bcd', 'def'],
        },
                            owner='election_house')
        self.election_house.register_policy(contract='masternodes')

        with self.assertRaises(AssertionError):
            self.election_house.vote(signer='abc',
                                     policy='masternodes',
                                     value=('introduce_motion', 1, 'blah'))

    def test_pass_add_seat_adds_most_popular(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe', amount=100_000, to='elect_members')

        self.elect_members.register(signer='joe')

        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.vote(vk=1, obj=['introduce_motion', 2])

        mn_contract.vote(vk=2, obj=['vote_on_motion', True])
        mn_contract.vote(vk=3, obj=['vote_on_motion', True])

        self.assertListEqual(mn_contract.current_value(), [1, 2, 3, 'joe'])

    def test_current_value_returns_dict(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        d = mn_contract.current_value()

        self.assertEqual(d, [1, 2, 3])

    # S['current_motion'] = NO_MOTION
    # S['master_in_question'] = None
    # S['votes'] = 0
    # S.clear('positions')
    def test_reset_alters_state_correctly(self):
        self.submit_members(constructor_args={
            'initial_members': [1, 2, 3],
        })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'current_motion', 1)
        mn_contract.quick_write('S', 'member_in_question', 'abc')
        mn_contract.quick_write('S', 'yays', 100)
        mn_contract.quick_write('S', 'nays', 999)
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id1'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id2'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id3'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id4'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id5'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id6'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id7'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id8'])

        mn_contract.run_private_function(f='reset', )

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'member_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'yays'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'nays'), 0)
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id1']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id2']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id3']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id4']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id5']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id6']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id7']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id8']))

    def test_vote_introduce_motion_affects_state_when_done_properly(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 3)
        self.assertEqual(mn_contract.quick_read('S', 'motion_opened'),
                         env['now'])

    def test_vote_no_motion_fails(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        with self.assertRaises(AssertionError):
            mn_contract.vote(vk='a' * 64,
                             obj=('vote_on_motion', False),
                             environment=env)

    def test_vote_on_motion_works(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        mn_contract.vote(vk='b' * 64, obj=['vote_on_motion', True])

        self.assertEqual(mn_contract.quick_read('S', 'yays'), 1)
        self.assertEqual(
            mn_contract.quick_read(variable='S',
                                   key='positions',
                                   args=['b' * 64]), True)

    def test_vote_on_motion_works_nays(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        mn_contract.vote(vk='b' * 64, obj=['vote_on_motion', False])

        self.assertEqual(mn_contract.quick_read('S', 'nays'), 1)
        self.assertEqual(mn_contract.quick_read('S', 'yays'), 0)
        self.assertEqual(
            mn_contract.quick_read(variable='S',
                                   key='positions',
                                   args=['b' * 64]), False)

    def test_vote_on_motion_twice_fails(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        mn_contract.vote(vk='b' * 64, obj=['vote_on_motion', True])

        with self.assertRaises(AssertionError):
            mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', False))

    def test_vote_reaches_more_than_half_passes(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        mn_contract.vote(vk='a' * 64, obj=['vote_on_motion', True])
        mn_contract.vote(vk='b' * 64, obj=['vote_on_motion', True])

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'member_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'yays'), 0)

    def test_vote_reaches_more_than_half_nays_fails(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        mn_contract.vote(vk='a' * 64, obj=['vote_on_motion', False])
        mn_contract.vote(vk='b' * 64, obj=['vote_on_motion', False])

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'member_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'nays'), 0)

    def test_vote_doesnt_reach_consensus_after_voting_period_fails(self):
        self.submit_members(constructor_args={
            'initial_members': ['a' * 64, 'b' * 64, 'c' * 64],
        })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=['introduce_motion', 3],
                         environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=2))}

        mn_contract.vote(vk='a' * 64,
                         obj=['vote_on_motion', True],
                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'member_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'nays'), 0)
class TestRandomsContract(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.flush()

        self.c.submit(con_module1)

        self.c.submit(con_all_in_one)
        self.c.submit(con_dynamic_import)

    def tearDown(self):
        self.c.flush()

    def test_ctx2(self):
        module = self.c.get_contract('con_module1')
        res = module.get_context2()
        expected = {
            'name': 'get_context2',
            'owner': None,
            'this': 'con_module1',
            'signer': 'stu',
            'caller': 'stu'
        }
        self.assertDictEqual(res, expected)

    def test_multi_call_doesnt_affect_parameters(self):
        aio = self.c.get_contract('con_all_in_one')
        res = aio.call_me()

        expected = {
            'name': 'call_me_again_again',
            'owner': None,
            'this': 'con_all_in_one',
            'signer': 'stu',
            'caller': 'stu'
        }

        self.assertDictEqual(res, expected)

    def test_dynamic_call(self):
        dy = self.c.get_contract('con_dynamic_import')
        res1, res2 = dy.called_from_a_far()

        expected1 = {
            'name': 'call_me_again_again',
            'owner': None,
            'this': 'con_all_in_one',
            'signer': 'stu',
            'caller': 'con_dynamic_import'
        }

        expected2 = {
            'name': 'called_from_a_far',
            'owner': None,
            'this': 'con_dynamic_import',
            'signer': 'stu',
            'caller': 'stu'
        }

        self.assertDictEqual(res1, expected1)
        self.assertDictEqual(res2, expected2)
class TokenTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()
        with open('tad.py') as file:
            code = file.read()
        self.client.submit(code, name='tad_token', constructor_args={
                           'owner': 'me'})
        self.tad = self.client.get_contract('tad_token')

        self.tad.mint(amount=1000000, signer='me')

    def tearDown(self):
        self.client.flush()

    def test_transfer_negative(self):
        try:
            self.tad.transfer(amount=-1, to='wallet2', signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_transfer_excess(self):
        try:
            self.tad.transfer(amount=1000001, to='wallet2', signer='me')
            raise
        except AssertionError as message:
            assert 'enough' in str(message)

    def test_transfer_normal(self):
        self.tad.transfer(amount=42, to='wallet2', signer='me')
        self.assertAlmostEqual(
            self.tad.balance_of(account='me'), 1000000 - 42)
        self.assertAlmostEqual(self.tad.balance_of(account='wallet2'), 42)

    def test_balance(self):
        self.assertAlmostEqual(self.tad.balance_of(account='me'), 1000000)
        self.assertAlmostEqual(self.tad.balance_of(account='wallet2'), 0)

    def test_accounts_negative(self):
        try:
            self.tad.approve(amount=-1, to='account1', signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_accounts_normal(self):
        self.tad.approve(amount=42, to='account1', signer='me')
        self.assertAlmostEqual(self.tad.allowance(
            owner='me', spender='account1', signer='me'), 42)

    def test_transfer_from_negative(self):
        self.tad.approve(amount=42, to='account1', signer='me')
        try:
            self.tad.transfer_from(amount=-1, to='wallet2',
                                   main_account='me', signer='account1')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_transfer_from_excess(self):
        self.tad.approve(amount=42, to='account1', signer='me')
        try:
            self.tad.transfer_from(amount=1000001, to='wallet2',
                                   main_account='me', signer='account1')
            raise
        except AssertionError as message:
            assert 'enough' in str(message)

    def test_transfer_from_approved(self):
        self.tad.approve(amount=42, to='account1', signer='me')
        try:
            self.tad.transfer_from(amount=1000000, to='wallet2',
                                   main_account='me', signer='account1')
            raise
        except AssertionError as message:
            assert 'approved' in str(message)

    def test_transfer_from_normal(self):
        self.tad.approve(amount=42, to='account1', signer='me')
        self.tad.transfer_from(amount=42, to='wallet2',
                               main_account='me', signer='account1')
        self.assertAlmostEqual(self.tad.allowance(
            owner='me', spender='account1', signer='me'), 0)
        self.assertAlmostEqual(
            self.tad.balance_of(account='me'), 1000000 - 42)
        self.assertAlmostEqual(self.tad.balance_of(account='wallet2'), 42)

    def test_burn_negative(self):
        try:
            self.tad.burn(amount=-1, signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_burn_excess(self):
        try:
            self.tad.burn(amount=1000001, signer='me')
            raise
        except AssertionError as message:
            assert 'enough' in str(message)

    def test_burn_normal(self):
        old_supply = self.tad.get_total_supply()
        self.tad.burn(amount=42, signer='me')
        self.assertAlmostEqual(self.tad.get_total_supply(), old_supply - 42)

    def test_mint_negative(self):
        try:
            self.tad.mint(amount=-1, signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_mint_unauthorised(self):
        try:
            self.tad.mint(amount=42, signer='wallet1')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)

    def test_mint_normal(self):
        old_supply = self.tad.get_total_supply()
        self.tad.mint(amount=42, signer='me')
        self.assertAlmostEqual(self.tad.get_total_supply(), old_supply + 42)

    def test_metadata_unauthorised(self):
        try:
            self.tad.change_metadata(
                key='testing', value='testing', signer='me')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)

    def test_metadata_normal(self):
        self.tad.change_metadata(key='testing', value='testing')
        assert self.tad.metadata['testing'] == 'testing'
        self.tad.change_metadata(key='testing', value='again')
        assert self.tad.metadata['testing'] == 'again'

    def test_change_owner_unauthorised(self):
        try:
            self.tad.change_owner(new_owner='wallet2', signer='wallet2')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)

    def test_change_owner_normal(self):
        self.tad.change_owner(new_owner='wallet2', signer='me')
        try:
            self.tad.change_owner(new_owner='me', signer='me')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)
class TestUpdateContractFix(TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        self.mn_wallets = [Wallet().verifying_key for _ in range(3)]
        self.dn_wallets = [Wallet().verifying_key for _ in range(3)]

        # Sync contracts
        sync.setup_genesis_contracts(initial_masternodes=self.mn_wallets,
                                     initial_delegates=self.dn_wallets,
                                     client=self.client,
                                     filename=lamden.contracts.__path__[0] +
                                     '/genesis.json',
                                     root=lamden.contracts.__path__[0])

        self.upgrade = self.client.get_contract('upgrade')

    def tearDown(self):
        self.client.flush()

    def test_initial_state(self):
        self.assertEqual(self.upgrade.upgrade_state['locked'], False)
        self.assertEqual(self.upgrade.upgrade_state['consensus'], False)

        self.assertEqual(self.upgrade.upgrade_state['votes'], 0)
        self.assertEqual(self.upgrade.upgrade_state['voters'], 0)

    def test_is_valid_voter_true_for_master(self):
        r = self.upgrade.run_private_function(f='is_valid_voter',
                                              address=self.mn_wallets[0])
        self.assertTrue(r)

    def test_is_valid_voter_true_for_delegate(self):
        r = self.upgrade.run_private_function(f='is_valid_voter',
                                              address=self.dn_wallets[0])
        self.assertTrue(r)

    def test_is_valid_voter_false_for_others(self):
        r = self.upgrade.run_private_function(f='is_valid_voter',
                                              address=Wallet().verifying_key)
        self.assertFalse(r)

    def test_start_vote_sets_state(self):
        self.upgrade.run_private_function(f='start_vote',
                                          cilantro_branch_name='hello1',
                                          contracting_branch_name='hello2',
                                          pepper='123xyz')

        self.assertEqual(self.upgrade.upgrade_state['locked'], True)
        self.assertEqual(self.upgrade.upgrade_state['consensus'], False)

        self.assertEqual(self.upgrade.upgrade_state['votes'], 0)
        self.assertEqual(self.upgrade.upgrade_state['voters'], 6)

        self.assertEqual(self.upgrade.upgrade_state['pepper'], '123xyz')
        self.assertEqual(self.upgrade.upgrade_state['cilantro_branch_name'],
                         'hello1')
        self.assertEqual(self.upgrade.upgrade_state['contracting_branch_name'],
                         'hello2')

    def test_first_vote_starts_vote(self):
        env = {'now': Datetime._from_datetime(datetime.now())}

        self.upgrade.vote(signer=self.mn_wallets[0],
                          cilantro_branch_name='hello1',
                          contracting_branch_name='hello2',
                          pepper='123xyz',
                          environment=env)

        self.assertEqual(self.upgrade.upgrade_state['locked'], True)
        self.assertEqual(self.upgrade.upgrade_state['consensus'], False)

        self.assertEqual(self.upgrade.upgrade_state['votes'], 1)
        self.assertEqual(self.upgrade.upgrade_state['voters'], 6)

        self.assertEqual(self.upgrade.upgrade_state['pepper'], '123xyz')
        self.assertEqual(self.upgrade.upgrade_state['cilantro_branch_name'],
                         'hello1')
        self.assertEqual(self.upgrade.upgrade_state['contracting_branch_name'],
                         'hello2')

        self.assertEqual(self.upgrade.has_voted[self.mn_wallets[0]], True)

        self.assertEqual(self.upgrade.upgrade_state['started'], env['now'])

    def test_second_vote_fails_if_already_voted(self):
        self.upgrade.vote(signer=self.mn_wallets[0],
                          cilantro_branch_name='hello1',
                          contracting_branch_name='hello2',
                          pepper='123xyz')

        with self.assertRaises(AssertionError):
            self.upgrade.vote(signer=self.mn_wallets[0])

    def test_non_voter_cannot_vote(self):
        with self.assertRaises(AssertionError):
            self.upgrade.vote(signer='someone')

    def test_two_thirds_sets_consensus_to_true(self):
        self.upgrade.vote(signer=self.mn_wallets[0],
                          cilantro_branch_name='hello1',
                          contracting_branch_name='hello2',
                          pepper='123xyz')

        self.upgrade.vote(signer=self.mn_wallets[1])
        self.upgrade.vote(signer=self.mn_wallets[2])
        self.upgrade.vote(signer=self.dn_wallets[0])

        self.assertTrue(self.upgrade.upgrade_state['consensus'])

    def test_vote_after_window_resets(self):
        self.upgrade.vote(signer=self.mn_wallets[0],
                          cilantro_branch_name='hello1',
                          contracting_branch_name='hello2',
                          pepper='123xyz')

        self.upgrade.vote(signer=self.mn_wallets[1])

        self.assertEqual(self.upgrade.upgrade_state['votes'], 2)

        env = {
            'now': Datetime._from_datetime(datetime.now() + timedelta(weeks=2))
        }

        # This will fail because it needs the keyword arguments
        with self.assertRaises(TypeError):
            self.upgrade.vote(signer=self.mn_wallets[2], environment=env)

        # This will pass
        self.upgrade.vote(signer=self.mn_wallets[2],
                          cilantro_branch_name='hello4',
                          contracting_branch_name='hello6',
                          pepper='693kdw',
                          environment=env)

        self.assertEqual(self.upgrade.upgrade_state['votes'], 1)

        self.assertEqual(self.upgrade.upgrade_state['pepper'], '693kdw')
        self.assertEqual(self.upgrade.upgrade_state['cilantro_branch_name'],
                         'hello4')
        self.assertEqual(self.upgrade.upgrade_state['contracting_branch_name'],
                         'hello6')

    def test_vote_after_window_reset_can_pass(self):
        self.upgrade.vote(signer=self.mn_wallets[0],
                          cilantro_branch_name='hello1',
                          contracting_branch_name='hello2',
                          pepper='123xyz')

        self.upgrade.vote(signer=self.mn_wallets[1])

        self.assertEqual(self.upgrade.upgrade_state['votes'], 2)

        env = {
            'now': Datetime._from_datetime(datetime.now() + timedelta(weeks=2))
        }

        # This will fail because it needs the keyword arguments
        with self.assertRaises(TypeError):
            self.upgrade.vote(signer=self.mn_wallets[2], environment=env)

        # This will pass
        self.upgrade.vote(signer=self.mn_wallets[2],
                          cilantro_branch_name='hello4',
                          contracting_branch_name='hello6',
                          pepper='693kdw',
                          environment=env)

        self.upgrade.vote(signer=self.mn_wallets[0], environment=env)
        self.upgrade.vote(signer=self.mn_wallets[1], environment=env)
        self.upgrade.vote(signer=self.dn_wallets[0], environment=env)

        self.assertTrue(self.upgrade.upgrade_state['consensus'])

    def test_build_pepper(self):
        p = build_pepper()
        self.assertEqual(p, p)

    def test_build_pepper_new(self):
        p = build_pepper2()
        self.assertEqual(
            p,
            '12efdca5ee2b4103c549feab7d9fdbb95b374d3e447cbb85be81c9021a641426')

    def test_git_branch(self):
        path = os.path.join(os.path.dirname(lamden.__file__), '..')
        os.chdir(path)

        from subprocess import check_output
        new_branch_name = check_output(
            ["git", "rev-parse", "--abbrev-ref", "HEAD"]).rstrip().decode()
        print(new_branch_name)
        old_branch = get_version()
        flag = 'ori1-rel-gov-socks-upg' == old_branch
        self.assertFalse(flag)
Exemple #27
0
class TestStamps(TestCase):
    def setUp(self):
        self.client = ContractingClient()

        self.client.flush()

        with open('./contracts/election_house.s.py') as f:
            contract = f.read()

        self.client.submit(contract, name='election_house')
        self.election_house = self.client.get_contract('election_house')

        with open('./contracts/masternodes.s.py') as f:
            contract = f.read()

        self.client.submit(
            contract,
            name='masternodes',
            owner='election_house',
            constructor_args={
                'initial_masternodes':
                ['stu', 'raghu', 'alex', 'monica', 'steve', 'tejas'],
                'initial_open_seats':
                0
            })

        self.election_house.register_policy(contract='masternodes')

        self.masternodes = self.client.get_contract('masternodes')

    def tearDown(self):
        self.client.flush()

    def test_init(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        self.assertEqual(stamps_contract.current_value(), 10000)

    def test_vote_is_not_int_fails(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        with self.assertRaises(AssertionError):
            stamps_contract.run_private_function(f='assert_vote_is_valid',
                                                 vk='sys',
                                                 obj='a')

    def test_vote_is_less_than_half_current_rate_fails(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        with self.assertRaises(AssertionError):
            stamps_contract.run_private_function(f='assert_vote_is_valid',
                                                 vk='sys',
                                                 obj=4000)

    def test_vote_is_greater_than_double_current_rate_fails(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        with self.assertRaises(AssertionError):
            stamps_contract.run_private_function(f='assert_vote_is_valid',
                                                 vk='sys',
                                                 obj=40000)

    def test_vk_is_not_masternode_fails(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        with self.assertRaises(AssertionError):
            stamps_contract.run_private_function(f='assert_vote_is_valid',
                                                 vk='sys',
                                                 obj=12000)

    def test_vote_works_if_vk_in_range_etc(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        stamps_contract.run_private_function(f='assert_vote_is_valid',
                                             vk='stu',
                                             obj=12000)

    def test_vk_has_already_voted_fails(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        stamps_contract.quick_write('S', 'votes', args=['stu'], value=123)

        with self.assertRaises(AssertionError):
            stamps_contract.run_private_function(f='assert_vote_is_valid',
                                                 vk='stu',
                                                 obj=12000)

    def test_median_performs_properly_on_even_lists(self):
        a = [12, 62, 16, 24, 85, 41, 84, 13, 1999, 47, 27, 43]
        expected = 42

        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        got = stamps_contract.run_private_function(
            f='median',
            vs=a,
        )

        self.assertEqual(expected, got)

    def test_median_performs_properly_on_odd_lists(self):
        a = [92, 73, 187, 2067, 10, 204, 307, 24, 478, 23, 11]
        expected = 92

        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        got = stamps_contract.run_private_function(
            f='median',
            vs=a,
        )

        self.assertEqual(expected, got)

    def test_reset_works(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        stamps_contract.quick_write('S', 'votes', value=123, args=['id1'])
        stamps_contract.quick_write('S', 'votes', value=124, args=['id2'])
        stamps_contract.quick_write('S', 'votes', value=125, args=['id3'])
        stamps_contract.quick_write('S', 'votes', value=126, args=['id4'])
        stamps_contract.quick_write('S', 'votes', value=127, args=['id5'])
        stamps_contract.quick_write('S', 'votes', value=128, args=['id6'])
        stamps_contract.quick_write('S', 'votes', value=129, args=['id7'])
        stamps_contract.quick_write('S', 'votes', value=130, args=['id8'])
        stamps_contract.quick_write('S', 'votes', value=131, args=['id9'])

        stamps_contract.quick_write('S', 'in_election', value=True)
        stamps_contract.quick_write('S',
                                    'last_election_end_time',
                                    value='something')

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}
        stamps_contract.run_private_function('reset', environment=env)

        self.client.raw_driver.commit()

        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id1']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id2']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id3']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id4']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id5']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id6']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id7']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id8']),
                         None)
        self.assertEqual(stamps_contract.quick_read('S', 'votes', ['id9']),
                         None)

        self.assertEqual(stamps_contract.quick_read('S', 'in_election'), False)
        self.assertEqual(
            stamps_contract.quick_read('S', 'last_election_end_time'),
            env['now'])

    def test_vote_starts_election_if_time_to(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')
        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}
        stamps_contract.vote(vk='stu', obj=20000, environment=env)

        self.assertEqual(stamps_contract.S['election_start_time'], env['now'])
        self.assertEqual(stamps_contract.S['in_election'], True)
        self.assertEqual(stamps_contract.S['votes', 'stu'], 20000)

    def test_vote_doesnt_start_election_if_not_valid(self):
        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        with self.assertRaises(AssertionError):
            stamps_contract.vote(vk='boo', obj=20000, environment=env)

        self.assertEqual(stamps_contract.S['in_election'], False)
        self.assertEqual(stamps_contract.S['votes', 'boo'], None)

    def test_vote_if_started_correct_votes_tally_properly(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        stamps_contract.vote(vk='stu', obj=20000, environment=env)
        stamps_contract.vote(vk='raghu', obj=15000, environment=env)

        self.assertEqual(stamps_contract.S['votes', 'raghu'], 15000)

    def test_vote_if_started_bad_votes_not_tallied(self):
        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        stamps_contract.vote(vk='stu', obj=20000, environment=env)
        with self.assertRaises(AssertionError):
            stamps_contract.vote(vk='raghu', obj=25000, environment=env)

        self.assertEqual(stamps_contract.S['votes', 'raghu'], None)

    def test_vote_passes_voting_period_runs_median_sets_new_rate_and_resets_properly(
            self):
        # 'stu', 'raghu', 'alex', 'monica', 'steve', 'tejas'

        self.client.submit(stamps, constructor_args={
            'initial_rate': 10000,
        })

        stamps_contract = self.client.get_contract('stamps')

        self.assertEqual(stamps_contract.S['rate'], 10000)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        stamps_contract.vote(vk='stu', obj=20000, environment=env)
        stamps_contract.vote(vk='raghu', obj=5000, environment=env)
        stamps_contract.vote(vk='alex', obj=12000, environment=env)
        stamps_contract.vote(vk='monica', obj=13000, environment=env)
        stamps_contract.vote(vk='steve', obj=7000, environment=env)

        self.assertEqual(stamps_contract.S['votes', 'stu'], 20000)
        self.assertEqual(stamps_contract.S['votes', 'raghu'], 5000)
        self.assertEqual(stamps_contract.S['votes', 'alex'], 12000)
        self.assertEqual(stamps_contract.S['votes', 'monica'], 13000)
        self.assertEqual(stamps_contract.S['votes', 'steve'], 7000)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=14))}

        stamps_contract.vote(vk='tejas', obj=15000, environment=env)

        expected = 12500

        self.assertEqual(stamps_contract.S['rate'], expected)

    def test_integration_into_election_house(self):
        self.client.submit(stamps,
                           constructor_args={
                               'initial_rate': 10000,
                           },
                           owner='election_house')

        self.election_house.register_policy(contract='stamps')

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        self.election_house.vote(policy='stamps',
                                 value=20000,
                                 signer='stu',
                                 environment=env)
        self.election_house.vote(policy='stamps',
                                 value=5000,
                                 signer='raghu',
                                 environment=env)
        self.election_house.vote(policy='stamps',
                                 value=12000,
                                 signer='alex',
                                 environment=env)
        self.election_house.vote(policy='stamps',
                                 value=13000,
                                 signer='monica',
                                 environment=env)
        self.election_house.vote(policy='stamps',
                                 value=7000,
                                 signer='steve',
                                 environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=14))}

        self.election_house.vote(policy='stamps',
                                 value=15000,
                                 signer='tejas',
                                 environment=env)

        self.assertEqual(
            self.election_house.current_value_for_policy(policy='stamps'),
            12500)
Exemple #28
0
class TestContract(unittest.TestCase):
    main_contract = None
    currency_contract = None

    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        self.client.submit(currency_code, name="currency")
        self.client.submit(contract_code, name=CONTRACT_NAME)
        self.main_contract = self.client.get_contract(CONTRACT_NAME)
        self.currency_contract = self.client.get_contract("currency")

    def tearDown(self):
        self.client.flush()

    def change_signer(self, signer: str):
        self.client.signer = signer

    def get_contracts(self):
        self.main_contract = self.client.get_contract(CONTRACT_NAME)
        self.currency_contract = self.client.get_contract("currency")

    def post(self):
        self.currency_contract.quick_write("balances", "me", 10000)
        self.currency_contract.approve(amount=1000, to=self.main_contract.name)
        self.main_contract.post(title="test",
                                content="test test",
                                bounty=500,
                                email="test")

    def award(self):
        self.change_signer("me")
        self.get_contracts()
        self.change_signer(self.main_contract.name)
        self.get_contracts()
        self.currency_contract.quick_write("balances", self.main_contract.name,
                                           10000)
        # self.currency_contract.approve(amount=1000, to=self.client.signer)
        self.change_signer("me")
        self.get_contracts()
        self.main_contract.award(title="test", winner="notme")

    def test_post(self):
        self.change_signer("me")
        self.get_contracts()
        self.assertRaises(
            AssertionError,
            lambda: self.main_contract.post(
                title="test", content="test test", bounty=300),
        )
        self.post()
        expected = {"content": "test test", "bounty": 500}
        for k, v in expected.items():
            self.assertEqual(
                self.main_contract.quick_read("posts", "me", ["test", k]),
                v,
            )

    def test_answer(self):
        self.change_signer("me")
        self.get_contracts()
        self.post()
        self.change_signer("notme")
        self.get_contracts()
        self.currency_contract.approve(amount=1000, to="notme")
        self.main_contract.answer(title="test",
                                  content="this is an answer",
                                  owner="me")
        self.assertEqual(
            self.main_contract.quick_read("answers", "notme", ["test"]),
            "this is an answer",
        )
        self.assertRaises(
            AssertionError,
            lambda: self.main_contract.answer(
                title="test", content="this is an answer", owner="me"),
        )

    def test_award(self):
        self.change_signer("me")
        self.get_contracts()
        self.post()
        self.assertEqual(
            self.main_contract.quick_read("posts", "me", ["test", "bounty"]),
            500)
        self.change_signer("notme")
        self.get_contracts()
        self.main_contract.answer(title="test",
                                  content="this is an answer",
                                  owner="me")
        self.award()
        self.assertEqual(
            self.main_contract.quick_read("posts", "me", ["test", "bounty"]),
            0)

    def test_empty_post(self):
        self.change_signer("me")
        self.get_contracts()
        self.assertRaises(
            AssertionError,
            lambda: self.main_contract.post(
                title="test", content="", bounty=300),
        )
        self.assertRaises(
            AssertionError,
            lambda: self.main_contract.post(
                title="test", content="asda", bounty=-1),
        )

    def test_empty_answer(self):
        self.change_signer("notme")
        self.get_contracts()
        self.assertRaises(
            AssertionError,
            lambda: self.main_contract.answer(
                title="test", content="", owner="me"),
        )

    def test_double_award(self):
        self.change_signer("me")
        self.get_contracts()
        self.post()
        self.assertEqual(
            self.main_contract.quick_read("posts", "me", ["test", "bounty"]),
            500)
        self.change_signer("notme")
        self.get_contracts()
        self.main_contract.answer(title="test",
                                  content="this is an answer",
                                  owner="me")
        self.award()
        self.assertEqual(
            self.main_contract.quick_read("posts", "me", ["test", "bounty"]),
            0)
        self.assertRaises(AssertionError, lambda: self.award())

    def test_award_not_owner(self):
        self.change_signer("me")
        self.get_contracts()
        self.post()
        self.assertEqual(
            self.main_contract.quick_read("posts", "me", ["test", "bounty"]),
            500)
        self.change_signer("notme")
        self.get_contracts()
        self.main_contract.answer(title="test",
                                  content="this is an answer",
                                  owner="me")
        self.change_signer(self.main_contract.name)
        self.get_contracts()
        self.currency_contract.quick_write("balances", self.main_contract.name,
                                           10000)
        self.currency_contract.approve(amount=1000, to=self.client.signer)
        self.assertRaises(
            AssertionError,
            lambda: self.main_contract.award(title="test", winner="notme"),
        )
Exemple #29
0
class VaultTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        with open('dai.py') as file:
            dai = file.read()

        with open('vault.py') as file:
            vault = file.read()

        with open('test_currency.py') as file:
            currency = file.read()

        with open('oracle.py') as file:
            oracle = file.read()

        self.client.submit(dai,
                           name='dai_contract',
                           constructor_args={'owner': 'vault_contract'})

        self.client.submit(vault, name='vault_contract')
        self.client.submit(currency, name='currency')
        self.client.submit(oracle, name='oracle')

        self.dai = self.client.get_contract('dai_contract')
        self.vault = self.client.get_contract('vault_contract')
        self.currency = self.client.get_contract('currency')
        self.oracle = self.client.get_contract('oracle')

        self.oracle.set_price(number=0, new_price=1.0)
        self.vault.change_any_state(key=('mint', 'DSR', 'owner'),
                                    new_value='sys')
        self.vault.change_any_state(key=(0, 'DSR', 'owner'), new_value='sys')
        self.vault.change_any_state(key=('currency', 'DSR', 'owner'),
                                    new_value='sys')

    def tearDown(self):
        self.client.flush()

    def test_create_vault_unavailable(self):
        with self.assertRaisesRegex(AssertionError, 'available'):
            self.vault.create_vault(vault_type=-1,
                                    amount_of_dai=100,
                                    amount_of_collateral=100)

    def test_create_vault_negative(self):
        with self.assertRaisesRegex(AssertionError, 'positive'):
            self.vault.create_vault(vault_type=0,
                                    amount_of_dai=-1,
                                    amount_of_collateral=100)

    def test_create_vault_insufficient_allowance(self):
        with self.assertRaisesRegex(AssertionError, 'allowance'):
            self.vault.create_vault(vault_type=0,
                                    amount_of_dai=1000001,
                                    amount_of_collateral=1000001)

    def test_create_vault_insufficient_collateral(self):
        self.currency.approve(to='vault_contract', amount=100)
        with self.assertRaisesRegex(AssertionError, 'collateral'):
            self.vault.create_vault(vault_type=0,
                                    amount_of_dai=100,
                                    amount_of_collateral=100)

    def test_create_vault_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)

    def test_create_vault_states(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)

        assert self.vault.cdp['current_value'] == 1
        assert self.vault.cdp[id, 'owner'] == 'sys'
        assert self.vault.cdp[id, 'open'] == True
        assert self.vault.cdp[id, 'collateral_type'] == self.vault.vaults[
            0, 'collateral_type']
        assert self.vault.cdp[id, 'vault_type'] == 0
        assert self.vault.cdp[id, 'dai'] == 100
        assert self.vault.cdp[id, 'collateral_amount'] == 1500
        assert self.vault.cdp[id, 'time'] == self.vault.get_timestamp()

    def test_create_vault_takes_collateral(self):
        self.currency.transfer(to='stu', amount=1500)
        self.currency.approve(to='vault_contract', amount=1500, signer='stu')

        self.vault.create_vault(
            vault_type=0,
            amount_of_dai=100,
            amount_of_collateral=1500,
            signer='stu')  # Might fail, not sure why commented

        self.assertEqual(self.currency.balances['stu'], 0)

    def test_create_vault_gives_dai(self):
        self.currency.transfer(to='stu', amount=1500)
        self.currency.approve(to='vault_contract', amount=1500, signer='stu')

        self.vault.create_vault(
            vault_type=0,
            amount_of_dai=100,
            amount_of_collateral=1500,
            signer='stu')  # Might fail, not sure why commented

        self.assertEqual(self.dai.balances['stu'], 100)

    def test_create_vault_updates_reserves(self):
        self.currency.approve(to='vault_contract', amount=1500)

        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)

        self.assertEqual(self.vault.vaults[0, 'issued'], 100)
        self.assertEqual(self.vault.vaults[0, 'total'], 100)

    def test_any_state_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.change_any_state(key='testing',
                                        new_value='testing',
                                        signer='me')

    def test_any_state_normal(self):
        self.vault.change_any_state(key='testing', new_value='testing')
        assert self.vault.vaults['testing'] == 'testing'
        self.vault.change_any_state(key='testing', new_value='again')
        assert self.vault.vaults['testing'] == 'again'

    def test_state_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.change_state(key='testing2',
                                    new_value='testing2',
                                    signer='me')

    def test_change_owner_works(self):
        self.vault.change_state(key='OWNER', new_value='stu')
        self.assertEqual(self.vault.vaults['OWNER'], 'stu')

        self.vault.change_state(key='OWNER', new_value='jeff', signer='stu')
        self.assertEqual(self.vault.vaults['OWNER'], 'jeff')

        self.vault.change_state(key='FOO',
                                new_value='1',
                                convert_to_decimal=True,
                                signer='jeff')
        self.assertEqual(self.vault.vaults['FOO'], 1)

    def test_change_owner_twice_fails(self):
        self.vault.change_state(key='OWNER', new_value='stu')
        self.assertEqual(self.vault.vaults['OWNER'], 'stu')

        with self.assertRaises(AssertionError):
            self.vault.change_state(key='OWNER', new_value='stu')

    def test_state_invalid_type_key(self):
        with self.assertRaisesRegex(AssertionError, 'key'):
            self.vault.change_state(key=42, new_value='value')

    def test_state_invalid_type_value(self):
        with self.assertRaisesRegex(AssertionError, 'value'):
            self.vault.change_state(key='value', new_value=42)

    def test_state_decimal(self):
        self.vault.change_state(key='testing2',
                                new_value='0.42',
                                convert_to_decimal=True)
        self.assertAlmostEqual(self.vault.vaults['testing2'], 0.42)

    def test_state_normal(self):
        self.vault.change_state(key='testing2', new_value='testing2')
        assert self.vault.vaults['testing2'] == 'testing2'
        self.vault.change_state(key='testing2', new_value='again2')
        assert self.vault.vaults['testing2'] == 'again2'

    def test_sync_burn_nonexistent(self):
        with self.assertRaisesRegex(AssertionError, 'available'):
            self.vault.sync_burn(vault_type=-1, amount=1)

    def test_sync_burn_insufficient(self):
        with self.assertRaisesRegex(AssertionError, 'enough'):
            self.vault.sync_burn(vault_type=0, amount=1)

    def test_sync_burn_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.sync_burn(vault_type=0, amount=1)

    def test_sync_burn_changes_state(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)
        total = self.dai.total_supply.get()
        original = self.vault.vaults[0, 'total']
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.sync_burn(vault_type=0, amount=1)

        self.assertAlmostEqual(total - 1, self.dai.total_supply.get())
        self.assertAlmostEqual(original - 1, self.vault.vaults[0, 'total'])

    def test_sync_stability_pool_nonexistent(self):
        with self.assertRaisesRegex(AssertionError, 'available'):
            self.vault.sync_stability_pool(vault_type=-1)

    def test_sync_stability_pool_zero(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)
        self.vault.sync_stability_pool(vault_type=0)
        assert 0 == self.vault.stability_pool[0]

    def test_sync_stability_pool_positive(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.id = self.vault.create_vault(vault_type=0,
                                          amount_of_dai=100,
                                          amount_of_collateral=1500)
        self.vault.open_force_close_auction(cdp_number=self.id)
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.bid_on_force_close(cdp_number=self.id, amount=1)
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        self.vault.settle_force_close(cdp_number=self.id, environment=env)
        self.vault.sync_stability_pool(vault_type=0)

    def test_sync_stability_pool_positive_changes_state(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.id = self.vault.create_vault(vault_type=0,
                                          amount_of_dai=100,
                                          amount_of_collateral=1500)
        self.vault.open_force_close_auction(cdp_number=self.id)
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.bid_on_force_close(cdp_number=self.id, amount=1)
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        self.vault.settle_force_close(cdp_number=self.id, environment=env)
        total = self.vault.vaults[0, 'total']
        issued = self.vault.vaults[0, 'issued']
        pool = self.vault.stability_pool[0]
        self.assertAlmostEqual(self.vault.sync_stability_pool(vault_type=0),
                               (issued + pool) / total)
        self.assertAlmostEqual(issued + pool, self.vault.vaults[0, 'issued'])
        self.assertAlmostEqual(self.vault.stability_pool[0], 0)

    def test_sync_stability_pool_negative(self):
        self.vault.vaults[0, 'total'] = 0
        self.vault.vaults[0, 'issued'] = 100
        self.vault.sync_stability_pool(vault_type=0)

    def test_sync_stability_pool_negative_changes_state(self):
        self.vault.vaults[0, 'total'] = 0
        self.vault.vaults[0, 'issued'] = 100
        self.vault.sync_stability_pool(vault_type=0)
        self.assertAlmostEqual(self.vault.vaults[0, 'issued'], 0)
        self.assertAlmostEqual(self.vault.stability_pool[0], 100)

    def test_remove_vault_unauthorised(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.remove_vault(vault_type=0, signer='bob')

    def test_remove_vault_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.vault.create_vault(vault_type=0,
                                amount_of_dai=100,
                                amount_of_collateral=1500)
        self.vault.remove_vault(vault_type=0)
        assert 0 not in self.vault.vaults['list']

    def test_close_vault_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)

    def test_close_vault_closes_vault(self):
        self.currency.approve(to='vault_contract', amount=1500)

        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)

        self.assertEqual(self.vault.cdp[id, 'open'], False)

    def test_close_vault_updates_reserves(self):
        self.currency.approve(to='vault_contract', amount=1500)

        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)

        self.assertEqual(self.vault.vaults[0, 'issued'], 100)
        self.assertEqual(self.vault.vaults[0, 'total'], 100)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)

        self.assertEqual(self.vault.vaults[0, 'issued'], 0)
        self.assertEqual(self.vault.vaults[0, 'total'], 0)

    def test_close_vault_takes_dai(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)

        self.assertEqual(self.vault.vaults[0, 'issued'], 100)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)

    def close_vault_takes_dai_and_stability_fee(self):
        pass

    def close_vault_adjusts_based_on_reserves(self):  # use ENV
        pass

    # use ENV
    def close_vault_adjusts_based_on_reserves_and_stability_fee(self):
        pass

    def test_close_vault_returns_collateral(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)

        self.assertAlmostEqual(self.currency.balance_of(account='sys'),
                               2147483647 - 1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)
        self.assertAlmostEqual(self.currency.balance_of(account='sys'),
                               2147483647)

    def test_close_vault_funds_burned(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.assertAlmostEqual(self.dai.total_supply.get(), 100)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)
        self.assertAlmostEqual(self.dai.total_supply.get(), 0)

    def close_vault_fee_not_burned(self):
        pass

    def test_close_vault_unauthorised(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.close_vault(cdp_number=id, signer='wallet2')

    def test_close_vault_twice_fails(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)
        with self.assertRaisesRegex(AssertionError, 'closed'):
            self.vault.close_vault(cdp_number=id)

    def test_open_and_close_vault_1000_times(self):
        id_list = [i for i in range(1000)]

        for x in range(1, 1001):
            self.currency.approve(to='vault_contract', amount=151)
            self.vault.create_vault(vault_type=0,
                                    amount_of_dai=100,
                                    amount_of_collateral=151)
            self.assertEqual(self.vault.vaults[0, 'issued'], x * 100)
            self.assertEqual(self.vault.vaults[0, 'total'], x * 100)
            self.assertEqual(self.dai.balances['sys'], x * 100)
            self.assertEqual(self.dai.total_supply.get(), x * 100)

        for x in range(1, 1001):
            id = random.choice(id_list)
            id_list.remove(id)
            self.dai.approve(to='vault_contract', amount=100)
            self.vault.close_vault(cdp_number=id)

            self.assertEqual(self.vault.vaults[0, 'issued'],
                             1000 * 100 - x * 100)
            self.assertEqual(self.vault.vaults[0, 'total'],
                             1000 * 100 - x * 100)
            self.assertEqual(self.dai.balances['sys'], 1000 * 100 - x * 100)
            self.assertEqual(self.dai.total_supply.get(), 1000 * 100 - x * 100)

    def test_timestamp_is_correct(self):
        assert abs(datetime.datetime.utcnow().timestamp() -
                   self.vault.get_timestamp()) % 14400 < 120

    def test_export_rewards_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.export_rewards(vault_type=0, amount=1, signer='wallet2')

    def test_export_rewards_insufficient(self):
        with self.assertRaisesRegex(AssertionError, 'enough'):
            self.vault.export_rewards(vault_type=0, amount=1)

    def test_export_rewards_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.id = self.vault.create_vault(vault_type=0,
                                          amount_of_dai=100,
                                          amount_of_collateral=1500)
        self.vault.open_force_close_auction(cdp_number=self.id)
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.bid_on_force_close(cdp_number=self.id, amount=1)
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        self.vault.settle_force_close(cdp_number=self.id, environment=env)
        self.vault.export_rewards(vault_type=0, amount=0.1)

    def test_export_rewards_gives_rewards(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.id = self.vault.create_vault(vault_type=0,
                                          amount_of_dai=100,
                                          amount_of_collateral=1500)
        self.vault.open_force_close_auction(cdp_number=self.id)
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.bid_on_force_close(cdp_number=self.id, amount=1)
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        self.vault.settle_force_close(cdp_number=self.id, environment=env)
        self.vault.export_rewards(vault_type=0, amount=0.1)
        self.assertAlmostEqual(self.dai.balance_of(account='sys'),
                               99.1)  # 99 from unused dai amount

    def test_export_rewards_changes_state(self):
        self.currency.approve(to='vault_contract', amount=1500)
        self.id = self.vault.create_vault(vault_type=0,
                                          amount_of_dai=100,
                                          amount_of_collateral=1500)
        self.vault.open_force_close_auction(cdp_number=self.id)
        self.dai.approve(to='vault_contract', amount=1)
        self.vault.bid_on_force_close(cdp_number=self.id, amount=1)
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        self.vault.settle_force_close(cdp_number=self.id, environment=env)
        self.vault.export_rewards(vault_type=0, amount=0.1)
        assert self.vault.stability_pool[0] == 0

    def test_mint_rewards_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.mint_rewards(amount=1, signer='wallet2')

    def test_mint_rewards_negative(self):
        with self.assertRaisesRegex(AssertionError, 'negative'):
            self.vault.mint_rewards(amount=-1)

    def test_mint_rewards_normal(self):
        self.vault.mint_rewards(amount=1)

    def test_mint_rewards_gives_rewards(self):
        self.vault.mint_rewards(amount=1)
        self.assertAlmostEqual(self.dai.balance_of(account='sys'), 1)

    def test_mint_rewards_changes_state(self):
        self.vault.mint_rewards(amount=1)
        assert self.vault.vaults[0, 'total'] == 1

    def test_mint_rewards_floating_point(self):
        total = 0
        for _ in range(1000):
            minting = random.random() * 100
            total += minting
            self.vault.mint_rewards(amount=minting)
        self.assertAlmostEqual(self.vault.vaults[0, 'total'], total)

    def test_get_collateralization_percent_nonexistent(self):
        with self.assertRaisesRegex(AssertionError, 'cdp'):
            self.vault.get_collateralization_percent(cdp_number=1)

    def test_get_collateralization_percent_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.assertAlmostEqual(
            self.vault.get_collateralization_percent(cdp_number=id), 15)

    def test_change_stability_rate_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'owner'):
            self.vault.change_stability_rate(key=0,
                                             new_value=1.2,
                                             signer='wallet2')

    def test_change_stability_rate_normal(self):
        assert self.vault.stability_rate[0] == 1.1
        self.vault.change_stability_rate(key=0, new_value=1.2)
        assert self.vault.stability_rate[0] == 1.2

    def test_fast_force_close_vault_closed(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.vault.close_vault(cdp_number=id)
        with self.assertRaisesRegex(AssertionError, 'closed'):
            self.vault.fast_force_close_vault(cdp_number=id)

    def test_fast_force_close_vault_nonexistent(self):
        with self.assertRaisesRegex(AssertionError, 'cdp'):
            self.vault.fast_force_close_vault(cdp_number=id)

    def test_fast_force_close_vault_above_minimum(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        with self.assertRaisesRegex(AssertionError, 'above'):
            self.vault.fast_force_close_vault(cdp_number=id)

    def test_fast_force_close_vault_under_103_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.oracle.set_price(number=0, new_price=0.01)
        self.vault.fast_force_close_vault(cdp_number=id)

    def test_fast_force_close_vault_above_103_normal(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        # since we set dsr owner in setup
        self.dai.mint(amount=10, signer='vault_contract')
        self.dai.transfer(amount=10, to='sys', signer='vault_contract')
        self.dai.approve(to='vault_contract', amount=110)
        self.oracle.set_price(number=0, new_price=0.09)
        self.vault.fast_force_close_vault(cdp_number=id)

    def test_fast_force_close_vault_takes_money(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.oracle.set_price(number=0, new_price=0.01)
        self.vault.fast_force_close_vault(cdp_number=id)
        assert self.dai.balance_of(account='sys') < 100

    def test_fast_force_close_vault_under_103_changes_state(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        self.dai.approve(to='vault_contract', amount=100)
        self.oracle.set_price(number=0, new_price=0.01)
        issued = self.vault.vaults[self.vault.cdp[0, 'vault_type'], 'issued']
        total = self.vault.vaults[self.vault.cdp[0, 'vault_type'], 'total']
        self.vault.fast_force_close_vault(cdp_number=id)

        # original, dai minted, collateral percent, collateral reward respectively
        redemption_cost_without_fee = (100) * (1500 * 0.01 /
                                               (100 * 1.1)) / 1.03
        self.assertAlmostEqual(self.dai.balance_of(account='sys'),
                               100 - redemption_cost_without_fee * 1.1)
        self.assertAlmostEqual(self.dai.total_supply.get(),
                               100 - redemption_cost_without_fee)
        self.assertAlmostEqual(self.currency.balance_of(account='sys'),
                               2147483647)  # reward to closer
        self.assertAlmostEqual(
            issued - 100, self.vault.vaults[self.vault.cdp[0, 'vault_type'],
                                            'issued'])
        self.assertAlmostEqual(
            total - redemption_cost_without_fee,
            self.vault.vaults[self.vault.cdp[0, 'vault_type'], 'total'])
        self.assertAlmostEqual(
            self.dai.balance_of(account='vault_contract'),
            self.vault.stability_pool[self.vault.cdp[0, 'vault_type']])

    def test_fast_force_close_vault_above_103_changes_state(self):
        self.currency.approve(to='vault_contract', amount=1500)
        id = self.vault.create_vault(vault_type=0,
                                     amount_of_dai=100,
                                     amount_of_collateral=1500)
        # since we set dsr owner in setup
        self.dai.mint(amount=10, signer='vault_contract')
        self.dai.transfer(amount=10, to='sys', signer='vault_contract')
        self.dai.approve(to='vault_contract', amount=110)
        self.oracle.set_price(number=0, new_price=0.09)
        issued = self.vault.vaults[self.vault.cdp[0, 'vault_type'], 'issued']
        total = self.vault.vaults[self.vault.cdp[0, 'vault_type'], 'total']
        self.vault.cdp[0, 'owner'] = 'wallet2'
        self.vault.fast_force_close_vault(cdp_number=id)
        redemption_cost_without_fee = 100
        self.assertAlmostEqual(self.dai.balance_of(account='sys'),
                               110 - redemption_cost_without_fee * 1.1)
        self.assertAlmostEqual(self.dai.total_supply.get(),
                               110 - redemption_cost_without_fee)
        self.assertAlmostEqual(
            self.currency.balance_of(account='sys'), 2147483647 - 1500 +
            (1 / 0.09) * 100 * 1.1 * 1.03)  # reward to closer
        self.assertAlmostEqual(
            self.currency.balance_of(account='wallet2'),
            1500 - (1 / 0.09) * 100 * 1.1 * 1.03)  # reward to owner
        self.assertAlmostEqual(
            issued - 100, self.vault.vaults[self.vault.cdp[0, 'vault_type'],
                                            'issued'])
        self.assertAlmostEqual(
            total - redemption_cost_without_fee,
            self.vault.vaults[self.vault.cdp[0, 'vault_type'], 'total'])
        self.assertAlmostEqual(
            self.dai.balance_of(account='vault_contract'),
            self.vault.stability_pool[self.vault.cdp[0, 'vault_type']])
Exemple #30
0
class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.c = ContractingClient()
        self.c.flush()

        with open('con_azduz_card_methods.py') as f:
            code = f.read()
            self.c.submit(code, name='con_azduz_card_methods')

        with open('currency.s.py') as f:
            code = f.read()
            self.c.submit(code,
                          name='currency',
                          constructor_args={'vk': 'sys'})

        with open('con_azduz_master.py') as f:
            code = f.read()
            self.c.submit(code, name='con_azduz_master')

        self.game_contract = self.c.get_contract('con_azduz_master')
        self.currency_contract = self.c.get_contract('currency')

    def tearDown(self):
        self.c.flush()

    def test_00a_ownership(self):
        owner = self.game_contract.quick_read('Owner')
        self.assertEqual(owner, 'sys')

    def test_01a_transferFunds(self):
        # Approve Add funds to 'sys'
        self.currency_contract.approve(amount=10, to='con_azduz_master')
        # Add Funds to 'sys'
        self.game_contract.addFunds(amount=10)
        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=10,
                                                    to='benji')
        self.assertEqual(self.game_contract.quick_read('Balances', 'benji'),
                         10)
        self.assertEqual(self.game_contract.quick_read('Balances', 'sys'), 0)
        with self.assertRaises(AssertionError):
            self.game_contract.transferFunds(signer="sys",
                                             amount=100,
                                             to='benji')

    def test_02a_createGame(self):
        ante = 5
        number_of_seats = 4
        game = self.game_contract.createGame(number_of_seats=number_of_seats,
                                             ante=ante)
        game_id = game['game_id']
        print(game)
        # game_state should be 'idle'
        game_state_key = 'games' + ':' + game['game_id'] + ':' + 'game_state'
        self.assertEqual(self.game_contract.quick_read('S', game_state_key),
                         'idle')

        game_ante_key = 'games' + ':' + game['game_id'] + ':ante'
        self.assertEqual(self.game_contract.quick_read('S', game_ante_key),
                         ante)

        game_seats_key = 'games' + ':' + game['game_id'] + ':number_of_seats'
        self.assertEqual(self.game_contract.quick_read('S', game_seats_key),
                         number_of_seats)

    def test_02b_createGame(self):
        with self.assertRaises(AssertionError):
            join_table_res = game = self.game_contract.createGame(
                number_of_seats=10, ante=4)

        with self.assertRaises(AssertionError):
            join_table_res = game = self.game_contract.createGame(
                number_of_seats=-10, ante=4)

        with self.assertRaises(AssertionError):
            join_table_res = game = self.game_contract.createGame(
                number_of_seats=4, ante=-4)

    def test_03a_joinTable(self):
        # Fails, user balance is less then number_of_seats * ante
        game = self.game_contract.createGame(number_of_seats=4, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=10, to='con_azduz_master')
        self.game_contract.addFunds(amount=10)

        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=10,
                                                    to='benji')
        with self.assertRaises(AssertionError):
            join_table_res = self.game_contract.joinTable(signer='benji',
                                                          game_id=game_id)

        self.assertEqual(self.game_contract.quick_read('Balances', 'benji'),
                         10)
        self.assertEqual(self.game_contract.quick_read('Balances', 'sys'), 0)

    def test_03b_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=4, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=80, to='con_azduz_master')
        self.game_contract.addFunds(amount=80)

        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='benji')
        join_table_res = self.game_contract.joinTable(signer='benji',
                                                      game_id=game_id)

        table_players_key = 'games' + ':' + game['game_id'] + ':players'
        self.assertEqual(
            len(self.game_contract.quick_read('S', table_players_key)), 1)

    def test_03c_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=4, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=80, to='con_azduz_master')
        self.game_contract.addFunds(amount=80)

        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='benji')
        join_table_res = self.game_contract.joinTable(signer='benji',
                                                      game_id=game_id)

        table_players_key = 'games' + ':' + game['game_id'] + ':players'
        self.assertEqual(
            len(self.game_contract.quick_read('S', table_players_key)), 1)
        # self.assertEqual(self.game_contract.quick_read('Balances', 'sys'), 0)

    def test_03d_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=4, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=160, to='con_azduz_master')
        self.game_contract.addFunds(amount=160)

        self.game_contract.transferFunds(signer="sys", amount=160, to='benji')

        self.game_contract.joinTable(signer='benji', game_id=game_id)

        with self.assertRaises(AssertionError):
            join_table_res = self.game_contract.joinTable(signer='benji',
                                                          game_id=game_id)

    # Waiting Flow Checks

    def test_03e_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=5, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=10000, to='con_azduz_master')
        self.game_contract.addFunds(amount=10000)

        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='benji')
        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='mick')
        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='julia')
        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='fred')
        test_res = self.game_contract.transferFunds(signer="sys",
                                                    amount=80,
                                                    to='mona')

        # Players benji + mick sit down and a round begins

        self.game_contract.joinTable(signer='benji', game_id=game_id)
        self.game_contract.joinTable(signer='mick', game_id=game_id)

        table_players_key = 'games' + ':' + game['game_id'] + ':game_state'
        self.assertEqual(self.game_contract.quick_read('S', table_players_key),
                         'playing')

        waiting_key = 'games' + ':' + game['game_id'] + ':waiting'
        waiting = self.game_contract.quick_read('S', waiting_key)

        players_key = 'games' + ':' + game['game_id'] + ':players'
        players = self.game_contract.quick_read('S', players_key)

        self.assertEqual(len(waiting), 0)
        self.assertEqual(len(players), 2)

        # Julia joins and as the round has begun, joins the waitlist

        self.game_contract.joinTable(signer='julia', game_id=game_id)

        players_key = 'games' + ':' + game['game_id'] + ':players'
        players = self.game_contract.quick_read('S', players_key)

        waiting_key = 'games' + ':' + game['game_id'] + ':waiting'
        waiting = self.game_contract.quick_read('S', waiting_key)

        self.assertEqual(len(waiting), 1)
        self.assertEqual(len(players), 3)

        ## Benji + Mick both take their turns, round ends and Julia is removed from the waitlist

        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')

        players = self.game_contract.quick_read('S', players_key)
        waiting = self.game_contract.quick_read('S', waiting_key)

        self.assertEqual(len(waiting), 0)
        self.assertEqual(len(players), 3)

        # Fred and Mona sit down, and again must wait for the round to complete before he can play.

        self.game_contract.joinTable(signer='fred', game_id=game_id)
        self.game_contract.joinTable(signer='mona', game_id=game_id)

        players = self.game_contract.quick_read('S', players_key)
        waiting = self.game_contract.quick_read('S', waiting_key)

        self.assertEqual(len(waiting), 2)
        self.assertEqual(len(players), 5)

        self.game_contract.dealDecisionCard(signer='benji',
                                            game_id=game_id,
                                            amount=4)
        self.game_contract.dealDecisionCard(signer='mick',
                                            game_id=game_id,
                                            amount=4)

        players = self.game_contract.quick_read('S', players_key)
        waiting = self.game_contract.quick_read('S', waiting_key)

        self.assertEqual(len(waiting), 2)
        self.assertEqual(len(players), 5)

        self.game_contract.dealDecisionCard(signer='julia',
                                            game_id=game_id,
                                            amount=4)

        players = self.game_contract.quick_read('S', players_key)
        waiting = self.game_contract.quick_read('S', waiting_key)

        print(players)
        print(waiting)

        self.assertEqual(len(waiting), 0)
        self.assertEqual(len(players), 5)

        self.game_contract.dealDecisionCard(signer='benji',
                                            game_id=game_id,
                                            amount=4)
        self.game_contract.dealDecisionCard(signer='mick',
                                            game_id=game_id,
                                            amount=4)
        self.game_contract.dealDecisionCard(signer='julia',
                                            game_id=game_id,
                                            amount=4)
        self.game_contract.dealDecisionCard(signer='fred',
                                            game_id=game_id,
                                            amount=4)
        self.game_contract.dealDecisionCard(signer='mona',
                                            game_id=game_id,
                                            amount=4)

    # Checking Balance Deductions work correctly.

    def test_03f_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=5, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=10000, to='con_azduz_master')
        self.game_contract.addFunds(amount=10000)

        players_key = 'games' + ':' + game['game_id'] + ':players'
        players = self.game_contract.quick_read('S', players_key)
        waiting_key = 'games' + ':' + game['game_id'] + ':waiting'
        waiting = self.game_contract.quick_read('S', waiting_key)
        sitting_out_key = 'games' + ':' + game['game_id'] + ':sitting_out'
        sitting_out = self.game_contract.quick_read('S', sitting_out_key)

        buy_in = 80

        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='benji')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='mick')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='julia')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='fred')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='mona')

        # Players benji + mick sit down and a round begins

        self.game_contract.joinTable(signer='benji', game_id=game_id)
        self.game_contract.joinTable(signer='mick', game_id=game_id)

        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')

        self.game_contract.decideStartRound(game_id=game_id)
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')

        active_players = self.game_contract.getActivePlayers(
            players=players, sitting_out=sitting_out, waiting=waiting)
        total_player_balance = 0
        for p in active_players:
            value = self.game_contract.quick_read('Balances', p)
            total_player_balance += value

        in_theory_balance = len(active_players) * buy_in

        pot_size_key = 'games:' + game_id + ':pot_size'
        pot_size = self.game_contract.quick_read('S', pot_size_key)
        total_game_balance = pot_size + total_player_balance
        # print(pot_size)
        # print(type(pot_size))

        self.assertEqual(total_game_balance, in_theory_balance)

    def test_03g_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=5, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=10000, to='con_azduz_master')
        self.game_contract.addFunds(amount=10000)

        players_key = 'games' + ':' + game['game_id'] + ':players'
        waiting_key = 'games' + ':' + game['game_id'] + ':waiting'
        sitting_out_key = 'games' + ':' + game['game_id'] + ':sitting_out'
        pot_size_key = 'games' + ':' + game['game_id'] + ':pot_size'

        buy_in = 80

        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='benji')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='mick')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='julia')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='fred')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='mona')

        # Players benji + mick sit down and a round begins

        self.game_contract.joinTable(signer='benji', game_id=game_id)
        self.game_contract.joinTable(signer='mick', game_id=game_id)

        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.joinTable(signer='mona', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')

        self.game_contract.decideStartRound(game_id=game_id)
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mona')

        self.game_contract.decideStartRound(game_id=game_id)
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mona')

        bal_benji = self.game_contract.quick_read('Balances', 'benji')
        bal_mona = self.game_contract.quick_read('Balances', 'mona')
        bal_mick = self.game_contract.quick_read('Balances', 'mick')
        bal_pot = self.game_contract.quick_read('S', pot_size_key)

        print(bal_benji)
        print(bal_mona)
        print(bal_mick)
        print(bal_pot)

        players = self.game_contract.quick_read('S', players_key)
        waiting = self.game_contract.quick_read('S', waiting_key)
        sitting_out = self.game_contract.quick_read('S', sitting_out_key)

        active_players = self.game_contract.getActivePlayers(
            players=players, sitting_out=sitting_out, waiting=waiting)
        total_player_balance = 0
        for p in active_players:
            value = self.game_contract.quick_read('Balances', p)
            total_player_balance += value

        in_theory_balance = len(active_players) * buy_in

        pot_size_key = 'games:' + game_id + ':pot_size'
        pot_size = self.game_contract.quick_read('S', pot_size_key)
        total_game_balance = pot_size + total_player_balance

        self.assertEqual(total_game_balance, in_theory_balance)

    def test_03h_joinTable(self):
        game = self.game_contract.createGame(number_of_seats=5, ante=5)
        game_id = game['game_id']

        self.currency_contract.approve(amount=10000, to='con_azduz_master')
        self.game_contract.addFunds(amount=10000)

        players_key = 'games' + ':' + game['game_id'] + ':players'
        waiting_key = 'games' + ':' + game['game_id'] + ':waiting'
        sitting_out_key = 'games' + ':' + game['game_id'] + ':sitting_out'
        pot_size_key = 'games' + ':' + game['game_id'] + ':pot_size'

        buy_in = 80

        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='benji')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='mick')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='julia')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='fred')
        self.game_contract.transferFunds(signer="sys",
                                         amount=buy_in,
                                         to='mona')

        # Players benji + mick sit down and a round begins

        self.game_contract.joinTable(signer='benji', game_id=game_id)
        self.game_contract.joinTable(signer='mick', game_id=game_id)

        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.joinTable(signer='mona', game_id=game_id)
        self.game_contract.joinTable(signer='fred', game_id=game_id)
        self.game_contract.joinTable(signer='julia', game_id=game_id)

        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')

        self.game_contract.decideStartRound(game_id=game_id)
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='benji')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mick')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='mona')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='fred')
        self.game_contract.dealHand(signer='benji', game_id=game_id)
        self.game_contract.dealDecisionCard(game_id=game_id,
                                            amount=4,
                                            signer='julia')

        bal_benji = self.game_contract.quick_read('Balances', 'benji')
        bal_mona = self.game_contract.quick_read('Balances', 'mona')
        bal_mick = self.game_contract.quick_read('Balances', 'mick')
        bal_pot = self.game_contract.quick_read('S', pot_size_key)

        print(bal_benji)
        print(bal_mona)
        print(bal_mick)
        print(bal_pot)

        players = self.game_contract.quick_read('S', players_key)
        waiting = self.game_contract.quick_read('S', waiting_key)
        sitting_out = self.game_contract.quick_read('S', sitting_out_key)

        active_players = self.game_contract.getActivePlayers(
            players=players, sitting_out=sitting_out, waiting=waiting)
        total_player_balance = 0
        for p in active_players:
            value = self.game_contract.quick_read('Balances', p)
            total_player_balance += value

        in_theory_balance = len(active_players) * buy_in

        pot_size_key = 'games:' + game_id + ':pot_size'
        pot_size = self.game_contract.quick_read('S', pot_size_key)
        total_game_balance = pot_size + total_player_balance

        self.assertEqual(total_game_balance, in_theory_balance)

    def test_04a_calcDecisionCardBalance(self):
        pot_size = 4
        result = 'win'
        amount = 4
        player_balance = 4

        result = self.game_contract.calcDecisionCardBalance(
            result=result,
            player_balance=player_balance,
            pot_size=pot_size,
            amount=amount)

        self.assertEqual(result['pot_size'], 0)
        self.assertEqual(result['player_balance'], 8)

    def test_04b_calcDecisionCardBalance(self):
        pot_size = 4
        result = 'lose'
        amount = 4
        player_balance = 4

        result = self.game_contract.calcDecisionCardBalance(
            result=result,
            player_balance=player_balance,
            pot_size=pot_size,
            amount=amount)

        self.assertEqual(result['pot_size'], 8)
        self.assertEqual(result['player_balance'], 0)

    def test_04c_calcDecisionCardBalance(self):
        pot_size = 4
        result = 'rail'
        amount = 4
        player_balance = 8

        result = self.game_contract.calcDecisionCardBalance(
            result=result,
            player_balance=player_balance,
            pot_size=pot_size,
            amount=amount)

        self.assertEqual(result['pot_size'], 12)
        self.assertEqual(result['player_balance'], 0)

    def test_05a_incrementPotByAntes(self):
        pot_size = 5
        ante = 5
        active_players = ['benji', 'julia', 'mick', 'fred', 'mona', 'borris']
        new_pot = self.game_contract.incrementPotByAntes(
            pot_size=pot_size, ante=ante, active_players=active_players)
        self.assertEqual(new_pot, 35)

    def test_05a_incrementPotByAntes(self):
        pot_size = 160
        ante = 10
        active_players = ['benji', 'julia', 'mick', 'fred', 'mona', 'borris']
        new_pot = self.game_contract.incrementPotByAntes(
            pot_size=pot_size, ante=ante, active_players=active_players)
        self.assertEqual(new_pot, 220)