-
Notifications
You must be signed in to change notification settings - Fork 81
Allowlist for Wallet Registry #3826
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
pdyraga
wants to merge
6
commits into
main
Choose a base branch
from
allowlist
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The current project configuration supports at most node 18.x so setting lts/hydrogen as the version to be used.
The project is on OpenZeppelin 4 and the latest version currently available is 4.9.6. This change will also allow us to use Ownable2StepUpgradeable that was not available in OpenZeppelin 4.6. The upgrade required increasing the version of @openzeppelin/hardhat-upgrades plugin given the bug in the previously used 1.20.0 version not resolving the correct version of dependencies used (OZ contracts vs contracts-upgradeable) and in our case complaining about the delegatecall used in the OZ's AddressUpgradeable code. The bug was fixed in 1.20.4 version of the plugin. This also required updates in the deployment tests as some functions are no longer available in the upgraded version. https://forum.openzeppelin.com/t/interacting-with-uups-upgradeable-contracts-in-test-throwing-contract-is-not-upgrade-safe-use-of-delegatecall-is-not-allowed/32743/5
The allowlist contract replaces the Threshold `TokenStaking` contract and is as an outcome of TIP-092 and TIP-100 governance decisions. Staking tokens is no longer required to operate nodes. Beta stakers are selected by the DAO and operate the network based on the allowlist maintained by the DAO. The contract will be integrated with the `WalletRegistry` and replace calls to `TokenStaking`. I have been experimenting with various approaches, and the most extreme one was to remove most of the `EcdsaAuthorization` logic as well as all `TokenStaking.seize` calls. This would have cascading effects on tBTC Bridge contracts as they rely on `WalletRegistry.seize`. That would also require implementing weight decrease delays in the `Allowlist,` so essentially doing work that is already done in `WalletRegistry`. Considering the pros and cons, I decided on the least invasive option. The `WalletRegistry` still thinks in terms of stake authorization, but everything is based on the staking provider's weight as set in the `Allowlist`, and weight decrease delays are enforced by the existing mechanism in `EcdsaAuthorization`. The `seize` function does nothing except of emitting an event about detecting beta staker misbehavior. This code is still a draft. Has to be integrated and covered with proper tests!
piotr-roslaniec
added a commit
that referenced
this pull request
Aug 4, 2025
Fixes PR #3826 by implementing missing components for Allowlist contract: - Add comprehensive test suite (432 lines, full coverage) - Create deployment script with upgradeable proxy pattern - Add migration script to initialize existing beta staker weights - Complete documentation with deployment and consolidation guides - Add one-click consolidation script based on authoritative research - Consolidates 18 operators → 3 operators (83% reduction) - Keeps 1 operator per entity (Boar, P2P, Staked) - Natural fund drainage through weight management (no forced migrations) - DAO-controlled operator management without token staking - Gradual, reversible consolidation process - Complete audit trails and safety checks - Production-ready deployment infrastructure This enables the transition from TokenStaking to Allowlist as specified in TIP-092 and TIP-100, with a direct path to beta staker consolidation.
- Add Allowlist contract to replace TokenStaking per TIP-092/TIP-100 - Implement weight-based operator management without token staking - Add deployment and initialization scripts - Include consolidation script for operator reduction (20→4 operators) - Includes NUCO operators (1 kept, 1 consolidated) - Add comprehensive test coverage - Maintain compatibility with existing WalletRegistry interface
- Add two-step process enforcement for weight decrease (Issue #1) - Introduce decreasePending flag to track valid decrease requests - Prevent bypassing the intended authorization flow - Add zero address validation (Issue #3) - Validate walletRegistry in initialize() - Validate stakingProvider in addStakingProvider() - Add zero weight validation (Issue #5) - Prevent adding staking providers with zero weight - Avoid potential duplicate additions - Add comprehensive test coverage for all security fixes Note: Issue #8 (seize function access) intentionally not restricted as public reporting of malicious behavior is desired functionality
lrsaturnino
approved these changes
Oct 9, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The allowlist contract replaces the Threshold
TokenStakingcontract and is as an outcome of TIP-092 and TIP-100 governance decisions. Staking tokens is no longer required to operate nodes. Beta stakers are selected by the DAO and operate the network based on the allowlist maintained by the DAO. The contract will be integrated with theWalletRegistryand replace calls toTokenStaking.I have been experimenting with various approaches, and the most extreme one was to remove most of the
EcdsaAuthorizationlogic as well as allTokenStaking.seizecalls. This would have cascading effects on tBTC Bridge contracts as they rely onWalletRegistry.seize. That would also require implementing weight decrease delays in theAllowlist,so essentially doing work that is already done inWalletRegistry. Considering the pros and cons, I decided on the least invasive option. TheWalletRegistrystill thinks in terms of stake authorization, but everything is based on the staking provider's weight as set in theAllowlist, and weight decrease delays are enforced by the existing mechanism inEcdsaAuthorization. Theseizefunction does nothing except of emitting an event about detecting beta staker misbehavior.To be done
Deployment script
We need to capture all existing beta stakers along with their current authorizations and initialize the
Allowlistcontract. We can do it by either replicating the existing weights or giving them all the same weight.Integrate with
WalletRegistryand testsThere are two approaches to achieve it. The first one is to get rid of all references to
TokenStakingfrom tests and update them to work withAllowlist. Another approach is to let them work withTokenStakingbut introduce another integration test for those two contracts. In this option, we could use inWalletRegistrysomething like:Note that the
WalletRegistryis close to the maximum allowed contract size and - surprise! - adding the logic above makes it exceed the allowed size. This could potentially be alleviated by removing some of the functionality. For example, in thechallengeDkgResultfunction we have a try catch as well as a call todkg.requireChallengeExtraGas(). This could potentially be eliminated as a no-opseizeinAllowlistis guaranteed to always succeed. Also, post EIP-7702, therequire(msg.sender == tx.origin, "Not EOA")check is no longer guaranteed to work as expected.