def test(): scenario=sp.test_scenario() scenario.h1("Fails when data is pushed from bad address") scenario.h2("GIVEN a Normalizer contract whitelisted to an address") contract=NormalizerContract( oracleContractAddress=defaultOracleContractAddress ) scenario += contract scenario.h2("WHEN an update is pushed from the wrong address") scenario.h2("THEN the update fails.") badAddress=sp.address("KT1FrRkunqmB7futF3EyRwTt8f7fPEVJW39P") scenario += contract.update( makeMap( assetCode="XTZ-USD", start=sp.timestamp(1595104501), end=sp.timestamp(1595104531), open=3059701, high=1, low=2, close=3, volume=4 ) ).run(sender=badAddress, valid=False)
def test(): alice = sp.test_account("Alice") bob = sp.test_account("Robert") scenario = sp.test_scenario() scenario.h1("Atomic Swap") # Here, two AtomicSwap contracts are created. One with Alice as the owner # and Bob as the counterparty, and the second with the identities reversed. # They are both secured with the same hash secret, so if the secret gets # revealed, then both swaps can happen. hashSecret = sp.blake2b(sp.bytes("0x12345678aabb")) c1 = AtomicSwap(sp.mutez(12), sp.timestamp(50), hashSecret, alice.address, bob.address) c2 = AtomicSwap(sp.mutez(20), sp.timestamp(50), hashSecret, bob.address, alice.address) scenario.h1("c1") scenario += c1 scenario += c1.knownSecret(secret = sp.bytes("0x12345678aa")).run(sender = bob, valid = False) scenario += c1.knownSecret(secret = sp.bytes("0x12345678aabb")).run(sender = bob) scenario.h1("c2") scenario += c2 scenario.h2("C2.export()") scenario.p(c2.export())
def test(): scenario=sp.test_scenario() scenario.h1("Correctly processes updates from the same time") scenario.h2("GIVEN a Normalizer contract with an update at a given time = 1") assetCode="XTZ-USD" contract=NormalizerContract() scenario += contract start1=sp.timestamp(1) end1=sp.timestamp(2) open1=1 high1=2 low1=3 close1=4 volume1=5 scenario += contract.update( makeMap( assetCode=assetCode, start=start1, end=end1, open=open1, high=high1, low=low1, close=close1, volume=volume1 ) ).run(sender=defaultOracleContractAddress) scenario.h2("WHEN an update is provided at the same time.") open2=6 high2=7 low2=8 close2=9 volume2=10 scenario += contract.update( makeMap( assetCode=assetCode, start=start1, end=end1, open=open2, high=high2, low=low2, close=close2, volume=volume2 ) ).run(sender=defaultOracleContractAddress) scenario.h2("THEN the original data is still reported.") expected = Harbinger.computeVWAP( high=high1, low=low1, close=close1, volume=volume1 ) // volume1 scenario.verify(contract.data.assetMap[assetCode].computedPrice == expected)
def test(): scenario=sp.test_scenario() scenario.h1("Calls back correctly when a valid asset is provided") scenario.h2("GIVEN a Normalizer contract") assetCode = "XTZ-USD" contract=NormalizerContract(assetCodes=[assetCode]) scenario += contract scenario.h2("AND a contract to call back to") dummyContract = DummyContract() scenario += dummyContract scenario.h2("AND a single data point") start1=sp.timestamp(1595104530) high1=1 low1=2 close1=3 volume1=4 assetCode = "XTZ-USD" scenario += contract.update( makeMap( assetCode=assetCode, start=start1, end=sp.timestamp(1595104531), open=3059701, high=high1, low=low1, close=close1, volume=volume1 ) ).run(sender=defaultOracleContractAddress) scenario.h2("WHEN a request is made") contractHandle = sp.contract( sp.TPair(sp.TString, sp.TPair(sp.TTimestamp, sp.TNat)), dummyContract.address, entry_point = "callback" ).open_some() param = (assetCode, contractHandle) scenario.h2("THEN it succeeds.") scenario += contract.get(param) scenario.h2("AND the dummy contract captured the expected values") scenario.verify(sp.fst(dummyContract.data.capturedCallbackValue) == assetCode) scenario.verify(sp.fst(sp.snd(dummyContract.data.capturedCallbackValue)) == start1) expectedPartialVWAP = Harbinger.computeVWAP( high=high1, low=low1, close=close1, volume=volume1 ) expectedPrice = expectedPartialVWAP // volume1 scenario.verify(sp.snd(sp.snd(dummyContract.data.capturedCallbackValue)) == expectedPrice)
def test(): scenario = sp.test_scenario() scenario.h1("Update Fails With Bad Signature") scenario.h2("GIVEN an Oracle contract") assetCode = "XTZ-USD" contract = OracleContract( publicKey=testAccountPublicKey, initialData=sp.big_map( l={ assetCode: initialOracleData }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ) scenario += contract scenario.h2("AND an update signed by an alternative key") alternativeAccount = sp.test_account("AlternativeAccount") alternativeSecretKey = alternativeAccount.secret_key start = sp.timestamp(1) end = sp.timestamp(2) open = 3 high = 4 low = 5 close = 6 volume = 7 updateData = ( start, (end, (open, (high, (low, (close, volume)))))) message = sp.pack(updateData) signature = sp.make_signature( alternativeSecretKey, message, message_format='Raw' ) scenario.h2("WHEN the oracle is updated") update = sp.pair(signature, updateData) parameter = sp.map( l={ assetCode: update }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario.h2("THEN the update fails") scenario += contract.update(parameter).run(valid=False)
def test(): scenario = sp.test_scenario() scenario.h1("TZButton - A social dApp experiment") scenario.table_of_contents() creator = sp.test_account("creator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") dan = sp.test_account("Dan") scenario.h2("Accounts") scenario.show([creator, alice, bob, dan]) tz_button_contract = TZButton() tz_button_contract.set_initial_balance(INITIAL_BALANCE) scenario += tz_button_contract viewer_contract = ViewConsumer() scenario += viewer_contract scenario.h2("Pay-In") scenario.p("Alice does not pay") scenario += tz_button_contract.default().run(sender=alice, valid=False) scenario.p("Alice pays too little") scenario += tz_button_contract.default().run(sender=alice, amount=sp.mutez(20000), valid=False) scenario.p("Alice pays too much") scenario += tz_button_contract.default().run(sender=alice, amount=sp.mutez(20001), valid=False) scenario.p("Alice pays correct amount") scenario += tz_button_contract.default().run(sender=alice, amount=sp.mutez(200000)) scenario.p("Bob pays correct amount") scenario += tz_button_contract.default().run(sender=bob, amount=sp.mutez(200000), now=sp.timestamp(1)) scenario.p("Alice pays correct amount after bob again") scenario += tz_button_contract.default().run(sender=alice, amount=sp.mutez(200000), now=sp.timestamp(2)) scenario.h2("Withdraw") scenario.p("Leader tries to withdraw before countdown") scenario += tz_button_contract.withdraw().run(sender=alice, valid=False) scenario.p("Non-Leader tries to withdraw after countdown") scenario += tz_button_contract.withdraw().run(sender=bob, valid=False, now=sp.timestamp(60*60*24)) scenario.p("Non-Leader tries to pays correct amount after countdown") scenario += tz_button_contract.default().run(sender=bob, amount=sp.mutez(200000), valid=False, now=sp.timestamp(60*60*24)) scenario.p("Leader tries to pays correct amount after countdown") scenario += tz_button_contract.default().run(sender=alice, amount=sp.mutez(200000), valid=False, now=sp.timestamp(60*60*24)) scenario.p("Leader tries to withdraw after countdown") scenario += tz_button_contract.withdraw().run(sender=alice, now=sp.timestamp(60*60*24))
def __init__(self,admin,endCycle,endWithdraw,token): self.init(contractBuyer= sp.big_map(),contractSellar = sp.big_map(), administrator = admin,buyerSet = sp.set(),poolSet=sp.set(), xtzPrice=400,validation=sp.record(cycleEnd=sp.timestamp(endCycle),withdrawTime=sp.timestamp(endWithdraw),totalSupply=sp.nat(0)), tokenContract=token,adminAccount=0,model = sp.map() )
def addMatch(self, params): sp.verify(sp.sender == self.data.administrator, message="Only Admin Can Start/End a Match.") sp.verify(~self.data.matches.contains(params.match_id), message="Match Already Exists.") self.data.matches[params.match_id] = sp.record( teamA=params.teamA, teamB=params.teamB, active=False, ends=sp.timestamp(0), date=params.date, finished=False, compete=False)
def selectWinner(self): #random id randomId = (sp.timestamp_from_utc_now() - sp.timestamp(0)) % 5 #pay out sp.send(self.data.ticketToAddress[randomId], sp.tez(5)) self.data.previousWinners.push(self.data.ticketToAddress[randomId])
def __init__(self): self.init( parties = sp.map(tkey=sp.TAddress, tvalue=sp.TMutez), minAmount = sp.tez(0), total = sp.tez(0), maxTime = sp.timestamp(0) # + 345600 )
def __init__( self, assetCodes=["XTZ-USD", "BTC-USD"], oracleContractAddress=sp.address( "KT1QLPABNCD4z1cSYVv3ntYDYgtWTed7LkYr"), numDataPoints=sp.int(3) ): # Set last update timestamp to unix epoch. lastUpdateTime = sp.timestamp(0) initialValues = {} for assetCode in assetCodes: # Populate the queues with an initial zero elements pricesQueue = fifoDT() volumesQueue = fifoDT() assetRecord = sp.record( prices= pricesQueue, volumes= volumesQueue, lastUpdateTime= lastUpdateTime, computedPrice= 0 ) initialValues[assetCode] = assetRecord assetMap = sp.big_map( l=initialValues, ) self.init( assetMap=assetMap, assetCodes=assetCodes, oracleContract=oracleContractAddress, numDataPoints=numDataPoints )
def __init__( self, publicKey=sp.some( sp.key("sppk7bkCcE4TZwnqqR7JAKJBybJ2XTCbKZu11ESTvvZQYtv3HGiiffN")), initialData=sp.big_map( l={ "XTZ-USD": (sp.timestamp(0), (sp.timestamp(0), (0, (0, (0, (0, 0)))))) }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ): self.init( publicKey=publicKey, oracleData=initialData )
def test(): scenario=sp.test_scenario() scenario.h1("Calls back correctly when a valid asset is provided") scenario.h2("GIVEN a Normalizer contract") assetCode = "XTZ-USD" contract=NormalizerContract(assetCodes=[assetCode]) scenario += contract scenario.h2("AND a contract to call back to") dummyContract = DummyContract() scenario += dummyContract scenario.h2("AND a single data point") start1=sp.timestamp(1595104530) high1=1 low1=2 close1=3 volume1=4 assetCode = "XTZ-USD" scenario += contract.update( makeMap( assetCode=assetCode, start=start1, end=sp.timestamp(1595104531), open=3059701, high=high1, low=low1, close=close1, volume=volume1 ) ).run(sender=defaultOracleContractAddress) scenario.h2("WHEN the onchain view is read") scenario.h2("THEN it the correct data is returned.") scenario.verify(sp.fst(contract.getPrice(assetCode)) == start1) expectedPartialVWAP = Harbinger.computeVWAP( high=high1, low=low1, close=close1, volume=volume1 ) expectedPrice = expectedPartialVWAP // volume1 scenario.verify(sp.snd(contract.getPrice(assetCode)) == expectedPrice)
def __init__(self, oracle): self.init( oracle = oracle, currencyPair = sp.string(""), value = sp.nat(0), precision = sp.nat(0), timestamp = sp.timestamp(0), source = sp.string(""))
def test(): admin = sp.test_account("Administrator") c1 = FeeStore(admin.address) scenario = sp.test_scenario() scenario.h1("Fee Store") scenario += c1 scenario += c1.update({"USDC": sp.record(approve=100000, initiateWait=100000, addCounterParty=100000, redeem=100000, update_time=sp.timestamp(1612864882))}).run(sender=sp.address("tz1-random"), valid=False) scenario += c1.update({"USDC": sp.record(approve=100000, initiateWait=100000, addCounterParty=100000, redeem=100000, update_time=sp.timestamp(1612864882))}).run(sender=admin) scenario += c1.update({"USDC": sp.record(approve=200000, initiateWait=100000, addCounterParty=100000, redeem=100000, update_time=sp.timestamp(1612864880))}).run(sender=admin) scenario.verify(c1.data.fees["USDC"].approve == 100000) scenario += c1.update_admin(sp.address("tz1-new-admin") ).run(sender=sp.address("tz1-random"), valid=False) scenario += c1.update_admin(sp.address("tz1-new-admin") ).run(sender=admin) scenario.verify(c1.data.admin == sp.address("tz1-new-admin"))
def __init__(self): self.init( time_out = sp.timestamp(0), signatures = sp.map(tkey = sp.TString, tvalue = sp.TString), immutability = False, proposal = '', ocasion = '', description = '' )
def test(): scenario = sp.test_scenario() #Test accounts admin1 = sp.test_account('Admin-1') admin2 = sp.test_account('Admin-2') alice = sp.test_account("Alice") bob = sp.test_account("Bob") mike = sp.test_account("Mike") john = sp.test_account("John") c = Market() c.set_storage(sp.record( admin = sp.pair(admin1.address, admin2.address), infoIPFS = "IPFSxyz", uuid = 0, endTime = sp.timestamp(1000000), result = sp.none, orders = {}, buyLongOrders = {}, buyShortOrders = {}, sellLongOrders = {}, sellShortOrders = {}, sharesLong = {}, sharesShort = {} )) scenario += c scenario.register(c.buyLong(quantity = 10, price = 700000).run(sender = alice, amount = sp.mutez(700000))) scenario.register(c.buyShort(quantity = 10, price = 300000).run(sender = bob, amount = sp.mutez(300000))) scenario.register(c.buyShort(quantity = 10, price = 400000).run(sender = mike, amount = sp.mutez(400000))) scenario.register(c.buyLong(quantity = 10, price = 600000).run(sender = john, amount = sp.mutez(600000))) scenario.h2('Admin sets the result') scenario += c.setResult(result = Position.Long).run(sender = admin1, now = sp.timestamp(1000005)) scenario.h2('Failed Withdrawal') scenario += c.withdrawPayout().run(sender = bob, valid = False) scenario.h2('Successful withdrawals') scenario += c.withdrawPayout().run(sender = alice) scenario += c.withdrawPayout().run(sender = john) scenario.verify(c.balance == sp.mutez(0))
def __init__(self): self.init( time_out = sp.timestamp(0), votes = sp.map(tkey = sp.TAddress, tvalue = sp.TString), parties = sp.list(t=sp.TAddress), immutability = False, proposal = '', ocasion = '', ammendment = '' )
def test(): hashSecret = sp.blake2b(sp.bytes("0x12345678aabb")) alice = sp.test_account("Alice") bob = sp.test_account("Robert") c1 = AtomicSwap(sp.mutez(12), sp.timestamp(50), hashSecret, alice.address, bob.address) scenario = sp.test_scenario() scenario.h1("Atomic Swap") scenario += c1
def __init__( self, publicKey=sp.some( sp.key("sppk7bkCcE4TZwnqqR7JAKJBybJ2XTCbKZu11ESTvvZQYtv3HGiiffN")), initialData=sp.big_map( l={ "XTZ-USD": (sp.timestamp(0), (sp.timestamp(0), (0, (0, (0, (0, 0)))))) }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ): self.exception_optimization_level = "Unit" self.add_flag("no_comment") self.init( publicKey=publicKey, oracleData=initialData )
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 test(): scenario = sp.test_scenario() contract = Petition() scenario += contract scenario.h3("Definie Proposal Parameters") scenario += contract.origin_entry(description='', time_out=sp.timestamp(1596067200), proposal="PELA CRIACAO DO PARQUE DO BIXIGA: APOIO A APROVACAO E IMEDIATA SANCAO DO PROJETO DE LEI 805/2017", ocasion="Teatro Oficina Uzyna Uzona").run(sender=sp.address("tz1")) # complemento? scenario.h3("Vote") scenario += contract.sign(name="Name", cpf="ID").run(sender=sp.address('tz3'))
def test(): owner = sp.test_account('Owner') alice = sp.test_account('Alice') bob = sp.test_account('Bob') c = myContract(owner = owner.address, max_collect_percent = sp.nat(50)) scenario = sp.test_scenario() scenario += c scenario.h1('Test Accounts') scenario.show(alice) scenario.show(bob) scenario.show(owner) c.deposit(sp.nat(20)).run(sender = alice.address, amount = sp.tez(100)) c.deposit(sp.nat(20)).run(sender = bob.address, amount = sp.tez(50), valid = False) c.deposit(sp.nat(40)).run(sender = bob.address, amount = sp.tez(200)) c.deposit(sp.nat(0)).run(sender = bob.address, amount = sp.tez(100), valid = False) c.collect(sp.tez(50)).run(sender = alice.address, valid = False) c.collect(sp.tez(50)).run(sender = owner.address) c.collect(sp.tez(40)).run(sender = owner.address, valid = False) c.collect(sp.tez(40)).run(sender = owner.address, valid = False) c.collect(sp.tez(40)).run(sender = owner.address, now = sp.timestamp(100), valid = False) c.collect(sp.tez(40)).run(sender = owner.address, now = sp.timestamp(150))
def test(): scenario=sp.test_scenario() scenario.h1("Normalizes One Data Point") scenario.h2("GIVEN a Normalizer contract.") contract=NormalizerContract() scenario += contract high=1 low=2 close=3 volume=4 assetCode = "XTZ-USD" scenario.h2("WHEN an update is provided") scenario += contract.update( makeMap( assetCode=assetCode, start=sp.timestamp(1595104530), end=sp.timestamp(1595104531), open=3059701, high=high, low=low, close=close, volume=volume ) ).run(sender=defaultOracleContractAddress) scenario.h2("THEN the ComputedPrice is the VWAP.") expected = Harbinger.computeVWAP( high=high, low=low, close=close, volume=volume ) // volume scenario.verify(contract.data.assetMap[assetCode].computedPrice == expected)
def __init__(self, admin): self.add_flag("edo") self.init(owner=admin, current_price=0, reserve_price=0, in_progress=sp.bool(False), start_time=sp.timestamp(0), round_time=0, ticket=sp.none) self.init_type(t=sp.TRecord(owner=sp.TAddress, current_price=sp.TNat, reserve_price=sp.TNat, in_progress=sp.TBool, start_time=sp.TTimestamp, round_time=sp.TInt, ticket=sp.TOption(sp.TTicket(sp.TNat))))
def createMarket(self, params): sp.set_type(params, sp.TRecord(end=sp.TInt, ipfsString=sp.TString)) contractAddress = sp.create_contract(storage=sp.record( admin=sp.pair(self.data.admin, sp.sender), infoIPFS=params.ipfsString, uuid=0, endTime=sp.timestamp(0).add_seconds(params.end), result=sp.none, orders={}, buyLongOrders={}, buyShortOrders={}, sellLongOrders={}, sellShortOrders={}, sharesLong={}, sharesShort={}), contract=self.market) self.data.markets[contractAddress] = sp.sender
def __init__(self, objkt, hdao, manager, metadata, curate): self.fee = 0 self.amount = 0 self.royalties = 0 self.init( swaps = sp.big_map(tkey=sp.TNat, tvalue=sp.TRecord(issuer=sp.TAddress, xtz_per_objkt=sp.TMutez, objkt_id=sp.TNat, objkt_amount=sp.TNat)), royalties = sp.big_map(tkey=sp.TNat, tvalue=sp.TRecord(issuer=sp.TAddress, royalties=sp.TNat)), swap_id = 0, objkt_id = 152, objkt = objkt, hdao = hdao, manager = manager, metadata = metadata, genesis = sp.timestamp(0), curate = curate, locked = False )
def completeBetFromOro(self,params): sp.verify(sp.sender==self.data.oracleAddress, message="complete bet can be invoked by oro only") data = self.data.tempCompleteBetData[params.uuid] sp.verify(data.betId + data.betType < params.cycleNumber, message="Bet not yet mature") sp.verify(self.data.betSize.contains(data.betType),message="Invalid bet type") # calculate winner betPool = self.data.betData[data.betType][data.betId] winnerIndex = (betPool.seed + abs(sp.now-sp.timestamp(0))) % sp.len(betPool.senderList) # calculating winner amount self.data.earnedAmount = self.data.betSize[data.betType] * sp.len(betPool.senderList) * self.data.yields[data.betType] / 10000 #disburse Amounts i = sp.local('i',0) amount = self.data.earnedAmount * 10 / 100 self.data.adminBalance += sp.mutez(amount) sp.for x in betPool.senderList: sp.if i.value==winnerIndex: amount = self.data.earnedAmount * 90 / 100 + self.data.betSize[data.betType] sp.send(x,sp.mutez(amount))
def test(): scenario = sp.test_scenario() #Test accounts admin1 = sp.test_account('Admin-1') admin2 = sp.test_account('Admin-2') alice = sp.test_account("Alice") bob = sp.test_account("Bob") mike = sp.test_account("Mike") john = sp.test_account("John") c = Market() c.set_storage(sp.record( admin = sp.pair(admin1.address, admin2.address), infoIPFS = "IPFSxyz", uuid = 0, endTime = sp.timestamp(1000000), result = sp.none, orders = {}, buyLongOrders = {}, buyShortOrders = {}, sellLongOrders = {}, sellShortOrders = {}, sharesLong = {}, sharesShort = {} )) scenario += c scenario.register(c.buyLong(quantity = 10, price = 700000).run(sender = alice, amount = sp.mutez(700000))) scenario.register(c.buyShort(quantity = 10, price = 300000).run(sender = bob, amount = sp.mutez(300000))) scenario.register(c.buyShort(quantity = 10, price = 400000).run(sender = mike, amount = sp.mutez(400000))) scenario.register(c.buyLong(quantity = 10, price = 600000).run(sender = john, amount = sp.mutez(600000))) scenario.h2('Sell Long') scenario += c.sellLong(quantity = 10, price_buy = 700000, price_sell = 700000).run(sender = alice) scenario.h2('Sell Short') scenario += c.sellShort(quantity = 10, price_buy = 400000, price_sell = 300000).run(sender = mike) scenario += c.sellShort(quantity = 10, price_buy = 300000, price_sell = 500000).run(sender = bob) scenario.h2('Withdraw') scenario += c.withdrawSellOrder(id = 4).run(sender = bob)
def test(): scenario = sp.test_scenario() contract = Proposal() scenario += contract scenario.h3("Definie Proposal Parameters") scenario += contract.origin_entry(time_out=sp.timestamp(1596067200), proposal="PELA CRIACAO DO PARQUE DO BIXIGA: APOIO A APROVACAO E IMEDIATA SANCAO DO PROJETO DE LEI 805/2017", ocasion="Teatro Oficina Uzyna Uzona").run(sender=sp.address("tz1")) # complemento? scenario.h3("Join parties") scenario += contract.parties_join().run(sender=sp.address('tz2')) scenario += contract.parties_join().run(sender=sp.address('tz3')) scenario.h3("Vote") scenario += contract.vote(vote="Y").run(sender=sp.address('tz2')) scenario += contract.vote(vote="N").run(sender=sp.address('tz3'))