public void Stake(Address from, BigInteger stakeAmount) { Runtime.Expect(stakeAmount >= MinimumValidStake, "invalid amount"); Runtime.Expect(Runtime.IsWitness(from), "witness failed"); var balance = Runtime.GetBalance(DomainSettings.StakingTokenSymbol, from); var currentStake = _stakes.Get <Address, EnergyAction>(from); var newStake = stakeAmount + currentStake.totalAmount; Runtime.Expect(balance >= stakeAmount, "not enough balance"); Runtime.Expect(Runtime.TransferTokens(DomainSettings.StakingTokenSymbol, from, this.Address, stakeAmount), "stake transfer failed"); var entry = new EnergyAction() { unclaimedPartials = stakeAmount + GetLastAction(from).unclaimedPartials, totalAmount = newStake, timestamp = this.Runtime.Time, }; _stakes.Set(from, entry); var logEntry = new VotingLogEntry() { timestamp = this.Runtime.Time, amount = stakeAmount }; var votingLogbook = _voteHistory.Get <Address, StorageList>(from); votingLogbook.Add(logEntry); var masterAccountThreshold = GetMasterThreshold(); if (Runtime.Nexus.GenesisAddress != from && newStake >= masterAccountThreshold && !IsMaster(from)) { var nextClaim = GetMasterClaimDate(2); _mastersList.Add(new EnergyMaster() { address = from, claimDate = nextClaim }); Runtime.Notify(EventKind.RolePromote, from, new RoleEventData() { role = "master", date = nextClaim }); } Runtime.Notify(EventKind.TokenStake, from, new TokenEventData() { chainAddress = this.Address, symbol = DomainSettings.StakingTokenSymbol, value = stakeAmount }); }
private BigInteger CalculateEntryVotingPower(VotingLogEntry entry, Timestamp currentTime) { BigInteger baseMultiplier = 100; BigInteger votingMultiplier = baseMultiplier; var diff = (currentTime - entry.timestamp) / 86400; var votingBonus = diff < MaxVotingPowerBonus ? diff : MaxVotingPowerBonus; votingMultiplier += DailyVotingBonus * votingBonus; var votingPower = (entry.amount * votingMultiplier) / 100; return(votingPower); }
public void Stake(Address from, BigInteger stakeAmount) { Runtime.Expect(stakeAmount >= MinimumValidStake, "invalid amount"); Runtime.Expect(Runtime.IsWitness(from), "witness failed"); var balance = Runtime.GetBalance(DomainSettings.StakingTokenSymbol, from); Runtime.Expect(balance >= stakeAmount, "not enough balance"); Runtime.TransferTokens(DomainSettings.StakingTokenSymbol, from, this.Address, stakeAmount); EnergyStake stake; if (_stakeMap.ContainsKey <Address>(from)) { stake = _stakeMap.Get <Address, EnergyStake>(from); } else { stake = new EnergyStake() { stakeTime = new Timestamp(0), stakeAmount = 0, }; } stake.stakeTime = Runtime.Time; stake.stakeAmount += stakeAmount; _stakeMap.Set <Address, EnergyStake>(from, stake); Runtime.AddMember(DomainSettings.StakersOrganizationName, this.Address, from); var claimList = _claimMap.Get <Address, StorageList>(from); var claimEntry = new EnergyClaim() { stakeAmount = stakeAmount, claimDate = this.Runtime.Time, isNew = true, }; claimList.Add(claimEntry); var logEntry = new VotingLogEntry() { timestamp = this.Runtime.Time, amount = stakeAmount }; var votingLogbook = _voteHistory.Get <Address, StorageList>(from); votingLogbook.Add(logEntry); // masters membership var masterAccountThreshold = GetMasterThreshold(); if (stake.stakeAmount >= masterAccountThreshold && !IsMaster(from)) { var nextClaim = GetMasterClaimDate(2); Runtime.AddMember(DomainSettings.MastersOrganizationName, this.Address, from); _masterClaims.Set <Address, Timestamp>(from, nextClaim); } }