I've looked into the code now, and I think I get an impression what could be the problem. (Take into account that I'm no expert, and that confirmation of a developer of my interpretation would be a "must" before something is changed.)
Like Peercoin and Novacoin, Slimcoin relies on the concept of "chain trust". Clients will always select the chain with the highest trust to consider it the "best chain" (or "valid chain"). Each block has a "trust" value that is calculated in a section of
main.cpp (search for "new protocol"), and the calculation is different for PoW/PoB and PoS blocks.
What's interesting for us is the calculation of PoS block trust:
CBigNum bnNewTrust = (CBigNum(1)<<256) / (bnTarget + 1);
This line is called every time when a PoS block is detected. It sets the "block trust" for PoS blocks basically to a value correlated directly with PoW difficulty. The higher the difficulty, the higher the "trust" of the block.
After that line, there are some mechanisms in place meant to ensure that there are not too many PoS blocks in a row. So the block trust is reduced to a third if:
- the parent block of the PoS block is not a PoW block
- there are less than 3 PoW blocks in the last 12 PoS blocks
If both conditions are met, chain trust gets reduced to 1/9 of the value of the first PoW block in the row.
However, if the difficulty is high enough, and hashrate drops temporarily, then the trust value of PoS blocks could be high enough even if it continuously stays at 1/9 of the initial chain trust value. Then big stakers (or a single staker with multiple accounts) could produce more than 12 blocks in a row, until miners catch up.
I would therefore propose a mechanism that further decreases the trust of PoS blocks or even reduces it to 0 if a certain number of PoS blocks in a row is detected.
For example, one could add the following line at the end of the section:
if (nPoWCount == 0)
return 0;
which means that there can
never be more than 12 blocks PoS in a row (nPoWCount is the number of PoW blocks in the last 12 blocks).
Or one could reduce it further (e.g. bnNewTrust gets smaller directly proportional to nPoWCount. E.g. if the formula is:
bnNewTrust = bnNewTrust / (12 - nPoWCount)
a PoS block after 10 PoS blocks would already have 1(3*10)=1/30 of the chain trust of the first PoS block in the row, because additionally the "parent block is not PoW block" condition is fulfilled.
However, the first method (reducing trust to zero after 12 PoS blocks) would be additionally needed if the goal is to make never possible PoS minters "take over" the chain (e.g. after a permanent hashrate drop).
Both ways would not really affect the "profitability" of PoS minting, as after a single PoW block a PoS block would be permitted again (albeit with relatively low trust value).
This is only what I interpret from reviewing the code at a first glance, so I would like to see some comments on it, if my interpretation is correct. There may be missing parts in the "consensus puzzle". And obviously, a simulation would be needed to see if no side effects are to be expected.
PS: If my interpretation of hard and soft forks is correct, then this change could be implemented as a soft fork (with supermajority of blocks produced by client versions supporting the change). Old clients would not reject chains produced by new clients, but they could temporarily "fork away" if they mint too many PoS blocks in a row, that get rejected by new clients, so a high supermajority is needed.
PS2: Edited as in the initial version of the post were some mistakes and imprecisions, so always refer to this last version of the post