feat(b20): add preauthorized spender allowances - #223
Conversation
Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
Interface Coverage✅ All interface functions have test coverage. |
📊 Forge Coverage (
|
| File | Lines | Stmts | Branches | Funcs |
|---|---|---|---|---|
| 🟡 B20FactoryLib.sol | 97.70% | 98.00% | 100.00% | 95.00% |
| 🔴 test/lib/ForceFeeder.sol | 0.00% | 0.00% | 100.00% | 0.00% |
| 🔴 test/lib/PrecompileProbe.sol | 0.00% | 0.00% | 0.00% | 0.00% |
| 🟢 MockActivationRegistry.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockActivationRegistryStorage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20Asset.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟡 MockB20Factory.sol | 98.96% | 99.10% | 100.00% | 100.00% |
| 🟢 MockB20Stablecoin.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20Storage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟡 MockPolicyRegistry.sol | 100.00% | 99.54% | 97.67% | 100.00% |
| 🟢 MockPolicyRegistryStorage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| Total | 97.08% | 97.53% | 98.18% | 97.00% |
Full report: download artifact. To browse locally: make coverage (runs forge coverage + genhtml + opens the HTML report).
|
Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
|
|
||
| ## Summary | ||
|
|
||
| Denim lets a B20 issuer grant an account permission to spend from every holder without holder approvals. The dedicated `AUTHORIZED_SPENDER_ROLE` keeps this authority separate from the Asset-only `OPERATOR_ROLE`. |
There was a problem hiding this comment.
no need to mention OPERATOR_ROLE
|
|
||
| ## Motivation | ||
|
|
||
| Some token integrations need one contract, such as a router or settlement system, to spend from every holder. Requiring each holder to call `approve` adds a transaction and prevents the integration from working for holders that cannot make an approval call. |
There was a problem hiding this comment.
Example: auto approve Permit2 to unlock signature-based transfers. This provides a workaround for lack of permit functionality for smart contract accounts
Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
|
|
||
| ## Motivation | ||
|
|
||
| Some token integrations need one contract, such as a router or settlement system, to spend from every holder. For example, an issuer can authorize Permit2 to unlock signature-based transfers. This provides a workaround when a smart contract account cannot use token-native permit functionality. Requiring each holder to call `approve` adds a transaction and prevents these integrations from working for holders that cannot make an approval call. |
There was a problem hiding this comment.
Remove part about not being able to make an approval call
|
|
||
| For any other caller, allowance behavior remains unchanged. A finite allowance decrements by the transferred amount, and `type(uint256).max` remains the non-decrementing ERC-20 sentinel. | ||
|
|
||
| ### Storage layout |
There was a problem hiding this comment.
Add gas section
| /// `address(0)` fields are skipped at bootstrap. | ||
| /// | ||
| /// @dev `DEFAULT_ADMIN_ROLE` is assigned via `B20StablecoinCreateParams.initialAdmin`, not this struct. | ||
| /// @dev Append `encodeGrantRole(B20Constants.AUTHORIZED_SPENDER_ROLE, spender)` when needed. |
| /// with an `OPERATOR_ROLE` slot. | ||
| /// | ||
| /// @dev `DEFAULT_ADMIN_ROLE` is assigned via `B20AssetCreateParams.initialAdmin`, not this struct. | ||
| /// @dev Append `encodeGrantRole(B20Constants.AUTHORIZED_SPENDER_ROLE, spender)` when needed. |
|
|
||
| ### Interface changes | ||
|
|
||
| `AUTHORIZED_SPENDER_ROLE()` is added to the shared [`IB20`](../src/interfaces/IB20.sol) interface. |
There was a problem hiding this comment.
let's go with PREAUTHORIZED_SPENDER_ROLE instead
Co-authored-by: OpenCode <opencode-noreply@coinbase.com>
Token issuers need to preauthorize trusted integrations to spend from every holder without per-holder approvals while keeping that authority separate from Asset operations. This adds a dedicated preauthorized spender role while preserving existing controls.
PREAUTHORIZED_SPENDER_ROLEsupport to Asset and Stablecoin.OPERATOR_ROLEAsset-only for announcements and multiplier administration.type=nonroutine
risk=medium
impact=sev4
backwards_compatible=false
automerge=false