def test(): scenario = sp.test_scenario() rightful_owner = sp.test_account("Alice") attacker = sp.test_account("Robert") c1 = TestCheckSignature(rightful_owner.public_key) scenario += c1 # Let's build a successful call: # scenario.h2("Successful Call") first_message_packed = sp.pack( sp.record(o="Hello World", n="should work", c=0)) sig_from_alice = sp.make_signature(secret_key=rightful_owner.secret_key, message=first_message_packed, message_format="Raw") scenario += c1.setCurrentValue( newValue="should work", userSignature=sig_from_alice).run(valid=True) # scenario.h2("Replay Attack") scenario.p( "Trying to reuse the same signature is blocked by the value of the counter." ) scenario += c1.setCurrentValue( newValue="should work", userSignature=sig_from_alice).run(valid=False) # # scenario.h2("Signature From Wrong Secret Key") scenario.p("Signing the right thing from a different secret-key.") # # # Gives: second_message_packed = sp.pack( sp.record(o="should work", n="Hello again World", c=1)) sig_from_bob = sp.make_signature(secret_key=attacker.secret_key, message=second_message_packed, message_format="Raw") scenario += c1.setCurrentValue(newValue="Hello again World", userSignature=sig_from_bob).run(valid=False) # scenario.h2("Second Successful Call") scenario.p( "Showing that the previous call failed <b>because</b> of the secret-key (signing same bytes)." ) sig_from_alice = sp.make_signature(secret_key=rightful_owner.secret_key, message=second_message_packed, message_format="Raw") scenario += c1.setCurrentValue( newValue="Hello again World", userSignature=sig_from_alice).run(valid=True)
def bobSignsState(): scenario.p("Bob signs the current state.") result = sp.make_signature(bob.secret_key, sp.pack( sp.record(id=c1.data.id, name="state", seq=cBob.data.seq, state=cBob.data.baseState))) result = scenario.compute(result) scenario.show(sp.record(seq=cBob.data.seq, sig=result)) return result
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(): c = myContract() alice = sp.test_account('Alice') scenario = sp.test_scenario() scenario += c scenario.show(alice) c.new_user().run(sender = alice.address) c.new_user().run(sender = alice.address, valid = False) secret = 'This is my secret.' message = sp.sha256(sp.sha256(sp.pack(secret))) sig = sp.make_signature(alice.secret_key, message, message_format = 'Raw') scenario.show(sig) check = sp.check_signature(alice.public_key, sig, message) scenario.show(check) c.add_record(message = message, sig = sig).run(sender = alice.address) c.add_record(message = message, sig = sig).run(sender = alice.address, valid = False) bob = sp.test_account('Bob') secret = '[{a:b, c:d},{e:f}]' message = sp.sha256(sp.sha256(sp.pack(secret))) sig = sp.make_signature(bob.secret_key, message, message_format = 'Raw') c.add_record(message = message, sig = sig).run(sender = bob.address, valid = False) c.new_user().run(sender = bob.address) c.add_record(message = message, sig = sig).run(sender = bob.address) bob = sp.test_account('Bob') # an alternative follows that combines the secret with the public key hash secret = sp.pack('This is my secret.') + sp.pack(bob.public_key_hash) message = sp.sha256(sp.sha256(secret)) sig = sp.make_signature(bob.secret_key, message, message_format = 'Raw') c.add_record(message = message, sig = sig).run(sender = bob.address)
def test(): scenario = sp.test_scenario() scenario.h1("Quote Updation SC with on-chain sig verification") first_owner = sp.test_account("Aniket") second_owner = sp.test_account("Sachin") # Let's display the accounts: scenario.h2("Accounts") scenario.show([first_owner, second_owner]) c1 = QuoteDapp(first_owner.public_key) scenario += c1 # Successful call: scenario.h2("Successful Call") scenario.p( "when the second owner is the signer and the pkh provided is also of the second_owner" ) first_message_packed = sp.pack( sp.record(o=second_owner.public_key, n="should work", c=0)) sig_from_sachin = sp.make_signature(secret_key=second_owner.secret_key, message=first_message_packed, message_format="Raw") scenario += c1.changeQuote( newQuote="should work", userSignature=sig_from_sachin, newOwner=second_owner.public_key).run(valid=True) scenario.h2("Replay Attack") scenario.p( "Trying to reuse the same signature is blocked by the value of the nonce." ) scenario += c1.changeQuote( newQuote="seems like a replay attack", userSignature=sig_from_sachin, newOwner=second_owner.public_key).run(valid=False) scenario.h2("Un-successful Call") scenario.p( "when the second owner is the signer and the pkh provided is also of the first_owner, then in this case the call should fail" ) scenario += c1.changeQuote( newQuote="should not work", userSignature=sig_from_sachin, newOwner=first_owner.public_key).run(valid=False)
def test(): scenario = sp.test_scenario() scenario.h1("Incorrect Revoke Fails to Revoke An Oracle") scenario.h2( "GIVEN an oracle contract and a revoke message signed by another account.") testAccount = sp.test_account("Incorrect_Account") message = sp.pack(sp.none) signature = sp.make_signature( testAccount.secret_key, message, message_format='Raw' ) assetCode = "XTZ-USD" contract = OracleContract( publicKey=testAccountPublicKey, initialData=sp.big_map( l={ assetCode: initialOracleData }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ) scenario += contract scenario.h2("WHEN revoke is called") scenario.h2("THEN the call fails") scenario += contract.revoke(signature).run(valid=False) scenario.h2("AND future updates succeed") 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((assetCode, updateData)) signature = sp.make_signature( testAccountSecretKey, message, message_format='Raw' ) update = sp.pair(signature, updateData) parameter = sp.map( l={ assetCode: update }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter)
def test(): scenario = sp.test_scenario() scenario.h1("Revokes An Oracle") scenario.h2( "GIVEN an oracle contract and a correctly signed revoke message.") message = sp.pack(sp.none) signature = sp.make_signature( testAccountSecretKey, message, message_format='Raw' ) assetCode = "XTZ-USD" contract = OracleContract( publicKey=testAccountPublicKey, initialData=sp.big_map( l={ assetCode: initialOracleData }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ) scenario += contract scenario.h2("WHEN revoke is called.") scenario += contract.revoke(signature) scenario.h2("THEN the oracle is revoked") scenario.verify(~contract.data.publicKey.is_some()) scenario.h2("AND the oracle's data no longer contains the original asset") scenario.verify(~contract.data.oracleData.contains(assetCode)) scenario.h2("AND future updates fail.") 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((assetCode, updateData)) signature = sp.make_signature( testAccountSecretKey, message, message_format='Raw' ) update = sp.pair(signature, updateData) parameter = sp.map( l={ assetCode: update }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter).run(valid=False)
def test(): scenario = sp.test_scenario() scenario.h1("Untracked Asset does not update oracle") scenario.h2("GIVEN an Oracle contract tracking an asset") assetCode = "XTZ-USD" contract = OracleContract( publicKey=testAccountPublicKey, initialData=sp.big_map( l={ assetCode: initialOracleData }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ) scenario += contract start1 = sp.timestamp(2) end1 = sp.timestamp(3) open1 = 3 high1 = 4 low1 = 5 close1 = 6 volume1 = 7 updateData1 = ( start1, (end1, (open1, (high1, (low1, (close1, volume1)))))) message1 = sp.pack((assetCode, updateData1)) signature1 = sp.make_signature( testAccountSecretKey, message1, message_format='Raw' ) update1 = sp.pair(signature1, updateData1) parameter1 = sp.map( l={ assetCode: update1 }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter1) scenario.h2("WHEN the oracle is updated with an untracked asset") untrackedAsset = "BTC-USD" start2 = sp.timestamp(4) end2 = sp.timestamp(5) open2 = 8 high2 = 9 low2 = 10 close2 = 11 volume2 = 12 updateData2 = ( start2, (end2, (open2, (high2, (low2, (close2, volume2)))))) message2 = sp.pack((untrackedAsset, updateData2)) signature2 = sp.make_signature( testAccountSecretKey, message2, message_format='Raw' ) update2 = sp.pair(signature2, updateData2) parameter2 = sp.map( l={ untrackedAsset: update2 }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter2) scenario.h2("THEN the oracle only contains the data for the tracked asset.") assetData = contract.data.oracleData[assetCode] endPair = sp.snd(assetData) openPair = sp.snd(endPair) highPair = sp.snd(openPair) lowPair = sp.snd(highPair) closeAndVolumePair = sp.snd(lowPair) oracleStart = sp.fst(assetData) oracleEnd = sp.fst(endPair) oracleOpen = sp.fst(openPair) oracleHigh = sp.fst(highPair) oracleLow = sp.fst(lowPair) oracleClose = sp.fst(closeAndVolumePair) oracleVolume = sp.snd(closeAndVolumePair) scenario.verify(oracleStart == start1) scenario.verify(oracleEnd == end1) scenario.verify(oracleOpen == open1) scenario.verify(oracleHigh == high1) scenario.verify(oracleLow == low1) scenario.verify(oracleClose == close1) scenario.verify(oracleVolume == volume1) scenario.h2("AND does not contain data for the untracked asset") scenario.verify(~contract.data.oracleData.contains(untrackedAsset))
def test(): scenario = sp.test_scenario() scenario.h1("Correctly Processes Updates With Data From The Past") scenario.h2("GIVEN an Oracle contract with some initial data.") assetCode = "XTZ-USD" contract = OracleContract( publicKey=testAccountPublicKey, initialData=sp.big_map( l={ assetCode: initialOracleData }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ) scenario += contract start1 = sp.timestamp(3) end1 = sp.timestamp(4) open1 = 3 high1 = 4 low1 = 5 close1 = 6 volume1 = 7 updateData1 = ( start1, (end1, (open1, (high1, (low1, (close1, volume1)))))) message1 = sp.pack((assetCode, updateData1)) signature1 = sp.make_signature( testAccountSecretKey, message1, message_format='Raw' ) update1 = sp.pair(signature1, updateData1) parameter1 = sp.map( l={ assetCode: update1 }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter1) scenario.h2("WHEN the oracle is updated with a time in the past") start2 = sp.timestamp(1) # In past end2 = sp.timestamp(2) open2 = 8 high2 = 9 low2 = 10 close2 = 11 volume2 = 12 updateData2 = ( start2, (end2, (open2, (high2, (low2, (close2, volume2)))))) message2 = sp.pack(updateData2) signature2 = sp.make_signature( testAccountSecretKey, message2, message_format='Raw' ) update2 = sp.pair(signature2, updateData2) parameter2 = sp.map( l={ assetCode: update2 }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter2) scenario.h2("THEN the update in the past does not modify the data.") assetData = contract.data.oracleData[assetCode] endPair = sp.snd(assetData) openPair = sp.snd(endPair) highPair = sp.snd(openPair) lowPair = sp.snd(highPair) closeAndVolumePair = sp.snd(lowPair) oracleStart = sp.fst(assetData) oracleEnd = sp.fst(endPair) oracleOpen = sp.fst(openPair) oracleHigh = sp.fst(highPair) oracleLow = sp.fst(lowPair) oracleClose = sp.fst(closeAndVolumePair) oracleVolume = sp.snd(closeAndVolumePair) scenario.verify(oracleStart == start1) scenario.verify(oracleEnd == end1) scenario.verify(oracleOpen == open1) scenario.verify(oracleHigh == high1) scenario.verify(oracleLow == low1) scenario.verify(oracleClose == close1) scenario.verify(oracleVolume == volume1)
def test(): scenario = sp.test_scenario() scenario.h1("Second Update Overwrites First Update") 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 two updates") start1 = sp.timestamp(1) end1 = sp.timestamp(2) open1 = 3 high1 = 4 low1 = 5 close1 = 6 volume1 = 7 updateData1 = ( start1, (end1, (open1, (high1, (low1, (close1, volume1)))))) message1 = sp.pack((assetCode, updateData1)) signature1 = sp.make_signature( testAccountSecretKey, message1, message_format='Raw' ) start2 = sp.timestamp(8) end2 = sp.timestamp(9) open2 = 10 high2 = 11 low2 = 12 close2 = 13 volume2 = 14 updateData2 = ( start2, (end2, (open2, (high2, (low2, (close2, volume2)))))) message2 = sp.pack((assetCode, updateData2)) signature2 = sp.make_signature( testAccountSecretKey, message2, message_format='Raw' ) scenario.h2("WHEN the oracle is updated") update1 = sp.pair(signature1, updateData1) update2 = sp.pair(signature2, updateData2) parameter1 = sp.map( l={ assetCode: update1 }, tkey=sp.TString, tvalue=SignedOracleDataType ) parameter2 = sp.map( l={ assetCode: update2 }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter1) scenario += contract.update(parameter2) scenario.h2("THEN the oracle contains the data points of the latter update") assetData = contract.data.oracleData[assetCode] endPair = sp.snd(assetData) openPair = sp.snd(endPair) highPair = sp.snd(openPair) lowPair = sp.snd(highPair) closeAndVolumePair = sp.snd(lowPair) oracleStart = sp.fst(assetData) oracleEnd = sp.fst(endPair) oracleOpen = sp.fst(openPair) oracleHigh = sp.fst(highPair) oracleLow = sp.fst(lowPair) oracleClose = sp.fst(closeAndVolumePair) oracleVolume = sp.snd(closeAndVolumePair) scenario.verify(oracleStart == start2) scenario.verify(oracleEnd == end2) scenario.verify(oracleOpen == open2) scenario.verify(oracleHigh == high2) scenario.verify(oracleLow == low2) scenario.verify(oracleClose == close2) scenario.verify(oracleVolume == volume2)
def test(): scenario = sp.test_scenario() scenario.h1("Onchain view returns correct data") scenario.h2("GIVEN an Oracle contract") contract = OracleContract( publicKey=testAccountPublicKey, ) scenario += contract scenario.h2("AND an update") assetCode = "XTZ-USD" 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((assetCode, updateData)) signature = sp.make_signature( testAccountSecretKey, message, message_format='Raw' ) scenario.h2("AND the oracle is updated") update = sp.pair(signature, updateData) parameter = sp.map( l={ assetCode: update }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter) scenario.h2("WHEN data is read from an onchain view") scenario.h2("THEN the data matches the latest update") scenario.verify(sp.fst(contract.getPrice(assetCode)) == start) scenario.verify(sp.fst(sp.snd(contract.getPrice(assetCode))) == end) scenario.verify(sp.fst(sp.snd(sp.snd(contract.getPrice(assetCode)))) == open) scenario.verify(sp.fst(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode))))) == high) scenario.verify(sp.fst(sp.snd(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode)))))) == low) scenario.verify(sp.fst(sp.snd(sp.snd(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode))))))) == close) scenario.verify(sp.snd(sp.snd(sp.snd(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode))))))) == volume)
def test(): chain_id=sp.chain_id_cst("0x9caecab9") scenario = sp.test_scenario() scenario.h1("Generic Multi Signature Executor") 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]) admin = sp.test_account("Administrator") # We have not found a way to pack for signature lambdas in smartpy directly # Hence we are using the tezos-client for helping out # The following payload assumes chain id 0x7a06a770, nonce 1, and a lambda hitting the honey pot at address tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz # tezos-client -S -P 443 -A delphinet-tezos.giganode.io hash data 'Pair 0x7a06a770 (Pair 1 { DROP; NIL operation; PUSH address "tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz"; CONTRACT unit; IF_SOME {} { UNIT; FAILWITH }; PUSH mutez 0; UNIT; TRANSFER_TOKENS; CONS })' of type 'pair (chain_id) (pair (nat) (lambda unit (list operation)))' # Raw packed data: 0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b honey_pot = HoneyPot() honey_pot.address = sp.address("tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz") executor = Executor(sp.nat(2), [sp.key("edpkumVGEtDQgDAcMyB5FRn7UBLuhzg6D7aEnCDamXgjqGxavnsgvP"), sp.key("edpkv6MFhAVnpAhrvMjdW1tGfLDDiU6i6P9kt3ZmyiiMpxCsB5Cg4v"), sp.key("edpktwdcwT8iMDWcg2ePJ6J1sbwXYdn7GYJWyRybi8vpkrv4aduFHt")]) scenario += executor scenario += honey_pot def execution_payload(x): sp.set_type(x, sp.TUnit) honey_pot_contract = sp.contract(sp.TUnit, honey_pot.address).open_some() sp.result([sp.transfer_operation(sp.unit, sp.mutez(0), honey_pot_contract)]) #lambda_packer = LambdaPacker(honey_pot.address) #scenario += lambda_packer #scenario += lambda_packer.pack_signing_payload() #execution_payload_pack = sp.pack(execution_payload) #scenario.show(execution_payload_pack) #signing_payload = ExecutionRequest.get_signing_payload(chain_id, sp.nat(1), execution_payload) alice_signature = sp.make_signature(alice.secret_key, sp.bytes("0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b")) bob_signature = sp.make_signature(bob.secret_key, sp.bytes("0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b")) dan_signature = sp.make_signature(dan.secret_key, sp.bytes("0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b")) signatures= sp.map({sp.hash_key(bob.public_key):bob_signature, sp.hash_key(alice.public_key): alice_signature, sp.hash_key(dan.public_key):dan_signature}) execution_request = sp.set_type_expr(sp.record(execution_payload=execution_payload, signatures=signatures),ExecutionRequest.get_type()) scenario.show(signatures) executor = TimeLockedExecutor(sp.nat(2), [alice.public_key, bob.public_key, dan.public_key], sp.nat(60)) scenario += executor signatures= sp.map({sp.hash_key(bob.public_key):bob_signature, sp.hash_key(alice.public_key): alice_signature, sp.hash_key(dan.public_key):dan_signature}) execution_request = sp.set_type_expr(sp.record(execution_payload=execution_payload, signatures=signatures),ExecutionRequest.get_type()) #scenario += executor.update_signatories() #scenario += executor.execute(execution_request).run(sender=admin, chain_id=sp.chain_id_cst("0x7a06a770")) #scenario += executor.default(test2).run(sender=admin) #scenario += honey_pot
def test(): scenario = sp.test_scenario() scenario.table_of_contents() scenario.h1("zkChannels") aliceCust = sp.test_account("Alice") bobMerch = sp.test_account("Bob") scenario.h2("Parties") scenario.p("We start with two accounts Alice (customer) and Bob (merchant):") scenario.show([aliceCust, bobMerch]) # Set zkChannel parameters chanID = sp.bls12_381_fr(CHAN_ID_FR) custAddr = aliceCust.address merchAddr = bobMerch.address revLock = sp.sha256(sp.bytes("0x12345678aabb")) # selfDelay = 60*60*24 # seconds in one day - 86,400 selfDelay = 3 # seconds in one day - 86,400 scenario.h2("On-chain installment") custFunding = sp.tez(20) merchFunding = sp.tez(10) g2 = sp.bls12_381_g2(PUB_GEN_G2) merchPk0 = sp.bls12_381_g2(MERCH_PK0_G2) merchPk1 = sp.bls12_381_g2(MERCH_PK1_G2) merchPk2 = sp.bls12_381_g2(MERCH_PK2_G2) merchPk3 = sp.bls12_381_g2(MERCH_PK3_G2) merchPk4 = sp.bls12_381_g2(MERCH_PK4_G2) scenario.h2("Scenario 1: escrow -> merchClose -> merchClaim") scenario.h3("escrow") c1 = ZkChannel(chanID, aliceCust.address, bobMerch.address, aliceCust.public_key, bobMerch.public_key, custFunding, merchFunding, selfDelay, revLock, g2, merchPk0, merchPk1, merchPk2, merchPk3, merchPk4) scenario += c1 scenario.h3("Funding the channel") scenario += c1.addFunding().run(sender = aliceCust, amount = custFunding) scenario += c1.addFunding().run(sender = bobMerch, amount = merchFunding) scenario.h3("merchClose") scenario += c1.merchClose().run(sender = bobMerch) scenario.h3("unsuccessful merchClaim before delay period") scenario += c1.merchClaim().run(sender = bobMerch, now = sp.timestamp(1), valid = False) scenario.h3("successful merchClaim after delay period") scenario += c1.merchClaim().run(sender = bobMerch, now = sp.timestamp(100000)) scenario.h2("Scenario 2: escrow -> custClose -> custClaim") scenario.h3("escrow") c2 = ZkChannel(chanID, aliceCust.address, bobMerch.address, aliceCust.public_key, bobMerch.public_key, custFunding, merchFunding, selfDelay, revLock, g2, merchPk0, merchPk1, merchPk2, merchPk3, merchPk4) scenario += c2 scenario.h3("Funding the channel") scenario += c2.addFunding().run(sender = aliceCust, amount = custFunding) scenario += c2.addFunding().run(sender = bobMerch, amount = merchFunding) scenario.p("Now the customer and merchant make a payment off chain.") scenario.p("For the payment to be considered complete, the customer should have received a signature from the merchant reflecting the final balances, and the merchant should have received the secret corresponding to the previous state's revLock.") scenario.h3("custClose") custBal = sp.tez(18) merchBal = sp.tez(12) revLock2 = sp.bytes(REV_LOCK_FR) scenario += c2.custClose( revLock = revLock2, custBal = custBal, merchBal = merchBal, s1 = sp.bls12_381_g1(SIG_S1_G1), s2 = sp.bls12_381_g1(SIG_S2_G1), g2 = sp.bls12_381_g2(PUB_GEN_G2) ).run(sender = aliceCust) scenario.h3("unsuccessful custClaim attempt before delay period") scenario += c2.custClaim().run(sender = aliceCust, now = sp.timestamp(1), valid = False) scenario.h3("successful custClaim after delay period") scenario += c2.custClaim().run(sender = aliceCust, now = sp.timestamp(100000)) scenario.h2("Scenario 3: escrow -> custClose -> merchDispute") scenario.h3("escrow") c3 = ZkChannel(chanID, aliceCust.address, bobMerch.address, aliceCust.public_key, bobMerch.public_key, custFunding, merchFunding, selfDelay, revLock, g2, merchPk0, merchPk1, merchPk2, merchPk3, merchPk4) scenario += c3 scenario.h3("Funding the channel") scenario += c3.addFunding().run(sender = aliceCust, amount = custFunding) scenario += c3.addFunding().run(sender = bobMerch, amount = merchFunding) scenario.h3("custClose") revLock2 = sp.bytes(REV_LOCK_FR) # sp.sha256(sp.bytes("0x12345678aacc")) scenario += c3.custClose( revLock = revLock2, custBal = custBal, merchBal = merchBal, s1 = sp.bls12_381_g1(SIG_S1_G1), s2 = sp.bls12_381_g1(SIG_S2_G1), g2 = sp.bls12_381_g2(PUB_GEN_G2), merchPk0 = sp.bls12_381_g2(MERCH_PK0_G2), merchPk1 = sp.bls12_381_g2(MERCH_PK1_G2), merchPk2 = sp.bls12_381_g2(MERCH_PK2_G2), merchPk3 = sp.bls12_381_g2(MERCH_PK3_G2), merchPk4 = sp.bls12_381_g2(MERCH_PK4_G2) ).run(sender = aliceCust) scenario.h3("merchDispute called with correct secret") # scenario += c3.merchDispute(secret = sp.bytes("0x12345678aacc")).run(sender = bobMerch, now = sp.timestamp(10)) scenario.h2("Scenario 4: escrow -> merchClose -> custClose") scenario.h3("escrow") c4 = ZkChannel(chanID, aliceCust.address, bobMerch.address, aliceCust.public_key, bobMerch.public_key, custFunding, merchFunding, selfDelay, revLock, g2, merchPk0, merchPk1, merchPk2, merchPk3, merchPk4) scenario += c4 scenario.h3("Funding the channel") scenario += c4.addFunding().run(sender = aliceCust, amount = custFunding) scenario += c4.addFunding().run(sender = bobMerch, amount = merchFunding) scenario.h3("merchClose") scenario += c4.merchClose().run(sender = bobMerch) scenario.h3("custClose") revLock3 = sp.sha256(sp.bytes("0x12345678aacc")) scenario += c4.custClose( revLock = revLock2, custBal = custBal, merchBal = merchBal, s1 = sp.bls12_381_g1(SIG_S1_G1), s2 = sp.bls12_381_g1(SIG_S2_G1), g2 = sp.bls12_381_g2(PUB_GEN_G2), merchPk0 = sp.bls12_381_g2(MERCH_PK0_G2), merchPk1 = sp.bls12_381_g2(MERCH_PK1_G2), merchPk2 = sp.bls12_381_g2(MERCH_PK2_G2), merchPk3 = sp.bls12_381_g2(MERCH_PK3_G2), merchPk4 = sp.bls12_381_g2(MERCH_PK4_G2) ).run(sender = aliceCust) scenario.h2("Scenario 5: escrow -> mutualClose") scenario.h3("escrow") c5 = ZkChannel(chanID, aliceCust.address, bobMerch.address, aliceCust.public_key, bobMerch.public_key, custFunding, merchFunding, selfDelay, revLock, g2, merchPk0, merchPk1, merchPk2, merchPk3, merchPk4) scenario += c5 scenario.h3("Funding the channel") scenario += c5.addFunding().run(sender = aliceCust, amount = custFunding) scenario += c5.addFunding().run(sender = bobMerch, amount = merchFunding) # Customer's signature on the latest state custSig = sp.make_signature(aliceCust.secret_key, sp.pack(sp.record(chanID = chanID, custAddr = custAddr, merchAddr = merchAddr, custBal = custBal, merchBal = merchBal))) # Merchant's signature on the latest state merchSig = sp.make_signature(bobMerch.secret_key, sp.pack(sp.record(chanID = chanID, custAddr = custAddr, merchAddr = merchAddr, custBal = custBal, merchBal = merchBal))) scenario.h3("mutualClose") scenario += c5.mutualClose(custBal = custBal, merchBal = merchBal, custSig = custSig, merchSig = merchSig).run(sender = aliceCust) scenario.h2("Scenario 6: escrow -> addCustFunding -> reclaimCustFunding") scenario.h3("escrow") c6 = ZkChannel(chanID, aliceCust.address, bobMerch.address, aliceCust.public_key, bobMerch.public_key, custFunding, merchFunding, selfDelay, revLock, g2, merchPk0, merchPk1, merchPk2, merchPk3, merchPk4) scenario += c6 scenario.h3("Customer Funding their side of the channel") scenario += c6.addFunding().run(sender = aliceCust, amount = custFunding) scenario.h3("Customer pulling out their side of the channel (before merchant funds their side)") scenario += c6.reclaimFunding().run(sender = aliceCust) scenario.table_of_contents()
def test(): scenario = sp.test_scenario() scenario.h1("eCoupon - Multi-asset contracts") 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") dan = sp.test_account("Dan") # Let's display the accounts: scenario.h2("Accounts") scenario.show([admin, alice, bob]) c1 = ECouponMultiToken(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, decimals=0, name="WETZ").run(sender=admin) scenario.h2("Meta Transacting") transaction1 = sp.record( to_=bob.address, token_id=0, amount=10) transaction2 = sp.record( to_=dan.address, token_id=0, amount=5) unsigned_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=1, txs=[transaction1, transaction2] ) payload = sp.pack( BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer)) signature = sp.make_signature(alice.secret_key, payload) signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=1, signature=signature, txs=[transaction1, transaction2] ) # scenario.show(sp.unpack(sp.pack(sp.hash_key(alice.public_key))),html=False) scenario.p("perform first metatransfer (with nonce 1)") scenario += c1.meta_transfer([signed_meta_transfer]).run(sender=admin) scenario.p("replay attack: same message with nonce 1") scenario += c1.meta_transfer([signed_meta_transfer] ).run(sender=admin, valid=False) transaction2 = sp.record( to_=dan.address, token_id=0, amount=6) unsigned_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=1, txs=[transaction1, transaction2] ) payload = sp.pack( BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer)) signature = sp.make_signature(alice.secret_key, payload) signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=1, signature=signature, txs=[transaction1, transaction2] ) scenario.p("replay attack: different message with nonce 1") scenario += c1.meta_transfer([signed_meta_transfer] ).run(sender=admin, valid=False) unsigned_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=2, txs=[transaction1, transaction2] ) payload = sp.pack( BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer)) signature = sp.make_signature(alice.secret_key, payload) signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=2, signature=signature, txs=[transaction1, transaction2] ) scenario.p("next nonce transfer") scenario += c1.meta_transfer([signed_meta_transfer]).run(sender=admin) scenario.p("replay attack: lie about nonce (signed 2, saying 3)") signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=3, signature=signature, txs=[transaction1, transaction2] ) scenario += c1.meta_transfer([signed_meta_transfer] ).run(sender=admin, valid=False) scenario.p("replay attack: lie about nonce (signed 2, saying 1)") signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=1, signature=signature, txs=[transaction1, transaction2] ) scenario += c1.meta_transfer([signed_meta_transfer] ).run(sender=admin, valid=False) scenario.p("multi user meta transaction batching") unsigned_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=3, txs=[transaction1, transaction2] ) payload = sp.pack( BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer)) signature = sp.make_signature(alice.secret_key, payload) signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=3, signature=signature, txs=[transaction1, transaction2] ) bob_transaction1 = sp.record( to_=alice.address, token_id=0, amount=1) bob_transaction2 = sp.record( to_=dan.address, token_id=0, amount=1) bob_unsigned_meta_transfer = sp.record( from_public_key=bob.public_key, nonce=1, txs=[bob_transaction1, bob_transaction2] ) payload = sp.pack(BatchMetaTransfer.get_signing_payload( bob_unsigned_meta_transfer)) signature = sp.make_signature(bob.secret_key, payload) bob_signed_meta_transfer = sp.record( from_public_key=bob.public_key, nonce=1, signature=signature, txs=[bob_transaction1, bob_transaction2] ) dan_transaction1 = sp.record( to_=bob.address, token_id=0, amount=1) dan_transaction2 = sp.record( to_=alice.address, token_id=0, amount=1) dan_unsigned_meta_transfer = sp.record( from_public_key=dan.public_key, nonce=1, txs=[dan_transaction1, dan_transaction2] ) payload = sp.pack(BatchMetaTransfer.get_signing_payload( dan_unsigned_meta_transfer)) signature = sp.make_signature(dan.secret_key, payload) dan_signed_meta_transfer = sp.record( from_public_key=dan.public_key, nonce=1, signature=signature, txs=[dan_transaction1, dan_transaction2] ) scenario += c1.meta_transfer([signed_meta_transfer, bob_signed_meta_transfer, dan_signed_meta_transfer]).run(sender=admin) scenario.p("normal user cannot publish meta transaction") unsigned_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=4, txs=[transaction1, transaction2] ) payload = sp.pack( BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer)) signature = sp.make_signature(alice.secret_key, payload) signed_meta_transfer = sp.record( from_public_key=alice.public_key, nonce=4, signature=signature, txs=[transaction1, transaction2] ) scenario += c1.meta_transfer([signed_meta_transfer] ).run(sender=alice, valid=False) scenario.h2("Normal Transfer (FA2)") scenario.p("normal user cannot transfer own funds") scenario += c1.transfer([BatchTransfer.item(from_=alice.address, txs=[ sp.record(to_=bob.address, amount=1, token_id=0)]), BatchTransfer.item(from_=alice.address, txs=[ sp.record(to_=dan.address, amount=1, token_id=0)]) ]).run(sender=alice, valid=False) scenario.p("normal user cannot transfer other's funds") scenario += c1.transfer([BatchTransfer.item(from_=bob.address, txs=[ sp.record(to_=alice.address, amount=1, token_id=0)]), BatchTransfer.item(from_=alice.address, txs=[ sp.record(to_=dan.address, amount=1, token_id=0)]) ]).run(sender=alice, valid=False) scenario.p("admin can transfer everything") scenario += c1.transfer([BatchTransfer.item(from_=bob.address, txs=[ sp.record(to_=alice.address, amount=1, token_id=0)]), BatchTransfer.item(from_=alice.address, txs=[ sp.record(to_=dan.address, amount=1, token_id=0)]) ]).run(sender=admin) scenario.p("only admin can cleanup nonce") scenario += c1.cleanup_nonce([alice.address, bob.address, admin.address]).run(sender=bob, valid=False) scenario.p("correct admin can cleanup nonce") scenario += c1.cleanup_nonce([alice.address, bob.address, admin.address]).run(sender=admin, valid=True) scenario.p("fail direct admin change") scenario += c1.set_administrator( bob.address).run(sender=admin, valid=False) scenario.p("admin change with wrong initial address") scenario += c1.propose_administrator( alice.address).run(sender=admin, valid=True) scenario += c1.set_administrator( bob.address).run(sender=bob, valid=False) scenario.p( "wrong admin change (bob needs to actually change admin, we want to validate he has ability to create txs)") scenario += c1.propose_administrator( bob.address).run(sender=admin, valid=True) scenario += c1.set_administrator( bob.address).run(sender=admin, valid=False) scenario.p("correct admin change") scenario += c1.propose_administrator( bob.address).run(sender=admin, valid=True) scenario += c1.set_administrator( bob.address).run(sender=bob, valid=True)
def test(): scenario = sp.test_scenario() scenario.h1("Update with stale asset does not fail") scenario.h2("GIVEN an Oracle contract tracking two assets with an initial update") assetCode1 = "XTZ-USD" assetCode2 = "BTC-USD" contract = OracleContract( publicKey=testAccountPublicKey, initialData=sp.big_map( l={ assetCode1: initialOracleData, assetCode2: initialOracleData }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ) scenario += contract start1 = sp.timestamp(1) end1 = sp.timestamp(2) open1 = 3 high1 = 4 low1 = 5 close1 = 6 volume1 = 7 updateData1 = ( start1, (end1, (open1, (high1, (low1, (close1, volume1)))))) asset1Message1 = sp.pack((assetCode1, updateData1)) asset1Signature1 = sp.make_signature( testAccountSecretKey, asset1Message1, message_format='Raw' ) asset2Message1 = sp.pack((assetCode2, updateData1)) asset2Signature1 = sp.make_signature( testAccountSecretKey, asset2Message1, message_format='Raw' ) asset1Update1 = sp.pair(asset1Signature1, updateData1) asset2Update1 = sp.pair(asset2Signature1, updateData1) parameter = sp.map( l={ assetCode1: asset1Update1, assetCode2: asset2Update1, }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter) scenario.h2("WHEN an update is posted to the oracle with only one asset containing new data") start2 = sp.timestamp(2) end2 = sp.timestamp(3) open2 = 8 high2 = 9 low2 = 10 close2 = 11 volume2 = 12 updateData2 = ( start2, (end2, (open2, (high2, (low2, (close2, volume2)))))) asset1Message2 = sp.pack((assetCode1, updateData2)) asset1Signature2 = sp.make_signature( testAccountSecretKey, asset1Message2, message_format='Raw' ) asset1Update2 = sp.pair(asset1Signature2, updateData2) parameter = sp.map( l={ assetCode1: asset1Update2, assetCode2: asset2Update1, }, tkey=sp.TString, tvalue=SignedOracleDataType ) scenario += contract.update(parameter) scenario.h2("THEN data for the asset with two updates is the second update.") assetData1 = contract.data.oracleData[assetCode1] endPair1 = sp.snd(assetData1) openPair1 = sp.snd(endPair1) highPair1 = sp.snd(openPair1) lowPair1 = sp.snd(highPair1) closeAndVolumePair1 = sp.snd(lowPair1) oracleStart1 = sp.fst(assetData1) oracleEnd1 = sp.fst(endPair1) oracleOpen1 = sp.fst(openPair1) oracleHigh1 = sp.fst(highPair1) oracleLow1 = sp.fst(lowPair1) oracleClose1 = sp.fst(closeAndVolumePair1) oracleVolume1 = sp.snd(closeAndVolumePair1) scenario.verify(oracleStart1 == start2) scenario.verify(oracleEnd1 == end2) scenario.verify(oracleOpen1 == open2) scenario.verify(oracleHigh1 == high2) scenario.verify(oracleLow1 == low2) scenario.verify(oracleClose1 == close2) scenario.verify(oracleVolume1 == volume2) scenario.h2("THEN data for the asset with two updates is the second update.") assetData2 = contract.data.oracleData[assetCode2] endPair2 = sp.snd(assetData2) openPair2 = sp.snd(endPair2) highPair2 = sp.snd(openPair2) lowPair2 = sp.snd(highPair2) closeAndVolumePair2 = sp.snd(lowPair2) oracleStart2 = sp.fst(assetData2) oracleEnd2 = sp.fst(endPair2) oracleOpen2 = sp.fst(openPair2) oracleHigh2 = sp.fst(highPair2) oracleLow2 = sp.fst(lowPair2) oracleClose2 = sp.fst(closeAndVolumePair2) oracleVolume2 = sp.snd(closeAndVolumePair2) scenario.verify(oracleStart2 == start1) scenario.verify(oracleEnd2 == end1) scenario.verify(oracleOpen2 == open1) scenario.verify(oracleHigh2 == high1) scenario.verify(oracleLow2 == low1) scenario.verify(oracleClose2 == close1) scenario.verify(oracleVolume2 == volume1)
def test(): scenario = sp.test_scenario() scenario.h1("FA1.2 template - Fungible assets") 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") carlos = sp.test_account("Carlos") # Let's display the accounts: scenario.h1("Accounts") scenario.show([admin, alice, bob, carlos]) scenario.h1("Contract") c1 = FA12(admin.address) scenario.h1("Entry points") scenario += c1 scenario.h2("Admin mints a few coins") scenario += c1.mint(address=alice.address, value=12).run(sender=admin) scenario += c1.mint(address=alice.address, value=3).run(sender=admin) scenario += c1.mint(address=alice.address, value=3).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 18) scenario.h2("Alice transfers to Bob") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=alice) scenario.verify(c1.data.balances[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=bob.address, value=5).run(sender=alice) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob) 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(address=bob.address, value=1).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 10) scenario.h2("Alice tries to burn Bob token") scenario += c1.burn(address=bob.address, value=1).run(sender=alice, valid=False) scenario.h2( "Admin pauses the contract and Alice cannot transfer anymore") scenario += c1.setPause(True).run(sender=admin) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=alice, valid=False) scenario.verify(c1.data.balances[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 transfers are allowed") scenario += c1.setPause(False).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 9) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run(sender=alice) scenario.verify(c1.data.totalSupply == 17) scenario.verify(c1.data.balances[alice.address].balance == 8) scenario.verify(c1.data.balances[bob.address].balance == 9) scenario.h2("Permit Submissions") scenario += c1.mint(address=carlos.address, value=10).run(sender=admin) scenario.verify(c1.data.balances[carlos.address].balance == 10) # add permit for transfer of 10 from carlos to bob. alice submits with correct info and also calls. params_bytes_1 = sp.pack( sp.pair(carlos.address, sp.pair(bob.address, 10))) params_bytes_2 = sp.pack( sp.pair(bob.address, sp.pair(carlos.address, 10))) params_hash_1 = sp.blake2b(params_bytes_1) params_hash_2 = sp.blake2b(params_bytes_2) unsigned_1 = sp.pack( sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address), sp.pair(0, params_hash_1))) signature_1 = sp.make_signature(secret_key=carlos.secret_key, message=unsigned_1, message_format="Raw") unsigned_2 = sp.pack( sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address), sp.pair(1, params_hash_2))) signature_2 = sp.make_signature(secret_key=bob.secret_key, message=unsigned_2, message_format="Raw") scenario += c1.permit([ sp.pair(carlos.public_key, sp.pair(signature_1, params_hash_1)), sp.pair(bob.public_key, sp.pair(signature_2, params_hash_2)) ]).run(sender=alice, now=sp.timestamp(1571761674), chain_id=sp.chain_id_cst("0x9caecab9")) scenario.verify(c1.data.counter == 2) scenario.verify_equal( c1.data.permits[(sp.pair(carlos.address, params_hash_1))], sp.timestamp(1571761674)) scenario.verify_equal( c1.data.permits[(sp.pair(bob.address, params_hash_2))], sp.timestamp(1571761674)) scenario.h2("Execute transfer using permit") scenario += c1.transfer(from_=carlos.address, to_=bob.address, value=10).run(sender=bob, now=sp.timestamp(1571761674)) scenario.verify(c1.data.balances[carlos.address].balance == 0) scenario.verify(c1.data.balances[bob.address].balance == 19) # Permit deleted scenario.verify( ~c1.data.permits.contains(sp.pair(carlos.address, params_hash_1))) scenario += c1.transfer(from_=bob.address, to_=carlos.address, value=10).run(sender=carlos, now=sp.timestamp(1571761674)) scenario.verify(c1.data.balances[carlos.address].balance == 10) scenario.verify(c1.data.balances[bob.address].balance == 9) # Permit deleted scenario.verify( ~c1.data.permits.contains(sp.pair(bob.address, params_hash_2))) # Set Expiry to 0 and try to execute transfer at time less than submission_time + default_expiry, expect invalid transfer scenario.h2("Expired Permit") unsigned_3 = sp.pack( sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address), sp.pair(2, params_hash_1))) signature_3 = sp.make_signature(secret_key=carlos.secret_key, message=unsigned_3, message_format="Raw") scenario += c1.permit([ sp.pair(carlos.public_key, sp.pair(signature_3, params_hash_1)) ]).run(sender=alice, now=sp.timestamp(1571761674), chain_id=sp.chain_id_cst("0x9caecab9")) scenario.verify(c1.data.counter == 3) scenario.verify_equal( c1.data.permits[(sp.pair(carlos.address, params_hash_1))], sp.timestamp(1571761674)) scenario += c1.setExpiry(address=carlos.address, seconds=0, permit=sp.some(params_hash_1)).run( sender=carlos, now=sp.timestamp(1571761674)) scenario.verify(c1.data.permit_expiries[sp.pair( carlos.address, params_hash_1)].open_some() == 0) scenario += c1.transfer(from_=carlos.address, to_=bob.address, value=10).run( sender=bob, now=sp.timestamp(1571761680), valid=False) # Uses later time stamp scenario.h2("Delete Expired Permit") scenario += c1.delete_permits([sp.pair(carlos.address, params_hash_1) ]).run(now=sp.timestamp(1571761680)) scenario.verify(~c1.data.permit_expiries.contains( sp.pair(carlos.address, params_hash_1))) scenario.verify( ~c1.data.permits.contains(sp.pair(carlos.address, params_hash_1))) scenario.h1("Views") scenario.h2("Balance") view_balance = Viewer(sp.TNat) scenario += view_balance scenario += c1.getBalance(arg=sp.record(owner=alice.address), target=view_balance.address) scenario.verify_equal(view_balance.data.last, sp.some(8)) scenario.h2("Administrator") view_administrator = Viewer(sp.TAddress) scenario += view_administrator scenario += c1.getAdministrator(target=view_administrator.address) scenario.verify_equal(view_administrator.data.last, sp.some(admin.address)) scenario.h2("Total Supply") view_totalSupply = Viewer(sp.TNat) scenario += view_totalSupply scenario += c1.getTotalSupply(target=view_totalSupply.address) scenario.verify_equal(view_totalSupply.data.last, sp.some(27)) scenario.h2("Allowance") view_allowance = Viewer(sp.TNat) scenario += view_allowance scenario += c1.getAllowance(arg=sp.record(owner=alice.address, spender=bob.address), target=view_allowance.address) scenario.verify_equal(view_allowance.data.last, sp.some(1)) scenario.h2("Counter") view_counter = Viewer(sp.TNat) scenario += view_counter scenario += c1.getCounter(target=view_counter.address) scenario.verify_equal(view_counter.data.last, sp.some(3)) scenario.h2("Default Expiry") view_defaultExpiry = Viewer(sp.TNat) scenario += view_defaultExpiry scenario += c1.getDefaultExpiry(target=view_defaultExpiry.address) scenario.verify_equal(view_defaultExpiry.data.last, sp.some(50000))
def test(): scenario = sp.test_scenario() scenario.h1("Update Once With Valid Data") scenario.h2("GIVEN an Oracle contract") contract = OracleContract( publicKey=testAccountPublicKey, ) scenario += contract scenario.h2("AND an update") assetCode = "XTZ-USD" 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((assetCode, updateData)) signature = sp.make_signature( testAccountSecretKey, 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 += contract.update(parameter) scenario.h2("THEN the oracle contains the data points") assetData = contract.data.oracleData["XTZ-USD"] endPair = sp.snd(assetData) openPair = sp.snd(endPair) highPair = sp.snd(openPair) lowPair = sp.snd(highPair) closeAndVolumePair = sp.snd(lowPair) expectedStart = sp.fst(assetData) expectedEnd = sp.fst(endPair) expectedOpen = sp.fst(openPair) expectedHigh = sp.fst(highPair) expecteLow = sp.fst(lowPair) expectedClose = sp.fst(closeAndVolumePair) expectedVolume = sp.snd(closeAndVolumePair) scenario.verify(start == expectedStart) scenario.verify(end == expectedEnd) scenario.verify(open == expectedOpen) scenario.verify(high == expectedHigh) scenario.verify(low == expecteLow) scenario.verify(close == expectedClose) scenario.verify(volume == expectedVolume)