Compare commits

..

2 Commits

Author SHA1 Message Date
9e5adc2ef4 start erc-20 sandbox stuff 2024-06-03 17:23:53 -04:00
fb4d0eff3f unfuck the calculator 2024-06-03 17:23:26 -04:00
3 changed files with 112 additions and 13 deletions

View File

@ -0,0 +1,37 @@
"""
ERC-20 monitoring sandbox
An exercise exploring ABIs and chain events
"""
import requests
from typing import Any, Optional, Dict
JENNER_ADDRESS = '0x482702745260ffd69fc19943f70cffe2cacd70e9'
def fetch_abi(
address: str,
headers: Optional[Dict[str, Any]] = None,
params: Optional[Dict[str, Any]] = None
) -> Optional[Dict[str, Any]]:
# TODO: Ensure it is a well-formed address
# TODO: Check for errors, such as a "status" key set to 0
url = f'https://api.etherscan.io/api?module=contract&action=getabi&address={address}'
try:
response = requests.get(url, headers=headers, params=params)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as err:
print(f'Error during the request: {err}')
return None
except ValueError as err:
print(f'Error parsing JSON: {err}')
def main():
jenner_abi = fetch_abi(JENNER_ADDRESS)
print(jenner_abi)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,3 @@
requests
loguru
web3

View File

@ -20,15 +20,25 @@ class StakingPool:
total_fee = amount * self.fee_rate
# Distribute fee
# TODO: Handle edge case where pool has no initial users == Community funds gets the reward
# 1. Community funds
community_fee = total_fee * self.community_pct
self.community_fund += community_fee
# 2. Developer funds
developer_fee = total_fee * self.developer_pct
self.developer_fund += developer_fee
# 3. Reward stakers
# If there are no users in the pool, the reward is placed in the community fund
reward_amount = total_fee - community_fee - developer_fee
########
# Test no community fund (distribute equally)
self.community_distribute()
if len(self.user_balances) < 1:
self.community_fund += reward_amount
else:
self.__distribute_reward(reward_amount)
# Deposit amount minus fee to contract_fund (wallet)
@ -42,19 +52,40 @@ class StakingPool:
def unstake(self, user: str):
# Fetch amount from user_balances
if user not in self.user_balances:
return 0.0
elif self.user_balances[user] <= 0:
return 0.0
user_balance = self.user_balances[user]
# Remove user from pool to prevent self-reward leaving a hanging balance
del self.user_balances[user]
# Calculate fee
total_fee = user_balance * self.fee_rate
# Adjust working balance
user_balance -= total_fee
# Distribute fee
# TODO: User needs to be removed from the pool first to avoid hanging balances after rewarding stakers
# 1. Community funds
community_fee = total_fee * self.community_pct
self.community_fund += community_fee
#########
# TEST DISTRIBUTE TO COMMUNITY
self.community_distribute()
# 2. Developer funds
developer_fee = total_fee * self.developer_pct
self.developer_fund += developer_fee
# 3. Reward stakers
reward_amount = total_fee - community_fee - developer_fee
self.__distribute_reward(reward_amount)
# Transfer tokens from contract_funds (wallet) to user's wallet address
pass
return user_balance
def dev_withdrawal(self, destination: str, amount: float):
pass
@ -62,23 +93,51 @@ class StakingPool:
def community_withdrawal(self, destination: str, amount: float):
pass
def __distribute_reward(self, amount):
# # # #
# Lock user_balances mutex
# # # #
def community_distribute(self):
# Take all funds in community stash and distribute it to stakers
amount = self.community_fund
self.__distribute_reward(amount)
self.community_fund = 0.0
def __distribute_reward(self, amount):
# Get total staked amount
staked_total = sum(self.user_balances.values())
# Determine distribution amongst users
# Update self.user_balances
for user, user_stake in self.user_balances.items():
pct = user_stake / staked_total
user_reward = pct * amount
self.user_balances[user] += user_reward
# # # #
# Unlock user_balances mutex
# # # #
pass
def stats(self):
print('\n--- POOL STATS ---')
print(f'staked: {sum(self.user_balances.values())}')
print(f'community fund: {self.community_fund}')
print(f'developer fund: {self.developer_fund}')
print('------------------')
print('--- USER TOTALS ---')
for user, balance in self.user_balances.items():
print(f'{user}: {balance}')
print('------------------')
def main():
pass
pool = StakingPool()
pool.stake("owner", 50000)
pool.stake("user1", 50000000)
# pool.stake("user2", 5000)
# pool.stake("user3", 50000)
# pool.stake("user3", 50000)
# pool.stake("user3", 50000)
# pool.stake("user3", 50000)
# pool.stake("user3", 50000)
# pool.stake("user3", 50000)
pool.stats()
# pool.community_distribute()
print(pool.unstake("owner"))
pool.stats()
if __name__ == '__main__':