Skip to content

Commit

Permalink
[RELEASE] 0.10.0 (#533)
Browse files Browse the repository at this point in the history
  • Loading branch information
aziolek authored Nov 4, 2024
2 parents e2faaaa + c07955c commit c9f93a8
Show file tree
Hide file tree
Showing 109 changed files with 3,617 additions and 168 deletions.
4 changes: 2 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@ module.exports = {
{
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
leadingUnderscore: 'allow',
prefix: ['IS_', 'is', 'can', 'does', 'has', 'should', 'are', 'was', 'show', 'hide'],
prefix: ['IS_', 'is', 'can', 'does', 'did', 'has', 'should', 'are', 'was', 'show', 'hide'],
selector: 'variable',
types: ['boolean'],
},
{
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
leadingUnderscore: 'allow',
prefix: ['IS_', 'is', 'can', 'does', 'has', 'should', 'are', 'was', 'show', 'hide'],
prefix: ['IS_', 'is', 'can', 'does', 'did', 'has', 'should', 'are', 'was', 'show', 'hide'],
selector: 'parameter',
types: ['boolean'],
},
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ jobs:
GC_PASSPORT_SCORER_API_KEY: "${{ secrets.GITCOIN_SCORER_API_KEY }}"
DELEGATION_SALT: "${{ secrets.DELEGATION_SALT }}"
DELEGATION_SALT_PRIMARY: "${{ secrets.DELEGATION_SALT_PRIMARY }}"
SABLIER_MAINNET_SUBGRAPH_URL: "${{ secrets.SABLIER_MAINNET_SUBGRAPH_URL }}"
SABLIER_SEPOLIA_SUBGRAPH_URL: "${{ secrets.SABLIER_SEPOLIA_SUBGRAPH_URL }}"
SABLIER_SENDER_ADDRESS: "0x4BEbdb9792ed50eBB00611083ba384F05791a9FB"
steps:
- uses: actions/checkout@v4.1.0
- uses: actions/cache/restore@v4
Expand Down
2 changes: 2 additions & 0 deletions backend/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ GLM_SENDER_ADDRESS=
GLM_SENDER_PRIVATE_KEY=
GLM_SENDER_NONCE=
MAINNET_PROPOSAL_CIDS=

SABLIER_MAINNET_SUBGRAPH_URL=
21 changes: 17 additions & 4 deletions backend/app/engine/epochs_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
NotSupportedCFCalculator,
)
from app.engine.octant_rewards.leftover.default import PreliminaryLeftover
from app.engine.octant_rewards.leftover.with_ppf import LeftoverWithPPF
from app.engine.octant_rewards.matched.preliminary import (
PreliminaryMatchedRewards,
)
Expand All @@ -23,12 +24,14 @@
from app.engine.projects.rewards.threshold.preliminary import (
PreliminaryProjectThreshold,
)
from app.engine.user import UserSettings
from app.engine.user.budget.preliminary import PreliminaryUserBudget
from app.engine.user import UserSettings, DefaultWeightedAverageEffectiveDeposit
from app.engine.user.effective_deposit.weighted_average.default import (
DefaultWeightedAverageEffectiveDeposit,
)
from app.engine.user.effective_deposit.weighted_average.weights.timebased.default import (
DefaultTimebasedWeights,
)
from app.engine.octant_rewards.leftover.with_ppf import LeftoverWithPPF


@dataclass
Expand Down Expand Up @@ -76,7 +79,10 @@ def register_epoch_settings():
community_fund=NotSupportedCFCalculator(),
leftover=PreliminaryLeftover(),
),
user=UserSettings(budget=PreliminaryUserBudget()),
user=UserSettings(
budget=PreliminaryUserBudget(),
effective_deposit=DefaultWeightedAverageEffectiveDeposit(),
),
project=ProjectSettings(
rewards=PreliminaryProjectRewards(
projects_threshold=PreliminaryProjectThreshold(2),
Expand All @@ -86,6 +92,13 @@ def register_epoch_settings():

SETTINGS[3] = EpochSettings(
octant_rewards=OctantRewardsSettings(leftover=LeftoverWithPPF()),
user=UserSettings(effective_deposit=DefaultWeightedAverageEffectiveDeposit()),
project=ProjectSettings(rewards=PreliminaryProjectRewards()),
)
SETTINGS[4] = EpochSettings()
SETTINGS[4] = EpochSettings(
user=UserSettings(effective_deposit=DefaultWeightedAverageEffectiveDeposit())
)
SETTINGS[5] = EpochSettings(
user=UserSettings(effective_deposit=DefaultWeightedAverageEffectiveDeposit())
)
SETTINGS[6] = EpochSettings()
6 changes: 3 additions & 3 deletions backend/app/engine/user/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
from app.engine.user.budget import UserBudget
from app.engine.user.budget.with_ppf import UserBudgetWithPPF
from app.engine.user.effective_deposit import UserEffectiveDeposit
from app.engine.user.effective_deposit.weighted_average.default import (
DefaultWeightedAverageEffectiveDeposit,
from app.engine.user.effective_deposit.weighted_average.default_with_sablier_timebox import (
DefaultWeightedAverageWithSablierTimebox,
)


@dataclass
class UserSettings:
effective_deposit: UserEffectiveDeposit = field(
default_factory=DefaultWeightedAverageEffectiveDeposit
default_factory=DefaultWeightedAverageWithSablierTimebox
)
budget: UserBudget = field(default_factory=UserBudgetWithPPF)
29 changes: 28 additions & 1 deletion backend/app/engine/user/effective_deposit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ class EventType(StrEnum):
UNLOCK = "Unlocked"


class SablierEventType(StrEnum):
CREATE = "Create"
WITHDRAW = "Withdraw"
CANCEL = "Cancel"


class DepositSource(StrEnum):
OCTANT = "Octant"
SABLIER = "Sablier"


def _calculate_deposit_after_event(
event_type: EventType, before: int, amount: int
) -> int:
Expand All @@ -32,6 +43,8 @@ class DepositEvent:
amount: int
deposit_before: int
deposit_after: int
source: DepositSource
mapped_event: Optional[SablierEventType]

def __init__(
self,
Expand All @@ -40,6 +53,8 @@ def __init__(
timestamp: int,
amount: int,
deposit_before: int,
source: DepositSource = DepositSource.OCTANT,
mapped_event: Optional[SablierEventType] = None,
):
self.user = user
self.type = type
Expand All @@ -49,10 +64,17 @@ def __init__(
self.deposit_after = _calculate_deposit_after_event(
type, deposit_before, amount
)
self.source = source
self.mapped_event = mapped_event

@staticmethod
def from_dict(event: Dict):
event_type = EventType(event["__typename"])
source = DepositSource.OCTANT
mapped_event = None
if event.get("__source") == DepositSource.SABLIER:
mapped_event = event["type"]
source = DepositSource.SABLIER
user = to_checksum_address(event["user"])
timestamp = int(event["timestamp"])
amount = int(event["amount"])
Expand All @@ -64,6 +86,8 @@ def from_dict(event: Dict):
timestamp=timestamp,
amount=amount,
deposit_before=deposit_before,
source=source,
mapped_event=mapped_event,
)


Expand All @@ -79,11 +103,14 @@ def __iter__(self):
yield self.deposit


LockEventsByAddr = Dict[str, List[DepositEvent]]


@dataclass
class UserEffectiveDepositPayload:
epoch_start: int = None
epoch_end: int = None
lock_events_by_addr: Dict[str, List[DepositEvent]] = None
lock_events_by_addr: LockEventsByAddr = None


@dataclass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from dataclasses import dataclass
from typing import Tuple, List

from app.engine.user.effective_deposit import (
UserEffectiveDepositPayload,
LockEventsByAddr,
DepositSource,
EventType,
UserDeposit,
)
from app.engine.user.effective_deposit.weighted_average.default import (
DefaultWeightedAverageEffectiveDeposit,
)


@dataclass
class DefaultWeightedAverageWithSablierTimebox(DefaultWeightedAverageEffectiveDeposit):
def calculate_users_effective_deposits(
self, payload: UserEffectiveDepositPayload
) -> Tuple[List[UserDeposit], int]:
payload.lock_events_by_addr = self._remove_unlock_and_lock_within_24_hours(
payload.lock_events_by_addr
)

return super().calculate_users_effective_deposits(payload)

def _remove_unlock_and_lock_within_24_hours(
self, events: LockEventsByAddr
) -> LockEventsByAddr:
"""
Removes the unlock event from Sablier if it is followed by a lock event in Octant within 24 hours.
"""
TWENTY_FOUR_HOURS_PERIOD = 24 * 60 * 60

for address, user_events in events.items():
if not user_events:
continue

filtered_events = []
skip_next = False

for prev_event, next_event in zip(user_events, user_events[1:]):
if skip_next:
# Skip adding the next_event as it was part of a pair that should be ignored.
skip_next = False
continue

if (
prev_event.source == DepositSource.SABLIER
and prev_event.type == EventType.UNLOCK
and next_event.source == DepositSource.OCTANT
and next_event.type == EventType.LOCK
and next_event.timestamp - prev_event.timestamp
< TWENTY_FOUR_HOURS_PERIOD
):
# Skip both the unlock and the following lock.
skip_next = True
continue

filtered_events.append(prev_event)

# Add the last event if it was not skipped.
if not skip_next:
filtered_events.append(user_events[-1])

events[address] = filtered_events

return events
8 changes: 5 additions & 3 deletions backend/app/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from app.infrastructure.contracts.erc20 import ERC20
from app.infrastructure.contracts.projects import Projects
from app.infrastructure.contracts.vault import Vault
from app.infrastructure import GQLConnectionFactory
from app.infrastructure import GQLConnectionFactory, SubgraphEndpoints

# Flask extensions
api = Api(
Expand All @@ -39,7 +39,8 @@
vault = Vault(abi=abi.VAULT)

# GQL extensions
gql_factory = GQLConnectionFactory()
gql_octant_factory = GQLConnectionFactory()
gql_sablier_factory = GQLConnectionFactory()


def init_web3(app):
Expand All @@ -55,7 +56,8 @@ def init_web3(app):


def init_subgraph(app):
gql_factory.set_url(app.config)
gql_octant_factory.set_url(app.config, SubgraphEndpoints.OCTANT_SUBGRAPH)
gql_sablier_factory.set_url(app.config, SubgraphEndpoints.SABLIER_SUBGRAPH)


def init_scheduler(app):
Expand Down
9 changes: 7 additions & 2 deletions backend/app/infrastructure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
}


class SubgraphEndpoints:
OCTANT_SUBGRAPH = "SUBGRAPH_ENDPOINT"
SABLIER_SUBGRAPH = "SABLIER_MAINNET_SUBGRAPH_URL"


class OctantResource(Resource):
def __init__(self, *args, **kwargs):
Resource.__init__(self, *args, *kwargs)
Expand Down Expand Up @@ -108,8 +113,8 @@ class GQLConnectionFactory:
def __init__(self):
self._url = None

def set_url(self, config: Config):
self._url = config["SUBGRAPH_ENDPOINT"]
def set_url(self, config: Config, key: SubgraphEndpoints):
self._url = config[key]

def build(self):
if not self._url:
Expand Down
28 changes: 15 additions & 13 deletions backend/app/infrastructure/graphql/epochs.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
from flask import current_app as app
from gql import gql

from app.extensions import gql_factory
from app.extensions import gql_octant_factory

from app import exceptions


def get_epoch_by_number(epoch_number):
query = gql(
"""
query GetEpoch($epochNo: Int!) {
epoches(where: {epoch: $epochNo}) {
epoch
fromTs
toTs
duration
decisionWindow
}
}
"""
query GetEpoch($epochNo: Int!) {
epoches(where: {epoch: $epochNo}) {
epoch
fromTs
toTs
duration
decisionWindow
}
}
"""
)

variables = {"epochNo": epoch_number}
app.logger.debug(
f"[Subgraph] Getting epoch properties for epoch number: {epoch_number}"
)
data = gql_factory.build().execute(query, variable_values=variables)["epoches"]
data = gql_octant_factory.build().execute(query, variable_values=variables)[
"epoches"
]

if data:
app.logger.debug(f"[Subgraph] Received epoch properties: {data[0]}")
Expand Down Expand Up @@ -56,5 +58,5 @@ def get_epochs():
)

app.logger.debug("[Subgraph] Getting list of all epochs")
data = gql_factory.build().execute(query)
data = gql_octant_factory.build().execute(query)
return data
4 changes: 2 additions & 2 deletions backend/app/infrastructure/graphql/info.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from gql import gql

from app.extensions import gql_factory
from app.extensions import gql_octant_factory


def get_indexed_block_num() -> int:
Expand All @@ -15,7 +15,7 @@ def get_indexed_block_num() -> int:
}
"""
)
data = gql_factory.build().execute(query)
data = gql_octant_factory.build().execute(query)
if data:
return data["_meta"]["block"]["number"]
else:
Expand Down
Loading

0 comments on commit c9f93a8

Please sign in to comment.