Add ContractSignerAllowlist module to allow ERC1271 signatures for contracts in the allowlist#8
Merged
ksmith-circle merged 35 commits intocirclefin:masterfrom Nov 12, 2025
Conversation
This reverts commit 7574d11.
## Summary Implement 1271 contract signers functionality for Circle Unified Bridge (CUB) support. ## Detail 1. Introduce a new module `ContractSignersWhitelist`, that keeps track of whitelisted contract that can use 1271 signing 2. Update burn signature checking logic to support these 1271 whitelisted contract signers ### Checklist - [x] Did you add new tests and confirm all tests pass? (`forge test`) - [x] Did you update relevant docs? - [x] Did you run lint (`yarn lint`) and fix any issues? - [x] Did you run formatter (`forge fmt --check`) and fix any issues (`forge fmt`)? ## Testing Added unit and integration tests. Verified all source code tests pass after running `yarn test`. Verified contract sizes are within EIP-170 limits ``` \e[32m✅ GatewayWallet (deployed bytecode size: 22789) is within the EIP-170 size limit (24576)\e[0m \e[32m✅ GatewayMinter (deployed bytecode size: 12101) is within the EIP-170 size limit (24576)\e[0m \e[32m✅ UpgradeablePlaceholder (deployed bytecode size: 2799) is within the EIP-170 size limit (24576)\e[0m ``` ## Documentation - [CUB / Gateway Support ERC-1271 Spike](https://docs.google.com/document/d/1KwjpqWWIipbPRgpwY1SiHrGT4Vnyaa_SA7DIfA9ZYlQ/edit?usp=sharing)
… (#117) ## Summary In #116 we introduced an allowlist for contract signers that use ERC-1271 type signatures, with the assumption that signatures produced by these signers would never go stale. One gap in the "time delay" logic for these signatures is that, if we were to "disallowlist" a contract signer after they've been allowlisted, previous signatures produced by them will fail validation, causing burns to revert. This is unlikely since Circle controls the allowlist, but it'd be good to have contract-level guarantees that a "revoked" signer's signature still can be used for burns. This PR introduces enum `ContractSignerAllowlistStatus`, similar to delegates' `AuthorizationStatus`, and permit signatures from any contract signers that have once been allowlisted. Procedure for disallowing a contract signer is 1. Circle submits `disallow` function call to remove an allowed contract signer 2. RL observes the event, and rejects any future burn intents with disallowed signer 3. Existing burn signatures signed by previously allowed contract signers can still go through successfully. ### Checklist - [x] Did you add new tests and confirm all tests pass? (`forge test`) - [x] Did you update relevant docs? - [x] Did you run lint (`yarn lint`) and fix any issues? - [x] Did you run formatter (`forge fmt --check`) and fix any issues (`forge fmt`)?
…dContractSigner (#119) ## Summary - Removed a special case check in _wasEverAllowlistedContractSigner() that automatically returned true for address(0). It does not make sense to specialcase for address(0) here as zero address can never be on the allowlist. Removed this check for now, or alternatively can consider directly returning false for zero address. ### Checklist - [x] Did you add new tests and confirm all tests pass? (`forge test`) - [x] Did you update relevant docs? - [x] Did you run lint (`yarn lint`) and fix any issues? - [x] Did you run formatter (`forge fmt --check`) and fix any issues (`forge fmt`)? ## Testing - Added additional tests for changed behavior - Needed to modify artifacts and ensure bytecode match test still pass
## Summary
Adds “contract-signer allowlist” support (EIP-1271) to Gateway
Wallet/Burn flow
and wires it into deployment, upgrade, CI and docs.
## Detail
### Changeset
- Core
- `ContractSignersAllowlist` module (+storage, events, errors,
upgrade-safe
implementation).
- `GatewayWallet` now inherits the new module; `initialize` signature
extended
with `contractSignersAllowlister_` and protected by `reinitializer(2)`.
- `Burns` logic:
- Detects if `sourceSigner` is/was allow-listed contract.
- Validates signatures via `SignatureChecker` (EIP-1271) else falls back
to
ECDSA.
- New `InvalidSignature` error.
- `BurnIntentLib`
- Cursor helpers (`current`, `_getSourceSignerFromCursor`) to support
the
new signer flow.
- Deployment / upgrade
- `.env.example` – new
`GATEWAYWALLET_CONTRACT_SIGNERS_ALLOWLISTER_ADDRESS`.
- `001_DeployGatewayWallet.sol` encodes the extra param.
- `004_UpgradeGatewayWallet.sol` script to deploy new impl and upgrade
existing proxy.
- README: added upgrade instructions & reminder to compile artifacts.
- Tests
- Extensive unit tests for allowlist module & EIP-1271 burn paths
(`BurnsEIP1271.t.sol`).
- Storage slot magic-value test.
- Updated helpers & existing tests to pass new param.
- Misc
- Updated compiled artifacts, example addresses, CI to build
`cub-support`
branch, test script verbosity tweaks.
## Summary Removing cub-supported from protected branches now that the changes have been merged to master.
## Summary Verify contracts on etherscan and sourcify for the new mainnet contracts ## Detail Note: Sourcify does not support unichain verification at the time of this PR. Unichain only verified on etherscan. ### Changeset Added new rpc urls to `foundry.toml` Added new chains to verification script ### Checklist - [ ] Did you add new tests and confirm all tests pass? (`forge test`) - [ ] Did you update relevant docs? - [ ] Did you run lint (`yarn lint`) and fix any issues? - [ ] Did you run formatter (`forge fmt --check`) and fix any issues (`forge fmt`)? ## Testing ## Documentation
Reading AA-2596 ## Summary Introduces a project-level CHANGELOG to comply with open-source standards and give users a clear, versioned history of Gateway contract changes. ## Detail ### Changeset * Added `CHANGELOG.md` in Keep-a-Changelog style. * v1.0.0 (2025-07): initial public release with core Gateway contracts and security modules. * v1.1.0 (2025-11): planned upgrade adding contract allow-listing and ERC-1271 burn intents. * Purely documentation—no code, ABI, or deployment scripts modified. ### Why it matters * Transparency: external integrators and auditors can track what changed and when. * Release discipline: establishes a single source of truth for upcoming open-source publication and future versioning. ### Review focus / potential risks * Verify feature bullets accurately match the private repo history (no omissions or NDA material). * Confirm dates and semantic versioning align with published tags. * Ensure formatting meets OSS docs guidelines (Markdown rendering, section order). ### Checklist - [ ] Did you add new tests and confirm all tests pass? (`forge test`) - [ ] Did you update relevant docs? - [ ] Did you run lint (`yarn lint`) and fix any issues? - [ ] Did you run formatter (`forge fmt --check`) and fix any issues (`forge fmt`)? ## Testing N/A – documentation-only change. ## Documentation This file *is* new documentation; no additional updates required.
ksmith-circle
approved these changes
Nov 12, 2025
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
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.
Summary
Adds first-class support for ERC-1271 contract signatures by introducing a ContractSignerAllowlist module and wiring it into
GatewayWalletburn flows.Contracts that are explicitly allowlisted can now submit burn intents signed by an on-chain contract key instead of an EOA.
Detail
Changeset
src/modules/wallet/ContractSignersAllowlist.solcontractSignersAllowlister; statuses:Unallowlisted | Allowlisted | Revoked.GatewayWallet,Burnsinitialize(...).sourceSignerwas ever allow-listed →SignatureChecker.isValidERC1271SignatureNow.InvalidSignature.BurnIntentLibcurrent,_getSourceSignerFromCursor) to avoid extra copies..env.example– newGATEWAYWALLET_CONTRACT_SIGNERS_ALLOWLISTER_ADDRESS.script/001_DeployGatewayWallet.sol– passes allowlister during init.script/004_UpgradeGatewayWallet.sol– one-shot upgrade script.foundry.toml, scripts and verify-helpers extended with new chains.Checklist
forge test)yarn lint) and fix any issues?forge fmt --check) and fix any issues (forge fmt)?