From 496badd4069214c491b9e259bd29804aab2bf1ba Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 15 Sep 2024 14:19:38 -0400 Subject: [PATCH 1/9] feat: adds logic to mitigate against insufficent funds bug --- contracts/contracts/core/ProviderRegistry.sol | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 4ef959a41..8e3d9e26f 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -103,7 +103,6 @@ contract ProviderRegistry is function delegateStake(address provider) external payable whenNotPaused { _stake(provider); } - /** * @dev Slash funds from the provider and send the slashed amount to the bidder. * @dev reenterancy not necessary but still putting here for precaution. @@ -121,7 +120,18 @@ contract ProviderRegistry is ) external nonReentrant onlyPreConfirmationEngine whenNotPaused { uint256 residualAmt = (amt * residualBidPercentAfterDecay * PRECISION) / PERCENT; uint256 penaltyFee = (residualAmt * uint256(feePercent) * PRECISION) / PERCENT; - require(providerStakes[provider] >= residualAmt + penaltyFee, "Insufficient funds to slash"); + // if the provider's stake is less than the residual amount + penalty fee, we need to adjust the residual amount and penalty fee + // this is to prevent underflow and ensure the contract doesn't revert + // We also emit + if (providerStakes[provider] < residualAmt + penaltyFee) { + emit InsufficientFundsToSlash(provider, providerStakes[provider], residualAmt, penaltyFee); + if (providerStakes[provider] < residualAmt) { + penaltyFee = 0; + residualAmt = providerStakes[provider]; + } else { + penaltyFee = providerStakes[provider] - residualAmt; + } + } providerStakes[provider] -= residualAmt + penaltyFee; penaltyFeeTracker.accumulatedAmount += penaltyFee; From dc87e36f2acdab5a25f366a550e5d9816e2ab6fc Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 15 Sep 2024 15:40:21 -0400 Subject: [PATCH 2/9] feat: adds testing for edge cases of penatly and residual balance slashing --- .../interfaces/IProviderRegistry.sol | 8 +++ contracts/test/core/ProviderRegistryTest.sol | 50 +++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/contracts/contracts/interfaces/IProviderRegistry.sol b/contracts/contracts/interfaces/IProviderRegistry.sol index ddb5761b5..bb51ef92a 100644 --- a/contracts/contracts/interfaces/IProviderRegistry.sol +++ b/contracts/contracts/interfaces/IProviderRegistry.sol @@ -27,6 +27,14 @@ interface IProviderRegistry { /// @dev Event emitted when the fee payout period in blocks is updated event FeePayoutPeriodBlocksUpdated(uint256 indexed newFeePayoutPeriodBlocks); + /// @dev Event emitted when there are insufficient funds to slash + event InsufficientFundsToSlash( + address indexed provider, + uint256 providerStake, + uint256 residualAmount, + uint256 penaltyFee + ); + function registerAndStake(bytes calldata blsPublicKey) external payable; function stake() external payable; diff --git a/contracts/test/core/ProviderRegistryTest.sol b/contracts/test/core/ProviderRegistryTest.sol index aea0c916f..a6bb9618a 100644 --- a/contracts/test/core/ProviderRegistryTest.sol +++ b/contracts/test/core/ProviderRegistryTest.sol @@ -28,6 +28,12 @@ contract ProviderRegistryTest is Test { event FeeTransfer(uint256 amount, address indexed recipient); event PenaltyFeeRecipientUpdated(address indexed newPenaltyFeeRecipient); event FeePayoutPeriodBlocksUpdated(uint256 indexed newFeePayoutPeriodBlocks); + event InsufficientFundsToSlash( + address indexed provider, + uint256 providerStake, + uint256 residualAmt, + uint256 penaltyFee + ); function setUp() public { testNumber = 42; @@ -257,8 +263,7 @@ contract ProviderRegistryTest is Test { vm.expectRevert(bytes("")); providerRegistry.slash(1 ether, provider, payable(bidder),100); } - - function testFail_ShouldRetrieveFundsGreaterThanStake() public { + function test_ShouldRetrieveFundsWhenSlashIsGreaterThanStake() public { vm.prank(address(this)); providerRegistry.setPreconfirmationsContract(address(this)); @@ -266,12 +271,51 @@ contract ProviderRegistryTest is Test { vm.prank(provider); providerRegistry.registerAndStake{value: 2 ether}(validBLSPubkey); address bidder = vm.addr(4); - vm.expectRevert(bytes("")); vm.prank(address(this)); + vm.expectEmit(true, true, true, true); + emit InsufficientFundsToSlash(provider, 2 ether, 3 ether, 0.3 ether); + providerRegistry.slash(3 ether, provider, payable(bidder), 100); + + assertEq(providerRegistry.getAccumulatedPenaltyFee(), 0); + assertEq(providerRegistry.providerStakes(provider), 0 ether); + } + + function test_ShouldRetrieveFundsWhenSlashIsGreaterThanStakePenaltyNotCovered() public { + vm.prank(address(this)); + providerRegistry.setPreconfirmationsContract(address(this)); + + vm.deal(provider, 3 ether); + vm.prank(provider); + providerRegistry.registerAndStake{value: 3 ether}(validBLSPubkey); + address bidder = vm.addr(4); + vm.prank(address(this)); + + vm.expectEmit(true, true, true, true); + emit InsufficientFundsToSlash(provider, 3 ether, 3 ether, 0.3 ether); providerRegistry.slash(3 ether, provider, payable(bidder), 100); + + assertEq(providerRegistry.getAccumulatedPenaltyFee(), 0); + assertEq(providerRegistry.providerStakes(provider), 0 ether); } + function test_ShouldRetrieveFundsWhenSlashIsGreaterThanStakePenaltyNotFullyCovered() public { + vm.prank(address(this)); + providerRegistry.setPreconfirmationsContract(address(this)); + + vm.deal(provider, 3.1 ether); + vm.prank(provider); + providerRegistry.registerAndStake{value: 3.1 ether}(validBLSPubkey); + address bidder = vm.addr(4); + vm.prank(address(this)); + + vm.expectEmit(true, true, true, true); + emit InsufficientFundsToSlash(provider, 3.1 ether, 3 ether, 0.3 ether); + providerRegistry.slash(3 ether, provider, payable(bidder), 100); + + assertEq(providerRegistry.getAccumulatedPenaltyFee(), 0.1 ether); + assertEq(providerRegistry.providerStakes(provider), 0 ether); + } function test_PenaltyFeeBehavior() public { providerRegistry.setNewPenaltyFeeRecipient(vm.addr(6)); vm.deal(provider, 3 ether); From b31f9ae2b57eb374450095f2222e64dadbd3da0c Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 15 Sep 2024 15:41:29 -0400 Subject: [PATCH 3/9] chore: newline --- contracts/contracts/core/ProviderRegistry.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 8e3d9e26f..7c74ce9b4 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -103,6 +103,7 @@ contract ProviderRegistry is function delegateStake(address provider) external payable whenNotPaused { _stake(provider); } + /** * @dev Slash funds from the provider and send the slashed amount to the bidder. * @dev reenterancy not necessary but still putting here for precaution. From 474cdf288fd121f59cd0bf5ca4d3fdad4e2a6a98 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 15 Sep 2024 15:41:47 -0400 Subject: [PATCH 4/9] chore: remove whitespace --- contracts/contracts/core/ProviderRegistry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 7c74ce9b4..796530ece 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -103,7 +103,7 @@ contract ProviderRegistry is function delegateStake(address provider) external payable whenNotPaused { _stake(provider); } - + /** * @dev Slash funds from the provider and send the slashed amount to the bidder. * @dev reenterancy not necessary but still putting here for precaution. From 011ea511380e4714d93eb0e3dc0b6dbe6e8b8978 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 15 Sep 2024 16:01:48 -0400 Subject: [PATCH 5/9] chore: constructs the provider registry abi --- contracts-abi/abi/ProviderRegistry.abi | 31 ++++ .../ProviderRegistry/ProviderRegistry.go | 149 +++++++++++++++++- 2 files changed, 179 insertions(+), 1 deletion(-) diff --git a/contracts-abi/abi/ProviderRegistry.abi b/contracts-abi/abi/ProviderRegistry.abi index 555e50c7e..6039e05e8 100644 --- a/contracts-abi/abi/ProviderRegistry.abi +++ b/contracts-abi/abi/ProviderRegistry.abi @@ -668,6 +668,37 @@ ], "anonymous": false }, + { + "type": "event", + "name": "InsufficientFundsToSlash", + "inputs": [ + { + "name": "provider", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "providerStake", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "residualAmount", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "penaltyFee", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, { "type": "event", "name": "OwnershipTransferStarted", diff --git a/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go b/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go index 069737bb2..31239c09d 100644 --- a/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go +++ b/contracts-abi/clients/ProviderRegistry/ProviderRegistry.go @@ -31,7 +31,7 @@ var ( // ProviderregistryMetaData contains all meta data concerning the Providerregistry contract. var ProviderregistryMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"PERCENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PRECISION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegateRegisterAndStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"delegateStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eoaToBlsPubkey\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAccumulatedPenaltyFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKey\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProviderStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isProviderValid\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"manuallyWithdrawPenaltyFee\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minStake\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"penaltyFeeTracker\",\"inputs\":[],\"outputs\":[{\"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\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preConfirmationsContract\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerRegistered\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerStakes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerAndStake\",\"inputs\":[{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeePayoutPeriodBlocks\",\"inputs\":[{\"name\":\"_feePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewPenaltyFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfirmationsContract\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelay\",\"inputs\":[{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slash\",\"inputs\":[{\"name\":\"amt\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"residualBidPercentAfterDecay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unstake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawalDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalRequests\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"FeePayoutPeriodBlocksUpdated\",\"inputs\":[{\"name\":\"newFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeeTransfer\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsDeposited\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsSlashed\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PenaltyFeeRecipientUpdated\",\"inputs\":[{\"name\":\"newPenaltyFeeRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProviderRegistered\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"stakedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unstake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdraw\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayUpdated\",\"inputs\":[{\"name\":\"newWithdrawalDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"receive\",\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"PERCENT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PRECISION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"acceptOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"delegateRegisterAndStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"delegateStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"eoaToBlsPubkey\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"feePercent\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getAccumulatedPenaltyFee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getBLSKey\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getProviderStake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_minStake\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_feePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_penaltyFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"isProviderValid\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"manuallyWithdrawPenaltyFee\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"minStake\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"paused\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"penaltyFeeTracker\",\"inputs\":[],\"outputs\":[{\"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\":\"pendingOwner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preConfirmationsContract\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerRegistered\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"providerStakes\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proxiableUUID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerAndStake\",\"inputs\":[{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setFeePayoutPeriodBlocks\",\"inputs\":[{\"name\":\"_feePayoutPeriodBlocks\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewFeePercent\",\"inputs\":[{\"name\":\"newFeePercent\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNewPenaltyFeeRecipient\",\"inputs\":[{\"name\":\"newFeeRecipient\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setPreconfirmationsContract\",\"inputs\":[{\"name\":\"contractAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setWithdrawalDelay\",\"inputs\":[{\"name\":\"_withdrawalDelay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"slash\",\"inputs\":[{\"name\":\"amt\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"provider\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"bidder\",\"type\":\"address\",\"internalType\":\"addresspayable\"},{\"name\":\"residualBidPercentAfterDecay\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"stake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpause\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unstake\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeToAndCall\",\"inputs\":[{\"name\":\"newImplementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"withdraw\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"withdrawalDelay\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"withdrawalRequests\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"FeePayoutPeriodBlocksUpdated\",\"inputs\":[{\"name\":\"newFeePayoutPeriodBlocks\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FeeTransfer\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsDeposited\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"FundsSlashed\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InsufficientFundsToSlash\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"providerStake\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"residualAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"penaltyFee\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferStarted\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Paused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"PenaltyFeeRecipientUpdated\",\"inputs\":[{\"name\":\"newPenaltyFeeRecipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProviderRegistered\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"stakedAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"indexed\":false,\"internalType\":\"bytes\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unpaused\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Unstake\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Withdraw\",\"inputs\":[{\"name\":\"provider\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"WithdrawalDelayUpdated\",\"inputs\":[{\"name\":\"newWithdrawalDelay\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"EnforcedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ExpectedPause\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnauthorizedCallContext\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UUPSUnsupportedProxiableUUID\",\"inputs\":[{\"name\":\"slot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}]", } // ProviderregistryABI is the input ABI used to generate the binding from. @@ -1997,6 +1997,153 @@ func (_Providerregistry *ProviderregistryFilterer) ParseInitialized(log types.Lo return event, nil } +// ProviderregistryInsufficientFundsToSlashIterator is returned from FilterInsufficientFundsToSlash and is used to iterate over the raw logs and unpacked data for InsufficientFundsToSlash events raised by the Providerregistry contract. +type ProviderregistryInsufficientFundsToSlashIterator struct { + Event *ProviderregistryInsufficientFundsToSlash // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ProviderregistryInsufficientFundsToSlashIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ProviderregistryInsufficientFundsToSlash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ProviderregistryInsufficientFundsToSlash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ProviderregistryInsufficientFundsToSlashIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProviderregistryInsufficientFundsToSlashIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProviderregistryInsufficientFundsToSlash represents a InsufficientFundsToSlash event raised by the Providerregistry contract. +type ProviderregistryInsufficientFundsToSlash struct { + Provider common.Address + ProviderStake *big.Int + ResidualAmount *big.Int + PenaltyFee *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInsufficientFundsToSlash is a free log retrieval operation binding the contract event 0x8500678d5b1219298eaa4a4ad091fef08399d1c6001b3eae10514f876c29dab4. +// +// Solidity: event InsufficientFundsToSlash(address indexed provider, uint256 providerStake, uint256 residualAmount, uint256 penaltyFee) +func (_Providerregistry *ProviderregistryFilterer) FilterInsufficientFundsToSlash(opts *bind.FilterOpts, provider []common.Address) (*ProviderregistryInsufficientFundsToSlashIterator, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + + logs, sub, err := _Providerregistry.contract.FilterLogs(opts, "InsufficientFundsToSlash", providerRule) + if err != nil { + return nil, err + } + return &ProviderregistryInsufficientFundsToSlashIterator{contract: _Providerregistry.contract, event: "InsufficientFundsToSlash", logs: logs, sub: sub}, nil +} + +// WatchInsufficientFundsToSlash is a free log subscription operation binding the contract event 0x8500678d5b1219298eaa4a4ad091fef08399d1c6001b3eae10514f876c29dab4. +// +// Solidity: event InsufficientFundsToSlash(address indexed provider, uint256 providerStake, uint256 residualAmount, uint256 penaltyFee) +func (_Providerregistry *ProviderregistryFilterer) WatchInsufficientFundsToSlash(opts *bind.WatchOpts, sink chan<- *ProviderregistryInsufficientFundsToSlash, provider []common.Address) (event.Subscription, error) { + + var providerRule []interface{} + for _, providerItem := range provider { + providerRule = append(providerRule, providerItem) + } + + logs, sub, err := _Providerregistry.contract.WatchLogs(opts, "InsufficientFundsToSlash", providerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ProviderregistryInsufficientFundsToSlash) + if err := _Providerregistry.contract.UnpackLog(event, "InsufficientFundsToSlash", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInsufficientFundsToSlash is a log parse operation binding the contract event 0x8500678d5b1219298eaa4a4ad091fef08399d1c6001b3eae10514f876c29dab4. +// +// Solidity: event InsufficientFundsToSlash(address indexed provider, uint256 providerStake, uint256 residualAmount, uint256 penaltyFee) +func (_Providerregistry *ProviderregistryFilterer) ParseInsufficientFundsToSlash(log types.Log) (*ProviderregistryInsufficientFundsToSlash, error) { + event := new(ProviderregistryInsufficientFundsToSlash) + if err := _Providerregistry.contract.UnpackLog(event, "InsufficientFundsToSlash", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // ProviderregistryOwnershipTransferStartedIterator is returned from FilterOwnershipTransferStarted and is used to iterate over the raw logs and unpacked data for OwnershipTransferStarted events raised by the Providerregistry contract. type ProviderregistryOwnershipTransferStartedIterator struct { Event *ProviderregistryOwnershipTransferStarted // Event containing the contract specifics and raw log From a998e0b175d8f6fa393b282ab7fb3aa3e7fb9961 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 16 Sep 2024 11:29:26 -0400 Subject: [PATCH 6/9] feat: start reducing storage reads Co-authored-by: Mikhail Wall --- contracts/contracts/core/ProviderRegistry.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 796530ece..ec692210b 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -124,6 +124,7 @@ contract ProviderRegistry is // if the provider's stake is less than the residual amount + penalty fee, we need to adjust the residual amount and penalty fee // this is to prevent underflow and ensure the contract doesn't revert // We also emit + uint256 providerStake = providerStakes[provider]; if (providerStakes[provider] < residualAmt + penaltyFee) { emit InsufficientFundsToSlash(provider, providerStakes[provider], residualAmt, penaltyFee); if (providerStakes[provider] < residualAmt) { From 3e975024bc12105e54f4bc37ba5a8d25fcb0180e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 16 Sep 2024 11:30:41 -0400 Subject: [PATCH 7/9] feat: reduce storage reads --- contracts/contracts/core/ProviderRegistry.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index ec692210b..23afb4038 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -125,16 +125,16 @@ contract ProviderRegistry is // this is to prevent underflow and ensure the contract doesn't revert // We also emit uint256 providerStake = providerStakes[provider]; - if (providerStakes[provider] < residualAmt + penaltyFee) { - emit InsufficientFundsToSlash(provider, providerStakes[provider], residualAmt, penaltyFee); - if (providerStakes[provider] < residualAmt) { + if (providerStake < residualAmt + penaltyFee) { + emit InsufficientFundsToSlash(provider, providerStake, residualAmt, penaltyFee); + if (providerStake < residualAmt) { penaltyFee = 0; - residualAmt = providerStakes[provider]; + residualAmt = providerStake; } else { - penaltyFee = providerStakes[provider] - residualAmt; + penaltyFee = providerStake - residualAmt; } } - providerStakes[provider] -= residualAmt + penaltyFee; + providerStake -= residualAmt + penaltyFee; penaltyFeeTracker.accumulatedAmount += penaltyFee; if (FeePayout.isPayoutDue(penaltyFeeTracker)) { From 840d446acecfc9f096d43ed697a7b7b16d3c9fd0 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 17 Sep 2024 10:44:40 -0400 Subject: [PATCH 8/9] feat: fixes bug around not slashing the provider balance. --- contracts/contracts/core/ProviderRegistry.sol | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index 23afb4038..ae1c50ffc 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -121,20 +121,18 @@ contract ProviderRegistry is ) external nonReentrant onlyPreConfirmationEngine whenNotPaused { uint256 residualAmt = (amt * residualBidPercentAfterDecay * PRECISION) / PERCENT; uint256 penaltyFee = (residualAmt * uint256(feePercent) * PRECISION) / PERCENT; - // if the provider's stake is less than the residual amount + penalty fee, we need to adjust the residual amount and penalty fee - // this is to prevent underflow and ensure the contract doesn't revert - // We also emit + uint256 providerStake = providerStakes[provider]; + + if (providerStake < residualAmt + penaltyFee) { emit InsufficientFundsToSlash(provider, providerStake, residualAmt, penaltyFee); if (providerStake < residualAmt) { - penaltyFee = 0; residualAmt = providerStake; - } else { - penaltyFee = providerStake - residualAmt; } + penaltyFee = providerStake - residualAmt; } - providerStake -= residualAmt + penaltyFee; + providerStakes[provider] -= residualAmt + penaltyFee; penaltyFeeTracker.accumulatedAmount += penaltyFee; if (FeePayout.isPayoutDue(penaltyFeeTracker)) { From e8b529dedbc228cd98874abd73740d96726a69a2 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 17 Sep 2024 11:13:20 -0400 Subject: [PATCH 9/9] chore: remove empty line --- contracts/contracts/core/ProviderRegistry.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/contracts/core/ProviderRegistry.sol b/contracts/contracts/core/ProviderRegistry.sol index ae1c50ffc..8fdaad798 100644 --- a/contracts/contracts/core/ProviderRegistry.sol +++ b/contracts/contracts/core/ProviderRegistry.sol @@ -121,10 +121,8 @@ contract ProviderRegistry is ) external nonReentrant onlyPreConfirmationEngine whenNotPaused { uint256 residualAmt = (amt * residualBidPercentAfterDecay * PRECISION) / PERCENT; uint256 penaltyFee = (residualAmt * uint256(feePercent) * PRECISION) / PERCENT; - uint256 providerStake = providerStakes[provider]; - if (providerStake < residualAmt + penaltyFee) { emit InsufficientFundsToSlash(provider, providerStake, residualAmt, penaltyFee); if (providerStake < residualAmt) {