PIP: 5
  Title: Stablised difficulty algorithm
  Type: Protocol 
  Impact: Hard-Fork
  Author: Albert Molina <bpascalblockchain@gmail.com>
  Comments-URI: N/A
  Status: Active
  Created: 2017-04-01
***PIP Editor Note:** This PIP was created retrospectively based of the [Whitepaper V2][1] on 2017-08-15.** ## Summary A new difficulty adjustment algorithm is proposed to stablise sinusoidal volatility resulting from chaotic hashpower fluctuations. ## Motivation Due to the volatile nature of cryptocurrency valuations, miners will tend to migrate en masse based on profitability of coins. As miners migrate, blocktimes are temporarily affected as time is needed for difficulty adjustments. Cloud-mining has exacerbated this issue. Resolving this issue will result in more stable blocktime and more reliable daily supply. ## Specification An enhanced the difficulty calculation algorithm to to better adjust for sinusoidal volatility is proposed as follows. ```pascal function TPCSafeBox.GetActualTargetHash(UseProtocolV2 : Boolean): TRawBytes; { Target is calculated in each block with avg obtained in previous CT_CalcNewDifficulty blocks. If Block is lower than CT_CalcNewDifficulty then is calculated with all previous blocks. } Var ts1, ts2, tsTeorical, tsReal, tsTeoricalStop, tsRealStop: Int64; CalcBack : Integer; lastBlock : TOperationBlock; begin if (BlocksCount <= 1) then begin // Important: CT_MinCompactTarget is applied for blocks 0 until ((CT_CalcNewDifficulty*2)-1) Result := TPascalCoinProtocol.TargetFromCompact(CT_MinCompactTarget); end else begin if BlocksCount > CT_CalcNewTargetBlocksAverage then CalcBack := CT_CalcNewTargetBlocksAverage else CalcBack := BlocksCount-1; lastBlock := Block(BlocksCount-1).blockchainInfo; // Calc new target! ts1 := lastBlock.timestamp; ts2 := Block(BlocksCount-CalcBack-1).blockchainInfo.timestamp; tsTeorical := (CalcBack * CT_NewLineSecondsAvg); tsReal := (ts1 - ts2); If (Not UseProtocolV2) then begin Result := TPascalCoinProtocol.GetNewTarget(tsTeorical, tsReal,TPascalCoinProtocol.TargetFromCompact(lastBlock.compact_target)); end else begin CalcBack := CalcBack DIV CT_CalcNewTargetLimitChange_SPLIT; If CalcBack=0 then CalcBack := 1; ts2 := Block(BlocksCount-CalcBack-1).blockchainInfo.timestamp; tsTeoricalStop := (CalcBack * CT_NewLineSecondsAvg); tsRealStop := (ts1 - ts2); { Protocol 2 change: Only will increase/decrease Target if (CT_CalcNewTargetBlocksAverage DIV 10) needs to increase/decrease too, othewise use current Target. This will prevent sinusoidal movement and provide more stable hashrate, computing always time from CT_CalcNewTargetBlocksAverage } If ((tsTeorical>tsReal) and (tsTeoricalStop>tsRealStop)) Or ((tsTeorical