121 lines
3.3 KiB
Python
121 lines
3.3 KiB
Python
from decimal import Decimal, getcontext
|
|
|
|
# Set precision context if needed
|
|
getcontext().prec = 28
|
|
|
|
|
|
class StakingContract:
|
|
def __init__(self):
|
|
self.rewards_pct = Decimal('0.7')
|
|
self.community_pct = Decimal('0.2')
|
|
self.developer_pct = Decimal('0.1')
|
|
|
|
self.balances = {
|
|
"stakes": Decimal('0.0'),
|
|
"developer": Decimal('0.0'),
|
|
"community": Decimal('0.0'),
|
|
}
|
|
|
|
self.users = {}
|
|
|
|
def deposit(self, user: str, amount: float):
|
|
amount = Decimal(amount) # Convert to Decimal
|
|
stake, reward, community, developer = self.calc_fee(amount)
|
|
print(f'{user} staked {amount} ($JENNER)')
|
|
|
|
# Distribute reward to existing users first
|
|
self.distribute_reward(reward)
|
|
|
|
self.add_fees_to_balances(stake, community, developer)
|
|
self.add_stake_to_user(user, stake)
|
|
|
|
def withdraw(self, user: str):
|
|
if user not in self.users:
|
|
print(f"No staked amount found for user {user}.")
|
|
return Decimal('0.0')
|
|
|
|
initial_stake = self.users[user]
|
|
|
|
total_withdrawal = initial_stake
|
|
|
|
# Update balances
|
|
self.balances['stakes'] -= initial_stake
|
|
|
|
# Reset user's stake to 0
|
|
del self.users[user]
|
|
|
|
print(f'{user} withdrew {total_withdrawal:.4f} ($JENNER)')
|
|
return total_withdrawal
|
|
|
|
def calc_fee(self, amount):
|
|
fee = amount * Decimal('0.03')
|
|
stake_amount = amount - fee
|
|
|
|
rewards = fee * self.rewards_pct
|
|
community = fee * self.community_pct
|
|
developer = fee * self.developer_pct
|
|
|
|
return stake_amount, rewards, community, developer
|
|
|
|
def show_stats(self):
|
|
print('\n--- POOL STATS ---')
|
|
for k, v in self.balances.items():
|
|
print(f'{k}: {v}')
|
|
print('')
|
|
print('--- USERS IN POOL ---')
|
|
for k, v in self.users.items():
|
|
print(f'{k}: {v}')
|
|
print('')
|
|
|
|
def add_stake_to_user(self, user: str, stake: Decimal):
|
|
if user in self.users:
|
|
self.users[user] += stake
|
|
else:
|
|
self.users[user] = stake
|
|
|
|
def add_fees_to_balances(self, stake: Decimal, community: Decimal, developer: Decimal):
|
|
self.balances['stakes'] += stake
|
|
self.balances['developer'] += developer
|
|
self.balances['community'] += community
|
|
|
|
def distribute_reward(self, reward: Decimal):
|
|
total_stakes = self.balances['stakes']
|
|
if total_stakes > Decimal('0.0'):
|
|
for user in self.users:
|
|
user_stake = self.users[user]
|
|
reward_share = (user_stake / total_stakes) * reward
|
|
self.users[user] += reward_share
|
|
|
|
def user_total_balance(self, user: str):
|
|
if user in self.users:
|
|
return self.users[user]
|
|
return Decimal('0.0')
|
|
|
|
|
|
def main():
|
|
pool = StakingContract()
|
|
|
|
pool.deposit("owner", 50000)
|
|
pool.deposit("user1", 10000)
|
|
pool.deposit("user2", 10000)
|
|
pool.deposit("user3", 10000)
|
|
pool.deposit("user4", 10000)
|
|
pool.deposit("user5", 10000)
|
|
pool.deposit("user6", 10000)
|
|
|
|
pool.show_stats()
|
|
|
|
pool.withdraw("user1")
|
|
pool.withdraw("user2")
|
|
pool.withdraw("user3")
|
|
pool.withdraw("user4")
|
|
pool.withdraw("user5")
|
|
pool.withdraw("user6")
|
|
|
|
pool.withdraw("owner")
|
|
|
|
pool.show_stats()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main() |