Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
 def uv(s):
     return sp.variant(s, sp.unit)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
def value_int(s):
    return sp.variant("int", s)
Ejemplo n.º 7
0
def value_bytes(s):
    return sp.variant("bytes", s)
Ejemplo n.º 8
0
def value_string(s):
    return sp.variant("string", s)
Ejemplo n.º 9
0
 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()
Ejemplo n.º 10
0
        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
            ), 
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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))