Incorrect behavior of BridgedInflationCurve #57
	
		Labels
		
	
	
	
	
		No Label
		
			
	
	
	bug
		
			duplicate
		
			enhancement
		
			help wanted
		
			invalid
		
			question
		
			wontfix
		
		
			bug
		
			duplicate
		
			enhancement
		
			help wanted
		
			invalid
		
			question
		
			wontfix
		
	
		No Milestone
		
			
		
	
	
		
		
		
			No project
			
				
			
		
	
	
	
	
	
		No Assignees
		
			
		
	
	
	
		1 Participants
		
	
	
		
		
			Notifications
			
				
			
		
	
	
		
		
	
	
	Due Date
	No due date set.
			
				Dependencies
				
				
		
	
	
	No dependencies set.
			Reference: ghostchain/ghost-node#57
			
		
	
		Loading…
	
		Reference in New Issue
	
	Block a user
	
	No description provided.
		
		Delete Branch "%!s()"
	 
	Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Problem
During the recent redeployment of the
ghost-slow-clapfunctionality, we observed unusual behavior during the sixth era. The total accumulated commissions reached approximately1.3 CSPR,yet no distributions occurred at the end of the 6th era. Specifically, theera_payoutreturned(0, 0)and did not failed.A special thanks to the ghostie known as Sauron for bringing this to our attention.
Findings
The only way this issue could occur is due to an overflow or underflow in
checked_mulor checked_div, which caused a fallback to theNonebranch, resulting in the return of twoDefault::default()values, equating to 0 for the currenttype Balance = u128. You can check this by your hand here.After a thorough investigation, we identified two key issues:
BridgedImbalanceis not being nullified, whileAccumulatedCommissionis.payout.Nullification
The purpose of
BridgedImbalanceandAccumulatedCommissionis to track imbalances and commissions throughout the era, as we need to eliminate the impact of bridging on the current validators. This is crucial because validators are incentivized by the reward curve to achieve the so-called ideal ratio of staked coins. During the bridging process, after a successful applause, the number of coins should either be minted or burned, which directly affects thetotal_issuanceand consequently alters the current ratio of staked coins.To obtain the initial
total_issuancethat remains unaffected by bridging actions in each era, we need to recalculate it in the adjusted total issuance. At the end of the era finalization, it is essential to nullify not onlyAccumulatedCommissionsbutBridgedImbalancetoo in ordre to make sure the adjusted total issuance will not stuck.Overflow
Since staking relies on the
PiecewiseLineartrait, there is a function that defines:As you can see, we are calling it here. However, instead of multiplying the result by
dat the end, we need to multiply it byaccumulated_commission. Therefore, we should multiply byaccumulated_commissionand then divide byadjusted_total_issuance(actuallydfor the function above) to make sure that reward is dependant onaccumulated_commissionnot ontotal_issuance.As an example, what occured in 6th era:
This is clearly an overflow of
u128, whereu128::MAXis approximately3.4028237e+38. As a result, we received zero as the payout. This situation is absolutely unacceptable, especially since we can expect commissions to be significantly higher in the future.Fixes
BridgedImbalanceto its default value during the call tonullify_commissionat the end of the era finalization. You can find how it was fixed here.Bug Bounty
We are 99.999% confident in the current implementation of
MulDiv; however, if you discover any failing test cases or have suggestions for optimizing the implementation, please share your thoughts in the comments below or reach out through any of our community channels:Use the latest version from
pallet-networksbranch and code inpallets/networksfolder as a referrence.Rewards are TBD