mirror of https://github.com/nucypher/nucypher.git
Draft of the slashing method
parent
2ef2a8f9b6
commit
e24263dbd5
|
@ -84,15 +84,17 @@ contract ChallengeOverseer {
|
|||
// Extract miner's address and check that is real miner
|
||||
address miner = SignatureVerifier.recover(
|
||||
SignatureVerifier.hash(_minerPublicKey, hashAlgorithm), _minerPublicKeySignature);
|
||||
require(escrow.getLockedTokens(miner) > 0); // TODO check that miner can be slashed
|
||||
// Check that miner can be slashed
|
||||
uint256 minerValue;
|
||||
(minerValue,,,) = escrow.minerInfo(miner);
|
||||
require(minerValue > 0);
|
||||
|
||||
// Verify correctness of re-encryption
|
||||
UmbralDeserializer.Capsule memory capsule = _capsuleBytes.toCapsule();
|
||||
UmbralDeserializer.CapsuleFrag memory cFrag = _cFragBytes.toCapsuleFrag();
|
||||
UmbralDeserializer.PreComputedData memory data = _preComputedData.toPreComputedData();
|
||||
if (!isCapsuleFragCorrect(capsule, cFrag, data)) {
|
||||
//TODO calculate penalty - depends on how many time was slashed
|
||||
// escrow.slashMiner(miner, PENALTY);
|
||||
if (!isCapsuleFragCorrect(
|
||||
_capsuleBytes.toCapsule(), _cFragBytes.toCapsuleFrag(), _preComputedData.toPreComputedData())) {
|
||||
// TODO calculate penalty - depends on how many time was slashed
|
||||
// TODO set reward
|
||||
escrow.slashMiner(miner, PENALTY, msg.sender, PENALTY);
|
||||
}
|
||||
challengedCFrags[challengeHash] = true;
|
||||
}
|
||||
|
|
|
@ -114,12 +114,12 @@ contract Issuer is Upgradeable {
|
|||
)
|
||||
internal returns (uint256 amount)
|
||||
{
|
||||
if (currentSupply1 == totalSupply || currentSupply2 == totalSupply) {
|
||||
return;
|
||||
}
|
||||
uint256 currentSupply = _currentPeriod <= currentMintingPeriod ?
|
||||
Math.min(currentSupply1, currentSupply2) :
|
||||
Math.max(currentSupply1, currentSupply2);
|
||||
if (currentSupply == totalSupply) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//totalSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2) -
|
||||
//currentSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2)
|
||||
|
@ -157,6 +157,15 @@ contract Issuer is Upgradeable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Return tokens for future minting
|
||||
* @param _amount Amount of tokens
|
||||
**/
|
||||
function unMint(uint256 _amount) internal {
|
||||
currentSupply1 = currentSupply1.sub(_amount);
|
||||
currentSupply2 = currentSupply2.sub(_amount);
|
||||
}
|
||||
|
||||
function verifyState(address _testTarget) public onlyOwner {
|
||||
require(address(uint160(delegateGet(_testTarget, "token()"))) == address(token));
|
||||
require(delegateGet(_testTarget, "miningCoefficient()") == miningCoefficient);
|
||||
|
|
|
@ -710,6 +710,8 @@ contract MinersEscrow is Issuer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
uint16 constant MAX_PERIOD = 65535;
|
||||
// TODO complete
|
||||
function slashMiner(
|
||||
address _miner,
|
||||
|
@ -720,10 +722,13 @@ contract MinersEscrow is Issuer {
|
|||
public
|
||||
{
|
||||
require(msg.sender == address(challengeOverseer));
|
||||
require(_penalty > 0);
|
||||
MinerInfo storage info = minerInfo[_miner];
|
||||
//TODO maybe raise error
|
||||
if (info.value < _penalty) {
|
||||
_penalty = info.value;
|
||||
//clear or remove all sub stakes
|
||||
info.subStakes.length = 0;
|
||||
}
|
||||
info.value -= _penalty;
|
||||
//TODO maybe raise error
|
||||
|
@ -731,10 +736,71 @@ contract MinersEscrow is Issuer {
|
|||
_reward = _penalty;
|
||||
}
|
||||
|
||||
//choose short stake
|
||||
//decrease stake(s)
|
||||
//refresh values in Issuer
|
||||
token.safeTransfer(_investigator, _reward);
|
||||
// decrease sub stakes
|
||||
if (info.subStakes.length > 0) {
|
||||
uint16 currentPeriod = getCurrentPeriod();
|
||||
uint16 startPeriod = getStartPeriod(info, startPeriod);
|
||||
uint256 lockedTokens = getLockedTokens(_miner);
|
||||
if (info.value < lockedTokens) {
|
||||
slashMiner(info, lockedTokens - info.value, currentPeriod, startPeriod, false);
|
||||
}
|
||||
lockedTokens = getLockedTokens(_miner, 1);
|
||||
if (info.value < lockedTokens) {
|
||||
slashMiner(info, lockedTokens - info.value, currentPeriod.add16(1), startPeriod, false);
|
||||
}
|
||||
}
|
||||
|
||||
unMint(_penalty - _reward);
|
||||
if (_reward > 0) {
|
||||
token.safeTransfer(_investigator, _reward);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO complete
|
||||
function slashMiner(
|
||||
MinerInfo storage _info,
|
||||
uint256 _penalty,
|
||||
uint16 _period,
|
||||
uint16 _startPeriod,
|
||||
bool _strict
|
||||
)
|
||||
internal
|
||||
{
|
||||
while(_penalty > 0) {
|
||||
uint16 minSubStakeLastPeriod = MAX_PERIOD; //TODO
|
||||
for (uint256 i = 0; i < _info.subStakes.length; i++) {
|
||||
SubStakeInfo storage subStake = _info.subStakes[i];
|
||||
uint16 lastPeriod = getLastPeriodOfSubStake(subStake, _startPeriod);
|
||||
if ((_strict && subStake.firstPeriod == _period ||
|
||||
!_strict && subStake.firstPeriod <= _period) &&
|
||||
lastPeriod >= _period &&
|
||||
lastPeriod < minSubStakeLastPeriod)
|
||||
{
|
||||
SubStakeInfo storage shortestSubStake = subStake;
|
||||
minSubStakeLastPeriod = lastPeriod;
|
||||
}
|
||||
}
|
||||
if (minSubStakeLastPeriod == MAX_PERIOD) {
|
||||
break;
|
||||
}
|
||||
uint256 appliedPenalty = _penalty;
|
||||
if (_penalty < shortestSubStake.lockedValue) {
|
||||
shortestSubStake.lockedValue -= _penalty;
|
||||
_penalty = 0;
|
||||
} else {
|
||||
shortestSubStake.lastPeriod = 1;
|
||||
_penalty -= shortestSubStake.lockedValue;
|
||||
appliedPenalty = shortestSubStake.lockedValue;
|
||||
}
|
||||
if (_info.confirmedPeriod1 >= _period &&
|
||||
_info.confirmedPeriod1 <= lastPeriod) {
|
||||
lockedPerPeriod[_info.confirmedPeriod1] -= appliedPenalty;
|
||||
}
|
||||
if (_info.confirmedPeriod2 >= _period &&
|
||||
_info.confirmedPeriod2 <= lastPeriod) {
|
||||
lockedPerPeriod[_info.confirmedPeriod2] -= appliedPenalty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------Additional getters for miners info-------------
|
||||
|
|
Loading…
Reference in New Issue