def __init__(self, admin): with open('metadata/metadata.json', 'r') as f: #loads then dumps to confirm correctly formatted json metadata = json.dumps(json.load(f)) self.init( paused=False, balances=sp.big_map(tvalue=sp.TRecord( approvals=sp.TMap(sp.TAddress, sp.TNat), balance=sp.TNat)), administrator=admin, totalSupply=0, permits=sp.big_map(tkey=sp.TPair(sp.TAddress, sp.TBytes), tvalue=sp.TTimestamp), user_expiries=sp.big_map(tkey=sp.TAddress, tvalue=sp.TOption(sp.TNat)), permit_expiries=sp.big_map(tkey=sp.TPair( sp.TAddress, sp.TBytes), tvalue=sp.TOption(sp.TNat)), counter=0, default_expiry=50000, max_expiry=2628000, metadata=sp.big_map( l={ "": sp.bytes_of_string("tezos-storage:md-json"), "md-json": sp.bytes_of_string(metadata) }))
def test(): time = sp.timestamp(1571761674) # Create test scenario scenario = sp.test_scenario() scenario.table_of_contents() # sp.test_account generates ED25519 key-pairs deterministically: alice = sp.test_account("Alice") bob = sp.test_account("Robert") # Create HTML output for debugging scenario.h1("Dutch Auction") # Instantiate Auction contract auction = DutchAuction(alice.address) scenario += auction alice_wallet = NFTWallet(alice.address) bob_wallet = NFTWallet(bob.address) scenario += alice_wallet scenario += bob_wallet scenario.h2("Create NFT") token_metadata = sp.map({"name": sp.bytes_of_string("Nft1")}) scenario += alice_wallet.createNft(token_metadata).run(sender=alice) scenario.h2("Configure and start auction") scenario += alice_wallet.configNftAuction(auction_address=auction.address, opening_price=100, reserve_price=10, start_time=time, round_time=1000, ticket_id=0).run(source=alice, sender=alice, now=time) scenario.verify(~alice_wallet.data.tickets.contains(0)) time = time.add_seconds(1) scenario += auction.startAuction().run(sender=alice, now=time) time = time.add_seconds(6001) scenario += auction.dropPrice(90).run(sender=alice, now=time) scenario.h2("Bob buys") time = time.add_seconds(1) scenario += auction.buy(bob_wallet.address).run(sender=bob, source=bob, now=time, amount=sp.mutez(90)) scenario.verify(bob_wallet.data.tickets.contains(0)) scenario.verify(~auction.data.ticket.is_some())
def __init__(self, admin, supply, **extra_storage): contract_metadata = sp.big_map( l = { "": sp.bytes_of_string('tezos-storage:data'), "data": sp.bytes_of_string( """{ "name": "SmartLink", "description": "Decentralized escrow platform for Web 3.0", "authors": ["SmartLink Dev Team <*****@*****.**>"], "homepage": "https://smartlink.so/", "interfaces": [ "TZIP-007", "TZIP-016"], "symbol":"SMAK", "icon":"ipfs://QmU2C4jU154nwA71AKHeiEj79qe7ZQC4Mf7AeUj5ALXZfe", "decimals":"3" }""" ) }, tkey = sp.TString, tvalue = sp.TBytes ) token_metadata = sp.big_map( l = { 0: ( 0, sp.map( l = { "name": sp.bytes_of_string('Smartlink'), "decimals": sp.bytes_of_string('3'), "symbol": sp.bytes_of_string('SMAK'), "icon": sp.bytes_of_string('ipfs://QmU2C4jU154nwA71AKHeiEj79qe7ZQC4Mf7AeUj5ALXZfe') }, tkey = sp.TString, tvalue = sp.TBytes ) ) }, tkey = sp.TNat, tvalue = sp.TPair(sp.TNat, sp.TMap(sp.TString, sp.TBytes)) ) self.balances = sp.big_map( l = {admin: sp.record(balance = supply, approvals = {})}, tkey = sp.TAddress, tvalue = sp.TRecord(approvals = sp.TMap(sp.TAddress, sp.TNat), balance = sp.TNat) ) self.init( balances = self.balances, metadata = contract_metadata, token_metadata = token_metadata, frozen_accounts = sp.big_map(tkey = sp.TAddress, tvalue = sp.TTimestamp), totalSupply = supply, **extra_storage )
def init_metadata(md): return sp.big_map(l={"": sp.bytes_of_string("tezos-storage:data"), "data": sp.bytes_of_string(md)})
def test(): scenario = sp.test_scenario() scenario.h1("Simple ST12 Contract") # sp.test_account generates ED25519 key-pairs deterministically: admin = sp.test_account("AccessControl") alice = sp.test_account("Alice") bob = sp.test_account("Robert") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob]) c1 = ST12( config = config, administrators = sp.set([admin.address]), metadata = sp.map(l = { # Remember that michelson wants map already in ordered "decimals" : sp.bytes_of_string("%d" % 18), "name" : sp.bytes_of_string("Test Token"), "symbol" : sp.bytes_of_string("Test") }) ) scenario += c1 scenario.h2("Admin mints a few coins") scenario += c1.mint(sp.list([sp.record(address=alice.address, amount=12)])).run(sender=admin) scenario += c1.mint(sp.list([ sp.record(address=alice.address, amount=3), sp.record(address=alice.address, amount=3), ])).run(sender=admin) scenario.h2("Alice transfers her own tokens to Bob") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run( sender=alice ) scenario.verify(c1.data.ledger[alice.address].balance == 14) scenario.h2("Bob tries to transfer from Alice but he doesn't have her approval") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run( sender=bob, valid=False ) scenario.h2("Alice approves Bob and Bob transfers") scenario += c1.approve(spender=alice.address, value=5).run( sender=alice ) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run( sender=admin ) scenario.h2("Bob tries to over-transfer from Alice") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run( sender=bob, valid=False ) scenario.h2("Admin burns Bob token") scenario += c1.burn(sp.list([sp.record(address=bob.address, amount=1)])).run(sender=admin) scenario.verify(c1.data.ledger[alice.address].balance == 10) scenario.h2("Alice tries to burn Bob token") scenario += c1.burn(sp.list([sp.record(address=bob.address, amount=1)])).run( sender=alice, valid=False ) scenario.h2("Admin pauses the contract and Alice cannot transfer anymore") scenario += c1.set_paused(True).run(sender=admin) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run( sender=alice, valid=False ) scenario.verify(c1.data.ledger[alice.address].balance == 10) scenario.h2("Admin transfers while on pause") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run( sender=admin ) scenario.h2("Admin unpauses the contract and transferts are allowed") scenario += c1.set_paused(False).run(sender=admin) scenario.verify(c1.data.ledger[alice.address].balance == 9) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run( sender=admin ) scenario.verify(c1.data.total_supply == 17) scenario.verify(c1.data.ledger[alice.address].balance == 8) scenario.verify(c1.data.ledger[bob.address].balance == 9) scenario.h2("Burn") scenario += c1.burn( sp.list([ sp.record( address=alice.address, amount=3 ) ]) ).run(sender=admin) scenario += c1.burn( sp.list( [ sp.record( address=alice.address, amount=3 ) ] ) ).run(sender=admin) scenario.table_of_contents()
# This specific main uses the relative new feature of non-default tests # sp.for the browser version. if "templates" not in __name__: add_test(environment_config()) # if not global_parameter("only_environment_test", False): # add_test(FA12_config(debug_mode=True), is_default=not sp.in_browser) # add_test(FA12_config(readable=False), is_default=not sp.in_browser) # add_test(FA12_config(force_layouts=False), is_default=not sp.in_browser) # add_test(FA12_config(lazy_entry_points=True), is_default=not sp.in_browser) # add_test( # FA12_config(lazy_entry_points_multiple=True), is_default=not sp.in_browser # ) sp.add_compilation_target( "ST12_compiled", ST12( config = environment_config(), administrators = sp.set([sp.address("tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr")]), validators = sp.set([sp.address("KT1QkFxZqfCok6LZUJ7zDn6gCDBS7kSao26P")]), burners = sp.set([sp.address("KT1S3M3Cn7XBLcNi54cfvMP15j9ew4W4eb1C")]), minters = sp.set([sp.address("KT1S3M3Cn7XBLcNi54cfvMP15j9ew4W4eb1C")]), metadata = sp.big_map(l = { "": sp.bytes_of_string("tezos-storage:m"), "m" : sp.bytes_of_string("{\"name\":\"Test\",\"version\":\"security token v1.0\",\"description\":\"Test Digital Security Token\"}"), "name" : sp.bytes_of_string("Test"), "symbol" : sp.bytes_of_string("TST"), "decimals" : sp.bytes_of_string("18"), }) ) )
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 test(): scenario = sp.test_scenario() scenario.h1("VestingEscrowMinterBurnerWallet") admin = sp.test_account("Token Admin") alice = sp.test_account("Alice") bob = sp.test_account("Bob") fa12 = ST12(admin.address) fa2 = ST2(admin.address) v = VestingEscrowMinterBurnerWallet() scenario += fa12 scenario += fa2 scenario += v scenario += v.vest( sp.list([ sp.record( schedule_name = "4 Months Cliff Vesting From 12-12-2020", beneficiery = alice.address, start = sp.timestamp(0), cliff = sp.timestamp(5), end = sp.timestamp(10), vesting_amount = 100, token_address = fa2.address, token_id = sp.some(0), metadata = sp.some(sp.map({ "decimals": sp.bytes_of_string("%d" % 18), "name": sp.bytes_of_string("Test"), "symbol": sp.bytes_of_string("TEST") })) ) ]) ) scenario += v.claim().run(sender = alice, now = sp.timestamp(5)) scenario += v.claim().run(sender = alice, now = sp.timestamp(7)) scenario += v.claim().run(sender = alice, now = sp.timestamp(10)) scenario += v.claim().run(sender = alice, now = sp.timestamp(10), valid=False) scenario += v.claim().run(sender = alice, now = sp.timestamp(15), valid=False) scenario += v.vest( sp.list([ sp.record( schedule_name = "5 Months Cliff Vesting From 12-12-2020", beneficiery = alice.address, start = sp.timestamp(0), cliff = sp.timestamp(5), end = sp.timestamp(10), vesting_amount = 200, token_address = fa12.address, token_id = sp.none, metadata = sp.none ), sp.record( schedule_name = "8 Months Cliff Vesting From 12-12-2020", beneficiery = bob.address, start = sp.timestamp(0), cliff = sp.timestamp(5), end = sp.timestamp(10), vesting_amount = 200, token_address = fa12.address, token_id = sp.none, metadata = sp.none ) ]) ) scenario += v.changeBeneficiery( sp.list([ sp.record( schedule_name = "8 Months Cliff Vesting From 12-12-2020", from_ = bob.address, to_ = alice.address ) ]) ).run(sender = alice, valid = False) scenario += v.changeBeneficiery( sp.list([ sp.record( schedule_name = "8 Months Cliff Vesting From 12-12-2020", from_ = bob.address, to_ = alice.address ) ]) ).run(sender = admin) scenario += v.changeBeneficieryForAll( sp.list([ sp.record( from_ = alice.address, to_ = bob.address ) ]) ).run(sender = alice, valid = False) scenario += v.changeBeneficieryForAll( sp.list([ sp.record( from_ = alice.address, to_ = bob.address ) ]) ).run(sender = admin)