Beispiel #1
0
    def __init__(self,admin,endCycle,endWithdraw,token,oro):

        self.init(contractBuyer= sp.big_map(),contractSellar = sp.big_map(),
        administrator = admin,buyerSet = sp.set(),poolSet=sp.set(),
           validation=sp.record(cycleEnd=sp.timestamp(endCycle),withdrawTime=sp.timestamp(endWithdraw),totalSupply=sp.nat(0)),
            tokenContract=token,adminAccount=0,model=sp.map(),Oracle=oro)
def test():
    scenario = sp.test_scenario()
    scenario.h1("TzWrappedFA2 - A blueprint TzWrappedFA2 implementation")
    scenario.table_of_contents()

    administrator = sp.test_account("Adiministrator")
    alice = sp.test_account("Alice")
    bob = sp.test_account("Robert")
    dan = sp.test_account("Dan")


    scenario.h2("Accounts")
    scenario.show([administrator, alice, bob, dan])
    tzwrapped_fa2_contract = TzWrappedFA2({administrator.address:True})
    scenario += tzwrapped_fa2_contract
    
    scenario.h2("Admin Calls")
    scenario.h3("Initialise 3 tokens")
    token_metadata_list = [sp.record(token_id=sp.nat(0), token_metadata=sp.map()),sp.record(token_id=sp.nat(1), token_metadata=sp.map()),sp.record(token_id=sp.nat(2), token_metadata=sp.map())]
    scenario += tzwrapped_fa2_contract.set_token_metadata(token_metadata_list).run(sender=administrator)
    scenario += tzwrapped_fa2_contract.initialise_token([sp.nat(0),sp.nat(1),sp.nat(2)]).run(sender=administrator)
    
    
    scenario.h2("Owner Only Calls")
    scenario.h3("Transferring the Ownership to the individual owners")
    ownerships = [sp.record(token_id=sp.nat(0), owner=alice.address),sp.record(token_id=sp.nat(1), proposed_administrator=bob.address),sp.record(token_id=sp.nat(2), owner=dan.address)]
    
    scenario.p("Not admin trying to propose new owner")
    scenario += tzwrapped_fa2_contract.propose_administrator(LedgerKey.make(alice.address, sp.nat(0))).run(sender=alice, valid=False)
    
    scenario.p("Not admin trying to transfer directly")
    scenario += tzwrapped_fa2_contract.set_administrator(sp.nat(0)).run(sender=bob, valid=False)
    
    scenario.p("Correct admin trying to transfer directly")
    scenario += tzwrapped_fa2_contract.set_administrator(sp.nat(0)).run(sender=administrator, valid=False)
    
    scenario.p("Correct admin trying to propose transfer")
    scenario += tzwrapped_fa2_contract.propose_administrator(LedgerKey.make(alice.address, sp.nat(0))).run(sender=administrator, valid=True)
    scenario += tzwrapped_fa2_contract.propose_administrator(LedgerKey.make(bob.address, sp.nat(1))).run(sender=administrator, valid=True)
    scenario += tzwrapped_fa2_contract.propose_administrator(LedgerKey.make(dan.address, sp.nat(2))).run(sender=administrator, valid=True)
    
    scenario.p("Correct admin (but not proposed) trying to transfer")
    scenario += tzwrapped_fa2_contract.set_administrator(sp.nat(0)).run(sender=administrator, valid=False)    
    
    scenario.p("Proposed admin trying to transfer")
    scenario += tzwrapped_fa2_contract.set_administrator(sp.nat(0)).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.set_administrator(sp.nat(1)).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.set_administrator(sp.nat(2)).run(sender=dan, valid=True)
    
    scenario.p("Non Admin deletes rights")
    scenario += tzwrapped_fa2_contract.remove_administrator(LedgerKey.make(administrator.address, sp.nat(0))).run(sender=dan, valid=False)
    scenario += tzwrapped_fa2_contract.remove_administrator(LedgerKey.make(administrator.address, sp.nat(1))).run(sender=alice, valid=False)
    scenario += tzwrapped_fa2_contract.remove_administrator(LedgerKey.make(administrator.address, sp.nat(2))).run(sender=bob, valid=False)
    
    scenario.p("Admin deletes own rights")
    scenario += tzwrapped_fa2_contract.remove_administrator(LedgerKey.make(administrator.address, sp.nat(0))).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.remove_administrator(LedgerKey.make(administrator.address, sp.nat(1))).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.remove_administrator(LedgerKey.make(administrator.address, sp.nat(2))).run(sender=dan, valid=True)
   
    scenario.h3("Issuing")
    scenario.p("Correct admin but not owner trying to issue")
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(0), amount=sp.nat(100))]).run(sender=administrator, valid=False)
    
    scenario.p("Incorrect owner trying to issue (Alice is owner of 0 not 1)")
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=alice, valid=False)
    
    scenario.p("Correct owner trying to batch issue (Alice is owner of 0 not 1 and 2)")
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(0), amount=sp.nat(100)), sp.record(token_id=sp.nat(1), amount=sp.nat(100)), sp.record(token_id=sp.nat(2), amount=sp.nat(100))]).run(sender=alice, valid=False)
    
    scenario.p("Correct owners issuing tokens")
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(0), amount=sp.nat(100))]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(2), amount=sp.nat(100))]).run(sender=dan, valid=True)
    
    scenario.p("Correct owners issuing additional amounts of tokens")
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(0), amount=sp.nat(101))]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(1), amount=sp.nat(101))]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(2), amount=sp.nat(101))]).run(sender=dan, valid=True)
    scenario.verify(tzwrapped_fa2_contract.data.ledger[LedgerKey.make(alice.address, 0)] == 201)
    scenario.verify(tzwrapped_fa2_contract.data.ledger[LedgerKey.make(bob.address, 1)] == 201)
    scenario.verify(tzwrapped_fa2_contract.data.ledger[LedgerKey.make(dan.address, 2)] == 201)
    
    
    scenario.h3("Setting Redeem Address")
    scenario.p("Correct admin but not owner trying to set redeem address")
    scenario += tzwrapped_fa2_contract.set_redeem_addresses([sp.record(token_id=sp.nat(0), address=alice.address)]).run(sender=administrator, valid=False)
    
    scenario.p("Correct owners setting redeem addresses")
    scenario += tzwrapped_fa2_contract.set_redeem_addresses([sp.record(token_id=sp.nat(0), address=alice.address)]).run(sender=alice)
    scenario += tzwrapped_fa2_contract.set_redeem_addresses([sp.record(token_id=sp.nat(1), address=bob.address)]).run(sender=bob)
    scenario += tzwrapped_fa2_contract.set_redeem_addresses([sp.record(token_id=sp.nat(2), address=dan.address)]).run(sender=dan)
    
    scenario.p("Incorrect owner trying to burn (Alice is owner of 0 not 1)")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=alice, valid=False)
    
    scenario.p("Correct owner trying to batch burn (Alice is owner of 0 not 1 and 2)")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(0), amount=sp.nat(100)), sp.record(token_id=sp.nat(1), amount=sp.nat(100)), sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=alice, valid=False)
    
    scenario.h3("Redemption")
    scenario.p("Correct admin but not owner trying to burn")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(0), amount=sp.nat(100))]).run(sender=administrator, valid=False)
    
    scenario.p("Incorrect owner trying to burn (Alice is owner of 0 not 1)")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=alice, valid=False)
    
    scenario.p("Correct owner trying to batch burn (Alice is owner of 0 not 1 and 2)")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(0), amount=sp.nat(100)), sp.record(token_id=sp.nat(1), amount=sp.nat(100)), sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=alice, valid=False)
    
    scenario.p("Correct owners burning tokens")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(0), amount=sp.nat(100))]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(1), amount=sp.nat(100))]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(2), amount=sp.nat(100))]).run(sender=dan, valid=True)
    scenario.verify(tzwrapped_fa2_contract.data.ledger[LedgerKey.make(alice.address, 0)] == 101)
    scenario.verify(tzwrapped_fa2_contract.data.ledger[LedgerKey.make(bob.address, 1)] == 101)
    scenario.verify(tzwrapped_fa2_contract.data.ledger[LedgerKey.make(dan.address, 2)] == 101)
    
    scenario.p("Cannot burn more than owner has")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(0), amount=sp.nat(201))]).run(sender=alice, valid=False)
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(1), amount=sp.nat(201))]).run(sender=bob, valid=False)
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(2), amount=sp.nat(201))]).run(sender=dan, valid=False)
    
    scenario.p("Correct owners burning additional amounts of tokens")
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(0), amount=sp.nat(101))]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(1), amount=sp.nat(101))]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.burn([sp.record(token_id=sp.nat(2), amount=sp.nat(101))]).run(sender=dan, valid=True)
    scenario.verify(~tzwrapped_fa2_contract.data.ledger.contains(LedgerKey.make(alice.address, 0)))
    scenario.verify(~tzwrapped_fa2_contract.data.ledger.contains(LedgerKey.make(bob.address, 1)))
    scenario.verify(~tzwrapped_fa2_contract.data.ledger.contains(LedgerKey.make(dan.address, 2)))
    
    scenario.h3("Reassign")
    scenario.p("Bootstrapping by issuing some tokens")
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(0), amount=sp.nat(50))]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(1), amount=sp.nat(47))]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.mint([sp.record(token_id=sp.nat(2), amount=sp.nat(39))]).run(sender=dan, valid=True)
    
    scenario.h3("Pause")
    scenario.p("Correct admin but not owner trying to pause")
    scenario += tzwrapped_fa2_contract.pause([sp.nat(0)]).run(sender=administrator, valid=False)
    
    scenario.p("Incorrect owner trying to pause (Alice is owner of 0 not 1)")
    scenario += tzwrapped_fa2_contract.pause([sp.nat(1)]).run(sender=alice, valid=False)
    
    scenario.p("Correct owner trying to batch pause (Alice is owner of 0 not 1 and 2)")
    scenario += tzwrapped_fa2_contract.pause([sp.nat(0), sp.nat(1), sp.nat(2)]).run(sender=alice, valid=False)
    
    scenario.p("Correct owners pauseing tokens")
    scenario += tzwrapped_fa2_contract.pause([sp.nat(1)]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.pause([sp.nat(2)]).run(sender=dan, valid=True)
    
    
    scenario.h3("Unpause")
    scenario.p("Correct admin but not owner trying to unpause")
    scenario += tzwrapped_fa2_contract.unpause([sp.nat(0)]).run(sender=administrator, valid=False)
    
    scenario.p("Incorrect owner trying to unpause (Alice is owner of 0 not 1)")
    scenario += tzwrapped_fa2_contract.unpause([sp.nat(1)]).run(sender=alice, valid=False)
    
    scenario.p("Correct owner trying to batch unpause (Alice is owner of 0 not 1 and 2)")
    scenario += tzwrapped_fa2_contract.unpause([sp.nat(0), sp.nat(1), sp.nat(2)]).run(sender=alice, valid=False)
    
    scenario.p("Correct owners unpauseing tokens")
    scenario += tzwrapped_fa2_contract.unpause([sp.nat(1)]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.unpause([sp.nat(2)]).run(sender=dan, valid=True)
    
    scenario.h2("Token Holder Calls")
    scenario.h3("Transfer")
    scenario.p("Holder with no balance tries transfer")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=bob.address, txs=[sp.record(to_=dan.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=bob, valid=False)
    
    scenario.p("Admin with no balance tries transfer")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=administrator.address, txs=[sp.record(to_=dan.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=administrator, valid=False)
    
    scenario.p("Admin tries transfer of third parties balance")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=alice.address, txs=[sp.record(to_=dan.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=administrator, valid=False)
    
    scenario.p("Owner performs initial transfer of own balance")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=alice.address, txs=[sp.record(to_=dan.address, token_id=sp.nat(0), amount=sp.nat(10))])]).run(sender=alice, valid=True)
    
    scenario.p("Owner tries transfer of third party balance")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=dan.address, txs=[sp.record(to_=bob.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=alice, valid=False)
    
    scenario.p("Holder transfers own balance")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=dan.address, txs=[sp.record(to_=bob.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=dan, valid=True)
    
    scenario.p("Holder transfers too much")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=dan.address, txs=[sp.record(to_=bob.address, token_id=sp.nat(0), amount=sp.nat(11))])]).run(sender=dan, valid=False)
    
    scenario.h3("Pause/Unpause")
    scenario.p("Holder transfers too much")
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=dan.address, txs=[sp.record(to_=bob.address, token_id=sp.nat(0), amount=sp.nat(11))])]).run(sender=dan, valid=False)
    
    scenario.p("Holder transfers paused token")
    scenario += tzwrapped_fa2_contract.pause([sp.nat(0)]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.pause([sp.nat(1)]).run(sender=bob, valid=True)
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=dan.address, txs=[sp.record(to_=bob.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=dan, valid=False)
    
    scenario.p("Holder transfers resumed token")
    scenario += tzwrapped_fa2_contract.unpause([sp.nat(0)]).run(sender=alice, valid=True)
    scenario += tzwrapped_fa2_contract.transfer([sp.record(from_=dan.address, txs=[sp.record(to_=bob.address, token_id=sp.nat(0), amount=sp.nat(1))])]).run(sender=dan, valid=True)
Beispiel #3
0
 def __init__(self, admin):
     
     self.init(xtzPrice = sp.nat(0), keysset = sp.set([admin]) , owner = admin,StrikePrice=sp.map())
def test():
    scenario = sp.test_scenario()

    # The multisig address.
    multisigAddress = sp.address("tz1hoverof3f2F8NAavUyTjbFBstZXTqnUMS")

    # And there's a DAO
    daoAddress = sp.address("KT1Hkg5qeNhfwpKW4fXvq7HGZB9z2EnmCCA9")

    # A box contract is controlled by the MSig. Just like Kolibri contracts today.
    box = Box(governorAddress=multisigAddress)
    scenario += box

    # A break glass gets deployed which maps the dao and break glass to the store.
    breakGlass = BreakGlass(
        daoAddress=daoAddress,
        multisigAddress=multisigAddress,
        targetAddress=box.address,
    )
    scenario += breakGlass

    # The multisig gives up control to the break glass.
    scenario += box.setGovernorContract(
        breakGlass.address).run(sender=multisigAddress)

    # THEN permissions are set correctly
    scenario.verify(box.data.governorAddress == breakGlass.address)
    scenario.verify(breakGlass.data.targetAddress == box.address)
    scenario.verify(breakGlass.data.multisigAddress == multisigAddress)
    scenario.verify(breakGlass.data.daoAddress == daoAddress)

    # A lambda is crafted to update the store address.
    newValue = sp.nat(3)

    def updateLambda(unitParam):
        sp.set_type(unitParam, sp.TUnit)
        storeContractHandle = sp.contract(sp.TNat, box.address,
                                          'update').open_some()
        sp.result([
            sp.transfer_operation(newValue, sp.mutez(0), storeContractHandle)
        ])

    # AND the lambda is executed in the break glass by the dao.
    scenario += breakGlass.runLambda(updateLambda).run(sender=daoAddress)

    # Then things go as planned and the value in the box is updated
    scenario.verify(box.data.value == newValue)

    # Of course, if we try to update the box directly, that fails.
    scenario += box.update(sp.nat(4)).run(
        sender=multisigAddress,
        valid=False,
    )

    # Oh no, the DAO is unstable. Let's break glass to get back control
    scenario += breakGlass.breakGlass(multisigAddress).run(
        sender=multisigAddress)

    # THEN the permissions are updated
    scenario.verify(box.data.governorAddress == multisigAddress)

    # AND the multisig can update the value.
    multisigValue = sp.nat(5)
    scenario += box.update(multisigValue).run(sender=multisigAddress, )
    scenario.verify(box.data.value == multisigValue)

    # And the DAO has no perms.
    scenario += breakGlass.runLambda(updateLambda).run(
        sender=daoAddress,
        valid=False,
    )
def test():
    
    obj = StakePool(sp.address("tz1-Admin"))
    scenario = sp.test_scenario()
    scenario += obj
    
    scenario += obj.depositXTZ().run(sender = sp.address("tz1-Admin") , amount = sp.tez(1000))
    
    scenario += obj.recoverXTZ(amount = sp.tez(500)).run(sender = sp.address("tz1-Admin"))
    
    # Cycle - 63 Ongoing 
    # Betting Intitation 63 -> 65
    #scenario += obj.updatePrice(price = sp.int(4000)).run(level = 129661 ,sender = sp.address("tz1-Admin"))
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(4000000)))).run(level = 129661 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    #Placing Bet
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(250)).run(sender = sp.address("tz1-Bob") , amount = sp.tez(2) , level = 129668)
    
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(250)).run(sender = sp.address("tz1-Mark") , amount = sp.tez(2) , level = 129667)

    
    scenario += obj.placeBet(top = sp.int(-250) , bottom = sp.int(0)).run(sender = sp.address("tz1-Alice") , amount = sp.tez(2) , level = 129670)
    
    scenario += obj.placeBet(top = sp.int(250) , bottom = sp.int(500)).run(sender = sp.address("tz1-Joe") , amount = sp.tez(3) , level = 129671)
    
    scenario += obj.placeBet(top = sp.int(250) , bottom = sp.int(500)).run(sender = sp.address("tz1-John") , amount = sp.tez(4) , level = 129672)
    
    scenario += obj.placeBet(top = sp.int(1000) , bottom = sp.int(1000)).run(sender = sp.address("tz1-Elan") , amount = sp.tez(4) , level = 129672)
    
    # Cycle - 64 Ongoing 
    # Betting Intitation 64 -> 66
    # scenario += obj.updatePrice(price = sp.int(3900)).run(level = 131720 , sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(3900000)))).run(level = 131720 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    #Placing Bet
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(250)).run(sender = sp.address("tz1-Bob") , amount = sp.tez(4) , level = 131721)
    
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(250)).run(sender = sp.address("tz1-Mark") , amount = sp.tez(3) , level = 131722)

    
    scenario += obj.placeBet(top = sp.int(-250) , bottom = sp.int(0)).run(sender = sp.address("tz1-Alice") , amount = sp.tez(1) , level = 131723)
    
    scenario += obj.placeBet(top = sp.int(250) , bottom = sp.int(500)).run(sender = sp.address("tz1-Joe") , amount = sp.tez(6) , level = 131724)
    
    scenario += obj.placeBet(top = sp.int(-750) , bottom = sp.int(-500)).run(sender = sp.address("tz1-John") , amount = sp.tez(9) , level = 131725)
    
    scenario += obj.placeBet(top = sp.int(1000) , bottom = sp.int(1000)).run(sender = sp.address("tz1-Elan") , amount = sp.tez(5) , level = 131726)
    
    # Cycle - 65 Ongoing
    # Betting Intitation 65 -> 67
    #scenario += obj.updatePrice(price = sp.int(3900)).run(level = 133220 , sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(3900000)))).run(level = 133220 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    #Placing Bet
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(250)).run(sender = sp.address("tz1-Bob") , amount = sp.tez(7) , level = 133221)
    
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(250)).run(sender = sp.address("tz1-Mark") , amount = sp.tez(6) , level = 133222)

    
    scenario += obj.placeBet(top = sp.int(-250) , bottom = sp.int(0)).run(sender = sp.address("tz1-Alice") , amount = sp.tez(5) , level = 133223)
    
    scenario += obj.placeBet(top = sp.int(250) , bottom = sp.int(500)).run(sender = sp.address("tz1-Joe") , amount = sp.tez(8) , level = 133224)
    
    scenario += obj.placeBet(top = sp.int(1000) , bottom = sp.int(1000)).run(sender = sp.address("tz1-John") , amount = sp.tez(7) , level = 133225)
    
    scenario += obj.placeBet(top = sp.int(1000) , bottom = sp.int(1000)).run(sender = sp.address("tz1-Elan") , amount = sp.tez(9) , level = 133226)
    
    # Cycle - 66 Ongoing
    # Changing prediction ranges
    scenario += obj.changeBetRange(step=300,end=1200).run(sender=sp.address("tz1-Admin"))
    # Betting Intitation 66 -> 68
    # Concluding 65 
    #scenario += obj.updatePrice(price = sp.int(4050)).run(level = 135268,sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(4050000)))).run(level = 135268 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    
    #Placing Bet
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(300)).run(sender = sp.address("tz1-Bob") , amount = sp.tez(7) , level = 135270)
    
    scenario += obj.placeBet(top = sp.int(300) , bottom = sp.int(600)).run(sender = sp.address("tz1-Mark") , amount = sp.tez(6) , level = 135271)

    
    scenario += obj.placeBet(top = sp.int(-600) , bottom = sp.int(-300)).run(sender = sp.address("tz1-Alice") , amount = sp.tez(5) , level = 135272)
    
    scenario += obj.placeBet(top = sp.int(-1200) , bottom = sp.int(-1200)).run(sender = sp.address("tz1-Joe") , amount = sp.tez(8) , level = 135273)
    
    scenario += obj.placeBet(top = sp.int(1200) , bottom = sp.int(1200)).run(sender = sp.address("tz1-John") , amount = sp.tez(7) , level = 135274)
    
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(300)).run(sender = sp.address("tz1-Elan") , amount = sp.tez(9) , level = 135275)
    
    # Withdrawals of 65
    scenario += obj.withdrawAmount(cycle = sp.int(65)).run(sender = sp.address("tz1-Alice"))
    scenario += obj.withdrawAmount(cycle = sp.int(65)).run(sender = sp.address("tz1-Bob"))
    scenario += obj.withdrawAmount(cycle = sp.int(65)).run(sender = sp.address("tz1-Joe"))
    scenario += obj.withdrawAmount(cycle = sp.int(65)).run(sender = sp.address("tz1-John"))
    scenario += obj.withdrawAmount(cycle = sp.int(65)).run(sender = sp.address("tz1-Mark"))
    scenario += obj.withdrawAmount(cycle = sp.int(65)).run(sender = sp.address("tz1-Elan"))
    
    # Cycle - 67 Ongoing
    # Changing prediction ranges
    scenario += obj.changeBetRange(step=400,end=2000).run(sender=sp.address("tz1-Admin"))
    # Betting Intitation 66 -> 69
    # Concluding 66
    #scenario += obj.updatePrice(price = sp.int(3700)).run(level = 137316,sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(3700000)))).run(level = 137316 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    #Placing Bet
    scenario += obj.placeBet(top = sp.int(0) , bottom = sp.int(400)).run(sender = sp.address("tz1-Bob") , amount = sp.tez(7) , level = 137320)
    
    scenario += obj.placeBet(top = sp.int(800) , bottom = sp.int(1200)).run(sender = sp.address("tz1-Mark") , amount = sp.tez(6) , level = 137321)

    
    scenario += obj.placeBet(top = sp.int(-800) , bottom = sp.int(-400)).run(sender = sp.address("tz1-Alice") , amount = sp.tez(5) , level = 137322)
    
    scenario += obj.placeBet(top = sp.int(-1200) , bottom = sp.int(-800)).run(sender = sp.address("tz1-Joe") , amount = sp.tez(8) , level = 137323)
    
    scenario += obj.placeBet(top = sp.int(2000) , bottom = sp.int(2000)).run(sender = sp.address("tz1-John") , amount = sp.tez(7) , level = 137324)
    
    scenario += obj.placeBet(top = sp.int(800) , bottom = sp.int(1200)).run(sender = sp.address("tz1-Elan") , amount = sp.tez(9) , level = 137325)
    
    # Betting not allowed through contract
    scenario += obj.placeBet(top = sp.int(800) , bottom = sp.int(1200)).run(source = sp.address("KT1-Jane") , sender = sp.address("tz1-Jane") , amount = sp.tez(9) , level = 137326 ,valid=False)
    
    # Withdrawals of 66
    scenario += obj.withdrawAmount(cycle = sp.int(66)).run(sender = sp.address("tz1-Alice"))
    scenario += obj.withdrawAmount(cycle = sp.int(66)).run(sender = sp.address("tz1-Bob"))
    scenario += obj.withdrawAmount(cycle = sp.int(66)).run(sender = sp.address("tz1-Joe"))
    scenario += obj.withdrawAmount(cycle = sp.int(66)).run(sender = sp.address("tz1-John"))
    scenario += obj.withdrawAmount(cycle = sp.int(66)).run(sender = sp.address("tz1-Mark"))
    scenario += obj.withdrawAmount(cycle = sp.int(66)).run(sender = sp.address("tz1-Elan"))
    
    # Cycle - 68 Ongoing
    # Betting Intitation 68 -> 70
    # Concluding 67
    #scenario += obj.updatePrice(price = sp.int(5000)).run(level = 140264,sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(5000000)))).run(level = 140264 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    # Withdrawals of 67
    scenario += obj.withdrawAmount(cycle = sp.int(67)).run(sender = sp.address("tz1-Alice"))
    scenario += obj.withdrawAmount(cycle = sp.int(67)).run(sender = sp.address("tz1-Bob"))
    scenario += obj.withdrawAmount(cycle = sp.int(67)).run(sender = sp.address("tz1-Joe"))
    scenario += obj.withdrawAmount(cycle = sp.int(67)).run(sender = sp.address("tz1-John"))
    scenario += obj.withdrawAmount(cycle = sp.int(67)).run(sender = sp.address("tz1-Mark"))
    scenario += obj.withdrawAmount(cycle = sp.int(67)).run(sender = sp.address("tz1-Elan"))
    
    # Cycle - 69 Ongoing
    # Betting Intitation 69 -> 71
    # Concluding 68
    #scenario += obj.updatePrice(price = sp.int(4233)).run(level = 141412,sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(4233000)))).run(level = 141412 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    # Withdrawals of 68
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-Alice"))
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-Bob"))
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-Joe"))
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-John"))
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-Mark"))
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-Elan"))
    
    # Duplicate Withdrawal
    scenario += obj.withdrawAmount(cycle = sp.int(68)).run(sender = sp.address("tz1-Elan") , valid = False)
    
    # Cycle - 70 Ongoing
    # Betting Intitation 70 -> 72
    # Concluding 69
    #scenario += obj.updatePrice(price = sp.int(4070)).run(level = 143460,sender = sp.address("tz1-Admin"))
    
    scenario += obj.fetchPriceAndUpdateCycle(asset = "XTZ-USD" , harbingerContractAddress = sp.address("KT1-Normalizer-Harbinger") , targetAddress = sp.address("KT1-SELF")).run(sender = sp.address("tz1-Admin"))
    scenario += obj.getResponseFromHarbinger(("XTZ-USD" , (sp.timestamp(0) , sp.nat(4070000)))).run(level = 143460 ,sender = sp.address("KT1-Normalizer-Harbinger") ,source= sp.address("tz1-Admin"))
    
    
    # Withdrawals of 69
    scenario += obj.withdrawAmount(cycle = sp.int(69)).run(sender = sp.address("tz1-Alice"))
    scenario += obj.withdrawAmount(cycle = sp.int(69)).run(sender = sp.address("tz1-Bob"))
    scenario += obj.withdrawAmount(cycle = sp.int(69)).run(sender = sp.address("tz1-Joe"))
    scenario += obj.withdrawAmount(cycle = sp.int(69)).run(sender = sp.address("tz1-John"))
    scenario += obj.withdrawAmount(cycle = sp.int(69)).run(sender = sp.address("tz1-Mark"))
    scenario += obj.withdrawAmount(cycle = sp.int(69)).run(sender = sp.address("tz1-Elan"))
    
    
    
    # Admin Only Funstions Test
    
    scenario += obj.changeBettingPauseState().run(sender=sp.address("tz1-Admin"))
    scenario += obj.changeBettingPauseState().run(sender=sp.address("tz1-Admin"))
    scenario += obj.changeWithdrawalsPauseState().run(sender = sp.address("tz1-Admin"))
    scenario += obj.changeWithdrawalsPauseState().run(sender = sp.address("tz1-Admin"))
    
    scenario += obj.addAdmin(address = sp.address("tz1-Admin-2")).run(sender=sp.address("tz1-Admin"))
    scenario += obj.addAdmin(address = sp.address("tz1-Admin-3")).run(sender=sp.address("tz1-Admin"))
    scenario += obj.removeAdmin(address = sp.address("tz1-Admin-3")).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.changeROI(numerator = 400 , denominator = 100000).run(sender=sp.address("tz1-Admin"))
    scenario += obj.changeROI(numerator = 588 , denominator = 100000).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.changeBetRange(step=300,end=1200).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.changeBetRange(step=250,end=1000).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.changeBlocksPerCycle(blocksPerCycle = sp.int(4096)).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.changeBlocksPerCycle(blocksPerCycle = sp.int(2048)).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.changeBetLimit(betLimit = sp.tez(100)).run(sender=sp.address("tz1-Admin"))
    
    scenario += obj.delegate(sp.some(sp.key_hash("tz1-Baker"))).run(sender=sp.address("tz1-Admin"))
    
    
    
    
def test():
    scenario = sp.test_scenario()
    scenario.h1("Auction House")
    scenario.table_of_contents()

    admin = sp.test_account("Administrator")
    alice = sp.test_account("Alice")
    bob = sp.test_account("Robert")
    dan = sp.test_account("Dan")
    minter = sp.test_account("Minter")

    # Let's display the accounts:
    scenario.h2("Accounts")
    scenario.show([admin, alice, bob, dan, minter])

    auction_house = AuctionHouse()
    scenario += auction_house

    scenario.h2("AcuteArtFA2")
    fa2 = AcuteArtFA2(auction_house.address, minter.address)
    scenario += fa2

    scenario.h2("Initial minting")

    scenario.p("Minter mints token 0 with no royalty")
    scenario += fa2.mint(token_id = 0, royalty = sp.none, metadata = sp.bytes_of_string('ipfs://foo')).run(sender = minter.address)

    scenario.p("Alice fails to mint token 1")
    scenario += fa2.mint(token_id = 1, royalty = sp.none, metadata = sp.bytes_of_string('ipfs://foo')).run(sender = alice.address, valid=False)

    scenario.p("Minter fails to re-mint token 0")
    scenario += fa2.mint(token_id = 0, royalty = sp.none, metadata = sp.bytes_of_string('ipfs://foo')).run(sender = minter.address, valid=False)

    scenario.p("Minter sends token to Bob")
    scenario += fa2.transfer([BatchTransfer.item(minter.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=minter, valid=True)

    scenario.p("Bob updates operators")
    scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=sp.nat(0)))]).run(sender=bob)

    scenario.h2("User Auction")
    scenario.p("Bob creates auction")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(0), token_amount=sp.nat(1),  end_timestamp=sp.timestamp(60*60),  bid_amount=sp.mutez(100000))).run(sender=bob, now=sp.timestamp(0))

    scenario.p("Bob tries to withdraw")
    scenario += auction_house.withdraw(0).run(sender=bob, amount=sp.mutez(0), now=sp.timestamp(0), valid=False)

    scenario.p("Alice bids")
    scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(200000), now=sp.timestamp(0))

    scenario.p("Dan bids")
    scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(300000), now=sp.timestamp(1))

    scenario.p("Alice rebids")
    scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(400000), now=sp.timestamp(2))

    scenario.p("Bob tries to withdraw")
    scenario += auction_house.withdraw(0).run(sender=bob, amount=sp.mutez(0), now=sp.timestamp(60*60), valid=False)

    scenario.p("Dan bids")
    scenario += auction_house.bid(0).run(sender=dan,amount=sp.mutez(500000), now=sp.timestamp(60*60-5))

    scenario.p("Alice rebids")
    scenario += auction_house.bid(0).run(sender=alice,amount=sp.mutez(600000), now=sp.timestamp(60*60+5*60-6))

    scenario.p("Alice withdraws")
    scenario += auction_house.withdraw(0).run(sender=alice, amount=sp.mutez(0), now=sp.timestamp(60*60+5*60-6+5*60+1))

    scenario.h2("Self-Withdraw")
    scenario.p("Alice creates auction")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=alice.address,operator=auction_house.address,token_id=sp.nat(0)))]).run(sender=alice)
    scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=sp.nat(0), token_amount=sp.nat(1),  end_timestamp=sp.timestamp(60*60),  bid_amount=sp.mutez(100000))).run(sender=alice, now=sp.timestamp(0))


    scenario.h2("Transfers")
    scenario.p("Bob cannot transfer alice's token")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=bob, valid=False)
    scenario.p("Alice cannot transfer own token")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=bob.address, token_id=0, amount=1)])]).run(sender=alice, valid=False)

    scenario.p("Bob bids")
    scenario += auction_house.bid(0).run(sender=bob, amount=sp.mutez(100000000), now=sp.timestamp(60))

    scenario.p("Bob withdraws")
    scenario += auction_house.withdraw(0).run(sender=bob, now=sp.timestamp(120*60))

    scenario.p("Auction house cannot transfer Bob's token before allowance")
    scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=alice.address, token_id=0, amount=1)])]).run(sender=auction_house.address, valid=False)

    # scenario.show(fa2.data.ledger[LedgerKey.make(owner = auction_house.address, token_id = 0)])

    scenario.p("Auction house can transfer Bob's token after allowance")
    scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=bob.address,operator=auction_house.address,token_id=0))]).run(sender=bob)
    scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=alice.address, token_id=0, amount=1)])]).run(sender=auction_house.address)


    scenario.p("Bob cannot transfer more token")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += fa2.transfer([BatchTransfer.item(bob.address, [sp.record(to_=bob.address, token_id=0, amount=2)])]).run(sender=bob, valid=False)

    scenario.p("Bob cannot transfer from non balance address")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=dan.address, token_id=0, amount=1)])]).run(sender=bob, valid=False)

    scenario.p("Alice can transfer as owner")
    auction_id = sp.nat(0) # we can reuse 0
    scenario += fa2.transfer([BatchTransfer.item(alice.address, [sp.record(to_=dan.address, token_id=0, amount=1)])]).run(sender=alice)
    
    
    scenario.h2("Royalties Mechanics")
    auction_id = sp.nat(1)
    fraction = sp.nat(215000000) # 215000000/2**32 ~= 5%
    token_id = sp.nat(10)
    
    scenario.p("Minter mints token 10 with royalty")
    scenario += fa2.mint(token_id = token_id, royalty = sp.some(sp.record(recipient=minter.address, fraction=fraction)), metadata = sp.bytes_of_string('ipfs://foo')).run(sender = minter.address)

    scenario.p("Minter fails to send token to Bob")
    scenario += fa2.transfer([BatchTransfer.item(minter.address, [sp.record(to_=bob.address, token_id=token_id, amount=1)])]).run(sender=minter, valid=False)

    scenario.p("Minter updates operators")
    scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=minter.address,operator=auction_house.address,token_id=token_id))]).run(sender=minter)
    
    scenario.p("Minter creates auction")
    scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=token_id, token_amount=sp.nat(1),  end_timestamp=sp.timestamp(60*60),  bid_amount=sp.mutez(100000))).run(sender=minter, now=sp.timestamp(0))
    
    scenario.p("No one has bid, no royalty expected...")
    scenario += auction_house.withdraw(auction_id).run(sender=minter, now=sp.timestamp(60*60+1))
    scenario.verify(~auction_house.data.accumulated_royalties.contains(minter.address))
    
    scenario.p("Minter updates operators")
    scenario += fa2.update_operators([sp.variant('add_operator', sp.record(owner=minter.address,operator=auction_house.address,token_id=token_id))]).run(sender=minter)
    
    scenario.p("Minter creates new auction")
    scenario += auction_house.create_auction(sp.record(auction_id=auction_id, token_address=fa2.address, token_id=token_id, token_amount=sp.nat(1),  end_timestamp=sp.timestamp(60*60),  bid_amount=sp.mutez(100000))).run(sender=minter, now=sp.timestamp(0))
    
    scenario += auction_house.bid(auction_id).run(sender=alice,amount=sp.tez(100), now=sp.timestamp(0))
    
    scenario.p("Now we have a bid, we expect royalty")
    scenario += auction_house.withdraw(auction_id).run(sender=minter, now=sp.timestamp(60*60+1))
    scenario.verify(auction_house.data.accumulated_royalties.contains(minter.address))
    scenario.verify_equal(auction_house.data.accumulated_royalties[minter.address],sp.mutez(5005858))
    
    scenario.p("Only minter can collect royalties")
    scenario += auction_house.collect_royalties(bob.address).run(sender=bob, valid=False)
    scenario += auction_house.collect_royalties(minter.address).run(sender=minter, valid=True)
    scenario.verify(~auction_house.data.accumulated_royalties.contains(minter.address))
    
    
    scenario.p("Only royalty recipient can update _own_ recipient")
    scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=token_id)).run(sender=bob, valid=False)
    
    scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=sp.nat(0))).run(sender=bob, valid=False)
    
    scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=sp.nat(0))).run(sender=minter, valid=False)
    
    
    scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=bob.address, token_id=token_id)).run(sender=minter, valid=True)
    
    scenario += auction_house.update_royalty_recipient(sp.record(fa2_address=fa2.address, new_recipient=alice.address, token_id=token_id)).run(sender=minter, valid=False)
 def crzy(self, params):
     sp.verify (sp.amount >= sp.tez(5))
     sp.verify (sp.tez(sp.nat(params)) == sp.amount)
        from_user = self.ledger_key.make(sp.sender, params.token_id)
        to_user = self.ledger_key.make(highest_bidder.value.bidder, params.token_id)
        
        self.data.ledger[from_user].balance = sp.as_nat(
            self.data.ledger[from_user].balance - params.nft_amount)
            
        sp.if self.data.ledger.contains(to_user):
            self.data.ledger[to_user].balance += params.nft_amount
        sp.else:
             self.data.ledger[to_user] = FA2.Ledger_value.make(params.nft_amount)
        
        # transfer bid amount to seller
        # take out x percentage and send it to admin account
        
        # 10% commission
        commission = sp.split_tokens(highest_bidder.value.bid_value, sp.nat(10), sp.nat(100))
        
        # Transfer xtz to the seller
        sp.send(sp.sender, highest_bidder.value.bid_value - commission)
        
        # Transfer commission to the admin
        sp.send(self.data.administrator, commission)
        
        # return the xtz amount to the rest of the bidders if any
        sp.for bidder in self.data.bid[params.token_id]:
            sp.if bidder.bidder != highest_bidder.value.bidder:
                sp.send(bidder.bidder, bidder.bid_value)
        
        del self.data.offer[params.token_id]
        del self.data.bid[params.token_id]
Beispiel #9
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 = FA2.FA2(config = FA2.environment_config(),
                 metadata = sp.utils.metadata_of_url("https://example.com"),
                 admin = admin.address)
    c1 = FA2Swap(_admin=admin.address, _fa2=c2.address, _tokenID=0)
    scenario = sp.test_scenario()
    scenario.table_of_contents()
    scenario.h1("Atomic Swap")
    scenario += c1

    scenario.h2("Accounts")
    scenario.show([admin, alice, bob])

    scenario.h2("FA2")
    scenario.h3("Entry points")
    scenario += c2
    scenario.h3("Admin mints a few coins")
    tok0_md = FA2.FA2.make_metadata(
            name = "The Token Zero",
            decimals = 2,
            symbol= "TK0" )
    scenario += c2.mint(address = alice.address,
                            amount = 18,
                            metadata = tok0_md,
                            token_id = 0).run(sender = admin)
    scenario.h2("Alice approves Contract")
    scenario += c2.update_operators([
                sp.variant("add_operator", c2.operator_param.make(
                    owner = alice.address,
                    operator = c1.address,
                    token_id = 0))
            ]).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.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(5))
    scenario.verify(c2.data.ledger[c2.ledger_key.make(alice.address, 0)].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.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(0))
    scenario.verify(c2.data.ledger[c2.ledger_key.make(bob.address, 0)].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.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(5))
    scenario.verify(c2.data.ledger[c2.ledger_key.make(alice.address, 0)].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.ledger[c2.ledger_key.make(c1.address, 0)].balance == sp.nat(0))
    scenario.verify(c2.data.ledger[c2.ledger_key.make(alice.address, 0)].balance == sp.nat(13))
 def __init__(self, admin):
     
     self.init(USDPrice = sp.nat(0), keysset = sp.set([admin]) , owner = admin,securities = admin)
Beispiel #11
0
def test():
    alice = sp.test_account("Alice")
    bob = sp.test_account("Bob")
    admin = sp.test_account("Admin")
    swapHash = sp.bytes("0x68656c6c6f666473667364666c64736a666c73646a6664736a6673646a6b666a")

    swapContract = Swap(_admin=admin.address, _swapFee=15, _commission=1000000)
    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",
    }
    tokenContract = FA12.FA12(admin.address,
            config              = FA12.FA12_config(support_upgradable_metadata = True),
            token_metadata      = token_metadata,
            contract_metadata   = contract_metadata)

    scenario = sp.test_scenario()
    scenario.table_of_contents()

    scenario.h2("Accounts")
    scenario.show([admin, alice, bob])

    scenario.h2("Swap")
    scenario += swapContract

    scenario.h2("FA1.2")
    scenario += tokenContract

    scenario.h3("Admin mints token balances to participants")
    scenario += tokenContract.mint(address=alice.address, value=2000000).run(sender=admin)
    scenario += tokenContract.mint(address=bob.address, value=3000000).run(sender=admin)

    scenario.h3("Alice & Bob approve token balances for the Swap contract")
    scenario += tokenContract.approve(spender=swapContract.address, value=1900000).run(sender=alice)
    scenario += tokenContract.approve(spender=swapContract.address, value=3000000).run(sender=bob)

    scenario.h2("Swap Scenarios")

    scenario.h3("Alice fails to add a swap pair")
    scenario += swapContract.addSwapPair({"xtz/usdtz":{"xtz": sp.record(counterAsset="usdtz", decimals=6, contract=swapContract.address), "usdtz": sp.record(counterAsset="xtz", decimals=6, contract=tokenContract.address)}}).run(sender=alice, valid=False)

    scenario.h3("Admin adds a swap pair")
    scenario += swapContract.addSwapPair({"xtz/usdtz":{"xtz":sp.record(counterAsset="usdtz",decimals=6,contract=swapContract.address), "usdtz":sp.record(counterAsset="xtz",decimals=6,contract=tokenContract.address)}}).run(sender=admin)

    scenario.h3("Bob fails to offer a swap, swap contract is inactive")
    # no operations work without contract being active
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="xtz").run(sender=bob, amount=sp.tez(3), now=sp.timestamp(159682400), valid=False)

    # activate only by admin
    scenario.h3("Alice fails activate swap contract")
    scenario += swapContract.toggleContractState(True).run(sender=alice, valid=False)

    scenario.h3("Admin activates swap contract")
    scenario += swapContract.toggleContractState(True).run(sender=admin)

    # swap must include service fee
    scenario.h3("Bob fails to offer a swap without service fee included in amount")
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="xtz").run(sender=bob, amount=sp.tez(2), now=sp.timestamp(159682400), valid=False)

    # initiate new swap
    scenario.h3("Bob offers a swap")
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="xtz").run(sender=bob, amount=sp.tez(3), now=sp.timestamp(159682400))

    # cannot initiate new swap with same hash
    scenario.h3("Alice fails to offer a swap with duplicate hash")
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="xtz").run(sender=alice, amount=sp.tez(3), now=sp.timestamp(159682400), valid=False)

    # balance check
    scenario.verify(swapContract.balance == sp.tez(3))

    scenario.h3("Alice fails to take swap below expected return")
    # cannot redeem without value matching the required expected value
    scenario += swapContract.take(_swapHash=swapHash, _value=1800000, _pair="xtz/usdtz", _asset="xtz").run(sender=alice, now=sp.timestamp(159682450), valid=False)

    scenario.h3("Alice takes swap at expected value")
    scenario += swapContract.take(_swapHash=swapHash, _value=1900000, _pair="xtz/usdtz", _asset="usdtz").run(sender=alice, now=sp.timestamp(159682450))

    scenario.verify(swapContract.balance == sp.tez(1))
    scenario.verify(tokenContract.data.balances[bob.address].balance == sp.nat(4900000))

    scenario.h3("Alice fails to update swap fees")
    # update fees only by admin
    scenario += swapContract.updateSwapFees(_swapFee=20, _commission=1500000).run(sender=alice, valid=False)

    scenario.h3("Admin updates swap fees")
    scenario += swapContract.updateSwapFees(_swapFee=20, _commission=1500000).run(sender=admin)

    scenario.h3("Bob fails to offer a swap with outdated fees")
    # need to use updated service fees
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="usdtz").run(sender=bob, amount=sp.tez(1), now=sp.timestamp(159682400), valid=False)

    scenario.h3("Bob offers a new swap with updated commission, reusing a hash")
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="usdtz").run(sender=bob, amount=sp.utils.nat_to_mutez(1500000), now=sp.timestamp(159682400))

    # balance check
    scenario.verify(swapContract.balance == sp.utils.nat_to_mutez(2500000))

    # # cannot be refunded before the refund time
    scenario += swapContract.refund(swapHash).run(sender=bob, now=sp.timestamp(159682450), valid=False)

    scenario.h3("Alice refunds Bob's expired swap")
    # can be refunded by anyone but funds transferred only to initiator after expiry
    scenario += swapContract.refund(swapHash).run(sender=alice, now=sp.timestamp(159682550))

    scenario.h3("Alice fails to refund a removed swap")
    # cannot be refunded again once it has been refunded
    scenario += swapContract.refund(swapHash).run(sender=alice, now=sp.timestamp(159682550), valid=False)
    # balance check [refunded swap service fees are also returned]
    scenario.verify(swapContract.balance == sp.tez(1))

    scenario.h2("Other admin functions")
    scenario.h3("Alice fails to remove a pair")
    # only admin can remove swap pair
    scenario += swapContract.removeSwapPair(["xtz/usdtz"]).run(sender=alice, valid=False)

    scenario.h3("Admin removes a pair")
    scenario += swapContract.removeSwapPair(["xtz/usdtz"]).run(sender=admin)

    # only swap pairs available can be used 
    scenario += swapContract.offer(_swapHash=swapHash, _value=2000000, _expected=1900000, _refundTimestamp=sp.timestamp(159682500), _pair="xtz/usdtz", _asset="xtz").run(sender=bob, amount=sp.utils.nat_to_mutez(3500000), now=sp.timestamp(159682400), valid=False)

    scenario.h3("Alice fails to set a delegate")
    voting_powers = {
        sp.key_hash("tz1YB12JHVHw9GbN66wyfakGYgdTBvokmXQk"): 0,
    }
    # only admin can set baker
    scenario += swapContract.setBaker(sp.some(sp.key_hash("tz1YB12JHVHw9GbN66wyfakGYgdTBvokmXQk"))).run(sender=alice,voting_powers = voting_powers, valid=False)

    scenario.h3("Admin sets a delegate")
    scenario += swapContract.setBaker(sp.some(sp.key_hash("tz1YB12JHVHw9GbN66wyfakGYgdTBvokmXQk"))).run(sender=admin,voting_powers = voting_powers)
    scenario.verify(swapContract.baker==sp.some(sp.key_hash("tz1YB12JHVHw9GbN66wyfakGYgdTBvokmXQk")))

    scenario.h3("Alice fails to withdraw commission fees")
    # only admin can transfer service fees
    scenario += swapContract.transferFees(bob.address).run(sender=alice, valid=False)

    scenario.h3("Update Baker")
    scenario += swapContract.transferFees(bob.address).run(sender=admin)
    scenario.verify(swapContract.balance == sp.tez(0))

    scenario.h3("Transfer rights from Admin to Bob")
    scenario += swapContract.updateAdmin(bob.address).run(sender=admin)
        sp.verify(params.amount >= 1000000000)
        sp.verify(params.amount % 1000000000 == 0 )

        sp.verify(sp.len(self.data.poolSet.elements()) <= self.data.PoolSize)

        sp.if self.data.poolSet.contains(sp.sender):

            self.data.LiquidityProvider[sp.sender].amount += params.amount 

        sp.else:  

            sp.if self.data.LiquidityProvider.contains(sp.sender):
                self.data.LiquidityProvider[sp.sender].amount += params.amount 

            sp.else:
                self.data.LiquidityProvider[sp.sender] = sp.record(amount=0,premium=sp.nat(0),locked = sp.nat(0))        
                self.data.LiquidityProvider[sp.sender].amount += params.amount 

            self.data.poolSet.add(sp.sender)

        self.data.totalSupply += params.amount 

        # Transfer function 

        c = sp.contract(sp.TRecord(from_ = sp.TAddress, to_ = sp.TAddress , value = sp.TNat), self.data.token, entry_point = "transfer").open_some()

        mydata = sp.record(from_ = sp.sender,to_ = sp.self_address, value = params.amount)

        sp.transfer(mydata, sp.mutez(0), c)

        self.data.shares[sp.sender] = abs(share - sharesBurned)
        tezPerShare = sp.split_tokens(self.data.tezPool, sp.nat(1), self.data.totalShares)
        tokensPerShare = sp.nat(self.data.tokenPool / self.data.totalShares)
        tezDivested = sp.split_tokens(tezPerShare, sharesBurned, sp.nat(1))
        tokensDivested = tokensPerShare * sharesBurned

        sp.verify(tezDivested >= minTez, message="Wrong minTez")
        sp.verify(tokensDivested >= minTokens, message="Wrong minTokens")

        self.data.totalShares -= sharesBurned
        self.data.tezPool -= tezDivested
        self.data.tokenPool -= tokensDivested
        sp.if self.data.totalShares == 0:
            self.data.invariant = sp.mutez(0)
        sp.else:
            self.data.invariant = sp.split_tokens(self.data.tezPool, self.data.tokenPool, sp.nat(1))

        sp.if self.data.candidates.contains(sp.sender):
            prevVotes = self.data.votes.get(self.data.candidates[sp.sender], 0)
            self.data.votes[self.data.candidates[sp.sender]] = abs(
                prevVotes - sharesBurned)

        token_contract = sp.contract(
            sp.TRecord(account_from=sp.TAddress,
                       destination=sp.TAddress,
                       value=sp.TNat),
            address=self.data.tokenAddress,
            entry_point="Transfer"
        ).open_some()

        sp.transfer(sp.record(account_from=self.data.address,
Beispiel #14
0
        return allowed

    @sp.entry_point
    def Transfer(self, params):
        account_from = params.account_from
        destination = params.destination
        value = params.value
        sp.if account_from != destination:
            sp.verify(self.IsAllowed(account_from=account_from,
                                     value=value),
                      message="Sender not allowed to spend token from source")
        src = self.data.ledger[account_from]
        sp.verify(value <= src.balance, message="Source balance is too low")
        src.balance = abs(src.balance - value)
        self.data.ledger[account_from] = src
        dst = sp.record(balance=sp.nat(0), allowances=sp.map(
            tkey=sp.TAddress, tvalue=sp.TNat))
        self.data.ledger[destination] = self.data.ledger.get(destination, dst)
        self.data.ledger[destination].balance += value
        sp.if src.allowances.contains(sp.sender):
            allow_value = sp.local(
                "allow_value", src.allowances[sp.sender]).value - value
            src.allowances[sp.sender] = sp.as_nat(allow_value)
        self.data.ledger[account_from] = src

    @sp.entry_point
    def Mint(self, params):
        value = params.value
        sp.verify(sp.sender == self.data.owner,
                  message="You must be the owner of the contract to mint tokens")
        def_val = sp.record(balance=sp.nat(0), allowances=sp.map(
Beispiel #15
0
 def empty(self):
     if self.config.assume_consecutive_token_ids:
         # The "set" is its cardinal.
         return sp.nat(0)
     else:
         return sp.set(t = token_id_type)
Beispiel #16
0
import smartpy as sp
from time import sleep

LEADERSHIP_PAYMENT_AMOUNT = sp.mutez(200000) # two tenths of a tez
COUNTDOWN_DROP_FACTOR = sp.nat(3*60*60*1000)
MINIMAL_COUNT_DOWN_MILLISECONDS = sp.nat(5*60*1000)
INITIAL_BALANCE = sp.mutez(100000000)

class TZButton(sp.Contract):
    def __init__(self):
        self.init(
            leader=sp.address("tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz"),
            leadership_start_timestamp=sp.timestamp(999999999999999),
            countdown_milliseconds = sp.nat(24*60*60*1000)
        )

    @sp.entry_point
    def default(self, params):
        sp.verify(sp.amount == LEADERSHIP_PAYMENT_AMOUNT)
        sp.verify(self.data.leadership_start_timestamp.add_seconds(sp.to_int(self.data.countdown_milliseconds/1000)) > sp.now)
        self.data.leader = sp.sender
        self.data.leadership_start_timestamp = sp.now
        
        balance_weight_tenthtez = sp.fst(sp.ediv(sp.balance-INITIAL_BALANCE,sp.mutez(1)).open_some())/sp.nat(100000) # mutez becomes tenth of a tez

        countdown_drop_milliseconds = (COUNTDOWN_DROP_FACTOR+balance_weight_tenthtez)/balance_weight_tenthtez
        sp.if self.data.countdown_milliseconds - countdown_drop_milliseconds > sp.to_int(MINIMAL_COUNT_DOWN_MILLISECONDS):
            self.data.countdown_milliseconds = sp.as_nat(self.data.countdown_milliseconds - countdown_drop_milliseconds)
        sp.else:
            self.data.countdown_milliseconds = MINIMAL_COUNT_DOWN_MILLISECONDS
                sp.TVariant(
                    add_operator = UpdateOperatorsRequest.get_operator_param_type(),
                    remove_operator = UpdateOperatorsRequest.get_operator_param_type())
        )

class TokenMetadata():
    def get_type():
        return sp.TRecord(
                    token_id=sp.TNat, token_info=sp.TMap(k = sp.TString, v= sp.TBytes)).layout(("token_id", "token_info"))

INITIAL_BID = sp.mutez(900000)
MINIMAL_BID = sp.mutez(100000)
INITIAL_AUCTION_DURATION = sp.int(24*5)
MINIMAL_AUCTION_DURATION = sp.int(1)
MAXIMAL_AUCTION_DURATION = sp.int(24*7)
MAXIMAL_TOKEN_ID = sp.nat(1689)
THRESHOLD_ADDRESS = sp.address("tz3jfebmewtfXYD1Xef34TwrfMg2rrrw6oum") # this is the biggest tz3 after this only KT...
DEFAULT_ADDRESS = sp.address("tz1RKmJwoAiaqFdjQYSbFy1j7u7UhEFsqXq7")
AUCTION_EXTENSION_THRESHOLD = sp.int(60*5) # 5 minutes
BID_STEP_THRESHOLD = sp.mutez(100000)

class AcuteArtFA2(sp.Contract):
    def __init__(self, initial_auction_house_address, minter):
        self.init(
            initial_auction_house_address = initial_auction_house_address,
            ledger = sp.big_map(tkey=LedgerKey.get_type(), tvalue=sp.TNat),
            token_metadata = sp.big_map(tkey=sp.TNat, tvalue=TokenMetadata.get_type()),
            total_supply=sp.big_map(tkey=sp.TNat, tvalue=sp.TNat),
            allowances = sp.big_map(tkey=AllowanceKey.get_type(), tvalue=sp.TBool),
            minter = minter,
            token_royalties = sp.big_map(tkey=sp.TNat, tvalue=sp.TUnit),
Beispiel #18
0
 def __init__(self):
     self.init(
         leader=sp.address("tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz"),
         leadership_start_timestamp=sp.timestamp(999999999999999),
         countdown_milliseconds = sp.nat(24*60*60*1000)
     )
Beispiel #19
0
    def test():
        c1 = HENDao([sp.address("tz1owner1"), sp.address("tz1owner2")])
        scenario = sp.test_scenario()
        scenario.h1("Test Buy")
        scenario += c1
        user1 = sp.address("tz1owner1")
        user2 = sp.address("tz1owner2")

        scenario.h2("Buying disabled when locked")
        c1.vote_buy(swap_id=sp.nat(123), price=sp.mutez(0), objkt_amount=sp.nat(1)).run(valid=False, sender=user1)
        
        scenario.h2("Buying enabled when unlocked")
        c1.vote_lock(True).run(sender=user1)
        c1.vote_lock(True).run(sender=user2)
        
        c1.vote_buy(swap_id=sp.nat(123), objkt_amount=sp.nat(1), price=sp.mutez(0)).run(sender=user1)
        
        # Proposal should pass
        c1.vote_buy(swap_id=sp.nat(123), objkt_amount=sp.nat(1), price=sp.mutez(0)).run(sender=user2)
        scenario.verify(c1.data.buy_proposals[123].passed == True)
        
        # Double vote fails
        c1.vote_buy(swap_id=sp.nat(123), objkt_amount=sp.nat(1), price=sp.mutez(0)).run(sender=user2, valid=False)
        c1.vote_buy(swap_id=sp.nat(123), objkt_amount=sp.nat(1), price=sp.mutez(0)).run(sender=user1, valid=False)

        # Test undo
        c1.vote_buy(swap_id=sp.nat(456), objkt_amount=sp.nat(1), price=sp.mutez(5)).run(sender=user1)
        c1.undo_vote_buy(456).run(sender=user1)
        scenario.verify(c1.data.buy_proposals[456].votes.contains(user1) == False)
Beispiel #20
0
    def default(self, params):
        sp.verify(sp.amount == LEADERSHIP_PAYMENT_AMOUNT)
        sp.verify(self.data.leadership_start_timestamp.add_seconds(sp.to_int(self.data.countdown_milliseconds/1000)) > sp.now)
        self.data.leader = sp.sender
        self.data.leadership_start_timestamp = sp.now
        
        balance_weight_tenthtez = sp.fst(sp.ediv(sp.balance-INITIAL_BALANCE,sp.mutez(1)).open_some())/sp.nat(100000) # mutez becomes tenth of a tez

        countdown_drop_milliseconds = (COUNTDOWN_DROP_FACTOR+balance_weight_tenthtez)/balance_weight_tenthtez
        sp.if self.data.countdown_milliseconds - countdown_drop_milliseconds > sp.to_int(MINIMAL_COUNT_DOWN_MILLISECONDS):
            self.data.countdown_milliseconds = sp.as_nat(self.data.countdown_milliseconds - countdown_drop_milliseconds)
Beispiel #21
0
        self.addAddressIfNecessary(sp.sender)
        sp.verify(~self.is_paused(), FA12_Error.Paused)
        alreadyApproved = self.data.balances[sp.sender].approvals.get(params.spender, 0)
        sp.verify((alreadyApproved == 0) | (params.value == 0), FA12_Error.UnsafeAllowanceChange)
        self.data.balances[sp.sender].approvals[params.spender] = params.value

    def addAddressIfNecessary(self, address):
        sp.if ~ self.data.balances.contains(address):
            self.data.balances[address] = sp.record(balance = 0, approvals = {})

    @sp.utils.view(sp.TNat)
    def getBalance(self, params):
        sp.if self.data.balances.contains(params):
            sp.result(self.data.balances[params].balance)
        sp.else:
            sp.result(sp.nat(0))

    @sp.utils.view(sp.TNat)
    def getAllowance(self, params):
        sp.if self.data.balances.contains(params.owner):
            sp.result(self.data.balances[params.owner].approvals.get(params.spender, 0))
        sp.else:
            sp.result(sp.nat(0))

    @sp.utils.view(sp.TNat)
    def getTotalSupply(self, params):
        sp.set_type(params, sp.TUnit)
        sp.result(self.data.totalSupply)

    # this is not part of the standard but can be supported through inheritance.
    def is_paused(self):
class AdministratorState:
    """Static enum used for the admin rights and propose flow"""    
    IS_ADMIN = sp.nat(1)
    """This state shows that the admin right is there"""
    IS_PROPOSED_ADMIN = sp.nat(2)
    """This state shows that the admin has been proposed but not full admin yet"""
 def __init__(
         self,
         governorAddress=sp.address("tz1abmz7jiCV2GH2u81LRrGgAFFgvQgiDiaf"),
 ):
     self.init(governorAddress=governorAddress, value=sp.nat(0))
Beispiel #24
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))