Skip to content

Commit 36c7e27

Browse files
authored
feat: whitelist for vanilla staking (#698)
1 parent 613216d commit 36c7e27

7 files changed

Lines changed: 638 additions & 5 deletions

File tree

contracts-abi/abi/VanillaRegistry.abi

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,19 @@
379379
],
380380
"stateMutability": "view"
381381
},
382+
{
383+
"type": "function",
384+
"name": "removeWhitelistedStakers",
385+
"inputs": [
386+
{
387+
"name": "stakers",
388+
"type": "address[]",
389+
"internalType": "address[]"
390+
}
391+
],
392+
"outputs": [],
393+
"stateMutability": "nonpayable"
394+
},
382395
{
383396
"type": "function",
384397
"name": "renounceOwnership",
@@ -633,6 +646,38 @@
633646
"outputs": [],
634647
"stateMutability": "payable"
635648
},
649+
{
650+
"type": "function",
651+
"name": "whitelistStakers",
652+
"inputs": [
653+
{
654+
"name": "stakers",
655+
"type": "address[]",
656+
"internalType": "address[]"
657+
}
658+
],
659+
"outputs": [],
660+
"stateMutability": "nonpayable"
661+
},
662+
{
663+
"type": "function",
664+
"name": "whitelistedStakers",
665+
"inputs": [
666+
{
667+
"name": "staker",
668+
"type": "address",
669+
"internalType": "address"
670+
}
671+
],
672+
"outputs": [
673+
{
674+
"name": "whitelisted",
675+
"type": "bool",
676+
"internalType": "bool"
677+
}
678+
],
679+
"stateMutability": "view"
680+
},
636681
{
637682
"type": "function",
638683
"name": "withdraw",
@@ -941,6 +986,44 @@
941986
],
942987
"anonymous": false
943988
},
989+
{
990+
"type": "event",
991+
"name": "StakerRemovedFromWhitelist",
992+
"inputs": [
993+
{
994+
"name": "msgSender",
995+
"type": "address",
996+
"indexed": true,
997+
"internalType": "address"
998+
},
999+
{
1000+
"name": "staker",
1001+
"type": "address",
1002+
"indexed": false,
1003+
"internalType": "address"
1004+
}
1005+
],
1006+
"anonymous": false
1007+
},
1008+
{
1009+
"type": "event",
1010+
"name": "StakerWhitelisted",
1011+
"inputs": [
1012+
{
1013+
"name": "msgSender",
1014+
"type": "address",
1015+
"indexed": true,
1016+
"internalType": "address"
1017+
},
1018+
{
1019+
"name": "staker",
1020+
"type": "address",
1021+
"indexed": false,
1022+
"internalType": "address"
1023+
}
1024+
],
1025+
"anonymous": false
1026+
},
9441027
{
9451028
"type": "event",
9461029
"name": "TotalStakeWithdrawn",
@@ -1188,6 +1271,17 @@
11881271
}
11891272
]
11901273
},
1274+
{
1275+
"type": "error",
1276+
"name": "SenderIsNotWhitelistedStaker",
1277+
"inputs": [
1278+
{
1279+
"name": "sender",
1280+
"type": "address",
1281+
"internalType": "address"
1282+
}
1283+
]
1284+
},
11911285
{
11921286
"type": "error",
11931287
"name": "SenderIsNotWithdrawalAddress",
@@ -1250,6 +1344,28 @@
12501344
}
12511345
]
12521346
},
1347+
{
1348+
"type": "error",
1349+
"name": "StakerAlreadyWhitelisted",
1350+
"inputs": [
1351+
{
1352+
"name": "staker",
1353+
"type": "address",
1354+
"internalType": "address"
1355+
}
1356+
]
1357+
},
1358+
{
1359+
"type": "error",
1360+
"name": "StakerNotWhitelisted",
1361+
"inputs": [
1362+
{
1363+
"name": "staker",
1364+
"type": "address",
1365+
"internalType": "address"
1366+
}
1367+
]
1368+
},
12531369
{
12541370
"type": "error",
12551371
"name": "TransferToRecipientFailed",

contracts-abi/clients/VanillaRegistry/VanillaRegistry.go

Lines changed: 364 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/contracts/interfaces/IVanillaRegistry.sol

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ interface IVanillaRegistry {
4848
/// @dev Event emitted when the slashing payout period blocks parameter is set.
4949
event SlashingPayoutPeriodBlocksSet(address indexed msgSender, uint256 newSlashingPayoutPeriodBlocks);
5050

51+
/// @dev Event emitted when a staker is whitelisted.
52+
event StakerWhitelisted(address indexed msgSender, address staker);
53+
54+
/// @dev Event emitted when a staker is removed from the whitelist.
55+
event StakerRemovedFromWhitelist(address indexed msgSender, address staker);
56+
5157
error ValidatorRecordMustExist(bytes valBLSPubKey);
5258
error ValidatorRecordMustNotExist(bytes valBLSPubKey);
5359
error ValidatorCannotBeUnstaking(bytes valBLSPubKey);
@@ -70,6 +76,9 @@ interface IVanillaRegistry {
7076
error SlashReceiverMustBeSet();
7177
error UnstakePeriodMustBePositive();
7278
error SlashingPayoutPeriodMustBePositive();
79+
error SenderIsNotWhitelistedStaker(address sender);
80+
error StakerAlreadyWhitelisted(address staker);
81+
error StakerNotWhitelisted(address staker);
7382

7483
/// @dev Initializes the contract with the provided parameters.
7584
function initialize(

contracts/contracts/validator-registry/VanillaRegistry.sol

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ contract VanillaRegistry is IVanillaRegistry, VanillaRegistryStorage,
3131
_;
3232
}
3333

34+
/// @dev Modifier to confirm the sender is whitelisted.
35+
modifier onlyWhitelistedStaker() {
36+
require(whitelistedStakers[msg.sender], IVanillaRegistry.SenderIsNotWhitelistedStaker(msg.sender));
37+
_;
38+
}
39+
3440
/// @dev See https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializing_the_implementation_contract
3541
/// @custom:oz-upgrades-unsafe-allow constructor
3642
constructor() {
@@ -69,7 +75,7 @@ contract VanillaRegistry is IVanillaRegistry, VanillaRegistryStorage,
6975
* @param blsPubKeys The validator BLS public keys to stake.
7076
*/
7177
function stake(bytes[] calldata blsPubKeys) external payable
72-
onlyValidBLSPubKeys(blsPubKeys) whenNotPaused() {
78+
onlyValidBLSPubKeys(blsPubKeys) onlyWhitelistedStaker() whenNotPaused() {
7379
_stake(blsPubKeys, msg.sender);
7480
}
7581

@@ -90,7 +96,7 @@ contract VanillaRegistry is IVanillaRegistry, VanillaRegistryStorage,
9096
* @dev A staking entry must already exist for each provided BLS pubkey.
9197
* @param blsPubKeys The BLS public keys to add stake to.
9298
*/
93-
function addStake(bytes[] calldata blsPubKeys) external payable whenNotPaused() {
99+
function addStake(bytes[] calldata blsPubKeys) external payable onlyWhitelistedStaker() whenNotPaused() {
94100
_addStake(blsPubKeys);
95101
}
96102

@@ -180,6 +186,26 @@ contract VanillaRegistry is IVanillaRegistry, VanillaRegistryStorage,
180186
FeePayout.transferToRecipient(slashingFundsTracker);
181187
}
182188

189+
/// @dev Enables the owner to whitelist stakers.
190+
function whitelistStakers(address[] calldata stakers) external onlyOwner {
191+
uint256 len = stakers.length;
192+
for (uint256 i = 0; i < len; ++i) {
193+
require(!whitelistedStakers[stakers[i]], IVanillaRegistry.StakerAlreadyWhitelisted(stakers[i]));
194+
whitelistedStakers[stakers[i]] = true;
195+
emit StakerWhitelisted(msg.sender, stakers[i]);
196+
}
197+
}
198+
199+
/// @dev Enables the owner to remove stakers from the whitelist.
200+
function removeWhitelistedStakers(address[] calldata stakers) external onlyOwner {
201+
uint256 len = stakers.length;
202+
for (uint256 i = 0; i < len; ++i) {
203+
require(whitelistedStakers[stakers[i]], IVanillaRegistry.StakerNotWhitelisted(stakers[i]));
204+
whitelistedStakers[stakers[i]] = false;
205+
emit StakerRemovedFromWhitelist(msg.sender, stakers[i]);
206+
}
207+
}
208+
183209
/// @dev Returns true if a validator is considered "opted-in" to mev-commit via this registry.
184210
function isValidatorOptedIn(bytes calldata valBLSPubKey) external view returns (bool) {
185211
return _isValidatorOptedIn(valBLSPubKey);

contracts/contracts/validator-registry/VanillaRegistryStorage.sol

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ contract VanillaRegistryStorage {
2626
/// @dev Mapping of withdrawal addresses to claimable ETH that was force withdrawn by the owner.
2727
mapping(address withdrawalAddress => uint256 amountToClaim) public forceWithdrawnFunds;
2828

29+
/// @dev Mapping of staker addresses to whether they are whitelisted.
30+
mapping(address staker => bool whitelisted) public whitelistedStakers;
31+
2932
/// @dev See https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#storage-gaps
3033
uint256[48] private __gap;
3134
}

0 commit comments

Comments
 (0)