Skip to content

Commit

Permalink
require all slash commit-reveal
Browse files Browse the repository at this point in the history
  • Loading branch information
3esmit committed Oct 3, 2018
1 parent 5d75325 commit 1855141
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 102 deletions.
77 changes: 35 additions & 42 deletions contracts/registry/UsernameRegistrar.sol
Expand Up @@ -20,7 +20,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {


uint256 public constant releaseDelay = 365 days; uint256 public constant releaseDelay = 365 days;
mapping (bytes32 => Account) public accounts; mapping (bytes32 => Account) public accounts;
mapping (bytes32 => address) reservedSlashers; mapping (bytes32 => SlashReserve) reservedSlashers;


//Slashing conditions //Slashing conditions
uint256 public usernameMinLength; uint256 public usernameMinLength;
Expand All @@ -43,6 +43,11 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
address owner; address owner;
} }


struct SlashReserve {
address reserver;
uint256 blockNumber;
}

/** /**
* @notice Callable only by `parentRegistry()` to continue migration of ENSSubdomainRegistry. * @notice Callable only by `parentRegistry()` to continue migration of ENSSubdomainRegistry.
*/ */
Expand Down Expand Up @@ -181,41 +186,43 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {


/** /**
* @notice secretly reserve the slashing reward to `msg.sender` * @notice secretly reserve the slashing reward to `msg.sender`
* @param _secret keccak256(abi.encodePacked(namehash, creationTime)) * @param _secret keccak256(abi.encodePacked(namehash, creationTime, reserveSecret))
*/ */
function reserveSlash(bytes32 _secret) external { function reserveSlash(bytes32 _secret) external {
require(reservedSlashers[_secret] == address(0), "Already Reserved"); require(reservedSlashers[_secret].blockNumber == 0, "Already Reserved");
reservedSlashers[_secret] = msg.sender; reservedSlashers[_secret] = SlashReserve(msg.sender, block.number);
} }


/** /**
* @notice Slash username smaller then `usernameMinLength`. * @notice Slash username smaller then `usernameMinLength`.
* @param _username Raw value of offending username. * @param _username Raw value of offending username.
*/ */
function slashSmallUsername( function slashSmallUsername(
string _username string _username,
uint256 _reserveSecret
) )
external external
{ {
bytes memory username = bytes(_username); bytes memory username = bytes(_username);
require(username.length < usernameMinLength, "Not a small username."); require(username.length < usernameMinLength, "Not a small username.");
slashUsername(username); slashUsername(username, _reserveSecret);
} }


/** /**
* @notice Slash username starting with "0x" and with length greater than 12. * @notice Slash username starting with "0x" and with length greater than 12.
* @param _username Raw value of offending username. * @param _username Raw value of offending username.
*/ */
function slashAddressLikeUsername( function slashAddressLikeUsername(
string _username string _username,
uint256 _reserveSecret
) )
external external
{ {
bytes memory username = bytes(_username); bytes memory username = bytes(_username);
require(username.length > 12, "Too small to look like an address."); require(username.length > 12, "Too small to look like an address.");
require(username[0] == byte("0"), "First character need to be 0"); require(username[0] == byte("0"), "First character need to be 0");
require(username[1] == byte("x"), "Second character need to be x"); require(username[1] == byte("x"), "Second character need to be x");
slashUsername(username); slashUsername(username, _reserveSecret);
} }


/** /**
Expand All @@ -225,7 +232,8 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
*/ */
function slashReservedUsername( function slashReservedUsername(
string _username, string _username,
bytes32[] _proof bytes32[] _proof,
uint256 _reserveSecret
) )
external external
{ {
Expand All @@ -238,7 +246,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
), ),
"Invalid Proof." "Invalid Proof."
); );
slashUsername(username); slashUsername(username, _reserveSecret);
} }


/** /**
Expand All @@ -248,7 +256,8 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
*/ */
function slashInvalidUsername( function slashInvalidUsername(
string _username, string _username,
uint256 _offendingPos uint256 _offendingPos,
uint256 _reserveSecret
) )
external external
{ {
Expand All @@ -258,7 +267,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {


require(!((b >= 48 && b <= 57) || (b >= 97 && b <= 122)), "Not invalid character."); require(!((b >= 48 && b <= 57) || (b >= 97 && b <= 122)), "Not invalid character.");


slashUsername(username); slashUsername(username, _reserveSecret);
} }


/** /**
Expand Down Expand Up @@ -481,22 +490,6 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
} }
} }


/**
* @notice returns address that reserved slashing of an account
* @param _label Username hash.
* @return Reserved Slasher
**/
function getReservedSlasher(bytes32 _label)
external
view
returns(address reservedSlasher)
{
bytes32 namehash = keccak256(abi.encodePacked(ensNode, _label));
uint256 creationTime = accounts[_label].creationTime;
bytes32 secret = keccak256(abi.encodePacked(namehash, creationTime));
reservedSlasher = reservedSlashers[secret];
}

/** /**
* @notice calculate reward part an account could payout on slash * @notice calculate reward part an account could payout on slash
* @param _label Username hash. * @param _label Username hash.
Expand Down Expand Up @@ -653,10 +646,15 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
* @dev Removes account hash of `_username` and send account.balance to msg.sender. * @dev Removes account hash of `_username` and send account.balance to msg.sender.
* @param _username Username being slashed. * @param _username Username being slashed.
*/ */
function slashUsername(bytes _username) internal { function slashUsername(
bytes _username,
uint256 _reserveSecret
)
internal
{
bytes32 label = keccak256(_username); bytes32 label = keccak256(_username);
bytes32 namehash = keccak256(abi.encodePacked(ensNode, label)); bytes32 namehash = keccak256(abi.encodePacked(ensNode, label));
uint256 amountToTransfer; uint256 amountToTransfer = 0;
uint256 creationTime = accounts[label].creationTime; uint256 creationTime = accounts[label].creationTime;
address owner = ensRegistry.owner(namehash); address owner = ensRegistry.owner(namehash);
if(creationTime == 0) { if(creationTime == 0) {
Expand All @@ -679,18 +677,13 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
reserveAmount -= amountToTransfer; reserveAmount -= amountToTransfer;
uint256 partialDeposit = amountToTransfer / 3; uint256 partialDeposit = amountToTransfer / 3;
amountToTransfer = partialDeposit * 2; // reserve 1/3 to network (controller) amountToTransfer = partialDeposit * 2; // reserve 1/3 to network (controller)
address slasher = msg.sender; bytes32 secret = keccak256(abi.encodePacked(namehash, creationTime, _reserveSecret));
bytes32 secret = keccak256(abi.encodePacked(namehash, creationTime)); SlashReserve memory reserve = reservedSlashers[secret];
address reservedSlasher = reservedSlashers[secret]; require(reserve.reserver != address(0), "Not reserved.");
if (reservedSlasher != address(0)) { require(reserve.blockNumber < block.number, "Cannot reveal in same block");
delete reservedSlashers[secret]; delete reservedSlashers[secret];
if (reservedSlasher != msg.sender) {
amountToTransfer -= partialDeposit; // 1/3 goes to msg.sender require(token.transfer(reserve.reserver, amountToTransfer), "Error in transfer.");
require(token.transfer(msg.sender, partialDeposit), "Error in transfer.");
}
slasher = reservedSlasher; // reservedSlasher will receive the amountToTransfer instead of msg.sender
}
require(token.transfer(slasher, amountToTransfer), "Error in transfer.");
} }
emit UsernameOwner(namehash, address(0)); emit UsernameOwner(namehash, address(0));
} }
Expand Down

0 comments on commit 1855141

Please sign in to comment.