Add update redeemable positions command#630
Conversation
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR adds a new command to update redeemable positions for users who have minted osToken shares. The command fetches allocator data from the graph, filters out leverage positions, calculates kept tokens (both in wallets and locked in protocols), determines redeemable amounts, and uploads the results to IPFS.
Key Changes:
- Introduces the
update_redeemable_positionscommand with supporting graph queries and API client - Adds ERC20 contract wrapper and OS_TOKEN_CONTRACT_ADDRESS configuration for each network
- Expands IPFS configuration to support multiple upload clients (local, Infura, Pinata)
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/commands/internal/update_redeemable_positions.py | Main command implementation to fetch, calculate, and upload redeemable positions |
| src/redeem/typings.py | Data classes for Allocator and RedeemablePosition entities |
| src/redeem/graph.py | Graph queries to fetch allocators and leverage position proxies |
| src/redeem/api_client.py | API client to fetch locked osToken data from external protocol |
| src/common/contracts.py | ERC20 contract wrapper for token balance queries |
| src/common/clients.py | IPFS upload client builder supporting multiple providers |
| src/config/settings.py | IPFS upload settings and increased graph timeout/page size defaults |
| src/config/networks.py | OS_TOKEN_CONTRACT_ADDRESS added for each network |
| src/main.py | Command registration in CLI |
| src/reward_splitter/graph.py | Added pagination parameters to existing graph queries |
| src/common/abi/Erc20Token.json | ERC20 ABI definition |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 16 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async def _fetch_json(self, url: str, params: dict | None = None) -> dict | list: | ||
| async with aiohttp.ClientSession() as session: | ||
| async with session.get( | ||
| url=url, | ||
| params=params, | ||
| headers={'user-agent': DEFAULT_USER_AGENT}, | ||
| ) as response: | ||
| response.raise_for_status() | ||
| return await response.json() |
There was a problem hiding this comment.
Creating a new aiohttp.ClientSession for each request is inefficient. Create the session once in init or use a session pool to reuse connections across multiple API calls.
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 16 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 18 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 18 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: cyc60 <avsysoev60@gmail.com> # Conflicts: # poetry.lock
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 18 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 18 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 26 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36' | ||
| ) | ||
| SUPPORTED_CHAINS = {'eth', 'arb'} | ||
| API_SLEEP_TIMEOUT = 1 |
There was a problem hiding this comment.
The API_SLEEP_TIMEOUT is a hardcoded constant. Consider making this configurable via settings to allow different timeout values for different environments or when rate limits change.
| API_SLEEP_TIMEOUT = 1 | |
| API_SLEEP_TIMEOUT = getattr(settings, 'API_SLEEP_TIMEOUT', 1) |
| ) | ||
| allocators = _reduce_boosted_amount(allocators, boost_ostoken_shares) | ||
|
|
||
| # filter zero positions. Filter before kept shares calculation to reduce api calls |
There was a problem hiding this comment.
The variable min_os_token_position_amount_gwei is already in Gwei units based on its name and CLI parameter, so converting it using Web3.to_wei(..., 'gwei') is correct. However, this could be made clearer by renaming the parameter to explicitly indicate it's in Gwei or adding a comment explaining the conversion.
| # filter zero positions. Filter before kept shares calculation to reduce api calls | |
| # filter zero positions. Filter before kept shares calculation to reduce api calls | |
| # NOTE: min_os_token_position_amount_gwei is already specified in Gwei (e.g. via CLI), | |
| # so we intentionally convert it from Gwei to Wei here for on-chain comparisons. |
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 26 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self.ipfs_local_password: str | None = decouple_config('IPFS_LOCAL_PASSWORD', default=None) | ||
|
|
||
| # infura | ||
| self.ipfs_infura_client_endpoint: str = '/dns/ipfs.infura.io/tcp/5001/https' |
There was a problem hiding this comment.
The Infura IPFS endpoint is hardcoded rather than being configurable via environment variable. Consider making this configurable like the local endpoint to allow flexibility for different environments or alternative IPFS gateways.
| self.ipfs_infura_client_endpoint: str = '/dns/ipfs.infura.io/tcp/5001/https' | |
| self.ipfs_infura_client_endpoint: str = decouple_config( | |
| 'IPFS_INFURA_CLIENT_ENDPOINT', | |
| default='/dns/ipfs.infura.io/tcp/5001/https', | |
| ) |
| tmp_allocators: defaultdict[str, dict[str, Wei]] = defaultdict(dict) | ||
| allocators: list[Allocator] = [] | ||
| for item in response: | ||
| if int(item['mintedOsTokenShares']) > 0: |
There was a problem hiding this comment.
The request will be much faster if you add this filter to the query: 141k vs 2.6k entries
Signed-off-by: cyc60 <avsysoev60@gmail.com> # Conflicts: # poetry.lock # pyproject.toml
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com> # Conflicts: # poetry.lock
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com>
Signed-off-by: cyc60 <avsysoev60@gmail.com> # Conflicts: # src/common/contracts.py
Signed-off-by: cyc60 <avsysoev60@gmail.com>
No description provided.