From 449b920cb83879023df2e4fcffef3fc38ffb7298 Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Fri, 10 May 2024 14:32:44 -0400 Subject: [PATCH 1/2] Add from parameter in the style of other entrypoints --- smartpy_fa2_fungible/part_4_complete.py | 29 +++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/smartpy_fa2_fungible/part_4_complete.py b/smartpy_fa2_fungible/part_4_complete.py index 4833b42..ed76812 100644 --- a/smartpy_fa2_fungible/part_4_complete.py +++ b/smartpy_fa2_fungible/part_4_complete.py @@ -9,6 +9,7 @@ def my_module(): conversion_type: type = sp.record( + from_ = sp.address, # Account to convert tokens from source_token_id = sp.nat, # The ID of the source token target_token_id = sp.nat, # The ID of the target token amount = sp.nat, # The number of source tokens to convert @@ -46,7 +47,12 @@ def convert(self, batch): for conversion in batch: - record(source_token_id, target_token_id, amount).match = conversion + record( + from_, + source_token_id, + target_token_id, + amount + ).match = conversion # Verify that transfers are allowed assert self.private.policy.supports_transfer, "FA2_TX_DENIED" @@ -54,8 +60,15 @@ def convert(self, batch): assert self.is_defined_(source_token_id), "FA2_TOKEN_UNDEFINED" assert self.is_defined_(target_token_id), "FA2_TOKEN_UNDEFINED" + # Verify that the sender is either the owner or the operator of the source tokens + assert (sp.sender == from_) or self.data.operators.contains( + sp.record( + owner=from_, operator=sp.sender, token_id=source_token_id + ) + ), "FA2_NOT_OPERATOR" + # Get a pair to represent the key for the ledger for the source tokens - from_source = (sp.sender, source_token_id) + from_source = (from_, source_token_id) # Burn the source tokens self.data.ledger[from_source] = sp.as_nat( @@ -72,7 +85,7 @@ def convert(self, batch): self.data.supply[source_token_id] = 0 # Get a pair to represent the key for the ledger for the target tokens - from_target = (sp.sender, target_token_id) + from_target = (from_, target_token_id) # Mint the target tokens target_amount = self.data.ledger.get(from_target, default=0) @@ -299,7 +312,7 @@ def test(): # Verify that you can convert your own tokens conversions = [ - sp.record(source_token_id = 0, target_token_id = 1, amount = 2), + sp.record(from_ = alice.address, source_token_id = 0, target_token_id = 1, amount = 2), ] contract.convert( conversions, @@ -313,3 +326,11 @@ def test(): ) scenario.verify(_total_supply(contract, sp.record(token_id=0)) == 12) scenario.verify(_total_supply(contract, sp.record(token_id=1)) == 16) + + # Verify that you can't convert someone else's tokens + contract.convert( + conversions, + _sender=bob, + _valid=False, + _exception="FA2_NOT_OPERATOR" + ) From 8c8490828911f279cdd28ac9f1e228e928152776 Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Fri, 10 May 2024 14:35:42 -0400 Subject: [PATCH 2/2] Add operator tests --- smartpy_fa2_fungible/part_4_complete.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/smartpy_fa2_fungible/part_4_complete.py b/smartpy_fa2_fungible/part_4_complete.py index ed76812..16d38a0 100644 --- a/smartpy_fa2_fungible/part_4_complete.py +++ b/smartpy_fa2_fungible/part_4_complete.py @@ -334,3 +334,25 @@ def test(): _valid=False, _exception="FA2_NOT_OPERATOR" ) + + # Make Bob an operator of Alice's token 0 + operator_update = sp.record(owner=alice.address, operator=bob.address, token_id=0) + contract.update_operators( + [ + sp.variant.add_operator(operator_update) + ], + _sender=alice + ) + # Have Bob convert Alice's tokens + contract.convert( + conversions, + _sender=bob + ) + scenario.verify( + _get_balance(contract, sp.record(owner=alice.address, token_id=0)) == 6 + ) + scenario.verify( + _get_balance(contract, sp.record(owner=alice.address, token_id=1)) == 7 + ) + scenario.verify(_total_supply(contract, sp.record(token_id=0)) == 10) + scenario.verify(_total_supply(contract, sp.record(token_id=1)) == 18)