Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue10 - Detect and claim unclaimed profits #91

15 changes: 15 additions & 0 deletions pdr_backend/models/predictoor_contract.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import time
from typing import List

from enforce_typing import enforce_types
from eth_keys import KeyAPI
Expand Down Expand Up @@ -218,6 +219,20 @@ def get_agg_predval(self, timestamp):
print(e)
return None

def payout_multiple(self, slots: List[int], wait_for_receipt=True):
"""Claims the payout for given slots"""
gasPrice = self.config.w3.eth.gas_price
try:
tx = self.contract_instance.functions.payoutMultiple(
slots, self.config.owner
).transact({"from": self.config.owner, "gasPrice": gasPrice})
if not wait_for_receipt:
return tx
return self.config.w3.eth.wait_for_transaction_receipt(tx)
except Exception as e:
print(e)
return None

def payout(self, slot, wait_for_receipt=False):
"""Claims the payout for a slot"""
gasPrice = self.config.w3.eth.gas_price
Expand Down
4 changes: 2 additions & 2 deletions pdr_backend/predictoor/approach1/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def process_topic(address, timestamp):
predictoor_contract.payout(slot, False)

if seconds_till_epoch_end <= int(os.getenv("SECONDS_TILL_EPOCH_END", 60)):
"""Timestamp of prediction"""
# Timestamp of prediction
if do_prediction(topic, epoch, predictoor_contract):
topics[address]["last_submited_epoch"] = epoch

Expand All @@ -87,7 +87,7 @@ def do_prediction(topic, epoch, predictoor_contract):
)
return False

"""We have a prediction, let's submit it"""
# We have a prediction, let's submit it
stake_amount = (
os.getenv("STAKE_AMOUNT", 1) * predicted_confidence / 100
) # TODO have a customizable function to handle this
Expand Down
23 changes: 23 additions & 0 deletions pdr_backend/predictoor/payout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import List

from pdr_backend.models.predictoor_contract import PredictoorContract
from pdr_backend.util.subgraph import query_pending_payouts


def request_payout(predictoor_contract: PredictoorContract, timestamps: List[int]):
predictoor_contract.payout_multiple(timestamps, True)


def batchify(data, batch_size):
return [data[i : i + batch_size] for i in range(0, len(data), batch_size)]


def claim_pending_payouts(
subgraph_url: str, predictoor_contract: PredictoorContract, batch_size: int
):
addr = predictoor_contract.config.owner
pending = query_pending_payouts(subgraph_url, addr)
batches = batchify(pending, batch_size)

for batch in batches:
request_payout(predictoor_contract, batch)
35 changes: 35 additions & 0 deletions pdr_backend/util/subgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"""

import os
import requests
from typing import Optional, Dict, List

import requests
Expand Down Expand Up @@ -135,6 +136,40 @@ def query_subgraph(subgraph_url: str, query: str) -> Dict[str, dict]:
return result


def query_pending_payouts(subgraph_url: str, addr: str) -> List[int]:
chunk_size = 1000
offset = 0
timestamps: List[int] = []

while True:
query = """
{
predictPredictions(
where: {user: "%s", payout: null}
) {
id
timestamp
}
}
""" % (
addr
)

offset += chunk_size
try:
result = query_subgraph(subgraph_url, query)
if not "data" in result:
print("No data in result")
break
predict_predictions = result["data"]["predictPredictions"]
timestamps_query = [i["timestamp"] for i in predict_predictions]
timestamps.extend(timestamps_query)
except Exception as e:
print("An error occured", e)

return timestamps


@enforce_types
def query_predictContracts( # pylint: disable=too-many-statements
subgraph_url: str,
Expand Down