Beispiel #1
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
def test():
    scenario=sp.test_scenario()
    scenario.h1("Calls back correctly when a valid asset is provided")

    scenario.h2("GIVEN a Normalizer contract")
    assetCode = "XTZ-USD"
    contract=NormalizerContract(assetCodes=[assetCode])
    scenario += contract

    scenario.h2("AND a contract to call back to")
    dummyContract = DummyContract()
    scenario += dummyContract

    scenario.h2("AND a single data point")
    start1=sp.timestamp(1595104530) 
    high1=1
    low1=2
    close1=3
    volume1=4
    assetCode = "XTZ-USD"

    scenario += contract.update(
        makeMap(
            assetCode=assetCode,
            start=start1,
            end=sp.timestamp(1595104531),
            open=3059701,
            high=high1,
            low=low1,
            close=close1,
            volume=volume1
        )
    ).run(sender=defaultOracleContractAddress)

    scenario.h2("WHEN a request is made")
    contractHandle = sp.contract(
        sp.TPair(sp.TString, sp.TPair(sp.TTimestamp, sp.TNat)),
        dummyContract.address,
        entry_point = "callback"
    ).open_some()
    param = (assetCode, contractHandle)

    scenario.h2("THEN it succeeds.")
    scenario += contract.get(param)

    scenario.h2("AND the dummy contract captured the expected values")
    scenario.verify(sp.fst(dummyContract.data.capturedCallbackValue) == assetCode)
    scenario.verify(sp.fst(sp.snd(dummyContract.data.capturedCallbackValue)) == start1)

    expectedPartialVWAP = Harbinger.computeVWAP(
        high=high1,
        low=low1,
        close=close1,
        volume=volume1
    )
    expectedPrice = expectedPartialVWAP //  volume1
    scenario.verify(sp.snd(sp.snd(dummyContract.data.capturedCallbackValue)) == expectedPrice)
 def receiveNft(self, nft):
     sp.set_type(nft, sp.TTicket(sp.TNat))
     ticket_data, ticket_next = sp.read_ticket(nft)
     qty = sp.compute(sp.snd(sp.snd(ticket_data)))
     originator = sp.compute(sp.fst(ticket_data))
     id = sp.compute(sp.fst(sp.snd(ticket_data)))
     sp.verify(qty == 1, "Only send 1 Nft to this entrypoint")
     sp.verify(sp.source == self.data.admin,
               "Ticket needs to be sent by wallet admin")
     current_id = self.data.current_id
     new_map = sp.update_map(self.data.tickets, current_id,
                             sp.some(ticket_next))
     self.data.tickets = new_map
     self.data.current_id = current_id + 1
    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
 def setExpiry(self, params):
     sp.set_type(params, sp.TPair(sp.TAddress, sp.TPair(sp.TNat, sp.TOption(
         sp.TBytes))))
     address = sp.fst(params)
     new_expiry = sp.fst(sp.snd(params))
     possible_bytes = sp.snd(sp.snd(params))
     sp.verify(new_expiry <= self.data.permit_data.max_expiry, self.error_message.expiry_exceeds_max())
     sp.verify_equal(address, sp.sender, message=self.error_message.user_unauthorized())
     sp.if possible_bytes.is_some():
         some_permit = possible_bytes.open_some()
         permit_key = sp.pair(address, some_permit)
         sp.verify(self.data.permit_data.permits.contains(
             permit_key), self.error_message.permit_nonexistent())
         permit_submission_timestamp = self.data.permit_data.permits[permit_key]
         effective_expiry = self.getEffectiveExpiry(permit_key)
         sp.verify(sp.as_nat(sp.now - permit_submission_timestamp)
             < effective_expiry, self.error_message.permit_revoked())
         self.data.permit_data.permit_expiries[permit_key] = sp.some(new_expiry)
 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
 def getResponseFromHarbinger(self,response):
     sp.verify(self.data.admin.contains(sp.source) , "Un-authorized")
     
     sp.set_type(response , sp.TPair(sp.TString , sp.TPair(sp.TTimestamp , sp.TNat)))
     currentPrice=sp.local("currentPrice",sp.int(0))
     currentPrice = sp.to_int(sp.fst(sp.ediv(sp.snd(sp.snd(response)) , sp.nat(1000)).open_some()))
     
     currentCycle = sp.local("currentCycle" ,sp.int(0))
     currentCycle = sp.fst(sp.ediv(sp.level,self.data.blocksPerCycle).open_some())
     
     sp.verify(~self.data.cycleData.contains(currentCycle+self.data.stakingPeriod))
     
     
     
     rangeMap = sp.local("rangeMap" , sp.map(tkey = sp.TPair(sp.TInt, sp.TInt) , tvalue = sp.TMutez))
     
     iterator = sp.local("iterator" , sp.int(0))
     
     sp.while iterator.value<=self.data.rangeEnd:
         sp.if iterator.value+self.data.rangeStep<=self.data.rangeEnd:
             rangeMap.value[sp.pair(iterator.value,iterator.value+self.data.rangeStep)] =sp.mutez(0)
             rangeMap.value[(sp.int(-1)*(iterator.value+self.data.rangeStep),sp.int(-1)*iterator.value)] =sp.mutez(0)
    def test():
        scenario=sp.test_scenario()
        scenario.h1("Calls back correctly when a valid asset is provided")

        scenario.h2("GIVEN a Normalizer contract")
        assetCode = "XTZ-USD"
        contract=NormalizerContract(assetCodes=[assetCode])
        scenario += contract

        scenario.h2("AND a contract to call back to")
        dummyContract = DummyContract()
        scenario += dummyContract

        scenario.h2("AND a single data point")
        start1=sp.timestamp(1595104530) 
        high1=1
        low1=2
        close1=3
        volume1=4
        assetCode = "XTZ-USD"

        scenario += contract.update(
            makeMap(
                assetCode=assetCode,
                start=start1,
                end=sp.timestamp(1595104531),
                open=3059701,
                high=high1,
                low=low1,
                close=close1,
                volume=volume1
            )
        ).run(sender=defaultOracleContractAddress)

        scenario.h2("WHEN the onchain view is read")
        scenario.h2("THEN it the correct data is returned.")
        scenario.verify(sp.fst(contract.getPrice(assetCode)) == start1)

        expectedPartialVWAP = Harbinger.computeVWAP(
            high=high1,
            low=low1,
            close=close1,
            volume=volume1
        )
        expectedPrice = expectedPartialVWAP //  volume1
        scenario.verify(sp.snd(contract.getPrice(assetCode)) == expectedPrice)
 def checkIfWinnerAndDisburse(self,cycle):
     change = sp.local("change",sp.int(0))
     change = self.data.cycleData[cycle].endingPrice - self.data.cycleData[cycle].referencePrice
     changePercentQuotient = sp.local("changePercentQuotient",sp.int(0))
     changePercentQuotient.value = sp.mul(change , 10000)
     changePercentQuotient.value = sp.fst(sp.ediv(changePercentQuotient.value,self.data.cycleData[cycle].referencePrice).open_some())
     
     upperLimit = sp.local("upperLimit",sp.int(0))
     lowerLimit = sp.local("lowerLimit",sp.int(0))
     
     betsByCycle = self.data.bettors[sp.sender]
     lowerLimit = sp.fst(betsByCycle[cycle].range)
     upperLimit = sp.snd(betsByCycle[cycle].range)
     
     
     sp.if upperLimit != lowerLimit:
         sp.if lowerLimit<= changePercentQuotient.value:
             sp.if changePercentQuotient.value<upperLimit:
                 self.hasWon(cycle,betsByCycle[cycle].range)
    def get(self, requestPair):
        sp.set_type(requestPair, sp.TPair(sp.TString, sp.TContract(sp.TPair(sp.TString, sp.TPair(sp.TTimestamp, sp.TNat)))))

        # Destructure the arguments.
        requestedAsset = sp.compute(sp.fst(requestPair))
        callback = sp.compute(sp.snd(requestPair))

        # Verify this normalizer has data for the requested asset.
        sp.verify(
            self.data.assetMap.contains(requestedAsset),
            message="bad request"
        )

        # Callback with the requested data.
        assetData = self.data.assetMap[requestedAsset]
        normalizedPrice = assetData.computedPrice
        lastUpdateTime = assetData.lastUpdateTime
        callbackParam = (requestedAsset, (lastUpdateTime, normalizedPrice))
        sp.transfer(callbackParam, sp.mutez(0), callback)
    def update(self, updateMap):
        sp.set_type(updateMap, sp.TBigMap(sp.TString, Harbinger.OracleDataType))

        # Verify the sender is the whitelisted oracle contract.
        sp.verify(
            sp.sender == self.data.oracleContract,
            message="bad sender"
        )

        # Iterate over assets this normalizer is tracking
        sp.for assetCode in self.data.assetCodes:
            # Only process updates if this normalizer is tracking the asset code.
            sp.if updateMap.contains(assetCode):
                assetData = updateMap.get(assetCode)

                # Only process updates that are monotonically increasing in start times.
                updateStartTime = sp.compute(sp.fst(assetData))
                sp.if updateStartTime > self.data.assetMap[assetCode].lastUpdateTime:
                    # Extract required information
                    endPair = sp.compute(sp.snd(assetData))
                    openPair = sp.compute(sp.snd(endPair))
                    highPair = sp.compute(sp.snd(openPair))
                    lowPair = sp.compute(sp.snd(highPair))
                    closeAndVolumePair = sp.compute(sp.snd(lowPair))

                    high = sp.compute(sp.fst(highPair))
                    low = sp.compute(sp.fst(lowPair))
                    close = sp.compute(sp.fst(closeAndVolumePair))
                    volume = sp.compute(sp.snd(closeAndVolumePair))

                    # Ignore candles with zero volumes.
                    sp.if volume > 0:
                        # Calculate the the price for this data point.
                        # average price * volume
                        volumePrice = ((high + low + close) / 3) * volume

                        # Update the last updated time.
                        self.data.assetMap[assetCode].lastUpdateTime = updateStartTime

                        # Push the latest items to the FIFO queue
                        fifoDT.push(self.data.assetMap[assetCode].prices, volumePrice)
                        fifoDT.push(self.data.assetMap[assetCode].volumes, volume)

                        # Trim the queue if it exceeds the number of data points.
                        sp.if fifoDT.len(self.data.assetMap[assetCode].prices) > self.data.numDataPoints:
                            fifoDT.pop(self.data.assetMap[assetCode].prices)
                            fifoDT.pop(self.data.assetMap[assetCode].volumes)
Beispiel #12
0
    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))
Beispiel #13
0
    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 #14
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 #15
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)
Beispiel #16
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)
Beispiel #17
0
 def mul(self, pair):
     self.data.mulResult = sp.some(sp.fst(pair) * sp.snd(pair))
Beispiel #18
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 #19
0
 def setResult(self, params):
     sp.verify(sp.now >= self.data.endTime)
     sp.verify(~self.data.result.is_some())
     sp.verify((sp.sender == sp.fst(self.data.admin)) | (sp.sender == sp.snd(self.data.admin)))
     sp.verify((params.result == Position.Long) | (params.result == Position.Short))
     self.data.result = sp.some(params.result)
 def hasWon(self,cycle,range):
     betsByCycle = self.data.bettors[sp.sender]
     betAmount = sp.local("betAmount",sp.mutez(0))
     betAmount = betsByCycle[cycle].amount
     
     totalRewards = sp.local("totalRewards",sp.mutez(0))
     
     totalRewards = sp.split_tokens(self.data.cycleData[cycle].totalAmount , sp.as_nat(sp.fst(self.data.cycleData[cycle].roi)) , sp.as_nat(sp.snd(self.data.cycleData[cycle].roi)))
     
     totalRewards = sp.split_tokens(totalRewards , sp.nat(98) , sp.nat(100))
     
     reward = sp.split_tokens(totalRewards , sp.fst(sp.ediv(betAmount , sp.mutez(1)).open_some()) , sp.fst(sp.ediv(self.data.cycleData[cycle].amountByRange[range],sp.mutez(1)).open_some()) )
     
     betsByCycle[cycle].withdrawn=True
     betsByCycle[cycle].withdrawnAmount = betsByCycle[cycle].amount + reward
     sp.send(sp.sender , betsByCycle[cycle].amount + reward)