Пример #1
0
 def mutualClose(self, params):
     sp.verify(self.data.status == OPEN)
     # Check customer signature
     sp.verify(sp.check_signature(self.data.custPk,
                                  params.custSig,
                                  sp.pack(sp.record(
                                          chanID = self.data.chanID,
                                          custAddr = self.data.custAddr,
                                          merchAddr = self.data.merchAddr,
                                          custBal = params.custBal,
                                          merchBal = params.merchBal)
                                         )
                                 ))
     # Check merchant signature
     sp.verify(sp.check_signature(self.data.merchPk,
                                  params.merchSig,
                                  sp.pack(sp.record(
                                          chanID = self.data.chanID,
                                          custAddr = self.data.custAddr,
                                          merchAddr = self.data.merchAddr,
                                          custBal = params.custBal,
                                          merchBal = params.merchBal)
                                         )
                                 ))
     self.data.custBal = params.custBal
     self.data.merchBal = params.merchBal
     sp.send(self.data.custAddr, self.data.custBal)
     sp.send(self.data.merchAddr, self.data.merchBal)
     self.data.custBal = sp.tez(0)
     self.data.merchBal = sp.tez(0)
     self.data.status = CLOSED
Пример #2
0
def test():
    c = myContract()

    secret = sp.string('My secret message')
    password = sp.string('avada_kedavra')
    packed = sp.pack(secret) + sp.pack(password)
    hashed = sp.sha256(packed)

    scenario = sp.test_scenario()
    scenario.register(c, show=True)  # same as scenario += c
    c.store_hash(hashed)
 def channelAccuseDoubleMove(self, params):
     sp.verify(self.data.active)
     self.data.active = False
     sp.verify(params.msg1.seq == params.msg2.seq)
     sp.set_type(params.msg1.seq, sp.TInt)
     sp.set_type(params.msg1.state, sp.type_of(self.data.baseState))
     sp.set_type(params.msg2.state, sp.type_of(self.data.baseState))
     sp.verify(sp.pack(params.msg1) != sp.pack(params.msg2))
     sp.if params.party == 1:
         self.checkHasDoubleSigned(self.data.party1, params)
         sp.send(self.data.party2.address, self.data.party1.bond + self.data.party2.bond)
Пример #4
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)
Пример #5
0
    def update(self, params):
        # If there is no value for the public key, the oracle is revoked. Ignore updates.
        sp.verify(self.data.publicKey.is_some(), "revoked")

        # Iterate over assets in the input map.
        keyValueList = params.items()
        sp.for assetData in keyValueList:
            # Extract asset names, signatures, and the new data.
            assetName = assetData.key
            signature = sp.compute(sp.fst(assetData.value))
            newData = sp.compute(sp.snd(assetData.value))

            # Verify Oracle is tracking this asset.
            sp.if self.data.oracleData.contains(assetName):
                # Verify start timestamp is newer than the last update.
                oldData = sp.compute(self.data.oracleData[assetName])
                oldStartTime = sp.compute(sp.fst(oldData))
                newStartTime = sp.compute(sp.fst(newData))    
                sp.if newStartTime > oldStartTime:                
                    # Verify signature.
                    bytes = sp.pack((assetName, newData))
                    sp.verify(
                        sp.check_signature(
                            self.data.publicKey.open_some(), signature, bytes
                        ),
                        "bad sig"
                    )

                    # Replace the data.
                    self.data.oracleData[assetName] = newData
Пример #6
0
    def meta_transfer(self, params):
        sp.verify(sp.sender == self.data.administrator)
        sp.set_type(params, BatchMetaTransfer.get_type())

        sp.for meta_transfer in params:
            source_account_key_hash = sp.hash_key(
                meta_transfer.from_public_key)
            source_account = sp.to_address(
                sp.implicit_account(source_account_key_hash))

            sp.verify(self.data.nonces.get(
                source_account, 0)+1 == meta_transfer.nonce)

            packed_data = sp.pack(
                BatchMetaTransfer.get_signing_payload(meta_transfer))

            sp.verify(sp.check_signature(meta_transfer.from_public_key,
                                         meta_transfer.signature, packed_data), message=ErrorMessage.invalid_signature())

            self.data.nonces[source_account] = meta_transfer.nonce

            sp.for tx in meta_transfer.txs:
                from_user = LedgerKey.make(source_account, tx.token_id)
                to_user = LedgerKey.make(tx.to_, tx.token_id)
                sp.verify(tx.amount > 0,
                          message=ErrorMessage.transfer_of_zero())
                sp.verify(self.data.ledger[from_user] >= tx.amount,
                          message=ErrorMessage.insufficient_balance())
                self.data.ledger[from_user] = sp.as_nat(
                    self.data.ledger[from_user] - tx.amount)
                self.data.ledger[to_user] = self.data.ledger.get(
                    to_user, 0) + tx.amount

                sp.if self.data.ledger[from_user] == 0:
                    del self.data.ledger[from_user]
Пример #7
0
 def permit(self, params):
     sp.set_type(
         params,
         sp.TList(sp.TPair(sp.TKey, sp.TPair(sp.TSignature, sp.TBytes))))
     sp.verify(~self.data.paused)
     with sp.for_('permit', params) as permit:
         params_hash = sp.snd(sp.snd(permit))
         unsigned = sp.pack(
             sp.pair(sp.pair(sp.chain_id, sp.self_address),
                     sp.pair(self.data.counter, params_hash)))
         pk_address = sp.to_address(
             sp.implicit_account(sp.hash_key(sp.fst(permit))))
         permit_key = sp.pair(pk_address, params_hash)
         permit_exists = self.data.permits.contains(permit_key)
         effective_expiry = self.getEffectiveExpiry(
             sp.pair(pk_address, params_hash))
         permit_submission_timestamp = self.data.permits[permit_key]
         sp.verify(
             ~(permit_exists &
               (sp.as_nat(sp.now - permit_submission_timestamp) <
                effective_expiry)), sp.pair("DUP_PERMIT", params_hash))
         sp.verify(
             sp.check_signature(sp.fst(permit), sp.fst(sp.snd(permit)),
                                unsigned), sp.pair("MISSIGNED", unsigned))
         self.data.permits[sp.pair(pk_address, params_hash)] = sp.now
         self.data.counter = self.data.counter + 1
Пример #8
0
 def transfer_presigned(self, params):
     sp.set_type(
         params,
         sp.TRecord(from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat))
     params_hash = sp.blake2b(sp.pack(params))
     #unsigned = sp.blake2b(mi.operator("SELF; ADDRESS; CHAIN_ID; PAIR; PAIR; PACK", [sp.TPair(sp.TNat, sp.TBytes)], [sp.TBytes])(sp.pair(self.data.counter, params_hash)))
     permit_key = sp.pair(params.from_, params_hash)
     effective_expiry = sp.local("effective_expiry", 0)
     with sp.if_(self.data.permits.contains(permit_key)):
         permit_submission_timestamp = self.data.permits[permit_key]
         with sp.if_(
                 self.data.permit_expiries.contains(permit_key)
                 & self.data.permit_expiries[permit_key].is_some()):
             effective_expiry.value = self.data.permit_expiries[
                 permit_key].open_some()
         with sp.else_():
             with sp.if_(
                     self.data.user_expiries.contains(params.from_)
                     & self.data.user_expiries[params.from_].is_some()):
                 effective_expiry.value = self.data.user_expiries[
                     params.from_].open_some()
             with sp.else_():
                 effective_expiry.value = self.data.default_expiry
         # Deleting permit regardless of whether or not its expired
         with sp.if_(
                 sp.as_nat(sp.now - permit_submission_timestamp) >=
                 effective_expiry.value):
             # Expired
             self.delete_permit(permit_key)
             sp.result(sp.bool(False))
         with sp.else_():
             self.delete_permit(permit_key)
             sp.result(sp.bool(True))
     with sp.else_():
         sp.result(sp.bool(False))
Пример #9
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
Пример #10
0
 def make_key(self, owner, operator):
     metakey = sp.record(owner=owner, operator=operator)
     metakey = sp.set_type_expr(metakey, self.inner_type())
     if self.config.readable:
         return metakey
     else:
         return sp.pack(metakey)
Пример #11
0
def channelRenounce(self, params):
    sp.verify(self.data.active)
    self.data.active = False
    sp.
    if params.party == 1:
        if 1 not in self.no_checks:
            sig = params.sig.open_some() if self.no_checks else params.sig
            sp.verify(
                sp.check_signature(self.data.party1.pk, sig, sp.pack(sp.record(id=self.data.id, name="renounce"))))
        sp.send(self.data.party2.address, self.data.party1.bond + self.data.party2.bond - self.data.party1.looserClaim)
        sp.send(self.data.party1.address, self.data.party1.looserClaim)
    sp. else:
    if 2 not in self.no_checks:
        sig = params.sig.open_some() if self.no_checks else params.sig
        sp.verify(sp.check_signature(self.data.party2.pk, sig, sp.pack(sp.record(id=self.data.id, name="renounce"))))
    sp.send(self.data.party1.address, self.data.party1.bond + self.data.party2.bond - self.data.party2.looserClaim)
    sp.send(self.data.party2.address, self.data.party2.looserClaim)
Пример #12
0
 def make(user, token):
     sp.set_type(user, sp.TAddress)
     sp.set_type(token, token_id_type)
     result = sp.pair(user, token)
     if readable:
         return result
     else:
         return sp.pack(result)
Пример #13
0
 def changeQuote(self, params):
     thingToSign = sp.pack(
         sp.record(o=params.newOwner, n=params.newQuote, c=self.data.nonce))
     sp.verify(
         sp.check_signature(params.newOwner, params.userSignature,
                            thingToSign))
     self.data.currentQuote = params.newQuote
     self.data.owner = params.newOwner
     self.data.nonce = self.data.nonce + 1
Пример #14
0
    def make(self, user):
        user = sp.set_type_expr(user, sp.TAddress)

        result = user

        if self.config.readable:
            return result
        else:
            return sp.pack(result)
Пример #15
0
    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)
Пример #16
0
 def transfer_presigned(self, params):
     sp.set_type(params, sp.TRecord(
         from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat))
     params_hash = sp.blake2b(sp.pack(params))
     #unsigned = sp.blake2b(mi.operator("SELF; ADDRESS; CHAIN_ID; PAIR; PAIR; PACK", [sp.TPair(sp.TNat, sp.TBytes)], [sp.TBytes])(sp.pair(self.data.counter, params_hash)))
     permit_key = sp.pair(params.from_, params_hash)
     effective_expiry = sp.local("effective_expiry", 0)
     sp.if self.data.permits.contains(permit_key):
         permit_submission_timestamp = self.data.permits[permit_key]
         sp.if self.data.permit_expiries.contains(permit_key) & self.data.permit_expiries[permit_key].is_some():
             effective_expiry.value = self.data.permit_expiries[permit_key].open_some()
Пример #17
0
 def setCurrentValue(self, params):
     # We will also need Michelson SELF and CHAIN_ID to avoid all replay attacks:
     thingToSign = sp.pack(
         sp.record(o=self.data.currentValue,
                   n=params.newValue,
                   c=self.data.counter))
     sp.verify(
         sp.check_signature(self.data.bossPublicKey, params.userSignature,
                            thingToSign))
     self.data.currentValue = params.newValue
     self.data.counter = self.data.counter + 1
Пример #18
0
 def make(self, user, token):
     user = sp.set_type_expr(user, sp.TAddress)
     # token = sp.set_type_expr(token, token_id_type)
     if self.config.single_asset:
         result = user
     else:
         result = user
     if self.config.readable:
         return result
     else:
         return sp.pack(result)
Пример #19
0
    def request_fortune(self, params):
        
        self.data.client_requests[self.data.next_request_id] = sp.sender

        self.request_helper(params.payment,   
                            self.data.fortune_job_id,
                            sp.map(l = {"sender": sp.variant("bytes", sp.pack(sp.sender))}), 
                            self.data.oracle, 
                            self.data.waiting_fortune_id, 
                            sp.self_entry_point("receive_fortune"), 
                            params.timeout)
Пример #20
0
 def transfer_presigned(self, params):
     sp.set_type(params, sp.TRecord(
         from_=sp.TAddress, to_=sp.TAddress, value=sp.TNat))
     params_hash = sp.blake2b(sp.pack(params))
     permit_key = sp.pair(params.from_, params_hash)
     sp.if self.data.permit_data.permits.contains(permit_key):
         permit_submission_timestamp = self.data.permit_data.permits[permit_key]
         effective_expiry = self.getEffectiveExpiry(permit_key)
         # Deleting permit regardless of whether or not its expired
         sp.if sp.as_nat(sp.now - permit_submission_timestamp) >= effective_expiry:
             # Expired
             self.delete_permit(permit_key)
             sp.result(sp.bool(False))
Пример #21
0
 def revealBid(self, params):
     sp.verify(self.data.started)
     sp.verify(~self.data.ended)
     # verify now is more than round end time = start_time + round_time but 
     # less than start time + twice of round time
     sp.verify(sp.now > self.data.start_time.add_seconds(self.data.round_time))
     sp.verify(sp.now < self.data.start_time.add_seconds(2 * self.data.round_time))
     # bidder sends amt committed previusly minus amt locked as participation fee
     # if this doesn't match, possibly penalise the participant by seizing his deposit
     sp.verify(sp.mutez(params.value + self.data.deposit) == sp.amount)
     sp.verify(sp.sha256(sp.pack(params.value + self.data.deposit)) == self.data.sealed_bids[sp.sender])
     sp.if ~self.data.first_revealed:
         self.data.first_revealed = sp.bool(True)
Пример #22
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)
Пример #23
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)
Пример #24
0
    def revoke(self, param):
        # Recreate the message which should have been signed.
        message = sp.set_type_expr(sp.none, sp.TOption(sp.TKey))
        bytes = sp.pack(message)

        # Verify that the message is signed correctly.
        publicKey = self.data.publicKey.open_some()
        sp.verify(sp.check_signature(publicKey, param, bytes))

        # Revoke the Oracle's public Key.
        self.data.publicKey = sp.none

        # Remove all entries in the Oracle's map.
        self.data.oracleData = sp.big_map(
            l={},
            tkey=sp.TString,
            tvalue=Harbinger.OracleDataType
        )
Пример #25
0
 def permit(self, params):
     sp.set_type(params, sp.TList(
         sp.TPair(sp.TKey, sp.TPair(sp.TSignature, sp.TBytes))))
     sp.for permit in params:
         public_key = sp.fst(permit)
         signature = sp.fst(sp.snd(permit))
         params_hash = sp.snd(sp.snd(permit))
         #unsigned = sp.blake2b(mi.operator("SELF; ADDRESS; CHAIN_ID; PAIR; PAIR; PACK", [sp.TPair(sp.TNat, sp.TBytes)], [sp.TBytes])(sp.pair(self.data.permit_data.counter, params_hash)))
         unsigned = sp.pack(sp.pair(sp.pair(sp.chain_id, sp.self_address), sp.pair(
             self.data.permit_data.counter, params_hash)))
         pk_address = sp.to_address(
             sp.implicit_account(sp.hash_key(public_key)))
         permit_key = sp.pair(pk_address, params_hash)
         permit_exists = self.data.permit_data.permits.contains(permit_key)
         permit_submission_timestamp = self.data.permit_data.permits[permit_key]
         effective_expiry = self.getEffectiveExpiry(permit_key)
         sp.verify(~ (permit_exists & (sp.as_nat(sp.now - permit_submission_timestamp) < effective_expiry)),
             sp.pair(self.error_message.duplicate_permit(), params_hash))
         sp.verify(sp.check_signature(public_key, signature, unsigned), sp.pair(self.error_message.permit_missigned(), unsigned))
         self.data.permit_data.permits[permit_key] = sp.now
         self.data.permit_data.counter = self.data.permit_data.counter + 1
Пример #26
0
 def join_hDAO(self, params):
     sp.verify((sp.amount > sp.mutez(0)) & (sp.balance < sp.tez(730000)))
     
     c = sp.contract(
         sp.TRecord(
         address=sp.TAddress,
         amount=sp.TNat,
         token_id=sp.TNat,
         token_info=sp.TMap(sp.TString, sp.TBytes)
         ), 
         self.data.ung, 
         entry_point = "mint").open_some()
         
     sp.transfer(
         sp.record(
         address=sp.sender,
         amount=sp.fst(sp.ediv(sp.amount, sp.mutez(1)).open_some()),
         token_id=1,
         token_info={"": sp.pack("ipfs://QmS87PA42aKj6WgPM1vQMHxyavKJkswa5ycgAn1wbSrNgi")}
         ), 
         sp.mutez(0), 
         c)
     
     self.data.balance += sp.amount
Пример #27
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))
Пример #28
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)
 def checkSeqStateSignature(self, party, sig, seq, state):
     sp.verify(sp.check_signature(party.pk, sig, sp.pack(sp.record(id = self.data.id, name = "state", seq = seq, state = state))))
    # At any point, a party can renounce.
    # Doing so means that they keep their looserClaim.
    @sp.entry_point
    def channelRenounce(self, params):
        sp.verify(self.data.active)
        self.data.active = False
        sp.if params.party == 1:
            if 1 not in self.no_checks:
                sig = params.sig.open_some() if self.no_checks else params.sig
                sp.verify(sp.check_signature(self.data.party1.pk, sig, sp.pack(sp.record(id = self.data.id, name = "renounce"))))
            sp.send(self.data.party2.address, self.data.party1.bond + self.data.party2.bond - self.data.party1.looserClaim)
            sp.send(self.data.party1.address, self.data.party1.looserClaim)
        sp.else:
            if 2 not in self.no_checks:
                sig = params.sig.open_some() if self.no_checks else params.sig
                sp.verify(sp.check_signature(self.data.party2.pk, sig, sp.pack(sp.record(id = self.data.id, name = "renounce"))))
            sp.send(self.data.party1.address, self.data.party1.bond + self.data.party2.bond - self.data.party2.looserClaim)
            sp.send(self.data.party2.address, self.data.party2.looserClaim)

    # When a party wants to come back on-chain from off-chain interactions,
    # it can do two different things: renounce or call channelNewState.
    # channelNewState is called with a state that has been agreed upon off-chain and
    # two signatures to prove the agreement.
    @sp.entry_point
    def channelNewState(self, params):
        sp.verify(self.data.active)
        sp.verify(self.data.seq < params.msg.seq)
        self.data.seq = params.msg.seq
        self.checkSeqStateSignature(self.data.party1, params.sig1, params.msg.seq, params.msg.state)
        self.checkSeqStateSignature(self.data.party2, params.sig2, params.msg.seq, params.msg.state)
        self.data.baseState = params.msg.state