Skip to content

Commit

Permalink
More constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
ShayanShiravani committed Oct 9, 2023
1 parent 3b92067 commit c1076e9
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 3 deletions.
6 changes: 6 additions & 0 deletions core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,9 @@ def send_raw_tx(self, signed_tx):

def wait_for_transaction_receipt(self, tx_hash):
return self.w3.eth.wait_for_transaction_receipt(tx_hash)

def current_block(self):
return self.w3.eth.block_number

def get_transaction_by_hash(self, hash):
return self.w3.eth.get_transaction(hash)
46 changes: 46 additions & 0 deletions faucet/constraints.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import requests
from core.constraints import *
from core.utils import Web3Utils
from .models import DonationReceipt, Chain, ClaimReceipt

class DonationConstraint(ConstraintVerification):
Expand All @@ -17,6 +19,50 @@ def is_observed(self, *args, **kwargs):
class OptimismDonationConstraint(DonationConstraint):
_param_keys = []

def is_observed(self, *args, **kwargs):
try:
chain = Chain.objects.get(chain_id=10)
except:
return False
self._param_values[ConstraintParam.CHAIN] = chain.pk
return super().is_observed(*args, **kwargs)

class EvmClaimingGasConstraint(ConstraintVerification):
_param_keys = [
ConstraintParam.CHAIN
]

def is_observed(self, *args, **kwargs):
chain_pk = self._param_values[ConstraintParam.CHAIN]
chain = Chain.objects.get(pk=chain_pk)
w3 = Web3Utils(chain.rpc_url_private, chain.poa)
current_block = w3.current_block()
user_address = self.user_profile.wallets.get(wallet_type=chain.chain_type).address

first_internal_tx = requests.get(
f"{chain.explorer_api_url}/api?module=account&action=txlistinternal&address={user_address}&startblock=0&endblock={current_block}&page=1&offset=1&sort=asc&apikey={chain.explorer_api_key}"
)
first_internal_tx = first_internal_tx.json()
if first_internal_tx and first_internal_tx['status'] == '1':
first_internal_tx = first_internal_tx['result'][0]
if first_internal_tx and first_internal_tx['from'] == chain.fund_manager_address.lower()\
and first_internal_tx['isError'] == '0':
first_tx = requests.get(
f"{chain.explorer_api_url}/api?module=account&action=txlist&address={user_address}&startblock=0&endblock={current_block}&page=1&offset=1&sort=asc&apikey={chain.explorer_api_key}"
)
first_tx = first_tx.json()
if first_tx:
if not first_tx['result']:
return True
first_tx = first_tx['result'][0]
claiming_gas_tx = w3.get_transaction_by_hash(first_internal_tx['hash'])
web3_first_tx = w3.get_transaction_by_hash(first_tx['hash'])
return web3_first_tx['blockNumber'] > claiming_gas_tx['blockNumber']
return False

class OptimismClaimingGasConstraint(EvmClaimingGasConstraint):
_param_keys = []

def is_observed(self, *args, **kwargs):
try:
chain = Chain.objects.get(chain_id=10)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.0.4 on 2023-10-08 19:28

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('faucet', '0058_alter_claimreceipt_amount'),
]

operations = [
migrations.AddField(
model_name='chain',
name='explorer_api_key',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='chain',
name='explorer_api_url',
field=models.URLField(blank=True, max_length=255, null=True),
),
]
2 changes: 2 additions & 0 deletions faucet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ class Chain(models.Model):
decimals = models.IntegerField(default=18)

explorer_url = models.URLField(max_length=255, blank=True, null=True)
explorer_api_url = models.URLField(max_length=255, blank=True, null=True)
explorer_api_key = models.CharField(max_length=255, blank=True, null=True)
rpc_url = models.URLField(max_length=255, blank=True, null=True)
logo_url = models.URLField(max_length=255, blank=True, null=True)
modal_url = models.URLField(max_length=255, blank=True, null=True)
Expand Down
44 changes: 43 additions & 1 deletion faucet/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@
GlobalSettings,
WalletAccount,
TransactionBatch,
LightningConfig
LightningConfig,
Wallet,
NetworkTypes
)
from unittest.mock import patch
from dotenv import dotenv_values
from faucet.helpers import memcache_lock
from faucet.constants import *
from faucet.constraints import *

address = "0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1"
fund_manager = "0x5802f1035AbB8B191bc12Ce4668E3815e8B7Efa0"
Expand Down Expand Up @@ -646,3 +649,42 @@ def test_unclaimed(self):

unclaimed = self.strategy.get_unclaimed()
self.assertEqual(unclaimed, t_chain_max - 100)


class TestConstraints(APITestCase):
def setUp(self) -> None:
self.wallet = WalletAccount.objects.create(
name="Test Wallet", private_key=test_wallet_key
)

self.optimism = Chain.objects.create(
chain_name="Optimism",
native_currency_name="ETH",
symbol="ETH",
rpc_url_private="https://optimism.llamarpc.com",
wallet=self.wallet,
fund_manager_address="0xb3A97684Eb67182BAa7994b226e6315196D8b364",
chain_id=10,
max_claim_amount=t_chain_max,
explorer_url="https://optimistic.etherscan.io/",
explorer_api_url = "https://api-optimistic.etherscan.io",
explorer_api_key = "6PGF5HBTT7DG9CQCQZK3MWR9146JAWQKAC"
)

self.user_profile = create_new_user("0x5A73E32a77E04Fb3285608B0AdEaa000B8e248F2")
self.wallet = Wallet.objects.create(
user_profile=self.user_profile,
wallet_type=NetworkTypes.EVM,
address="0x5A73E32a77E04Fb3285608B0AdEaa000B8e248F2",
)
self.client.force_authenticate(user=self.user_profile.user)

def test_optimism_claiming_gas_contraint(self):
constraint = OptimismClaimingGasConstraint(self.user_profile)
self.assertTrue(constraint.is_observed())
self.wallet.address = "0xE3eEBaB360E367b4e200759F0D955D1140F27430"
self.wallet.save()
self.assertTrue(constraint.is_observed())
self.wallet.address = "0xB9e291b68E584be657477289389B3a6DEED3E34C"
self.wallet.save()
self.assertFalse(constraint.is_observed())
18 changes: 18 additions & 0 deletions prizetap/migrations/0031_alter_constraint_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.0.4 on 2023-10-09 10:12

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('prizetap', '0030_alter_constraint_name'),
]

operations = [
migrations.AlterField(
model_name='constraint',
name='name',
field=models.CharField(choices=[('BrightIDMeetVerification', 'BrightIDMeetVerification'), ('BrightIDAuraVerification', 'BrightIDAuraVerification'), ('HaveUnitapPass', 'HaveUnitapPass'), ('NotHaveUnitapPass', 'NotHaveUnitapPass'), ('OptimismDonationConstraint', 'OptimismDonationConstraint'), ('OptimismClaimingGasConstraint', 'OptimismClaimingGasConstraint')], max_length=255, unique=True),
),
]
5 changes: 3 additions & 2 deletions prizetap/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.db import models
from faucet.models import Chain
from faucet.constraints import OptimismDonationConstraint
from faucet.constraints import OptimismDonationConstraint, OptimismClaimingGasConstraint
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from authentication.models import NetworkTypes, UserProfile
Expand All @@ -14,7 +14,8 @@ class Constraint(UserConstraint):
constraints = UserConstraint.constraints + [
HaveUnitapPass,
NotHaveUnitapPass,
OptimismDonationConstraint
OptimismDonationConstraint,
OptimismClaimingGasConstraint
]
name = UserConstraint.create_name_field(constraints)

Expand Down

0 comments on commit c1076e9

Please sign in to comment.