def make(owner, operator, tokens = None): r = sp.record(owner = owner, operator = operator, tokens = sp.variant("All_tokens", sp.unit) if tokens == None else sp.variant("Some_tokens", tokens)) Operator_param.set_type_and_layout(r) return r
def request_fortune(self, params): self.data.client_requests[self.data.next_request_id] = sp.sender self.request_helper(params.payment, self.data.fortune_job_id, sp.map(l = {"sender": sp.variant("bytes", sp.pack(sp.sender))}), self.data.oracle, self.data.waiting_fortune_id, sp.self_entry_point("receive_fortune"), params.timeout)
def uv(s): return sp.variant(s, sp.unit)
def test(): scenario = sp.test_scenario() scenario.h1("Auction House") scenario.table_of_contents() admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") dan = sp.test_account("Dan") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob, dan]) auction_house = AuctionHouse() scenario += auction_house scenario.h2("TZColorsFA2") fa2 = TZColorsFA2(auction_house.address)#sp.address("KT1CpeSQKdkhWi4pinYcseCFKmDhs5M74BkU")) scenario += fa2 scenario.h2("Initial Auction") scenario.p("Kick-off initial Auctions") scenario += fa2.initial_auction(auction_id_start=sp.nat(0),token_ids=[sp.nat(0),sp.nat(1),sp.nat(2)]).run(sender=admin) scenario.p("Try to re-auction existing stuff") scenario += fa2.initial_auction(auction_id_start=sp.nat(0),token_ids=[sp.nat(0),sp.nat(1),sp.nat(2)]).run(sender=admin, valid=False) scenario.p("Bob bids") scenario += auction_house.bid(0).run(sender=bob,amount=sp.mutez(2000000), now=sp.timestamp(0).add_minutes(1)) scenario.p("Dan bids") scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(3000000), now=sp.timestamp(0).add_minutes(2)) scenario.p("Bob rebids") scenario += auction_house.bid(0).run(sender=bob,amount=sp.mutez(4000000), now=sp.timestamp(0).add_minutes(3)) scenario.p("Bob withdraws") scenario += auction_house.withdraw(0).run(sender=bob,amount=sp.mutez(2000000), now=sp.timestamp(0).add_minutes(5).add_days(5)) scenario.p("Bob updates operators") scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=sp.nat(0)))]).run(sender=bob) scenario.h2("User Auction") scenario.p("Bob creates auction") auction_id = sp.nat(0) # we can reuse 0 scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(0), token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=bob, now=sp.timestamp(0)) scenario.p("Bob tries to withdraw") scenario += auction_house.withdraw(0).run(sender=bob, amount=sp.mutez(0), now=sp.timestamp(0), valid=False) scenario.p("Alice bids") scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(200000), now=sp.timestamp(0)) scenario.p("Dan bids") scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(300000), now=sp.timestamp(1)) scenario.p("Alice rebids") scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(400000), now=sp.timestamp(2)) scenario.p("Bob tries to withdraw") scenario += auction_house.withdraw(0).run(sender=bob, amount=sp.mutez(0), now=sp.timestamp(60*60), valid=False) scenario.p("Dan bids") scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(500000), now=sp.timestamp(60*60-5)) scenario.p("Alice rebids") scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(600000), now=sp.timestamp(60*60+5*60-6)) scenario.p("Alice withdraws") scenario += auction_house.withdraw(0).run(sender=alice, amount=sp.mutez(0), now=sp.timestamp(60*60+5*60-6+5*60+1)) scenario.h2("Self-Withdraw") scenario.p("Alice creates auction") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=alice.address,operator=auction_house.address,token_id=sp.nat(0)))]).run(sender=alice) scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(0), token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=alice, now=sp.timestamp(0)) scenario.p("Bob funds in parallel another auction") scenario += fa2.initial_auction(auction_id_start=sp.nat(10),token_ids=[sp.nat(4),sp.nat(5),sp.nat(6)]).run(sender=admin) scenario.p("Bob bids") scenario += auction_house.bid(10).run(sender=bob, amount=sp.mutez(1000000), now=sp.timestamp(0)) scenario.p("Alice withdraws (something that had minimal bid, but nobody who bidded)") scenario += auction_house.withdraw(0).run(sender=alice, amount=sp.mutez(0), now=sp.timestamp(3+60*60)) scenario.p("Bob withdraws") scenario += auction_house.withdraw(10).run(sender=bob, now=sp.timestamp(1+5*24*60*60)) scenario.h2("Self-Bid") scenario.p("Bob creates auction") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=sp.nat(4)))]).run(sender=bob) scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(4), token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=bob, now=sp.timestamp(0)) scenario += auction_house.bid(0).run(sender=bob, amount=sp.mutez(200000), valid=False, now=sp.timestamp(2)) scenario += auction_house.withdraw(0).run(sender=bob, now=sp.timestamp(1+5*24*60*60)) scenario.h2("Existing Auctions") scenario.p("Bob creates auction with same id") scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=sp.nat(4)))]).run(sender=bob) scenario += auction_house.create_auction(sp.record(auction_id=1, token_address=fa2.address, token_id=sp.nat(4), token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=bob, now=sp.timestamp(0), valid=False) scenario.h2("Transfers") scenario.p("Bob cannot transfer alice's token") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=bob, valid=False) scenario.p("Alice can transfer own token") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=alice) scenario.p("Bob cannot transfer more token") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=bob.address, token_id=0, amount=2)])]).run(sender=bob, valid=False) scenario.p("Bob cannot transfer from non balance address") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=dan.address, token_id=0, amount=1)])]).run(sender=bob, valid=False) scenario.p("Bob can transfer as owner") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=dan.address, token_id=0, amount=1)])]).run(sender=bob) scenario.p("Try to re-auction existing stuff") scenario += fa2.initial_auction(auction_id_start=sp.nat(0),token_ids=[sp.nat(0),sp.nat(1),sp.nat(2)]).run(sender=admin, valid=False) scenario.p("Try large token id") scenario += fa2.initial_auction(auction_id_start=sp.nat(123),token_ids=[sp.nat(1689)]).run(sender=admin) scenario.p("Try too large token id") scenario += fa2.initial_auction(auction_id_start=sp.nat(124),token_ids=[sp.nat(1690)]).run(sender=admin, valid=False)
def test(): scenario = sp.test_scenario() scenario.h1("Simple FA2 Contract") # sp.test_account generates ED25519 key-pairs deterministically: admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob]) c1 = FA2(admin.address) scenario += c1 scenario.h2("Initial Minting") scenario.p("The administrator mints 100 token-0's to Alice.") scenario += c1.mint(address = alice.address, amount = 100, symbol = 'TK0', token_id = 0).run(sender = admin) scenario.h2("Transfers Alice -> Bob") scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 10, i = 0) ]).run(sender = alice) scenario.verify( c1.data.ledger[Ledger_key.make(alice.address, 0)].balance == 90) scenario.verify( c1.data.ledger[Ledger_key.make(bob.address, 0)].balance == 10) scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 10, i = 0), Transfer.make(alice.address, bob.address, a = 11, i = 0) ]).run(sender = alice) scenario.verify( c1.data.ledger[Ledger_key.make(alice.address, 0)].balance == 90 - 10 - 11) scenario.verify( c1.data.ledger[Ledger_key.make(bob.address, 0)].balance == 10 + 10 + 11) scenario.h2("More Token Types") scenario += c1.mint(address = bob.address, amount = 100, symbol = 'TK1', token_id = 1).run(sender = admin) scenario += c1.mint(address = bob.address, amount = 200, symbol = 'TK2', token_id = 2).run(sender = admin) scenario.h3("Multi-token Transfer Bob -> Alice") scenario += c1.transfer( [ Transfer.make(bob.address, alice.address, a = 10, i = 0), Transfer.make(bob.address, alice.address, a = 10, i = 1), Transfer.make(bob.address, alice.address, a = 10, i = 2) ]).run(sender = bob) scenario.h2("Other Basic Permission Tests") scenario.h3("Bob cannot transfer Alice's tokens.") scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 10, i = 0), Transfer.make(alice.address, bob.address, a = 11, i = 0) ]).run(sender = bob, valid = False) scenario.h3("Admin can transfer anything.") scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 10, i = 0), Transfer.make(alice.address, bob.address, a = 10, i = 1), Transfer.make(bob.address, alice.address, a = 11, i = 0) ]).run(sender = admin) scenario.h3("Even Admin cannot transfer too much.") scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 1000, i = 0) ]).run(sender = admin, valid = False) scenario.h3("Consumer Contract for Callback Calls.") consumer = View_consumer() scenario += consumer scenario.p("Consumer virtual address: " + sp.contract_address(consumer).export()) scenario.h2("Balance-of.") scenario += c1.balance_of(arguments_for_balance_of(consumer, [ sp.record(owner = alice.address, token_id = 0), sp.record(owner = alice.address, token_id = 1), sp.record(owner = alice.address, token_id = 2) ])) scenario.verify(consumer.data.last_sum == 90) scenario.h2("Total Supply.") scenario += c1.total_supply( sp.record( callback = sp.contract( Total_supply.response_type(), sp.contract_address(consumer), entry_point = "receive_total_supplies").open_some(), token_ids = [0, 1])) scenario.verify(consumer.data.last_sum == 200) scenario.h2("Token Metadata.") scenario += c1.token_metadata( sp.record( callback = sp.contract( sp.TList(Token_meta_data.get_type()), sp.contract_address(consumer), entry_point = "receive_metadata").open_some(), token_ids = [0, 1])) scenario.verify(consumer.data.last_acc == "TK0TK1") scenario.h2("Operators") if not support_operator: scenario.h3("This version was compiled with no operator support") scenario.p("Calls should fail even for the administrator:") scenario += c1.update_operators([]).run(sender = admin, valid = False) scenario += c1.permissions_descriptor( sp.contract( Permissions_descriptor.get_type(), sp.contract_address(consumer), entry_point = "receive_permissions_descriptor").open_some()) scenario.verify(consumer.data.operator_support == False) else: scenario.p("This version was compiled with operator support") scenario += c1.update_operators([]).run(sender = admin) scenario.h3("Operator Accounts") op0 = sp.test_account("Operator0") op1 = sp.test_account("Operator1") op2 = sp.test_account("Operator2") scenario.show([op0, op1, op2]) scenario.p("Admin can change Alice's operator.") scenario += c1.update_operators([ sp.variant("Add_operator", Operator_param.make( owner = alice.address, operator = op1.address)) ]).run(sender = admin) scenario.p("Operator1 can transfer Alice's tokens") scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 2, i = 0), Transfer.make(alice.address, op1.address, a = 2, i = 2) ]).run(sender = op1) scenario.p("Operator1 cannot transfer Bob's tokens") scenario += c1.transfer( [ Transfer.make(bob.address, op1.address, a = 2, i = 1) ]).run(sender = op1, valid = False) scenario.p("Operator2 cannot transfer Alice's tokens") scenario += c1.transfer( [ Transfer.make(alice.address, bob.address, a = 2, i = 1) ]).run(sender = op2, valid = False) scenario.p("Alice can remove their operator") scenario += c1.update_operators([ sp.variant("Remove_operator", Operator_param.make( owner = alice.address, operator = op1.address)) ]).run(sender = alice) scenario.p("Operator1 cannot transfer Alice's tokens any more") scenario += c1.transfer( [ Transfer.make(alice.address, op1.address, a = 2, i = 1) ]).run(sender = op1, valid = False) scenario.p("Bob can add Operator0 only for token 0 and 1.") scenario += c1.update_operators([ sp.variant("Add_operator", Operator_param.make( owner = bob.address, operator = op0.address, tokens = sp.set([0,1]) )) ]).run(sender = bob) scenario.p("Operator0 can transfer Bob's tokens '0' and '1'") scenario += c1.transfer( [ Transfer.make(bob.address, alice.address, a = 1, i = 0), Transfer.make(bob.address, alice.address, a = 1, i = 1) ]).run(sender = op0) scenario.p("Operator0 cannot transfer Bob's tokens '2'") scenario += c1.transfer( [ Transfer.make(bob.address, alice.address, a = 1, i = 2) ]).run(sender = op0, valid = False) scenario.p("Bob cannot add Operator0 for Alice's tokens.") scenario += c1.update_operators([ sp.variant("Add_operator", Operator_param.make( owner = alice.address, operator = op0.address, tokens = sp.set([0,1]) )) ]).run(sender = bob, valid = False) scenario.h3("Testing is_operator") scenario.p("Operator0 is still active for Bob's 0 and 1, \ Alice has no operator") def test_is_operator(scenario, owner, operator, tokens, valid, comment): scenario.p("test_is_operator: " + comment ) is_operator = Operator_param.make( owner = owner.address, operator = operator.address, tokens = tokens) scenario += c1.is_operator( sp.record( callback = sp.contract( Operator_param.is_operator_response_type(), sp.contract_address(consumer), entry_point = "receive_is_operator").open_some(), operator = is_operator )) scenario.verify(consumer.data.last_operator == valid) test_is_operator(scenario, bob, op0, sp.set([0, 1]), True, "bob, op0, [0,1]") test_is_operator(scenario, bob, op0, sp.set([0]), True, "bob, op0, [0]") test_is_operator(scenario, bob, op0, sp.set([0, 2]), False, "bob, op0, [0,2]") test_is_operator(scenario, bob, op0, None, False, "bob, op0, all") test_is_operator(scenario, alice, op0, None, False, "alice, op0, all") scenario.h3("Testing permissions_descriptor") scenario.verify(consumer.data.operator_support == False) scenario += c1.permissions_descriptor( sp.contract( Permissions_descriptor.get_type(), sp.contract_address(consumer), entry_point = "receive_permissions_descriptor").open_some()) scenario.verify(consumer.data.operator_support == True)
def value_int(s): return sp.variant("int", s)
def value_bytes(s): return sp.variant("bytes", s)
def value_string(s): return sp.variant("string", s)
def test(): scenario = sp.test_scenario() scenario.h1("FA2 Contract Name: " + config.name) scenario.table_of_contents() # sp.test_account generates ED25519 key-pairs deterministically: admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob]) c1 = FA2(config = config, metadata = sp.utils.metadata_of_url("https://example.com"), admin = admin.address) scenario += c1 if config.non_fungible: # TODO return scenario.h2("Initial Minting") scenario.p("The administrator mints 100 token-0's to Alice.") tok0_md = FA2.make_metadata( name = "The Token Zero", decimals = 2, symbol= "TK0" ) c1.mint(address = alice.address, amount = 100, metadata = tok0_md, token_id = 0).run(sender = admin) scenario.h2("Transfers Alice -> Bob") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0) ]) ]).run(sender = alice) scenario.verify( c1.data.ledger[c1.ledger_key.make(alice.address, 0)].balance == 90) scenario.verify( c1.data.ledger[c1.ledger_key.make(bob.address, 0)].balance == 10) c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0), sp.record(to_ = bob.address, amount = 11, token_id = 0) ]) ]).run(sender = alice) scenario.verify( c1.data.ledger[c1.ledger_key.make(alice.address, 0)].balance == 90 - 10 - 11 ) scenario.verify( c1.data.ledger[c1.ledger_key.make(bob.address, 0)].balance == 10 + 10 + 11) if config.single_asset: return scenario.h2("More Token Types") tok1_md = FA2.make_metadata( name = "The Second Token", decimals = 0, symbol= "TK1" ) c1.mint(address = bob.address, amount = 100, metadata = tok1_md, token_id = 1).run(sender = admin) tok2_md = FA2.make_metadata( name = "The Token Number Three", decimals = 0, symbol= "TK2" ) c1.mint(address = bob.address, amount = 200, metadata = tok2_md, token_id = 2).run(sender = admin) scenario.h3("Multi-token Transfer Bob -> Alice") c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 10, token_id = 0), sp.record(to_ = alice.address, amount = 10, token_id = 1)]), # We voluntarily test a different sub-batch: c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 10, token_id = 2)]) ]).run(sender = bob) scenario.h2("Other Basic Permission Tests") scenario.h3("Bob cannot transfer Alice's tokens.") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0), sp.record(to_ = bob.address, amount = 1, token_id = 0)]) ]).run(sender = bob, valid = False) scenario.h3("Admin can transfer anything.") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0), sp.record(to_ = bob.address, amount = 10, token_id = 1)]), c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 11, token_id = 0)]) ]).run(sender = admin) scenario.h3("Even Admin cannot transfer too much.") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 1000, token_id = 0)]) ]).run(sender = admin, valid = False) scenario.h3("Consumer Contract for Callback Calls.") consumer = View_consumer(c1) scenario += consumer scenario.p("Consumer virtual address: " + consumer.address.export()) scenario.h2("Balance-of.") def arguments_for_balance_of(receiver, reqs): return (sp.record( callback = sp.contract( Balance_of.response_type(), receiver.address, entry_point = "receive_balances").open_some(), requests = reqs)) c1.balance_of(arguments_for_balance_of(consumer, [ sp.record(owner = alice.address, token_id = 0), sp.record(owner = alice.address, token_id = 1), sp.record(owner = alice.address, token_id = 2) ])) scenario.verify(consumer.data.last_sum == 90) scenario.h2("Operators") if not c1.config.support_operator: scenario.h3("This version was compiled with no operator support") scenario.p("Calls should fail even for the administrator:") c1.update_operators([]).run(sender = admin, valid = False) else: scenario.p("This version was compiled with operator support.") scenario.p("Calling 0 updates should work:") c1.update_operators([]).run() scenario.h3("Operator Accounts") op0 = sp.test_account("Operator0") op1 = sp.test_account("Operator1") op2 = sp.test_account("Operator2") scenario.show([op0, op1, op2]) scenario.p("Admin can change Alice's operator.") c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op1.address, token_id = 0)), sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op1.address, token_id = 2)) ]).run(sender = admin) scenario.p("Operator1 can now transfer Alice's tokens 0 and 2") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 2, token_id = 0), sp.record(to_ = op1.address, amount = 2, token_id = 2)]) ]).run(sender = op1) scenario.p("Operator1 cannot transfer Bob's tokens") c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = op1.address, amount = 2, token_id = 1)]) ]).run(sender = op1, valid = False) scenario.p("Operator2 cannot transfer Alice's tokens") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 2, token_id = 1)]) ]).run(sender = op2, valid = False) scenario.p("Alice can remove their operator") c1.update_operators([ sp.variant("remove_operator", c1.operator_param.make( owner = alice.address, operator = op1.address, token_id = 0)), sp.variant("remove_operator", c1.operator_param.make( owner = alice.address, operator = op1.address, token_id = 0)) ]).run(sender = alice) scenario.p("Operator1 cannot transfer Alice's tokens any more") c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = op1.address, amount = 2, token_id = 1)]) ]).run(sender = op1, valid = False) scenario.p("Bob can add Operator0.") c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = bob.address, operator = op0.address, token_id = 0)), sp.variant("add_operator", c1.operator_param.make( owner = bob.address, operator = op0.address, token_id = 1)) ]).run(sender = bob) scenario.p("Operator0 can transfer Bob's tokens '0' and '1'") c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]), c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 1)]) ]).run(sender = op0) scenario.p("Bob cannot add Operator0 for Alice's tokens.") c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op0.address, token_id = 0 )) ]).run(sender = bob, valid = False) scenario.p("Alice can also add Operator0 for their tokens 0.") c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op0.address, token_id = 0 )) ]).run(sender = alice, valid = True) scenario.p("Operator0 can now transfer Bob's and Alice's 0-tokens.") c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]), c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 1, token_id = 0)]) ]).run(sender = op0) scenario.p("Bob adds Operator2 as second operator for 0-tokens.") c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = bob.address, operator = op2.address, token_id = 0 )) ]).run(sender = bob, valid = True) scenario.p("Operator0 and Operator2 can transfer Bob's 0-tokens.") c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]) ]).run(sender = op0) c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]) ]).run(sender = op2) scenario.table_of_contents()
t = sp.TRecord(owner=sp.TAddress, operator=sp.TAddress, token_id=sp.TNat) t = t.layout(("owner", ("operator", "token_id"))) nft_contract = sp.contract(sp.TList( sp.TVariant( add_operator=t, remove_operator=t ) ), self.data.hen_nft_address, entry_point="update_operators").open_some() sp.transfer( sp.list([sp.variant("add_operator", sp.record( owner=sp.self_address, operator=self.data.hen_address, token_id=swap_info.objkt_id ))]), sp.mutez(0), nft_contract ) # Call into HEN contract c = sp.contract( sp.TRecord( creator=sp.TAddress, objkt_amount=sp.TNat, objkt_id=sp.TNat, royalties=sp.TNat, xtz_per_objkt=sp.TMutez ),
def test(): scenario = sp.test_scenario() scenario.h1("Auction House") scenario.table_of_contents() admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") dan = sp.test_account("Dan") minter = sp.test_account("Minter") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob, dan, minter]) auction_house = AuctionHouse() scenario += auction_house scenario.h2("AcuteArtFA2") fa2 = AcuteArtFA2(auction_house.address, minter.address) scenario += fa2 scenario.h2("Initial minting") scenario.p("Minter mints token 0 with no royalty") scenario += fa2.mint(token_id = 0, royalty = sp.none, metadata = sp.bytes_of_string('ipfs://foo')).run(sender = minter.address) scenario.p("Alice fails to mint token 1") scenario += fa2.mint(token_id = 1, royalty = sp.none, metadata = sp.bytes_of_string('ipfs://foo')).run(sender = alice.address, valid=False) scenario.p("Minter fails to re-mint token 0") scenario += fa2.mint(token_id = 0, royalty = sp.none, metadata = sp.bytes_of_string('ipfs://foo')).run(sender = minter.address, valid=False) scenario.p("Minter sends token to Bob") scenario += fa2.transfer([BatchTransfer.item(minter.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=minter, valid=True) scenario.p("Bob updates operators") scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=sp.nat(0)))]).run(sender=bob) scenario.h2("User Auction") scenario.p("Bob creates auction") auction_id = sp.nat(0) # we can reuse 0 scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(0), token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=bob, now=sp.timestamp(0)) scenario.p("Bob tries to withdraw") scenario += auction_house.withdraw(0).run(sender=bob, amount=sp.mutez(0), now=sp.timestamp(0), valid=False) scenario.p("Alice bids") scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(200000), now=sp.timestamp(0)) scenario.p("Dan bids") scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(300000), now=sp.timestamp(1)) scenario.p("Alice rebids") scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(400000), now=sp.timestamp(2)) scenario.p("Bob tries to withdraw") scenario += auction_house.withdraw(0).run(sender=bob, amount=sp.mutez(0), now=sp.timestamp(60*60), valid=False) scenario.p("Dan bids") scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(500000), now=sp.timestamp(60*60-5)) scenario.p("Alice rebids") scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(600000), now=sp.timestamp(60*60+5*60-6)) scenario.p("Alice withdraws") scenario += auction_house.withdraw(0).run(sender=alice, amount=sp.mutez(0), now=sp.timestamp(60*60+5*60-6+5*60+1)) scenario.h2("Self-Withdraw") scenario.p("Alice creates auction") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=alice.address,operator=auction_house.address,token_id=sp.nat(0)))]).run(sender=alice) scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(0), token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=alice, now=sp.timestamp(0)) scenario.h2("Transfers") scenario.p("Bob cannot transfer alice's token") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=bob, valid=False) scenario.p("Alice cannot transfer own token") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=alice, valid=False) scenario.p("Bob bids") scenario += auction_house.bid(0).run(sender=bob, amount=sp.mutez(100000000), now=sp.timestamp(60)) scenario.p("Bob withdraws") scenario += auction_house.withdraw(0).run(sender=bob, now=sp.timestamp(120*60)) scenario.p("Auction house cannot transfer Bob's token before allowance") scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=alice.address, token_id=0, amount=1)])]).run(sender=auction_house.address, valid=False) # scenario.show(fa2.data.ledger[LedgerKey.make(owner = auction_house.address, token_id = 0)]) scenario.p("Auction house can transfer Bob's token after allowance") scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=0))]).run(sender=bob) scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=alice.address, token_id=0, amount=1)])]).run(sender=auction_house.address) scenario.p("Bob cannot transfer more token") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=bob.address, token_id=0, amount=2)])]).run(sender=bob, valid=False) scenario.p("Bob cannot transfer from non balance address") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=dan.address, token_id=0, amount=1)])]).run(sender=bob, valid=False) scenario.p("Alice can transfer as owner") auction_id = sp.nat(0) # we can reuse 0 scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=dan.address, token_id=0, amount=1)])]).run(sender=alice) scenario.h2("Royalties Mechanics") auction_id = sp.nat(1) fraction = sp.nat(215000000) # 215000000/2**32 ~= 5% token_id = sp.nat(10) scenario.p("Minter mints token 10 with royalty") scenario += fa2.mint(token_id = token_id, royalty = sp.some(sp.record(recipient=minter.address, fraction=fraction)), metadata = sp.bytes_of_string('ipfs://foo')).run(sender = minter.address) scenario.p("Minter fails to send token to Bob") scenario += fa2.transfer([BatchTransfer.item(minter.address, [sp.record(to_=bob.address, token_id=token_id, amount=1)])]).run(sender=minter, valid=False) scenario.p("Minter updates operators") scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=minter.address,operator=auction_house.address,token_id=token_id))]).run(sender=minter) scenario.p("Minter creates auction") scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=token_id, token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=minter, now=sp.timestamp(0)) scenario.p("No one has bid, no royalty expected...") scenario += auction_house.withdraw(auction_id).run(sender=minter, now=sp.timestamp(60*60+1)) scenario.verify(~auction_house.data.accumulated_royalties.contains(minter.address)) scenario.p("Minter updates operators") scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=minter.address,operator=auction_house.address,token_id=token_id))]).run(sender=minter) scenario.p("Minter creates new auction") scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=token_id, token_amount=sp.nat(1), end_timestamp=sp.timestamp(60*60), bid_amount=sp.mutez(100000))).run(sender=minter, now=sp.timestamp(0)) scenario += auction_house.bid(auction_id).run(sender=alice,amount=sp.tez(100), now=sp.timestamp(0)) scenario.p("Now we have a bid, we expect royalty") scenario += auction_house.withdraw(auction_id).run(sender=minter, now=sp.timestamp(60*60+1)) scenario.verify(auction_house.data.accumulated_royalties.contains(minter.address)) scenario.verify_equal(auction_house.data.accumulated_royalties[minter.address],sp.mutez(5005858)) scenario.p("Only minter can collect royalties") scenario += auction_house.collect_royalties(bob.address).run(sender=bob, valid=False) scenario += auction_house.collect_royalties(minter.address).run(sender=minter, valid=True) scenario.verify(~auction_house.data.accumulated_royalties.contains(minter.address)) scenario.p("Only royalty recipient can update _own_ recipient") scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=token_id)).run(sender=bob, valid=False) scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=sp.nat(0))).run(sender=bob, valid=False) scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=sp.nat(0))).run(sender=minter, valid=False) scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=token_id)).run(sender=minter, valid=True) scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=alice.address, token_id=token_id)).run(sender=minter, valid=False)
def add_test(config, is_default = True): @sp.add_test(name = config.name, is_default = is_default) def test(): scenario = sp.test_scenario() scenario.h1("FA2 Contract Name: " + config.name) scenario.table_of_contents() # sp.test_account generates ED25519 key-pairs deterministically: admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob]) c1 = FA2(config, admin.address) scenario += c1 if config.non_fungible: # TODO return scenario.h2("Initial Minting") scenario.p("The administrator mints 100 token-0's to Alice.") scenario += c1.mint(address = alice.address, amount = 100, symbol = 'TK0', token_id = 0).run(sender = admin) scenario.h2("Transfers Alice -> Bob") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0) ]) ]).run(sender = alice) scenario.verify( c1.data.ledger[c1.ledger_key.make(alice.address, 0)].balance == 90) scenario.verify( c1.data.ledger[c1.ledger_key.make(bob.address, 0)].balance == 10) scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0), sp.record(to_ = bob.address, amount = 11, token_id = 0) ]) ]).run(sender = alice) scenario.verify( c1.data.ledger[c1.ledger_key.make(alice.address, 0)].balance == 90 - 10 - 11) scenario.verify( c1.data.ledger[c1.ledger_key.make(bob.address, 0)].balance == 10 + 10 + 11) if config.single_asset: return scenario.h2("More Token Types") scenario += c1.mint(address = bob.address, amount = 100, symbol = 'TK1', token_id = 1).run(sender = admin) scenario += c1.mint(address = bob.address, amount = 200, symbol = 'TK2', token_id = 2).run(sender = admin) scenario.h3("Multi-token Transfer Bob -> Alice") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 10, token_id = 0), sp.record(to_ = alice.address, amount = 10, token_id = 1)]), # We voluntarily test a different sub-batch: c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 10, token_id = 2)]) ]).run(sender = bob) scenario.h2("Other Basic Permission Tests") scenario.h3("Bob cannot transfer Alice's tokens.") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0), sp.record(to_ = bob.address, amount = 1, token_id = 0)]) ]).run(sender = bob, valid = False) scenario.h3("Admin can transfer anything.") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 10, token_id = 0), sp.record(to_ = bob.address, amount = 10, token_id = 1)]), c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 11, token_id = 0)]) ]).run(sender = admin) scenario.h3("Even Admin cannot transfer too much.") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 1000, token_id = 0)]) ]).run(sender = admin, valid = False) scenario.h3("Consumer Contract for Callback Calls.") consumer = View_consumer(c1) scenario += consumer scenario.p("Consumer virtual address: " + sp.contract_address(consumer).export()) scenario.h2("Balance-of.") def arguments_for_balance_of(receiver, reqs): return (sp.record( callback = sp.contract( Balance_of.response_type(), sp.contract_address(receiver), entry_point = "receive_balances").open_some(), requests = reqs)) scenario += c1.balance_of(arguments_for_balance_of(consumer, [ sp.record(owner = alice.address, token_id = 0), sp.record(owner = alice.address, token_id = 1), sp.record(owner = alice.address, token_id = 2) ])) scenario.verify(consumer.data.last_sum == 90) scenario.h2("Token Metadata.") scenario.p("The view-receiver does the verification that the address" + "received is the one of the FA2 contract.") scenario += c1.token_metadata_registry( sp.contract( sp.TAddress, sp.contract_address(consumer), entry_point = "receive_metadata_registry").open_some()) def check_metadata_list(l): res = sp.local("toks", sp.string("")) sp.for md in l: res.value = sp.concat([md.symbol, res.value]) sp.verify((md.symbol == "TK0") | (md.symbol == "TK1")) sp.verify(res.value == "TK1TK0") scenario += c1.token_metadata( sp.record( token_ids = [0, 1], handler = check_metadata_list )) scenario.h2("Operators") if not c1.config.support_operator: scenario.h3("This version was compiled with no operator support") scenario.p("Calls should fail even for the administrator:") scenario += c1.update_operators([]).run(sender = admin, valid = False) if config.add_permissions_descriptor: scenario += c1.permissions_descriptor( sp.contract( c1.permissions_descriptor_.get_type(), sp.contract_address(consumer), entry_point = "receive_permissions_descriptor" ).open_some()) scenario.verify(consumer.data.operator_support == False) else: scenario.p("This version was compiled with operator support.") scenario.p("Calling 0 updates should work:") scenario += c1.update_operators([]).run() scenario.h3("Operator Accounts") op0 = sp.test_account("Operator0") op1 = sp.test_account("Operator1") op2 = sp.test_account("Operator2") scenario.show([op0, op1, op2]) scenario.p("Admin can change Alice's operator.") scenario += c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op1.address)) ]).run(sender = admin) scenario.p("Operator1 can now transfer Alice's tokens") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 2, token_id = 0), sp.record(to_ = op1.address, amount = 2, token_id = 2)]) ]).run(sender = op1) scenario.p("Operator1 cannot transfer Bob's tokens") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = op1.address, amount = 2, token_id = 1)]) ]).run(sender = op1, valid = False) scenario.p("Operator2 cannot transfer Alice's tokens") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 2, token_id = 1)]) ]).run(sender = op2, valid = False) scenario.p("Alice can remove their operator") scenario += c1.update_operators([ sp.variant("remove_operator", c1.operator_param.make( owner = alice.address, operator = op1.address)) ]).run(sender = alice) scenario.p("Operator1 cannot transfer Alice's tokens any more") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = op1.address, amount = 2, token_id = 1)]) ]).run(sender = op1, valid = False) scenario.p("Bob can add Operator0.") scenario += c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = bob.address, operator = op0.address )) ]).run(sender = bob) scenario.p("Operator0 can transfer Bob's tokens '0' and '1'") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]), c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 1)]) ]).run(sender = op0) scenario.p("Bob cannot add Operator0 for Alice's tokens.") scenario += c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op0.address )) ]).run(sender = bob, valid = False) scenario.p("Alice can also add Operator0 for themselves.") scenario += c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = alice.address, operator = op0.address )) ]).run(sender = alice, valid = True) scenario.p("Operator0 can now transfer Bob's and Alice's tokens.") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]), c1.batch_transfer.item(from_ = alice.address, txs = [ sp.record(to_ = bob.address, amount = 1, token_id = 1)]) ]).run(sender = op0) scenario.p("Bob adds Operator2 as second operator.") scenario += c1.update_operators([ sp.variant("add_operator", c1.operator_param.make( owner = bob.address, operator = op2.address )) ]).run(sender = bob, valid = True) scenario.p("Operator0 and Operator2 can transfer Bob's tokens.") scenario += c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]) ]).run(sender = op0) scenario += c1.transfer( [ c1.batch_transfer.item(from_ = bob.address, txs = [ sp.record(to_ = alice.address, amount = 1, token_id = 0)]) ]).run(sender = op2) if config.add_permissions_descriptor: scenario.h3("Testing permissions_descriptor") scenario.verify(consumer.data.operator_support == False) scenario += c1.permissions_descriptor( sp.contract( c1.permissions_descriptor_.get_type(), sp.contract_address(consumer), entry_point = "receive_permissions_descriptor").open_some()) scenario.verify(consumer.data.operator_support == True) scenario.table_of_contents()
def test(): admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Bob") init_eth = "0x91f79893E7B923410Ef1aEba6a67c6fab0sfsdgffd" hashSecret = sp.sha256(sp.sha256(sp.bytes( "0x68656c6c6f666473667364666c64736a666c73646a6664736a6673646a6b666a"))) token_metadata = { "decimals" : "18", # Mandatory by the spec "name" : "My Great Token", # Recommended "symbol" : "MGT", # Recommended # Extra fields "icon" : 'https://smartpy.io/static/img/logo-only.svg' } contract_metadata = { "" : "ipfs://QmaiAUj1FFNGYTu8rLBjc3eeN9cSKwaF8EGMBNDmhzPNFd", } c2 = FA2.FA2(config = FA2.environment_config(), metadata = sp.utils.metadata_of_url("https://example.com"), admin = admin.address) c1 = FA2Swap(_admin=admin.address, _fa2=c2.address, _tokenID=0) scenario = sp.test_scenario() scenario.table_of_contents() scenario.h1("Atomic Swap") scenario += c1 scenario.h2("Accounts") scenario.show([admin, alice, bob]) scenario.h2("FA2") scenario.h3("Entry points") scenario += c2 scenario.h3("Admin mints a few coins") tok0_md = FA2.FA2.make_metadata( name = "The Token Zero", decimals = 2, symbol= "TK0" ) scenario += c2.mint(address = alice.address, amount = 18, metadata = tok0_md, token_id = 0).run(sender = admin) scenario.h2("Alice approves Contract") scenario += c2.update_operators([ sp.variant("add_operator", c2.operator_param.make( owner = alice.address, operator = c1.address, token_id = 0)) ]).run(sender = alice) scenario.h2("Swap[Wait] Testing") # no operations work without contract being active scenario += c1.initiateWait(_hashedSecret=hashSecret, initiator_eth_addr=init_eth, _refundTimestamp=sp.timestamp( 159682500), _amount=5).run(sender=alice, now=sp.timestamp(159682400), valid=False) # activate only by admin scenario += c1.toggleContractState(True).run(sender=alice, valid=False) scenario += c1.toggleContractState(True).run(sender=admin) # update reward only by admin scenario += c1.updateReward(50).run(sender=alice, valid=False) scenario += c1.updateReward(50).run(sender=admin) # initiate new swap scenario += c1.initiateWait(_hashedSecret=hashSecret, initiator_eth_addr=init_eth, _refundTimestamp=sp.timestamp( 159682500), _amount=5).run(sender=alice, now=sp.timestamp(159682400)) # balance check scenario.verify(c2.data.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(5)) scenario.verify(c2.data.ledger[c2.ledger_key.make(alice.address, 0)].balance == sp.nat(13)) # cannot redeem before it is activated & initiated scenario += c1.redeem(_hashedSecret=hashSecret, _secret=sp.bytes( "0x68656c6c6f666473667364666c64736a666c73646a6664736a6673646a6b666a")).run(sender=bob, now=sp.timestamp(159682450), valid=False) # successful add participant only by initiator scenario += c1.addCounterParty(_hashedSecret=hashSecret, _participant=bob.address).run(sender=bob, valid=False) # successful add participant only by initiator scenario += c1.addCounterParty(_hashedSecret=hashSecret, _participant=bob.address).run(sender=alice) # cannot be redeemed with wrong secret scenario += c1.redeem(_hashedSecret=hashSecret, _secret=sp.bytes( "0x12345678aa")).run(sender=bob, now=sp.timestamp(159682450), valid=False) # cannot be redeemed after refundtime has come scenario += c1.redeem(_hashedSecret=hashSecret, _secret=sp.bytes( "0x68656c6c6f666473667364666c64736a666c73646a6664736a6673646a6b666a")).run(sender=bob, now=sp.timestamp(159682550), valid=False) # new swap with the same hash cannot be added unless the previous one is redeemed/refunded scenario += c1.initiateWait(_hashedSecret=hashSecret, initiator_eth_addr=init_eth, _refundTimestamp=sp.timestamp( 159682500), _amount=5).run(sender=alice, amount=sp.tez(2), now=sp.timestamp(159682400), valid=False) # successful redeem can be initiated by anyone but funds transfered to participant scenario += c1.redeem(_hashedSecret=hashSecret, _secret=sp.bytes("0x68656c6c6f666473667364666c64736a666c73646a6664736a6673646a6b666a")).run(sender=bob, now=sp.timestamp(159682450)) # balance check scenario.verify(c2.data.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(0)) scenario.verify(c2.data.ledger[c2.ledger_key.make(bob.address, 0)].balance == sp.nat(5)) # successful swap creation with same hash after redeem scenario += c1.initiateWait(_hashedSecret=hashSecret, initiator_eth_addr=init_eth, _refundTimestamp=sp.timestamp( 159682500), _amount=5).run(sender=alice, now=sp.timestamp(159682400)) # balance check scenario.verify(c2.data.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(5)) scenario.verify(c2.data.ledger[c2.ledger_key.make(alice.address, 0)].balance== sp.nat(8)) # cannot be refunded before the refundtime scenario += c1.refund(hashSecret).run(sender=bob, now=sp.timestamp(159682450), valid=False) scenario += c1.refund(hashSecret).run(sender=alice, now=sp.timestamp(159682450), valid=False) # can be refunded in any initated or waiting state if refund time has come, can be done by anyone but funds transfered only to initiator scenario += c1.refund(hashSecret).run(sender=bob, now=sp.timestamp(159682550)) # cannot be refunded again once it has been refunded scenario += c1.refund(hashSecret).run(sender=alice, now=sp.timestamp(159682550), valid=False) # balance check scenario.verify(c2.data.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(0)) scenario.verify(c2.data.ledger[c2.ledger_key.make(alice.address, 0)].balance == sp.nat(13))