Skip to content

Commit

Permalink
feat: introduces additive slashing penalty (#301)
Browse files Browse the repository at this point in the history
* feat: updates fee mechanism for slashing to additive penalty

* feat: updates penalty to be 5% for slashing

* chore: renames for more descriptive explaination

* feat: adds fixes to tests

* chore: fix fee is 10 in tests

* feat: updates naming of variable

* chore: revert geth

* chore: fix naming in tests

* feat: update naming more and bump abi

* chore: update naming in comments

* Adds logging for preconfirmations (#314)

* feat: logs details of preconf in logs

* feat: stops sending bid rejection over node

* chore: leave bid reject for now
  • Loading branch information
ckartik authored Aug 7, 2024
1 parent 6481bfa commit c78997d
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 225 deletions.
54 changes: 27 additions & 27 deletions contracts-abi/abi/ProviderRegistry.abi
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
},
{
"type": "function",
"name": "getAccumulatedProtocolFee",
"name": "getAccumulatedPenaltyFee",
"inputs": [],
"outputs": [
{
Expand Down Expand Up @@ -151,7 +151,7 @@
"internalType": "uint256"
},
{
"name": "_protocolFeeRecipient",
"name": "_penaltyFeeRecipient",
"type": "address",
"internalType": "address"
},
Expand All @@ -171,7 +171,7 @@
"internalType": "uint256"
},
{
"name": "_protocolFeePayoutPeriodBlocks",
"name": "_penaltyFeePayoutPeriodBlocks",
"type": "uint256",
"internalType": "uint256"
}
Expand All @@ -194,7 +194,7 @@
},
{
"type": "function",
"name": "manuallyWithdrawProtocolFee",
"name": "manuallyWithdrawPenaltyFee",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
Expand Down Expand Up @@ -227,20 +227,35 @@
},
{
"type": "function",
"name": "pendingOwner",
"name": "penaltyFeeTracker",
"inputs": [],
"outputs": [
{
"name": "",
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "accumulatedAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "lastPayoutBlock",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "payoutPeriodBlocks",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"type": "function",
"name": "preConfirmationsContract",
"name": "pendingOwner",
"inputs": [],
"outputs": [
{
Expand All @@ -253,28 +268,13 @@
},
{
"type": "function",
"name": "protocolFeeTracker",
"name": "preConfirmationsContract",
"inputs": [],
"outputs": [
{
"name": "recipient",
"name": "",
"type": "address",
"internalType": "address"
},
{
"name": "accumulatedAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "lastPayoutBlock",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "payoutPeriodBlocks",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
Expand Down Expand Up @@ -378,7 +378,7 @@
},
{
"type": "function",
"name": "setNewProtocolFeeRecipient",
"name": "setNewPenaltyFeeRecipient",
"inputs": [
{
"name": "newFeeRecipient",
Expand Down Expand Up @@ -650,10 +650,10 @@
},
{
"type": "event",
"name": "ProtocolFeeRecipientUpdated",
"name": "PenaltyFeeRecipientUpdated",
"inputs": [
{
"name": "newProtocolFeeRecipient",
"name": "newPenaltyFeeRecipient",
"type": "address",
"indexed": true,
"internalType": "address"
Expand Down
270 changes: 135 additions & 135 deletions contracts-abi/clients/ProviderRegistry/ProviderRegistry.go

Large diffs are not rendered by default.

62 changes: 30 additions & 32 deletions contracts/contracts/ProviderRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ contract ProviderRegistry is
/// @dev Configurable withdrawal delay in milliseconds
uint256 public withdrawalDelay;

/// Struct enabling automatic protocol fee payouts
FeePayout.Tracker public protocolFeeTracker;
/// Struct enabling automatic penalty fee payouts
FeePayout.Tracker public penaltyFeeTracker;

/// @dev Mapping from provider address to whether they are registered or not
mapping(address => bool) public providerRegistered;
Expand All @@ -59,8 +59,8 @@ contract ProviderRegistry is
event Withdraw(address indexed provider, uint256 amount);
/// @dev Event emitted when the withdrawal delay is updated
event WithdrawalDelayUpdated(uint256 newWithdrawalDelay);
/// @dev Event emitted when the protocol fee recipient is updated
event ProtocolFeeRecipientUpdated(address indexed newProtocolFeeRecipient);
/// @dev Event emitted when the penalty fee recipient is updated
event PenaltyFeeRecipientUpdated(address indexed newPenaltyFeeRecipient);
/// @dev Event emitted when the fee payout period in blocks is updated
event FeePayoutPeriodBlocksUpdated(uint256 indexed newFeePayoutPeriodBlocks);

Expand All @@ -78,21 +78,21 @@ contract ProviderRegistry is
/**
* @dev Initializes the contract with a minimum stake requirement.
* @param _minStake The minimum stake required for provider registration.
* @param _protocolFeeRecipient The address that accumulates protocol fees
* @param _feePercent The fee percentage for protocol
* @param _penaltyFeeRecipient The address that accumulates penalty fees
* @param _feePercent The fee percentage for penalty
* @param _owner Owner of the contract, explicitly needed since contract is deployed w/ create2 factory.
* @param _withdrawalDelay The withdrawal delay in milliseconds.
* @param _protocolFeePayoutPeriodBlocks The min number of blocks between protocol fee payouts
* @param _penaltyFeePayoutPeriodBlocks The min number of blocks between penalty fee payouts
*/
function initialize(
uint256 _minStake,
address _protocolFeeRecipient,
address _penaltyFeeRecipient,
uint16 _feePercent,
address _owner,
uint256 _withdrawalDelay,
uint256 _protocolFeePayoutPeriodBlocks
uint256 _penaltyFeePayoutPeriodBlocks
) external initializer {
FeePayout.init(protocolFeeTracker, _protocolFeeRecipient, _protocolFeePayoutPeriodBlocks);
FeePayout.init(penaltyFeeTracker, _penaltyFeeRecipient, _penaltyFeePayoutPeriodBlocks);
minStake = _minStake;
feePercent = _feePercent;
withdrawalDelay = _withdrawalDelay;
Expand Down Expand Up @@ -159,31 +159,29 @@ contract ProviderRegistry is
uint256 residualBidPercentAfterDecay
) external nonReentrant onlyPreConfirmationEngine {
uint256 residualAmt = (amt * residualBidPercentAfterDecay * PRECISION) / PERCENT;
require(providerStakes[provider] >= residualAmt, "Insufficient funds to slash");
providerStakes[provider] -= residualAmt;
uint256 penaltyFee = (residualAmt * uint256(feePercent) * PRECISION) / PERCENT;
require(providerStakes[provider] >= residualAmt + penaltyFee, "Insufficient funds to slash");
providerStakes[provider] -= residualAmt + penaltyFee;

uint256 feeAmt = (residualAmt * uint256(feePercent) * PRECISION) / PERCENT;
uint256 amtMinusFee = residualAmt - feeAmt;

protocolFeeTracker.accumulatedAmount += feeAmt;
if (FeePayout.isPayoutDue(protocolFeeTracker)) {
FeePayout.transferToRecipient(protocolFeeTracker);
penaltyFeeTracker.accumulatedAmount += penaltyFee;
if (FeePayout.isPayoutDue(penaltyFeeTracker)) {
FeePayout.transferToRecipient(penaltyFeeTracker);
}

(bool success, ) = payable(bidder).call{value: amtMinusFee}("");
(bool success, ) = payable(bidder).call{value: residualAmt}("");
require(success, "Transfer to bidder failed");

emit FundsSlashed(provider, amtMinusFee);
emit FundsSlashed(provider, residualAmt + penaltyFee);
}

/**
* @notice Sets a new protocol fee recipient
* @notice Sets a new penalty fee recipient
* @dev onlyOwner restriction
* @param newFeeRecipient The address of the new protocol fee recipient
* @param newFeeRecipient The address of the new penalty fee recipient
*/
function setNewProtocolFeeRecipient(address newFeeRecipient) external onlyOwner {
protocolFeeTracker.recipient = newFeeRecipient;
emit ProtocolFeeRecipientUpdated(newFeeRecipient);
function setNewPenaltyFeeRecipient(address newFeeRecipient) external onlyOwner {
penaltyFeeTracker.recipient = newFeeRecipient;
emit PenaltyFeeRecipientUpdated(newFeeRecipient);
}

/**
Expand All @@ -206,7 +204,7 @@ contract ProviderRegistry is
/// @dev Sets the fee payout period in blocks
/// @param _feePayoutPeriodBlocks The new fee payout period in blocks
function setFeePayoutPeriodBlocks(uint256 _feePayoutPeriodBlocks) external onlyOwner {
protocolFeeTracker.payoutPeriodBlocks = _feePayoutPeriodBlocks;
penaltyFeeTracker.payoutPeriodBlocks = _feePayoutPeriodBlocks;
emit FeePayoutPeriodBlocksUpdated(_feePayoutPeriodBlocks);
}

Expand Down Expand Up @@ -242,11 +240,11 @@ contract ProviderRegistry is
}

/**
* @dev Manually withdraws accumulated protocol fees to the recipient
* @dev Manually withdraws accumulated penalty fees to the recipient
* to cover the edge case that oracle doesn't slash/reward, and funds still need to be withdrawn.
*/
function manuallyWithdrawProtocolFee() external onlyOwner {
FeePayout.transferToRecipient(protocolFeeTracker);
function manuallyWithdrawPenaltyFee() external onlyOwner {
FeePayout.transferToRecipient(penaltyFeeTracker);
}

/**
Expand All @@ -263,9 +261,9 @@ contract ProviderRegistry is
return eoaToBlsPubkey[provider];
}

/// @return protocolFee amount not yet transferred to recipient
function getAccumulatedProtocolFee() external view returns (uint256) {
return protocolFeeTracker.accumulatedAmount;
/// @return penaltyFee amount not yet transferred to recipient
function getAccumulatedPenaltyFee() external view returns (uint256) {
return penaltyFeeTracker.accumulatedAmount;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion contracts/scripts/DeployScripts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ contract DeployScript is Script {
0xfA0B0f5d298d28EFE4d35641724141ef19C05684 // Placeholder for now, L1 preconf.eth address
);
uint16 feePercent = 2;
uint16 providerPenaltyPercent = 5;
uint64 commitmentDispatchWindow = 2000;
uint256 blocksPerWindow = 10;
uint256 withdrawalDelay = 24 * 3600 * 1000; // 24 hours in milliseconds
Expand Down Expand Up @@ -60,7 +61,7 @@ contract DeployScript is Script {
abi.encodeCall(ProviderRegistry.initialize,
(minStake, // _minStake param
protocolFeeRecipient, // _protocolFeeRecipient param
feePercent, // _feePercent param
providerPenaltyPercent, // _feePercent param
msg.sender, // _owner param
withdrawalDelay, // _withdrawalDelay param
protocolFeePayoutPeriodBlocks)) // _protocolFeePayoutPeriodBlocks param
Expand Down
4 changes: 2 additions & 2 deletions contracts/test/OracleTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ contract OracleTest is Test {
);
vm.stopPrank();
assertEq(
providerRegistry.getProviderStake(provider) + ((bid * 50) / 100),
providerRegistry.getProviderStake(provider) + ((bid * 55) / 100),
250 ether
);
}
Expand Down Expand Up @@ -332,7 +332,7 @@ contract OracleTest is Test {
50
);
vm.stopPrank();
assertEq(providerRegistry.getProviderStake(provider), 250 ether - bid);
assertEq(providerRegistry.getProviderStake(provider), 250 ether - ((bid*110)/100));
assertEq(
bidderRegistry.getProviderAmount(provider),
(((bid * (100 - feePercent)) / 100) * residualAfterDecay) / 100
Expand Down
Loading

0 comments on commit c78997d

Please sign in to comment.