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
|
// Extract miner's address and check that is real miner
|
||||||
address miner = SignatureVerifier.recover(
|
address miner = SignatureVerifier.recover(
|
||||||
SignatureVerifier.hash(_minerPublicKey, hashAlgorithm), _minerPublicKeySignature);
|
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
|
// Verify correctness of re-encryption
|
||||||
UmbralDeserializer.Capsule memory capsule = _capsuleBytes.toCapsule();
|
if (!isCapsuleFragCorrect(
|
||||||
UmbralDeserializer.CapsuleFrag memory cFrag = _cFragBytes.toCapsuleFrag();
|
_capsuleBytes.toCapsule(), _cFragBytes.toCapsuleFrag(), _preComputedData.toPreComputedData())) {
|
||||||
UmbralDeserializer.PreComputedData memory data = _preComputedData.toPreComputedData();
|
// TODO calculate penalty - depends on how many time was slashed
|
||||||
if (!isCapsuleFragCorrect(capsule, cFrag, data)) {
|
// TODO set reward
|
||||||
//TODO calculate penalty - depends on how many time was slashed
|
escrow.slashMiner(miner, PENALTY, msg.sender, PENALTY);
|
||||||
// escrow.slashMiner(miner, PENALTY);
|
|
||||||
}
|
}
|
||||||
challengedCFrags[challengeHash] = true;
|
challengedCFrags[challengeHash] = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,12 +114,12 @@ contract Issuer is Upgradeable {
|
||||||
)
|
)
|
||||||
internal returns (uint256 amount)
|
internal returns (uint256 amount)
|
||||||
{
|
{
|
||||||
|
if (currentSupply1 == totalSupply || currentSupply2 == totalSupply) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint256 currentSupply = _currentPeriod <= currentMintingPeriod ?
|
uint256 currentSupply = _currentPeriod <= currentMintingPeriod ?
|
||||||
Math.min(currentSupply1, currentSupply2) :
|
Math.min(currentSupply1, currentSupply2) :
|
||||||
Math.max(currentSupply1, currentSupply2);
|
Math.max(currentSupply1, currentSupply2);
|
||||||
if (currentSupply == totalSupply) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//totalSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2) -
|
//totalSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2) -
|
||||||
//currentSupply * 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 {
|
function verifyState(address _testTarget) public onlyOwner {
|
||||||
require(address(uint160(delegateGet(_testTarget, "token()"))) == address(token));
|
require(address(uint160(delegateGet(_testTarget, "token()"))) == address(token));
|
||||||
require(delegateGet(_testTarget, "miningCoefficient()") == miningCoefficient);
|
require(delegateGet(_testTarget, "miningCoefficient()") == miningCoefficient);
|
||||||
|
|
|
@ -710,6 +710,8 @@ contract MinersEscrow is Issuer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16 constant MAX_PERIOD = 65535;
|
||||||
// TODO complete
|
// TODO complete
|
||||||
function slashMiner(
|
function slashMiner(
|
||||||
address _miner,
|
address _miner,
|
||||||
|
@ -720,10 +722,13 @@ contract MinersEscrow is Issuer {
|
||||||
public
|
public
|
||||||
{
|
{
|
||||||
require(msg.sender == address(challengeOverseer));
|
require(msg.sender == address(challengeOverseer));
|
||||||
|
require(_penalty > 0);
|
||||||
MinerInfo storage info = minerInfo[_miner];
|
MinerInfo storage info = minerInfo[_miner];
|
||||||
//TODO maybe raise error
|
//TODO maybe raise error
|
||||||
if (info.value < _penalty) {
|
if (info.value < _penalty) {
|
||||||
_penalty = info.value;
|
_penalty = info.value;
|
||||||
|
//clear or remove all sub stakes
|
||||||
|
info.subStakes.length = 0;
|
||||||
}
|
}
|
||||||
info.value -= _penalty;
|
info.value -= _penalty;
|
||||||
//TODO maybe raise error
|
//TODO maybe raise error
|
||||||
|
@ -731,10 +736,71 @@ contract MinersEscrow is Issuer {
|
||||||
_reward = _penalty;
|
_reward = _penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
//choose short stake
|
// decrease sub stakes
|
||||||
//decrease stake(s)
|
if (info.subStakes.length > 0) {
|
||||||
//refresh values in Issuer
|
uint16 currentPeriod = getCurrentPeriod();
|
||||||
token.safeTransfer(_investigator, _reward);
|
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-------------
|
//-------------Additional getters for miners info-------------
|
||||||
|
|
Loading…
Reference in New Issue