Exemple #1
0
 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
Exemple #2
0
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)
Exemple #3
0
 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))
Exemple #8
0
 def store_hash(self, message):
     self.data.hashed_secret = sp.some(sp.sha256(message))
Exemple #9
0
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()
Exemple #10
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"
            )))

    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))