예제 #1
0
    def test_unwrap_amount_for_account_and_distribute_fees(self):
        amount = 100
        fees = 1

        res = self.bender_contract.unwrap_erc20(
            unwrap_fungible_parameters(amount=amount, fees=fees)).interpret(
            storage=valid_storage(fees_ratio=100),
            self_address=self_address,
            source=user
        )

        self.assertEqual(2, len(res.operations))
        burn_operation = res.operations[0]
        self.assertEqual('0', burn_operation['amount'])
        self.assertEqual(f'{token_contract}', burn_operation['destination'])
        self.assertEqual('tokens', burn_operation['parameters']['entrypoint'])
        self.assertEqual(michelson_to_micheline(f'(Left {{ Pair "{user}" 1 {amount + fees} }})'),
                         burn_operation['parameters']['value'])
        mint_operation = res.operations[1]
        self.assertEqual('0', mint_operation['amount'])
        self.assertEqual(f'{token_contract}', mint_operation['destination'])
        self.assertEqual('tokens', mint_operation['parameters']['entrypoint'])
        self.assertEqual(michelson_to_micheline(f'(Right {{ Pair "{self_address}" 1 {fees} }})'),
                         mint_operation['parameters']['value'])
        self.assertEqual(fees, self._tokens_of(res.storage, self_address, (token_contract, 1)))
예제 #2
0
    def compile(self, view_name, return_type=None, description="", pure=True):
        (parameter, main_return_type) = self._compile_parameter(view_name)
        result = {
            "name":
            view_name,
            "description":
            description,
            "pure":
            pure,
            "implementations": [{
                "michelsonStorageView": {
                    "returnType":
                    michelson_to_micheline(return_type)
                    if return_type is not None else main_return_type,
                    "code":
                    self._compile_expression(view_name)
                }
            }]
        }

        if parameter != json.loads('{"prim": "unit"}'):
            result["implementations"][0]["michelsonStorageView"][
                "parameter"] = parameter

        return result
예제 #3
0
    def test_should_transfer_all_tokens_from_contract(self):
        storage = valid_storage()
        first_token_address = (token_contract, 0)
        second_token_address = (token_contract, 1)
        with_token_balance(signer_1_key, first_token_address, 100, storage)
        with_token_balance(signer_1_key, second_token_address, 200, storage)

        res = self.minter_contract.withdraw_all_tokens(
            token_contract, [0, 1]).interpret(storage=storage,
                                              sender=signer_1_key,
                                              self_address=self_address)

        self.assertEqual(1, len(res.operations))
        transfer = res.operations[0]
        self.assertEqual(token_contract, transfer['destination'])
        self.assertEqual("0", transfer['amount'])
        self.assertEqual('transfer', transfer['parameters']['entrypoint'])
        self.assertEqual(
            michelson_to_micheline(
                f'{{ Pair "{self_address}" {{ Pair "{signer_1_key}" 1 200 ; Pair "{signer_1_key}" 0 100 }} }}'
            ), transfer['parameters']['value'])

        self.assertEqual(
            None,
            self._tokens_of(res.storage, signer_1_key, first_token_address))
        self.assertEqual(
            None,
            self._tokens_of(res.storage, signer_1_key, second_token_address))
예제 #4
0
def packed_payload(amount, token_id, block_hash, log_index):
    ty = MichelsonType.match(payload_type)

    call = minter_call(amount, token_id, block_hash, log_index)
    payload_value = michelson_to_micheline(f"(Pair "
                                           f"   (Pair \"{chain_id}\" \"{self_address}\")"
                                           f"   (Pair {call} \"{minter_contract}%minter\")"
                                           f")")

    return ty.from_micheline_value(payload_value).pack().hex()
예제 #5
0
    def test_generates_only_one_mint_if_fees_to_low(self):
        amount = 1

        res = self.minter_contract.mint_erc20(
            mint_erc20_parameters(amount=amount)).interpret(
                storage=valid_storage(fees_ratio=1), sender=quorum_contract)

        self.assertEqual(1, len(res.operations))
        user_mint = res.operations[0]
        self.assertEqual(
            michelson_to_micheline(f'( Right {{ Pair "{user}" 1 {amount}}})'),
            user_mint['parameters']['value'])
예제 #6
0
    def test_calls_erc721_mint(self):
        res = self.bender_contract.mint_erc721(mint_erc721_parameters(token_id=5)) \
            .interpret(storage=valid_storage(nft_fees=20), sender=super_admin, amount=20, self_address=self_address)

        self.assertEqual(1, len(res.operations))
        user_mint = res.operations[0]
        self.assertEqual('0', user_mint['amount'])
        self.assertEqual(f'{nft_contract}', user_mint['destination'])
        self.assertEqual('tokens', user_mint['parameters']['entrypoint'])
        self.assertEqual(michelson_to_micheline(
            f'( Right {{ Pair "{user}" 5 1 }})'),
            user_mint['parameters']['value'])
        self.assertEqual(20, self._xtz_of(self_address, res.storage))
예제 #7
0
    def test_should_send_current_quorum_for_xtz_distribution(self):
        res = self.contract.distribute_xtz_with_quorum(minter_contract) \
            .interpret(
            storage=storage(),
            sender=first_signer_key.public_key_hash(), self_address=self_address)

        self.assertEqual(1, len(res.operations))
        op = res.operations[0]
        self.assertEqual(minter_contract, op["destination"])
        self.assertEqual('oracle', op["parameters"]["entrypoint"])
        self.assertEqual(michelson_to_micheline(
            f'(Right {{ "{first_signer_key.public_key_hash()}" }})'),
            op['parameters']['value'])
예제 #8
0
    def test_should_send_current_quorum_for_tokens_distribution(self):
        tokens = [('KT1RXpLtz22YgX24QQhxKVyKvtKZFaAVtTB9', 0)]
        res = self.contract.distribute_tokens_with_quorum(minter_contract=minter_contract, tokens=tokens) \
            .interpret(
            storage=storage(),
            sender=first_signer_key.public_key_hash(), self_address=self_address)

        self.assertEqual(1, len(res.operations))
        op = res.operations[0]
        self.assertEqual(minter_contract, op["destination"])
        self.assertEqual('oracle', op["parameters"]["entrypoint"])
        self.assertEqual(michelson_to_micheline(
            f'(Left (Pair {{ "{first_signer_key.public_key_hash()}" }} '
            f'{{  Pair "KT1RXpLtz22YgX24QQhxKVyKvtKZFaAVtTB9" 0 }} ))'),
            op['parameters']['value'])
예제 #9
0
    def test_takes_no_fees_if_amount_to_small(self):
        amount = 10
        fees = 0

        res = self.minter_contract.unwrap_erc20(
            unwrap_fungible_parameters(amount=amount, fees=fees)).interpret(
                storage=valid_storage(fees_ratio=200), source=user)

        self.assertEqual(1, len(res.operations))
        burn_operation = res.operations[0]
        self.assertEqual('0', burn_operation['amount'])
        self.assertEqual(f'{token_contract}', burn_operation['destination'])
        self.assertEqual('tokens', burn_operation['parameters']['entrypoint'])
        self.assertEqual(
            michelson_to_micheline(f'(Left {{ Pair "{user}" 1 {amount} }})'),
            burn_operation['parameters']['value'])
예제 #10
0
    def test_should_set_signer_payment_address(self):
        payment_address = Key.generate(export=False).public_key_hash()
        signature = first_signer_key.sign(self._pack_set_payment_address(0, payment_address))

        res = self.contract.set_signer_payment_address(minter_contract=minter_contract, signer_id=first_signer_id,
                                                       signature=signature).interpret(
            storage=storage(),
            sender=payment_address, self_address=self_address, chain_id=chain_id)

        self.assertEqual(1, len(res.operations))
        op = res.operations[0]
        self.assertEqual(minter_contract, op["destination"])
        self.assertEqual('signer_ops', op["parameters"]["entrypoint"])
        self.assertEqual(michelson_to_micheline(
            f'(Pair "{first_signer_key.public_key_hash()}" "{payment_address}")'),
            op['parameters']['value'])
        self.assertEqual(1, res.storage["counters"][first_signer_id])
예제 #11
0
    def test_accepts_valid_signature(self):
        amount = 10000000
        token_id = b"contract_on_eth"
        block_hash = b"txId"
        log_index = 5
        packed = packed_payload(amount, token_id, block_hash, log_index)
        params = forge_params(amount, token_id, block_hash, log_index,
                              [[first_signer_id, first_signer_key.sign(packed)]])

        res = self.contract.minter(params).interpret(storage=storage(),
                                                     sender=first_signer_key.public_key_hash(),
                                                     chain_id=chain_id, self_address=self_address)

        self.assertEqual(1, len(res.operations))
        user_mint = res.operations[0]
        self.assertEqual(minter_contract, user_mint["destination"])
        self.assertEqual(michelson_to_micheline(minter_call(amount, token_id, block_hash, log_index)),
                         user_mint['parameters']['value'])
예제 #12
0
    def test_should_transfer_token(self):
        storage = valid_storage()
        token_address = (token_contract, 0)
        with_token_balance(signer_1_key, token_address, 100, storage)

        res = self.bender_contract.withdraw_token(token_contract, 0, 40).interpret(storage=storage,
                                                                                   sender=signer_1_key,
                                                                                   self_address=self_address)

        self.assertEqual(1, len(res.operations))
        self.assertEqual(token_contract, res.operations[0]['destination'])
        self.assertEqual("0", res.operations[0]['amount'])
        self.assertEqual('transfer', res.operations[0]['parameters']['entrypoint'])
        self.assertEqual(michelson_to_micheline(f'{{ Pair "{self_address}" {{ Pair "{signer_1_key}" 0 40 }} }}'),
                         res.operations[0]['parameters']['value'])

        t = self._tokens_of(res.storage, signer_1_key, token_address)
        self.assertEqual(60, t)
예제 #13
0
    def test_calls_fa2_mint_for_user_and_collect_fees(self):
        amount = 1 * 10 ** 16

        res = self.bender_contract.mint_erc20(
            mint_erc20_parameters(amount=amount)).interpret(
            storage=valid_storage(fees_ratio=1),
            self_address=self_address,
            sender=super_admin)

        self.assertEqual(1, len(res.operations))
        user_mint = res.operations[0]
        self.assertEqual('0', user_mint['amount'])
        self.assertEqual(f'{token_contract}', user_mint['destination'])
        self.assertEqual('tokens', user_mint['parameters']['entrypoint'])
        collected_fees = int(0.0001 * 10 ** 16)
        self.assertEqual(michelson_to_micheline(
            f'( Right {{ Pair "{user}"  1 {int(0.9999 * 10 ** 16)}  ; Pair "{self_address}" 1 {collected_fees} }})'),
            user_mint['parameters']['value'])
        self.assertEqual(collected_fees, self._tokens_of(res.storage, self_address, (token_contract, 1)))
예제 #14
0
    def test_unwrap_nft(self):
        token_id = 1337
        fees = 10

        res = self.bender_contract.unwrap_erc721(
            unwrap_nft_parameters(token_id=token_id)).interpret(
            storage=valid_storage(nft_fees=fees),
            sender=user,
            amount=10,
            self_address=self_address
        )

        self.assertEqual(1, len(res.operations))
        burn_operation = res.operations[0]
        self.assertEqual('0', burn_operation['amount'])
        self.assertEqual(f'{nft_contract}', burn_operation['destination'])
        self.assertEqual('tokens', burn_operation['parameters']['entrypoint'])
        self.assertEqual(michelson_to_micheline(f'(Left {{ Pair "{user}" 1337 1}})'),
                         burn_operation['parameters']['value'])
        self.assertEqual(10, self._xtz_of(self_address, res.storage))
예제 #15
0
    def test_accepts_minting_even_with_bad_signature_if_threshold_is_reached(self):
        amount = 10000000
        token_id = b"contract_on_eth"
        block_hash = b"txId"
        log_index = 3

        packed = packed_payload(amount, token_id, block_hash, log_index)
        bad = packed_payload(amount, token_id, block_hash, log_index + 1)
        params = forge_params(amount, token_id, block_hash, log_index, [
            [first_signer_id, first_signer_key.sign(packed)],
            [second_signer_id, second_signer_key.sign(bad)]
        ])

        res = self.contract.minter(params).interpret(storage=storage_with_two_keys(threshold=1),
                                                     sender=first_signer_key.public_key_hash(),
                                                     chain_id=chain_id, self_address=self_address)

        self.assertEqual(1, len(res.operations))
        user_mint = res.operations[0]
        self.assertEqual(minter_contract, user_mint["destination"])
        self.assertEqual(michelson_to_micheline(minter_call(amount, token_id, block_hash, log_index)),
                         user_mint['parameters']['value'])
예제 #16
0
    def _pack_set_payment_address(counter, payment_address):
        ty = MichelsonType.match(
            michelson_to_micheline(f"(pair (pair chain_id address) (pair nat (pair address address)))"))

        return ty.from_python_object([chain_id, self_address,
                                      counter, minter_contract, payment_address]).pack().hex()
예제 #17
0
minter_ep = """(or
                 (or (pair %add_fungible_token (bytes %eth_contract) (pair %token_address address nat))
                     (pair %add_nft (bytes %eth_contract) (address %token_contract)))
                 (or (pair %mint_fungible_token
                        (bytes %erc_20)
                        (pair (pair %event_id (bytes %block_hash) (nat %log_index))
                              (pair (address %owner) (nat %amount))))
                     (pair %mint_nft
                        (bytes %erc_721)
                        (pair (pair %event_id (bytes %block_hash) (nat %log_index))
                              (pair (address %owner) (nat %token_id))))))"""
first_signer_id = "k51qzi5uqu5dilfdi6xt8tfbw4zmghwewcvvktm7z9fk4ktsx4z7wn0mz2glje"
second_signer_id = "k51qzi5uqu5dhuc1pto6x98woksrqgwhq6d1lff2hfymxmlk4qd7vqgtf980yl"
first_signer_key = Key.generate(curve=b'sp', export=False)
second_signer_key = Key.generate(curve=b'sp', export=False)
payload_type = michelson_to_micheline(f"(pair (pair chain_id address) (pair {minter_ep} address))")
self_address = "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi"


class QuorumContractTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        root_dir = Path(__file__).parent.parent / "ligo"
        cls.contract = LigoContract(root_dir / "quorum" / "multisig.mligo", "main").get_contract()


class SignerTest(QuorumContractTest):
    def test_accepts_valid_signature(self):
        amount = 10000000
        token_id = b"contract_on_eth"