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

Polynomial eoa to scw mapping #55

Closed
wants to merge 10 commits into from
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ SCROLL_NODE_URL='https://rpc.scroll.io'
MODE_NODE_URL='https://mainnet.mode.network'
FRAXTAL_NODE_URL='https://rpc.frax.com'
LYRA_NODE_URL='https://rpc.derive.xyz'
POLYNOMIAL_NODE_URL = 'https://rpc.polynomial.fi'
SWELL_NODE_URL='https://rpc.ankr.com/swell'
SOLANA_NODE_URL='https://api.mainnet-beta.solana.com'
BASE_NODE_URL="https://mainnet.base.org"
Expand Down
51 changes: 51 additions & 0 deletions abi/polynomial_core_account.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenOfOwnerByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
}
]
36 changes: 36 additions & 0 deletions abi/polynomial_core_proxy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[
{
"inputs": [
{
"internalType": "uint128",
"name": "accountId",
"type": "uint128"
},
{
"internalType": "address",
"name": "collateral",
"type": "address"
}
],
"name": "getAccountCollateral",
"outputs": [
{
"internalType": "uint256",
"name": "totalDeposited",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalAssigned",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalLocked",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]
40 changes: 40 additions & 0 deletions abi/polynomial_owner_register.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "kernel",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnerRegistered",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "ecdsaValidatorStorage",
"outputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]
1 change: 1 addition & 0 deletions constants/chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Chain(Enum):
SCROLL = "Scroll"
MODE = "Mode"
OPTIMISM = "Optimism"
POLYNOMIAL = "Polynomial"
LYRA = "Lyra"
SWELL = "Swell"
SOLANA = "Solana"
Expand Down
21 changes: 21 additions & 0 deletions constants/polynomial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from web3 import Web3

POLYNOMIAL_CORE_PROXY_ADDRESS = Web3.to_checksum_address(
"0xc133983D6d9140923b5eaE52664221d9099cf119"
)
POLYNOMIAL_CORE_ACCOUNT_ADDRESS = Web3.to_checksum_address(
"0x5B05C63AB7122f136EBCf03E1256D8611dfDffF7"
)
POLYNOMIAL_DEPLOYMENT_BLOCK = 1981537

POLYNOMIAL_USDE_TOKEN_ADDRESS = Web3.to_checksum_address(
"0x2A06DEAc3E863c23DD6a89Eeacd80aBA9E08B77B"
)

POLYNOMIAL_OWNER_REGISTER_ADDRESS = Web3.to_checksum_address(
"0x845ADb2C711129d4f3966735eD98a9F09fC4cE57"
)

POLYNOMIAL_BYTECODE_HASH = '0x85d96aa1c9a65886d094915d76ccae85f14027a02c1647dde659f869460f03e6'
POLYNOMIAL_DEPLOYER_ADDRESS = '0xaac5D4240AF87249B3f71BC8E4A2cae074A3E419'

5 changes: 5 additions & 0 deletions integrations/integration_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@ class IntegrationID(Enum):
Token.SUSDE,
)

POLYNOMIAL_SUSDE = (
"polynomial_susde",
"Polynomial sUSDe",
Token.SUSDE
)
# Fluid
FLUID = ("Fluid_susde", "Fluid sUSDe", Token.SUSDE)

Expand Down
146 changes: 146 additions & 0 deletions integrations/polynomial_susde.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
from constants.chains import Chain
from integrations.integration import Integration
from integrations.integration_ids import IntegrationID
from utils.web3_utils import w3_polynomial, fetch_events_logs_with_retry, call_with_retry
from utils.polynomial import core_proxy_contract, core_account_proxy_contract, owner_register_contract
from constants.polynomial import POLYNOMIAL_DEPLOYMENT_BLOCK, POLYNOMIAL_USDE_TOKEN_ADDRESS, POLYNOMIAL_DEPLOYER_ADDRESS, POLYNOMIAL_BYTECODE_HASH
from eth_utils import keccak, remove_0x_prefix
from web3 import Web3
import requests

class PolynomialIntegration(Integration):
def __init__(self):
super().__init__(
IntegrationID.POLYNOMIAL_SUSDE,
POLYNOMIAL_DEPLOYMENT_BLOCK,
Chain.POLYNOMIAL,
[],
5,
1,
None,
None,
)


def get_balance(self, user: str, block: int) -> float:
scw_address = get_scw_address_from_eoa(user)
scw_address = Web3.to_checksum_address(scw_address)

total_balance = 0
try:
account_id = call_with_retry(
core_account_proxy_contract.functions.tokenOfOwnerByIndex(scw_address, 0),
block,
)
_, total_balance, _ = call_with_retry(
core_proxy_contract.functions.getAccountCollateral(
account_id, POLYNOMIAL_USDE_TOKEN_ADDRESS
),
block,
)
except Exception as e:
pass

return total_balance / 1e18


def get_participants(self, blocks: list[int] | None) -> set[str]:
page_size = 19000
start_block = POLYNOMIAL_DEPLOYMENT_BLOCK
target_block = w3_polynomial.eth.get_block_number()

all_users: set[str] = set()
registered_users: set[str] = set()

while start_block < target_block:
to_block = min(start_block + page_size, target_block)
transfers = fetch_events_logs_with_retry(
f"Polynomial users from {start_block} to {to_block}",
core_account_proxy_contract.events.Transfer(),
start_block,
to_block,
)
for transfer in transfers:
all_users.add(transfer["args"]["to"])

start_block += page_size

owner_registered_events = fetch_events_logs_with_retry(
f"Polynomial OwnerRegistered events from {POLYNOMIAL_DEPLOYMENT_BLOCK} to {target_block}",
owner_register_contract.events.OwnerRegistered(),
POLYNOMIAL_DEPLOYMENT_BLOCK,
target_block
)

for event in owner_registered_events:
owner_address = event["args"]["owner"]
kernel_address = event["args"]["kernel"]
if kernel_address in all_users:
all_users.remove(kernel_address)
registered_users.add(owner_address)


unregistered_users = all_users
addresses_json = {"accounts": list(unregistered_users)}

response = requests.post(
"https://perps-api-mainnet.polynomial.finance/core/zerodev-accounts/owners",
json=addresses_json
)

if response.status_code == 201:
response_data = response.json()

api_owners = set()
for entry in response_data:
if "owner" in entry:
api_owners.add(entry["owner"])

else:
api_owners = set()

combined_owners = registered_users.union(api_owners)
self.participants = combined_owners
return combined_owners

def get_scw_address_from_eoa(eoa_address: str) -> str:
w3 = Web3()

fn_signature = 'initialize(bytes21,address,bytes,bytes,bytes[])'
fn_selector = keccak(text=fn_signature)[:4].hex()

init_args = [
'0x01845ADb2C711129d4f3966735eD98a9F09fC4cE57',
'0x0000000000000000000000000000000000000000',
eoa_address,
'0x',
[]
]

init_data = w3.eth.codec.encode(
['bytes21', 'address', 'bytes', 'bytes', 'bytes[]'],
init_args
)
init_data = '0x' + fn_selector + init_data.hex()

encoded_index = '0x'+hex(8008)[2:].rjust(64,'0')

concat_hex = init_data + encoded_index[2:]
salt = keccak(hexstr=remove_0x_prefix(concat_hex))


create2_input = (
b'\xff' +
bytes.fromhex(remove_0x_prefix(POLYNOMIAL_DEPLOYER_ADDRESS)) +
salt +
bytes.fromhex(remove_0x_prefix(POLYNOMIAL_BYTECODE_HASH))
)

result_address = '0x' + keccak(create2_input)[12:].hex()
return result_address

if __name__ == "__main__":
polynomial = PolynomialIntegration()
participants = polynomial.get_participants(None)
print(len(participants))
print(polynomial.get_balance(list(participants)[0], 9415666))
29 changes: 29 additions & 0 deletions utils/polynomial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import os
import json
from dotenv import load_dotenv
from utils.web3_utils import (
w3_polynomial,
)

from constants.polynomial import POLYNOMIAL_CORE_ACCOUNT_ADDRESS, POLYNOMIAL_CORE_PROXY_ADDRESS, POLYNOMIAL_OWNER_REGISTER_ADDRESS
with open("abi/polynomial_core_proxy.json") as f:
core_proxy_abi = json.load(f)

with open("abi/polynomial_core_account.json") as f:
core_account_proxy_abi = json.load(f)

with open("abi/polynomial_owner_register.json") as f:
owner_register_abi = json.load(f)


core_proxy_contract = w3_polynomial.eth.contract(
address=POLYNOMIAL_CORE_PROXY_ADDRESS, abi=core_proxy_abi
)

core_account_proxy_contract = w3_polynomial.eth.contract(
address=POLYNOMIAL_CORE_ACCOUNT_ADDRESS, abi=core_account_proxy_abi
)

owner_register_contract = w3_polynomial.eth.contract(
address=POLYNOMIAL_OWNER_REGISTER_ADDRESS, abi=owner_register_abi
)
5 changes: 5 additions & 0 deletions utils/web3_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
w3_fraxtal = Web3(Web3.HTTPProvider(FRAXTAL_NODE_URL))
LYRA_NODE_URL = os.getenv("LYRA_NODE_URL")
w3_lyra = Web3(Web3.HTTPProvider(LYRA_NODE_URL))
POLYNOMIAL_NODE_URL = os.getenv("POLYNOMIAL_NODE_URL")
w3_polynomial = Web3(Web3.HTTPProvider(POLYNOMIAL_NODE_URL))
SWELL_NODE_URL = os.getenv("SWELL_NODE_URL")
w3_swell = Web3(Web3.HTTPProvider(SWELL_NODE_URL))
BASE_NODE_URL = os.getenv("BASE_NODE_URL")
Expand Down Expand Up @@ -60,6 +62,9 @@
Chain.LYRA: {
"w3": w3_lyra,
},
Chain.POLYNOMIAL:{
"w3": w3_polynomial,
}
Chain.SWELL: {
"w3": w3_swell,
},
Expand Down
Loading