Beispiel #1
0
def test():
    scenario = sp.test_scenario()
    rightful_owner = sp.test_account("Alice")
    attacker = sp.test_account("Robert")
    c1 = TestCheckSignature(rightful_owner.public_key)

    scenario += c1
    # Let's build a successful call:
    #
    scenario.h2("Successful Call")
    first_message_packed = sp.pack(
        sp.record(o="Hello World", n="should work", c=0))
    sig_from_alice = sp.make_signature(secret_key=rightful_owner.secret_key,
                                       message=first_message_packed,
                                       message_format="Raw")
    scenario += c1.setCurrentValue(
        newValue="should work", userSignature=sig_from_alice).run(valid=True)
    #
    scenario.h2("Replay Attack")
    scenario.p(
        "Trying to reuse the same signature is blocked by the value of the counter."
    )
    scenario += c1.setCurrentValue(
        newValue="should work", userSignature=sig_from_alice).run(valid=False)
    #
    #
    scenario.h2("Signature From Wrong Secret Key")
    scenario.p("Signing the right thing from a different secret-key.")
    #
    #
    # Gives:
    second_message_packed = sp.pack(
        sp.record(o="should work", n="Hello again World", c=1))
    sig_from_bob = sp.make_signature(secret_key=attacker.secret_key,
                                     message=second_message_packed,
                                     message_format="Raw")
    scenario += c1.setCurrentValue(newValue="Hello again World",
                                   userSignature=sig_from_bob).run(valid=False)
    #
    scenario.h2("Second Successful Call")
    scenario.p(
        "Showing that the previous call failed <b>because</b> of the secret-key (signing same bytes)."
    )
    sig_from_alice = sp.make_signature(secret_key=rightful_owner.secret_key,
                                       message=second_message_packed,
                                       message_format="Raw")
    scenario += c1.setCurrentValue(
        newValue="Hello again World",
        userSignature=sig_from_alice).run(valid=True)
Beispiel #2
0
 def bobSignsState():
     scenario.p("Bob signs the current state.")
     result = sp.make_signature(bob.secret_key, sp.pack(
         sp.record(id=c1.data.id, name="state", seq=cBob.data.seq, state=cBob.data.baseState)))
     result = scenario.compute(result)
     scenario.show(sp.record(seq=cBob.data.seq, sig=result))
     return result
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Update Fails With Bad Signature")

        scenario.h2("GIVEN an Oracle contract")
        assetCode = "XTZ-USD"

        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        scenario.h2("AND an update signed by an alternative key")
        alternativeAccount = sp.test_account("AlternativeAccount")
        alternativeSecretKey = alternativeAccount.secret_key
        start = sp.timestamp(1)
        end = sp.timestamp(2)
        open = 3
        high = 4
        low = 5
        close = 6
        volume = 7
        updateData = (
            start,
            (end,
            (open,
            (high,
            (low,
                (close, volume))))))
        message = sp.pack(updateData)
        signature = sp.make_signature(
            alternativeSecretKey,
            message,
            message_format='Raw'
        )

        scenario.h2("WHEN the oracle is updated")
        update = sp.pair(signature, updateData)
        parameter = sp.map(
            l={
                assetCode: update
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )

        scenario.h2("THEN the update fails")
        scenario += contract.update(parameter).run(valid=False)
Beispiel #4
0
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)
Beispiel #5
0
def test():
    scenario = sp.test_scenario()
    scenario.h1("Quote Updation SC with on-chain sig verification")
    first_owner = sp.test_account("Aniket")
    second_owner = sp.test_account("Sachin")

    # Let's display the accounts:
    scenario.h2("Accounts")
    scenario.show([first_owner, second_owner])

    c1 = QuoteDapp(first_owner.public_key)

    scenario += c1

    # Successful call:
    scenario.h2("Successful Call")
    scenario.p(
        "when the second owner is the signer and the pkh provided is also of the second_owner"
    )
    first_message_packed = sp.pack(
        sp.record(o=second_owner.public_key, n="should work", c=0))
    sig_from_sachin = sp.make_signature(secret_key=second_owner.secret_key,
                                        message=first_message_packed,
                                        message_format="Raw")
    scenario += c1.changeQuote(
        newQuote="should work",
        userSignature=sig_from_sachin,
        newOwner=second_owner.public_key).run(valid=True)

    scenario.h2("Replay Attack")
    scenario.p(
        "Trying to reuse the same signature is blocked by the value of the nonce."
    )
    scenario += c1.changeQuote(
        newQuote="seems like a replay attack",
        userSignature=sig_from_sachin,
        newOwner=second_owner.public_key).run(valid=False)

    scenario.h2("Un-successful Call")
    scenario.p(
        "when the second owner is the signer and the pkh provided is also of the first_owner, then in this case the call should fail"
    )
    scenario += c1.changeQuote(
        newQuote="should not work",
        userSignature=sig_from_sachin,
        newOwner=first_owner.public_key).run(valid=False)
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Incorrect Revoke Fails to Revoke An Oracle")

        scenario.h2(
            "GIVEN an oracle contract and a revoke message signed by another account.")
        testAccount = sp.test_account("Incorrect_Account")
        message = sp.pack(sp.none)
        signature = sp.make_signature(
            testAccount.secret_key,
            message,
            message_format='Raw'
        )

        assetCode = "XTZ-USD"
        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        scenario.h2("WHEN revoke is called")
        scenario.h2("THEN the call fails")
        scenario += contract.revoke(signature).run(valid=False)

        scenario.h2("AND future updates succeed")
        start = sp.timestamp(1)
        end = sp.timestamp(2)
        open = 3
        high = 4
        low = 5
        close = 6
        volume = 7
        updateData = (
            start,
            (end,
            (open,
            (high,
            (low,
                (close, volume))))))
        message = sp.pack((assetCode, updateData))
        signature = sp.make_signature(
            testAccountSecretKey,
            message,
            message_format='Raw'
        )

        update = sp.pair(signature, updateData)
        parameter = sp.map(
            l={
                assetCode: update
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter)
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Revokes An Oracle")

        scenario.h2(
            "GIVEN an oracle contract and a correctly signed revoke message.")
        message = sp.pack(sp.none)
        signature = sp.make_signature(
            testAccountSecretKey,
            message,
            message_format='Raw'
        )

        assetCode = "XTZ-USD"
        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        scenario.h2("WHEN revoke is called.")
        scenario += contract.revoke(signature)

        scenario.h2("THEN the oracle is revoked")
        scenario.verify(~contract.data.publicKey.is_some())

        scenario.h2("AND the oracle's data no longer contains the original asset")
        scenario.verify(~contract.data.oracleData.contains(assetCode))

        scenario.h2("AND future updates fail.")
        start = sp.timestamp(1)
        end = sp.timestamp(2)
        open = 3
        high = 4
        low = 5
        close = 6
        volume = 7
        updateData = (
            start,
            (end,
            (open,
            (high,
            (low,
                (close, volume))))))
        message = sp.pack((assetCode, updateData))
        signature = sp.make_signature(
            testAccountSecretKey,
            message,
            message_format='Raw'
        )

        update = sp.pair(signature, updateData)
        parameter = sp.map(
            l={
                assetCode: update
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter).run(valid=False)
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Untracked Asset does not update oracle")

        scenario.h2("GIVEN an Oracle contract tracking an asset")
        assetCode = "XTZ-USD"

        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        start1 = sp.timestamp(2)
        end1 = sp.timestamp(3)
        open1 = 3
        high1 = 4
        low1 = 5
        close1 = 6
        volume1 = 7
        updateData1 = (
            start1,
            (end1,
            (open1,
            (high1,
            (low1,
                (close1, volume1))))))
        message1 = sp.pack((assetCode, updateData1))
        signature1 = sp.make_signature(
            testAccountSecretKey,
            message1,
            message_format='Raw'
        )

        update1 = sp.pair(signature1, updateData1)
        parameter1 = sp.map(
            l={
                assetCode: update1
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter1)

        scenario.h2("WHEN the oracle is updated with an untracked asset")
        untrackedAsset = "BTC-USD"
        start2 = sp.timestamp(4)
        end2 = sp.timestamp(5)
        open2 = 8
        high2 = 9
        low2 = 10
        close2 = 11
        volume2 = 12
        updateData2 = (
            start2,
            (end2,
            (open2,
            (high2,
            (low2,
                (close2, volume2))))))
        message2 = sp.pack((untrackedAsset, updateData2))
        signature2 = sp.make_signature(
            testAccountSecretKey,
            message2,
            message_format='Raw'
        )

        update2 = sp.pair(signature2, updateData2)
        parameter2 = sp.map(
            l={
                untrackedAsset: update2
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter2)

        scenario.h2("THEN the oracle only contains the data for the tracked asset.")
        assetData = contract.data.oracleData[assetCode]
        endPair = sp.snd(assetData)
        openPair = sp.snd(endPair)
        highPair = sp.snd(openPair)
        lowPair = sp.snd(highPair)
        closeAndVolumePair = sp.snd(lowPair)

        oracleStart = sp.fst(assetData)
        oracleEnd = sp.fst(endPair)
        oracleOpen = sp.fst(openPair)
        oracleHigh = sp.fst(highPair)
        oracleLow = sp.fst(lowPair)
        oracleClose = sp.fst(closeAndVolumePair)
        oracleVolume = sp.snd(closeAndVolumePair)

        scenario.verify(oracleStart == start1)
        scenario.verify(oracleEnd == end1)
        scenario.verify(oracleOpen == open1)
        scenario.verify(oracleHigh == high1)
        scenario.verify(oracleLow == low1)
        scenario.verify(oracleClose == close1)
        scenario.verify(oracleVolume == volume1)

        scenario.h2("AND does not contain data for the untracked asset")
        scenario.verify(~contract.data.oracleData.contains(untrackedAsset))
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Correctly Processes Updates With Data From The Past")

        scenario.h2("GIVEN an Oracle contract with some initial data.")
        assetCode = "XTZ-USD"

        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        start1 = sp.timestamp(3)
        end1 = sp.timestamp(4)
        open1 = 3
        high1 = 4
        low1 = 5
        close1 = 6
        volume1 = 7
        updateData1 = (
            start1,
            (end1,
            (open1,
            (high1,
            (low1,
                (close1, volume1))))))
        message1 = sp.pack((assetCode, updateData1))
        signature1 = sp.make_signature(
            testAccountSecretKey,
            message1,
            message_format='Raw'
        )

        update1 = sp.pair(signature1, updateData1)
        parameter1 = sp.map(
            l={
                assetCode: update1
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter1)

        scenario.h2("WHEN the oracle is updated with a time in the past")
        start2 = sp.timestamp(1) # In past
        end2 = sp.timestamp(2)
        open2 = 8
        high2 = 9
        low2 = 10
        close2 = 11
        volume2 = 12
        updateData2 = (
            start2,
            (end2,
            (open2,
            (high2,
            (low2,
                (close2, volume2))))))
        message2 = sp.pack(updateData2)
        signature2 = sp.make_signature(
            testAccountSecretKey,
            message2,
            message_format='Raw'
        )

        update2 = sp.pair(signature2, updateData2)
        parameter2 = sp.map(
            l={
                assetCode: update2
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter2)

        scenario.h2("THEN the update in the past does not modify the data.")
        assetData = contract.data.oracleData[assetCode]
        endPair = sp.snd(assetData)
        openPair = sp.snd(endPair)
        highPair = sp.snd(openPair)
        lowPair = sp.snd(highPair)
        closeAndVolumePair = sp.snd(lowPair)

        oracleStart = sp.fst(assetData)
        oracleEnd = sp.fst(endPair)
        oracleOpen = sp.fst(openPair)
        oracleHigh = sp.fst(highPair)
        oracleLow = sp.fst(lowPair)
        oracleClose = sp.fst(closeAndVolumePair)
        oracleVolume = sp.snd(closeAndVolumePair)

        scenario.verify(oracleStart == start1)
        scenario.verify(oracleEnd == end1)
        scenario.verify(oracleOpen == open1)
        scenario.verify(oracleHigh == high1)
        scenario.verify(oracleLow == low1)
        scenario.verify(oracleClose == close1)
        scenario.verify(oracleVolume == volume1)
Beispiel #10
0
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Second Update Overwrites First Update")

        scenario.h2("GIVEN an Oracle contract")
        assetCode = "XTZ-USD"
        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        scenario.h2("AND two updates")
        start1 = sp.timestamp(1)
        end1 = sp.timestamp(2)
        open1 = 3
        high1 = 4
        low1 = 5
        close1 = 6
        volume1 = 7
        updateData1 = (
            start1,
            (end1,
            (open1,
            (high1,
            (low1,
                (close1, volume1))))))
        message1 = sp.pack((assetCode, updateData1))
        signature1 = sp.make_signature(
            testAccountSecretKey,
            message1,
            message_format='Raw'
        )

        start2 = sp.timestamp(8)
        end2 = sp.timestamp(9)
        open2 = 10
        high2 = 11
        low2 = 12
        close2 = 13
        volume2 = 14
        updateData2 = (
            start2,
            (end2,
            (open2,
            (high2,
            (low2,
                (close2, volume2))))))
        message2 = sp.pack((assetCode, updateData2))
        signature2 = sp.make_signature(
            testAccountSecretKey,
            message2,
            message_format='Raw'
        )

        scenario.h2("WHEN the oracle is updated")
        update1 = sp.pair(signature1, updateData1)
        update2 = sp.pair(signature2, updateData2)
        parameter1 = sp.map(
            l={
                assetCode: update1
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        parameter2 = sp.map(
            l={
                assetCode: update2
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter1)
        scenario += contract.update(parameter2)

        scenario.h2("THEN the oracle contains the data points of the latter update")
        assetData = contract.data.oracleData[assetCode]
        endPair = sp.snd(assetData)
        openPair = sp.snd(endPair)
        highPair = sp.snd(openPair)
        lowPair = sp.snd(highPair)
        closeAndVolumePair = sp.snd(lowPair)

        oracleStart = sp.fst(assetData)
        oracleEnd = sp.fst(endPair)
        oracleOpen = sp.fst(openPair)
        oracleHigh = sp.fst(highPair)
        oracleLow = sp.fst(lowPair)
        oracleClose = sp.fst(closeAndVolumePair)
        oracleVolume = sp.snd(closeAndVolumePair)

        scenario.verify(oracleStart == start2)
        scenario.verify(oracleEnd == end2)
        scenario.verify(oracleOpen == open2)
        scenario.verify(oracleHigh == high2)
        scenario.verify(oracleLow == low2)
        scenario.verify(oracleClose == close2)
        scenario.verify(oracleVolume == volume2)
Beispiel #11
0
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Onchain view returns correct data")

        scenario.h2("GIVEN an Oracle contract")
        contract = OracleContract(
            publicKey=testAccountPublicKey,
        )
        scenario += contract

        scenario.h2("AND an update")
        assetCode = "XTZ-USD"
        start = sp.timestamp(1)
        end = sp.timestamp(2)
        open = 3
        high = 4
        low = 5
        close = 6
        volume = 7
        updateData = (
            start,
            (
                end,
                (
                    open,
                    (
                        high,
                        (
                            low,
                           (close, volume)
                        )
                    )
                )
            )
        )
        message = sp.pack((assetCode, updateData))
        signature = sp.make_signature(
            testAccountSecretKey,
            message,
            message_format='Raw'
        )

        scenario.h2("AND the oracle is updated")
        update = sp.pair(signature, updateData)
        parameter = sp.map(
            l={
                assetCode: update
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter)

        scenario.h2("WHEN data is read from an onchain view")
        scenario.h2("THEN the data matches the latest update")
        scenario.verify(sp.fst(contract.getPrice(assetCode)) == start)
        scenario.verify(sp.fst(sp.snd(contract.getPrice(assetCode))) == end)
        scenario.verify(sp.fst(sp.snd(sp.snd(contract.getPrice(assetCode)))) == open)
        scenario.verify(sp.fst(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode))))) == high)
        scenario.verify(sp.fst(sp.snd(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode)))))) == low)
        scenario.verify(sp.fst(sp.snd(sp.snd(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode))))))) == close)
        scenario.verify(sp.snd(sp.snd(sp.snd(sp.snd(sp.snd(sp.snd(contract.getPrice(assetCode))))))) == volume)
def test():
    
    chain_id=sp.chain_id_cst("0x9caecab9")
    scenario = sp.test_scenario()
    scenario.h1("Generic Multi Signature Executor")
    scenario.table_of_contents()
    
    admin = sp.test_account("Administrator")
    alice = sp.test_account("Alice")
    bob = sp.test_account("Robert")
    dan = sp.test_account("Dan")
    
    # Let's display the accounts:
    scenario.h2("Accounts")
    scenario.show([admin, alice, bob, dan])
    
    admin = sp.test_account("Administrator")
    
    # We have not found a way to pack for signature lambdas in smartpy directly
    # Hence we are using the tezos-client for helping out
    # The following payload assumes chain id 0x7a06a770, nonce 1, and a lambda hitting the honey pot at address tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz
    # tezos-client -S -P 443 -A delphinet-tezos.giganode.io hash data 'Pair 0x7a06a770 (Pair 1 { DROP; NIL operation; PUSH address "tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz"; CONTRACT unit; IF_SOME {} { UNIT; FAILWITH }; PUSH mutez 0; UNIT; TRANSFER_TOKENS; CONS })' of type 'pair (chain_id) (pair (nat) (lambda unit (list operation)))'
    # Raw packed data: 0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b

    
    honey_pot = HoneyPot()
    honey_pot.address = sp.address("tz1d393dnaDkbGk8GiKhhy1PX5qgF8XDKpEz")
    executor = Executor(sp.nat(2), [sp.key("edpkumVGEtDQgDAcMyB5FRn7UBLuhzg6D7aEnCDamXgjqGxavnsgvP"), sp.key("edpkv6MFhAVnpAhrvMjdW1tGfLDDiU6i6P9kt3ZmyiiMpxCsB5Cg4v"), sp.key("edpktwdcwT8iMDWcg2ePJ6J1sbwXYdn7GYJWyRybi8vpkrv4aduFHt")])
    scenario += executor
    scenario += honey_pot
    
    
    def execution_payload(x):
        sp.set_type(x, sp.TUnit)
        honey_pot_contract = sp.contract(sp.TUnit, honey_pot.address).open_some()
        sp.result([sp.transfer_operation(sp.unit, sp.mutez(0), honey_pot_contract)])
    
    #lambda_packer = LambdaPacker(honey_pot.address)
    #scenario += lambda_packer
    #scenario += lambda_packer.pack_signing_payload()
    
    #execution_payload_pack = sp.pack(execution_payload)
    #scenario.show(execution_payload_pack)
    #signing_payload = ExecutionRequest.get_signing_payload(chain_id, sp.nat(1), execution_payload)
    alice_signature = sp.make_signature(alice.secret_key, sp.bytes("0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b"))
    bob_signature = sp.make_signature(bob.secret_key, sp.bytes("0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b"))
    dan_signature = sp.make_signature(dan.secret_key, sp.bytes("0x0507070a000000047a06a77007070001020000004a0320053d036d0743036e0a000000160000bed9025f33e3e29f09c45528114877c7628099e60555036c0200000010072f0200000004034f032702000000000743036a0000034f034d031b"))
    
    signatures= sp.map({sp.hash_key(bob.public_key):bob_signature, sp.hash_key(alice.public_key): alice_signature, sp.hash_key(dan.public_key):dan_signature})
    
    execution_request = sp.set_type_expr(sp.record(execution_payload=execution_payload, signatures=signatures),ExecutionRequest.get_type())
    scenario.show(signatures)
    
    
    executor = TimeLockedExecutor(sp.nat(2), [alice.public_key, bob.public_key, dan.public_key], sp.nat(60))
    scenario += executor
    
    signatures= sp.map({sp.hash_key(bob.public_key):bob_signature, sp.hash_key(alice.public_key): alice_signature, sp.hash_key(dan.public_key):dan_signature})
    
    execution_request = sp.set_type_expr(sp.record(execution_payload=execution_payload, signatures=signatures),ExecutionRequest.get_type())
    
    #scenario += executor.update_signatories()
    
    #scenario += executor.execute(execution_request).run(sender=admin, chain_id=sp.chain_id_cst("0x7a06a770"))
    #scenario += executor.default(test2).run(sender=admin)
    #scenario += honey_pot
    
Beispiel #13
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()
Beispiel #14
0
def test():
    scenario = sp.test_scenario()
    scenario.h1("eCoupon - Multi-asset contracts")
    scenario.table_of_contents()
    # sp.test_account generates ED25519 key-pairs deterministically:
    admin = sp.test_account("Administrator")
    alice = sp.test_account("Alice")
    bob = sp.test_account("Robert")
    dan = sp.test_account("Dan")
    # Let's display the accounts:
    scenario.h2("Accounts")
    scenario.show([admin, alice, bob])
    c1 = ECouponMultiToken(admin.address)
    scenario += c1
    scenario.h2("Initial Minting")
    scenario.p("The administrator mints 100 token-0's to Alice.")
    scenario += c1.mint(address=alice.address,
                        amount=100,
                        symbol='TK0',
                        token_id=0, decimals=0, name="WETZ").run(sender=admin)

    scenario.h2("Meta Transacting")
    transaction1 = sp.record(
        to_=bob.address,
        token_id=0,
        amount=10)
    transaction2 = sp.record(
        to_=dan.address,
        token_id=0,
        amount=5)
    unsigned_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=1,
        txs=[transaction1, transaction2]
    )
    payload = sp.pack(
        BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer))
    signature = sp.make_signature(alice.secret_key, payload)

    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=1,
        signature=signature,
        txs=[transaction1, transaction2]
    )

    # scenario.show(sp.unpack(sp.pack(sp.hash_key(alice.public_key))),html=False)
    scenario.p("perform first metatransfer (with nonce 1)")
    scenario += c1.meta_transfer([signed_meta_transfer]).run(sender=admin)

    scenario.p("replay attack: same message with nonce 1")
    scenario += c1.meta_transfer([signed_meta_transfer]
                                 ).run(sender=admin, valid=False)

    transaction2 = sp.record(
        to_=dan.address,
        token_id=0,
        amount=6)
    unsigned_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=1,
        txs=[transaction1, transaction2]
    )
    payload = sp.pack(
        BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer))
    signature = sp.make_signature(alice.secret_key, payload)

    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=1,
        signature=signature,
        txs=[transaction1, transaction2]
    )
    scenario.p("replay attack: different message with nonce 1")
    scenario += c1.meta_transfer([signed_meta_transfer]
                                 ).run(sender=admin, valid=False)

    unsigned_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=2,
        txs=[transaction1, transaction2]
    )
    payload = sp.pack(
        BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer))
    signature = sp.make_signature(alice.secret_key, payload)

    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=2,
        signature=signature,
        txs=[transaction1, transaction2]
    )
    scenario.p("next nonce transfer")
    scenario += c1.meta_transfer([signed_meta_transfer]).run(sender=admin)

    scenario.p("replay attack: lie about nonce (signed 2, saying 3)")
    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=3,
        signature=signature,
        txs=[transaction1, transaction2]
    )
    scenario += c1.meta_transfer([signed_meta_transfer]
                                 ).run(sender=admin, valid=False)

    scenario.p("replay attack: lie about nonce (signed 2, saying 1)")
    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=1,
        signature=signature,
        txs=[transaction1, transaction2]
    )
    scenario += c1.meta_transfer([signed_meta_transfer]
                                 ).run(sender=admin, valid=False)
    scenario.p("multi user meta transaction batching")
    unsigned_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=3,
        txs=[transaction1, transaction2]
    )
    payload = sp.pack(
        BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer))
    signature = sp.make_signature(alice.secret_key, payload)

    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=3,
        signature=signature,
        txs=[transaction1, transaction2]
    )

    bob_transaction1 = sp.record(
        to_=alice.address,
        token_id=0,
        amount=1)
    bob_transaction2 = sp.record(
        to_=dan.address,
        token_id=0,
        amount=1)
    bob_unsigned_meta_transfer = sp.record(
        from_public_key=bob.public_key,
        nonce=1,
        txs=[bob_transaction1, bob_transaction2]
    )
    payload = sp.pack(BatchMetaTransfer.get_signing_payload(
        bob_unsigned_meta_transfer))
    signature = sp.make_signature(bob.secret_key, payload)

    bob_signed_meta_transfer = sp.record(
        from_public_key=bob.public_key,
        nonce=1,
        signature=signature,
        txs=[bob_transaction1, bob_transaction2]
    )

    dan_transaction1 = sp.record(
        to_=bob.address,
        token_id=0,
        amount=1)
    dan_transaction2 = sp.record(
        to_=alice.address,
        token_id=0,
        amount=1)
    dan_unsigned_meta_transfer = sp.record(
        from_public_key=dan.public_key,
        nonce=1,
        txs=[dan_transaction1, dan_transaction2]
    )
    payload = sp.pack(BatchMetaTransfer.get_signing_payload(
        dan_unsigned_meta_transfer))
    signature = sp.make_signature(dan.secret_key, payload)

    dan_signed_meta_transfer = sp.record(
        from_public_key=dan.public_key,
        nonce=1,
        signature=signature,
        txs=[dan_transaction1, dan_transaction2]
    )
    scenario += c1.meta_transfer([signed_meta_transfer, bob_signed_meta_transfer,
                                  dan_signed_meta_transfer]).run(sender=admin)

    scenario.p("normal user cannot publish meta transaction")
    unsigned_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=4,
        txs=[transaction1, transaction2]
    )
    payload = sp.pack(
        BatchMetaTransfer.get_signing_payload(unsigned_meta_transfer))
    signature = sp.make_signature(alice.secret_key, payload)

    signed_meta_transfer = sp.record(
        from_public_key=alice.public_key,
        nonce=4,
        signature=signature,
        txs=[transaction1, transaction2]
    )
    scenario += c1.meta_transfer([signed_meta_transfer]
                                 ).run(sender=alice, valid=False)
    scenario.h2("Normal Transfer (FA2)")
    scenario.p("normal user cannot transfer own funds")
    scenario += c1.transfer([BatchTransfer.item(from_=alice.address,
                                                txs=[
                                                    sp.record(to_=bob.address,
                                                              amount=1,
                                                              token_id=0)]),
                             BatchTransfer.item(from_=alice.address,
                                                txs=[
                                                    sp.record(to_=dan.address,
                                                              amount=1,
                                                              token_id=0)])
                             ]).run(sender=alice, valid=False)

    scenario.p("normal user cannot transfer other's funds")
    scenario += c1.transfer([BatchTransfer.item(from_=bob.address,
                                                txs=[
                                                    sp.record(to_=alice.address,
                                                              amount=1,
                                                              token_id=0)]),
                             BatchTransfer.item(from_=alice.address,
                                                txs=[
                                                    sp.record(to_=dan.address,
                                                              amount=1,
                                                              token_id=0)])
                             ]).run(sender=alice, valid=False)

    scenario.p("admin can transfer everything")
    scenario += c1.transfer([BatchTransfer.item(from_=bob.address,
                                                txs=[
                                                    sp.record(to_=alice.address,
                                                              amount=1,
                                                              token_id=0)]),
                             BatchTransfer.item(from_=alice.address,
                                                txs=[
                                                    sp.record(to_=dan.address,
                                                              amount=1,
                                                              token_id=0)])
                             ]).run(sender=admin)

    scenario.p("only admin can cleanup nonce")
    scenario += c1.cleanup_nonce([alice.address, bob.address,
                                  admin.address]).run(sender=bob, valid=False)

    scenario.p("correct admin can cleanup nonce")
    scenario += c1.cleanup_nonce([alice.address, bob.address,
                                  admin.address]).run(sender=admin, valid=True)

    scenario.p("fail direct admin change")
    scenario += c1.set_administrator(
        bob.address).run(sender=admin, valid=False)

    scenario.p("admin change with wrong initial address")
    scenario += c1.propose_administrator(
        alice.address).run(sender=admin, valid=True)
    scenario += c1.set_administrator(
        bob.address).run(sender=bob, valid=False)

    scenario.p(
        "wrong admin change (bob needs to actually change admin, we want to validate he has ability to create txs)")
    scenario += c1.propose_administrator(
        bob.address).run(sender=admin, valid=True)
    scenario += c1.set_administrator(
        bob.address).run(sender=admin, valid=False)

    scenario.p("correct admin change")
    scenario += c1.propose_administrator(
        bob.address).run(sender=admin, valid=True)
    scenario += c1.set_administrator(
        bob.address).run(sender=bob, valid=True)
Beispiel #15
0
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Update with stale asset does not fail")

        scenario.h2("GIVEN an Oracle contract tracking two assets with an initial update")
        assetCode1 = "XTZ-USD"
        assetCode2 = "BTC-USD"

        contract = OracleContract(
            publicKey=testAccountPublicKey,
            initialData=sp.big_map(
                l={
                    assetCode1: initialOracleData,
                    assetCode2: initialOracleData
                },
                tkey=sp.TString,
                tvalue=Harbinger.OracleDataType
            )
        )
        scenario += contract

        start1 = sp.timestamp(1)
        end1 = sp.timestamp(2)
        open1 = 3
        high1 = 4
        low1 = 5
        close1 = 6
        volume1 = 7
        
        updateData1 = (
            start1,
            (end1,
            (open1,
            (high1,
            (low1,
                (close1, volume1))))))

        asset1Message1 = sp.pack((assetCode1, updateData1))
        asset1Signature1 = sp.make_signature(
            testAccountSecretKey,
            asset1Message1,
            message_format='Raw'
        )

        asset2Message1 = sp.pack((assetCode2, updateData1))
        asset2Signature1 = sp.make_signature(
            testAccountSecretKey,
            asset2Message1,
            message_format='Raw'
        )

        asset1Update1 = sp.pair(asset1Signature1, updateData1)
        asset2Update1 = sp.pair(asset2Signature1, updateData1)

        parameter = sp.map(
            l={
                assetCode1: asset1Update1,
                assetCode2: asset2Update1,            
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter)

        scenario.h2("WHEN an update is posted to the oracle with only one asset containing new data")
        start2 = sp.timestamp(2)
        end2 = sp.timestamp(3)
        open2 = 8
        high2 = 9
        low2 = 10
        close2 = 11
        volume2 = 12
        
        updateData2 = (
            start2,
            (end2,
            (open2,
            (high2,
            (low2,
                (close2, volume2))))))

        asset1Message2 = sp.pack((assetCode1, updateData2))
        asset1Signature2 = sp.make_signature(
            testAccountSecretKey,
            asset1Message2,
            message_format='Raw'
        )

        asset1Update2 = sp.pair(asset1Signature2, updateData2)

        parameter = sp.map(
            l={
                assetCode1: asset1Update2,
                assetCode2: asset2Update1,            
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter)

        scenario.h2("THEN data for the asset with two updates is the second update.")
        assetData1 = contract.data.oracleData[assetCode1]
        endPair1 = sp.snd(assetData1)
        openPair1 = sp.snd(endPair1)
        highPair1 = sp.snd(openPair1)
        lowPair1 = sp.snd(highPair1)
        closeAndVolumePair1 = sp.snd(lowPair1)

        oracleStart1 = sp.fst(assetData1)
        oracleEnd1 = sp.fst(endPair1)
        oracleOpen1 = sp.fst(openPair1)
        oracleHigh1 = sp.fst(highPair1)
        oracleLow1 = sp.fst(lowPair1)
        oracleClose1 = sp.fst(closeAndVolumePair1)
        oracleVolume1 = sp.snd(closeAndVolumePair1)

        scenario.verify(oracleStart1 == start2)
        scenario.verify(oracleEnd1 == end2)
        scenario.verify(oracleOpen1 == open2)
        scenario.verify(oracleHigh1 == high2)
        scenario.verify(oracleLow1 == low2)
        scenario.verify(oracleClose1 == close2)
        scenario.verify(oracleVolume1 == volume2)

        scenario.h2("THEN data for the asset with two updates is the second update.")
        assetData2 = contract.data.oracleData[assetCode2]
        endPair2 = sp.snd(assetData2)
        openPair2 = sp.snd(endPair2)
        highPair2 = sp.snd(openPair2)
        lowPair2 = sp.snd(highPair2)
        closeAndVolumePair2 = sp.snd(lowPair2)

        oracleStart2 = sp.fst(assetData2)
        oracleEnd2 = sp.fst(endPair2)
        oracleOpen2 = sp.fst(openPair2)
        oracleHigh2 = sp.fst(highPair2)
        oracleLow2 = sp.fst(lowPair2)
        oracleClose2 = sp.fst(closeAndVolumePair2)
        oracleVolume2 = sp.snd(closeAndVolumePair2)

        scenario.verify(oracleStart2 == start1)
        scenario.verify(oracleEnd2 == end1)
        scenario.verify(oracleOpen2 == open1)
        scenario.verify(oracleHigh2 == high1)
        scenario.verify(oracleLow2 == low1)
        scenario.verify(oracleClose2 == close1)
        scenario.verify(oracleVolume2 == volume1)
Beispiel #16
0
    def test():

        scenario = sp.test_scenario()
        scenario.h1("FA1.2 template - Fungible assets")

        scenario.table_of_contents()

        # sp.test_account generates ED25519 key-pairs deterministically:
        admin = sp.test_account("Administrator")
        alice = sp.test_account("Alice")
        bob = sp.test_account("Robert")
        carlos = sp.test_account("Carlos")

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

        scenario.h1("Contract")
        c1 = FA12(admin.address)

        scenario.h1("Entry points")
        scenario += c1
        scenario.h2("Admin mints a few coins")
        scenario += c1.mint(address=alice.address, value=12).run(sender=admin)
        scenario += c1.mint(address=alice.address, value=3).run(sender=admin)
        scenario += c1.mint(address=alice.address, value=3).run(sender=admin)
        scenario.verify(c1.data.balances[alice.address].balance == 18)
        scenario.h2("Alice transfers to Bob")
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=4).run(sender=alice)
        scenario.verify(c1.data.balances[alice.address].balance == 14)
        scenario.h2(
            "Bob tries to transfer from Alice but he doesn't have her approval"
        )
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=4).run(sender=bob, valid=False)
        scenario.h2("Alice approves Bob and Bob transfers")
        scenario += c1.approve(spender=bob.address, value=5).run(sender=alice)
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=4).run(sender=bob)
        scenario.h2("Bob tries to over-transfer from Alice")
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=4).run(sender=bob, valid=False)
        scenario.h2("Admin burns Bob token")
        scenario += c1.burn(address=bob.address, value=1).run(sender=admin)
        scenario.verify(c1.data.balances[alice.address].balance == 10)
        scenario.h2("Alice tries to burn Bob token")
        scenario += c1.burn(address=bob.address, value=1).run(sender=alice,
                                                              valid=False)
        scenario.h2(
            "Admin pauses the contract and Alice cannot transfer anymore")
        scenario += c1.setPause(True).run(sender=admin)
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=4).run(sender=alice, valid=False)
        scenario.verify(c1.data.balances[alice.address].balance == 10)
        scenario.h2("Admin transfers while on pause")
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=1).run(sender=admin)
        scenario.h2("Admin unpauses the contract and transfers are allowed")
        scenario += c1.setPause(False).run(sender=admin)
        scenario.verify(c1.data.balances[alice.address].balance == 9)
        scenario += c1.transfer(from_=alice.address, to_=bob.address,
                                value=1).run(sender=alice)

        scenario.verify(c1.data.totalSupply == 17)
        scenario.verify(c1.data.balances[alice.address].balance == 8)
        scenario.verify(c1.data.balances[bob.address].balance == 9)

        scenario.h2("Permit Submissions")
        scenario += c1.mint(address=carlos.address, value=10).run(sender=admin)
        scenario.verify(c1.data.balances[carlos.address].balance == 10)
        # add permit for transfer of 10 from carlos to bob. alice submits with correct info and also calls.
        params_bytes_1 = sp.pack(
            sp.pair(carlos.address, sp.pair(bob.address, 10)))
        params_bytes_2 = sp.pack(
            sp.pair(bob.address, sp.pair(carlos.address, 10)))
        params_hash_1 = sp.blake2b(params_bytes_1)
        params_hash_2 = sp.blake2b(params_bytes_2)
        unsigned_1 = sp.pack(
            sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address),
                    sp.pair(0, params_hash_1)))
        signature_1 = sp.make_signature(secret_key=carlos.secret_key,
                                        message=unsigned_1,
                                        message_format="Raw")
        unsigned_2 = sp.pack(
            sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address),
                    sp.pair(1, params_hash_2)))
        signature_2 = sp.make_signature(secret_key=bob.secret_key,
                                        message=unsigned_2,
                                        message_format="Raw")

        scenario += c1.permit([
            sp.pair(carlos.public_key, sp.pair(signature_1, params_hash_1)),
            sp.pair(bob.public_key, sp.pair(signature_2, params_hash_2))
        ]).run(sender=alice,
               now=sp.timestamp(1571761674),
               chain_id=sp.chain_id_cst("0x9caecab9"))
        scenario.verify(c1.data.counter == 2)
        scenario.verify_equal(
            c1.data.permits[(sp.pair(carlos.address, params_hash_1))],
            sp.timestamp(1571761674))
        scenario.verify_equal(
            c1.data.permits[(sp.pair(bob.address, params_hash_2))],
            sp.timestamp(1571761674))

        scenario.h2("Execute transfer using permit")
        scenario += c1.transfer(from_=carlos.address,
                                to_=bob.address,
                                value=10).run(sender=bob,
                                              now=sp.timestamp(1571761674))
        scenario.verify(c1.data.balances[carlos.address].balance == 0)
        scenario.verify(c1.data.balances[bob.address].balance == 19)
        # Permit deleted
        scenario.verify(
            ~c1.data.permits.contains(sp.pair(carlos.address, params_hash_1)))

        scenario += c1.transfer(from_=bob.address,
                                to_=carlos.address,
                                value=10).run(sender=carlos,
                                              now=sp.timestamp(1571761674))
        scenario.verify(c1.data.balances[carlos.address].balance == 10)
        scenario.verify(c1.data.balances[bob.address].balance == 9)
        # Permit deleted
        scenario.verify(
            ~c1.data.permits.contains(sp.pair(bob.address, params_hash_2)))

        # Set Expiry to 0 and try to execute transfer at time less than submission_time + default_expiry, expect invalid transfer
        scenario.h2("Expired Permit")
        unsigned_3 = sp.pack(
            sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address),
                    sp.pair(2, params_hash_1)))
        signature_3 = sp.make_signature(secret_key=carlos.secret_key,
                                        message=unsigned_3,
                                        message_format="Raw")
        scenario += c1.permit([
            sp.pair(carlos.public_key, sp.pair(signature_3, params_hash_1))
        ]).run(sender=alice,
               now=sp.timestamp(1571761674),
               chain_id=sp.chain_id_cst("0x9caecab9"))
        scenario.verify(c1.data.counter == 3)
        scenario.verify_equal(
            c1.data.permits[(sp.pair(carlos.address, params_hash_1))],
            sp.timestamp(1571761674))
        scenario += c1.setExpiry(address=carlos.address,
                                 seconds=0,
                                 permit=sp.some(params_hash_1)).run(
                                     sender=carlos,
                                     now=sp.timestamp(1571761674))
        scenario.verify(c1.data.permit_expiries[sp.pair(
            carlos.address, params_hash_1)].open_some() == 0)
        scenario += c1.transfer(from_=carlos.address,
                                to_=bob.address,
                                value=10).run(
                                    sender=bob,
                                    now=sp.timestamp(1571761680),
                                    valid=False)  # Uses later time stamp

        scenario.h2("Delete Expired Permit")
        scenario += c1.delete_permits([sp.pair(carlos.address, params_hash_1)
                                       ]).run(now=sp.timestamp(1571761680))
        scenario.verify(~c1.data.permit_expiries.contains(
            sp.pair(carlos.address, params_hash_1)))
        scenario.verify(
            ~c1.data.permits.contains(sp.pair(carlos.address, params_hash_1)))

        scenario.h1("Views")
        scenario.h2("Balance")
        view_balance = Viewer(sp.TNat)
        scenario += view_balance
        scenario += c1.getBalance(arg=sp.record(owner=alice.address),
                                  target=view_balance.address)
        scenario.verify_equal(view_balance.data.last, sp.some(8))

        scenario.h2("Administrator")
        view_administrator = Viewer(sp.TAddress)
        scenario += view_administrator
        scenario += c1.getAdministrator(target=view_administrator.address)
        scenario.verify_equal(view_administrator.data.last,
                              sp.some(admin.address))

        scenario.h2("Total Supply")
        view_totalSupply = Viewer(sp.TNat)
        scenario += view_totalSupply
        scenario += c1.getTotalSupply(target=view_totalSupply.address)
        scenario.verify_equal(view_totalSupply.data.last, sp.some(27))

        scenario.h2("Allowance")
        view_allowance = Viewer(sp.TNat)
        scenario += view_allowance
        scenario += c1.getAllowance(arg=sp.record(owner=alice.address,
                                                  spender=bob.address),
                                    target=view_allowance.address)
        scenario.verify_equal(view_allowance.data.last, sp.some(1))

        scenario.h2("Counter")
        view_counter = Viewer(sp.TNat)
        scenario += view_counter
        scenario += c1.getCounter(target=view_counter.address)
        scenario.verify_equal(view_counter.data.last, sp.some(3))

        scenario.h2("Default Expiry")
        view_defaultExpiry = Viewer(sp.TNat)
        scenario += view_defaultExpiry
        scenario += c1.getDefaultExpiry(target=view_defaultExpiry.address)
        scenario.verify_equal(view_defaultExpiry.data.last, sp.some(50000))
Beispiel #17
0
    def test():
        scenario = sp.test_scenario()
        scenario.h1("Update Once With Valid Data")

        scenario.h2("GIVEN an Oracle contract")
        contract = OracleContract(
            publicKey=testAccountPublicKey,
        )
        scenario += contract

        scenario.h2("AND an update")
        assetCode = "XTZ-USD"
        start = sp.timestamp(1)
        end = sp.timestamp(2)
        open = 3
        high = 4
        low = 5
        close = 6
        volume = 7
        updateData = (
            start,
            (end,
            (open,
            (high,
            (low,
                (close, volume))))))
        message = sp.pack((assetCode, updateData))
        signature = sp.make_signature(
            testAccountSecretKey,
            message,
            message_format='Raw'
        )

        scenario.h2("WHEN the oracle is updated")
        update = sp.pair(signature, updateData)
        parameter = sp.map(
            l={
                assetCode: update
            },
            tkey=sp.TString,
            tvalue=SignedOracleDataType
        )
        scenario += contract.update(parameter)

        scenario.h2("THEN the oracle contains the data points")
        assetData = contract.data.oracleData["XTZ-USD"]
        endPair = sp.snd(assetData)
        openPair = sp.snd(endPair)
        highPair = sp.snd(openPair)
        lowPair = sp.snd(highPair)
        closeAndVolumePair = sp.snd(lowPair)

        expectedStart = sp.fst(assetData)
        expectedEnd = sp.fst(endPair)
        expectedOpen = sp.fst(openPair)
        expectedHigh = sp.fst(highPair)
        expecteLow = sp.fst(lowPair)
        expectedClose = sp.fst(closeAndVolumePair)
        expectedVolume = sp.snd(closeAndVolumePair)

        scenario.verify(start == expectedStart)
        scenario.verify(end == expectedEnd)
        scenario.verify(open == expectedOpen)
        scenario.verify(high == expectedHigh)
        scenario.verify(low == expecteLow)
        scenario.verify(close == expectedClose)
        scenario.verify(volume == expectedVolume)