From e93d1f93f0e35554ab5e02c7d3f96e4cba42baa6 Mon Sep 17 00:00:00 2001 From: agatha Date: Mon, 3 Jun 2024 00:14:17 -0400 Subject: [PATCH] man this is broken, stakecalc2 will be the good one --- staking/gpt-fixed.py | 121 ++++++++++++++++++++++++++++++++++++++++++ staking/stakecalc2.py | 56 +++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 staking/gpt-fixed.py create mode 100644 staking/stakecalc2.py diff --git a/staking/gpt-fixed.py b/staking/gpt-fixed.py new file mode 100644 index 0000000..a7e69c7 --- /dev/null +++ b/staking/gpt-fixed.py @@ -0,0 +1,121 @@ +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() \ No newline at end of file diff --git a/staking/stakecalc2.py b/staking/stakecalc2.py new file mode 100644 index 0000000..6c29c2d --- /dev/null +++ b/staking/stakecalc2.py @@ -0,0 +1,56 @@ +class StakingPool: + def __init__(self): + # TODO: Add mutex + # self.mutex = None + + self.fee_rate = 0.03 + + self.share_pct = 0.6 + self.community_pct = 0.3 + self.developer_pct = 0.1 + + self.contract_fund = 0.0 + self.community_fund = 0.0 + self.developer_fund = 0.0 + + self.user_balances = {} + + def deposit(self, user: str, amount: float): + # Calculate fee + + # Distribute fee + # TODO: Handle edge case where pool has no initial users == Community funds gets the reward + # 1. Community funds + # 2. Developer funds + # 3. Reward stakers + + # Update user_balances with new deposit + pass + + def withdraw(self, user: str): + # Fetch amount from user_balances + + # Remove user from pool to prevent self-reward leaving a hanging balance + + # Calculate fee + + # Distribute fee + # TODO: User needs to be removed from the pool first to avoid hanging balances after rewarding stakers + # 1. Community funds + # 2. Developer funds + # 3. Reward stakers + pass + + def __distribute_reward(self, amount): + # # # # + # Lock user_balances mutex + # # # # + + # Get total staked amount + # Determine distribution amongst users + # Update self.user_balances + + # # # # + # Unlock user_balances mutex + # # # # + pass