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)
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)
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)
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)
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 mul(self, pair): self.data.mulResult = sp.some(sp.fst(pair) * sp.snd(pair))
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 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)