def merchDispute(self, params): sp.verify(self.data.merchAddr == sp.sender) sp.verify(self.data.status == CUST_CLOSE) sp.verify(self.data.revLock == sp.sha256(params.secret)) sp.send(self.data.merchAddr, self.data.custBal) self.data.custBal = sp.tez(0) self.data.status = CLOSED
def test(): c = myContract() secret = sp.string('My secret message') password = sp.string('avada_kedavra') packed = sp.pack(secret) + sp.pack(password) hashed = sp.sha256(packed) scenario = sp.test_scenario() scenario.register(c, show=True) # same as scenario += c c.store_hash(hashed)
def revealBid(self, params): sp.verify(self.data.started) sp.verify(~self.data.ended) # verify now is more than round end time = start_time + round_time but # less than start time + twice of round time sp.verify(sp.now > self.data.start_time.add_seconds(self.data.round_time)) sp.verify(sp.now < self.data.start_time.add_seconds(2 * self.data.round_time)) # bidder sends amt committed previusly minus amt locked as participation fee # if this doesn't match, possibly penalise the participant by seizing his deposit sp.verify(sp.mutez(params.value + self.data.deposit) == sp.amount) sp.verify(sp.sha256(sp.pack(params.value + self.data.deposit)) == self.data.sealed_bids[sp.sender]) sp.if ~self.data.first_revealed: self.data.first_revealed = sp.bool(True)
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 isRedeemable(self, _hashedSecret, _secret): sp.verify(self.data.swaps[_hashedSecret].refundTimestamp > sp.now) sp.verify(self.data.swaps[_hashedSecret].hashedSecret == sp.sha256( sp.sha256(_secret)))
def test(): alice = sp.test_account("Alice") bob = sp.test_account("Bob") init_eth = "0x91f79893E7B923410Ef1aEba6a67c6fab0sfsdgffd" hashSecret = sp.sha256( sp.sha256( sp.bytes( "0x68656c6c6f666473667364666c64736a666c73646a6664736a6673646a6b666a" ))) c1 = AtomicSwap(_admin=bob.address) scenario = sp.test_scenario() scenario.table_of_contents() scenario.h1("Atomic Swap") scenario += c1 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)).run( sender=alice, amount=sp.tez(2), 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=bob) # initiate new swap scenario += c1.initiateWait(_hashedSecret=hashSecret, initiator_eth_addr=init_eth, _refundTimestamp=sp.timestamp(159682500)).run( sender=alice, amount=sp.tez(2), now=sp.timestamp(159682400)) # balance check scenario.verify(c1.balance == sp.tez(2)) # 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)).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(c1.balance == sp.tez(0)) # successful swap creation with same hash after redeem scenario += c1.initiateWait(_hashedSecret=hashSecret, initiator_eth_addr=init_eth, _refundTimestamp=sp.timestamp(159682500)).run( sender=alice, amount=sp.tez(2), now=sp.timestamp(159682400)) # balance check scenario.verify(c1.balance == sp.tez(2)) # 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(c1.balance == sp.tez(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 = FA12.FA12(admin.address, config = FA12.FA12_config(support_upgradable_metadata = True), token_metadata = token_metadata, contract_metadata = contract_metadata) c1 = TokenSwap(_admin=admin.address, _fa12=c2.address) scenario = sp.test_scenario() scenario.table_of_contents() scenario.h1("Atomic Swap") scenario += c1 scenario.h2("Accounts") scenario.show([admin, alice, bob]) scenario.h2("FA1.2") scenario.h3("Entry points") scenario += c2 scenario.h3("Admin mints a few coins") scenario += c2.mint(address=alice.address, value=12).run(sender=admin) scenario += c2.mint(address=alice.address, value=3).run(sender=admin) scenario += c2.mint(address=alice.address, value=3).run(sender=admin) scenario.h2("Alice approves Contract") scenario += c2.approve(spender=c1.address, value=10).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.balances[c1.address].balance == sp.nat(5)) scenario.verify(c2.data.balances[alice.address].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.balances[c1.address].balance == sp.nat(0)) scenario.verify(c2.data.balances[bob.address].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.balances[c1.address].balance == sp.nat(5)) scenario.verify(c2.data.balances[alice.address].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.balances[c1.address].balance == sp.nat(0)) scenario.verify(c2.data.balances[alice.address].balance == sp.nat(13))
def store_hash(self, message): self.data.hashed_secret = sp.some(sp.sha256(message))
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(): 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" ))) c2 = FA12.FA12(admin.address) c1 = TokenSwap(_admin=admin.address, _fa12=c2.address) scenario = sp.test_scenario() scenario.table_of_contents() scenario.h1("Atomic Swap") scenario += c1 scenario.h2("Accounts") scenario.show([admin, alice, bob]) scenario.h2("FA1.2") scenario.h3("Entry points") scenario += c2 scenario.h3("Admin mints a few coins") scenario += c2.mint(address=alice.address, value=12).run(sender=admin) scenario += c2.mint(address=alice.address, value=3).run(sender=admin) scenario += c2.mint(address=alice.address, value=3).run(sender=admin) scenario.h2("Alice approves Contract") scenario += c2.approve(spender=c1.address, value=10).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.balances[c1.address].balance == sp.nat(5)) scenario.verify(c2.data.balances[alice.address].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.balances[c1.address].balance == sp.nat(0)) scenario.verify(c2.data.balances[bob.address].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.balances[c1.address].balance == sp.nat(5)) scenario.verify(c2.data.balances[alice.address].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.balances[c1.address].balance == sp.nat(0)) scenario.verify(c2.data.balances[alice.address].balance == sp.nat(13))