Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions src/Neo/SmartContract/Native/NeoToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,17 @@ private BigInteger CalculateBonus(DataCache snapshot, NeoAccountState state, uin
// Compute Neo holder reward

// In the unit of datoshi, 1 GAS = 10^8 datoshi
BigInteger sumNeoHold = 0;
BigInteger sumGasPerBlock = 0;
foreach (var (index, gasPerBlock) in GetSortedGasRecords(snapshot, end - 1))
{
if (index > start)
{
sumNeoHold += gasPerBlock * (end - index);
sumGasPerBlock += gasPerBlock * (end - index);
end = index;
}
else
{
sumNeoHold += gasPerBlock * (end - start);
sumGasPerBlock += gasPerBlock * (end - start);
break;
}
}
Expand All @@ -190,7 +190,7 @@ private BigInteger CalculateBonus(DataCache snapshot, NeoAccountState state, uin
voteReward = state.Balance * (latestGasPerVote - state.LastGasPerVote) / VoteFactor;
}

return (state.Balance * sumNeoHold * NeoHolderRewardRatio / 100 / TotalAmount, voteReward);
return (state.Balance * sumGasPerBlock * NeoHolderRewardRatio / 100 / TotalAmount, voteReward);
}

private void CheckCandidate(DataCache snapshot, ECPoint pubkey, CandidateState candidate)
Expand Down Expand Up @@ -272,18 +272,35 @@ internal override async ContractTask PostPersistAsync(ApplicationEngine engine)

if (ShouldRefreshCommittee(engine.PersistingBlock.Index, m))
{
BigInteger voterRewardOfEachCommittee = gasPerBlock * VoterRewardRatio * VoteFactor * m / (m + n) / 100; // Zoom in VoteFactor times, and the final calculation should be divided VoteFactor
var withFlatRewards = engine.IsHardforkEnabled(Hardfork.HF_Faun);
BigInteger voterRewardOfEachCommittee =
withFlatRewards ?
gasPerBlock * VoterRewardRatio * VoteFactor / 100 : // Total reward for voters when it's flat rewards
gasPerBlock * VoterRewardRatio * VoteFactor * m / (m + n) / 100; // Zoom in VoteFactor times, and the final calculation should be divided VoteFactor
var votersCount = (BigInteger)engine.SnapshotCache[_votersCount];

for (index = 0; index < committee.Count; index++)
{
var (publicKey, votes) = committee[index];
var factor = index < n ? 2 : 1; // The `voter` rewards of validator will double than other committee's
if (votes > 0)

if (withFlatRewards)
{
BigInteger voterSumRewardPerNEO = factor * voterRewardOfEachCommittee / votes;
BigInteger voterSumRewardPerNEO = voterRewardOfEachCommittee / votersCount;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another change apart of flat rewards, this also set a defined level among the committee itself

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see now, @shargon, one main point to change here is not just this factor but it is the votersCount.

We should not consider votersCount for each committee reward, that is what removes the incentive for free voting.

StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee, publicKey);
StorageItem lastRewardPerNeo = engine.SnapshotCache.GetAndChange(voterRewardKey, () => new StorageItem(BigInteger.Zero));
lastRewardPerNeo.Add(voterSumRewardPerNEO);
}
else
{
if (votes > 0)
{
var factor = index < n ? 2 : 1; // The `voter` rewards of validator will double than other committee's
BigInteger voterSumRewardPerNEO = factor * voterRewardOfEachCommittee / votes;
StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee, publicKey);
StorageItem lastRewardPerNeo = engine.SnapshotCache.GetAndChange(voterRewardKey, () => new StorageItem(BigInteger.Zero));
lastRewardPerNeo.Add(voterSumRewardPerNEO);
}
}
}
}
}
Expand Down
Loading