Docs/b20 reference - #1775
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
🟡 Heimdall Review Status
|
c095dfd to
5bf2799
Compare
There was a problem hiding this comment.
The following mirror comments left on #1766.
- Systematic selector/topic bug: enum params are hashed by type name instead of
uint8, so every enum-bearing selector/topic is wrong. SEIZE_RECEIVER_POLICYmissing: the standard has 6 policy scopes; the reference shows 5, which also makesseizeWithMemowrong (it gates the recipient).- Plus
seizeWithMemoreturn type,finalizeUpdateAdminaccess-control,ChildPoliciesOutsideOfRangesignature, theburnBlocked"no longer part of this interface" claim, and missingMIN/MAX_COMPOSITE_CHILD_POLICIES+UIMultiplierUpdated.
|
|
||
| | Field | Value | | ||
| |---|---| | ||
| | Selector | `0xb263cb84` | |
There was a problem hiding this comment.
I believe the selector is incorrect. The enum type name was hashed instead of uint8. ABI selectors normalize enums to uint8, so this should be createB20(uint8,bytes32,bytes,bytes[]) → 0x62975e6a (verified with cast). This is systematic across every enum-bearing signature; also wrong: getB20Address → 0x8c30260f, and the createPolicy* functions. The Canonical signature fields should show uint8 too.
|
|
||
| | Event | Topic0 | Summary | | ||
| |---|---|---| | ||
| | `B20Created` | `0x86ee7a93da43b07286ea4c925a31ba17c41eb00c5ea396883bf32abfe5e73cfc` | Emitted once per `createB20` invocation, after the token's identity is sealed | |
There was a problem hiding this comment.
Both enum-derived values in these tables are wrong (same root cause: enum name instead of uint8):
B20Createdtopic0 should be0xfd9bf2730513a1709722ff379a0844dfd8f997d600693c2bcc659e188bbdba0d(B20Created(address,uint8,string,string,uint8,bytes)).UnsupportedVersionselector should be0xc0d8b4e0(UnsupportedVersion(uint8,uint8)).
|
|
||
| | Field | Value | | ||
| |---|---| | ||
| | Selector | `0xe494a1f6` | |
There was a problem hiding this comment.
Same enum-selector bug: computed from createPolicy(address,PolicyType). Correct ABI signature is createPolicy(address,uint8) → 0xca5d55f6 (verified with cast). Related: createPolicyWithAccounts → 0xa2d3044f, createCompositePolicy → 0x6fdd1491.
| ## Signature | ||
|
|
||
| ```solidity | ||
| function seizeWithMemo(address from, address to, uint256 amount, bytes32 memo) external returns (bool); |
There was a problem hiding this comment.
Two issues vs IB20.sol:474:
- Return type: source is
... external;with no return value;returns (bool)(and "always true on success") is incorrect.
function seizeWithMemo(address from, address to, uint256 amount, bytes32 memo) external;
- Policy semantics (stale): source gates the recipient under
SEIZE_RECEIVER_POLICYand revertsPolicyForbids(SEIZE_RECEIVER_POLICY, …)whentoisn't authorized (IB20.sol:460–467); this page saystois not policy-checked. Documents an older version of the interface.
|
|
||
| ## Access control | ||
|
|
||
| Callable by the policy admin for the target policy. |
There was a problem hiding this comment.
Access control is inverted. Per IPolicyRegistry.sol:161–168, this must be called by the staged pending admin (reverts Unauthorized otherwise), it "promotes the caller to active admin." The current policy admin cannot call it; that's the point of the two-step transfer.
| | [`DEFAULT_ADMIN_ROLE`](/base-chain/specs/upgrades/beryl/b20/specification/reference/interfaces/IB20/DEFAULT_ADMIN_ROLE) | `0xa217fddf` | The default top-level admin role (`bytes32(0)`). Required to call `grantRole`, `revokeRole`, | | ||
| | [`MINT_ROLE`](/base-chain/specs/upgrades/beryl/b20/specification/reference/interfaces/IB20/MINT_ROLE) | `0xe9a9c850` | Required to call `mint` and `mintWithMemo`. | | ||
| | [`BURN_ROLE`](/base-chain/specs/upgrades/beryl/b20/specification/reference/interfaces/IB20/BURN_ROLE) | `0xb930908f` | Required to call `burn` and `burnWithMemo`. | | ||
| | [`BURN_BLOCKED_ROLE`](/base-chain/specs/upgrades/beryl/b20/specification/reference/interfaces/IB20/BURN_BLOCKED_ROLE) | `0x32ad9be8` | Required to call the deprecated `burnBlocked` (no longer part of this interface; retained for | |
There was a problem hiding this comment.
burnBlocked is still declared in IB20.sol:453 (marked DEPRECATED), so "no longer part of this interface" is inaccurate. Also: burnBlocked(address,uint256) has no reference page (the only non-constant IB20 function without one), and SEIZE_RECEIVER_POLICY() (IB20.sol:274) is missing from this function table.
| --- | ||
|
|
||
|
|
||
| ## Functions |
There was a problem hiding this comment.
Two functions from IPolicyRegistry.sol are missing from this index (and have no pages): MIN_COMPOSITE_CHILD_POLICIES() (:242) and MAX_COMPOSITE_CHILD_POLICIES() (:247). 16 in source, 14 documented — and these are what the composite-range prose references.
| | error | `LengthMismatch` | `0xab8b67c6` | `IB20Asset` | A batched function was called with parallel arrays of differing lengths. | | ||
| | event | `Memo` | `0x6989f5818dcfd11f8cd53b27c94cec33dae1589735f03e639cba54553a1825e8` | `IB20` | Emitted by `transferWithMemo`, `transferFromWithMemo`, `mintWithMemo`, and `burnWithMemo` | | ||
| | error | `MissingRequiredField` | `0x4a43ae87` | `IB20Factory` | A required string argument was the empty string. | | ||
| | event | `MultiplierUpdateCancelled` | `0xf8929975f3e67bbd1e5ec70d4cceaa7cce7ea0e811720f29c96cf1724de09397` | `IB20Asset` | A scheduled multiplier update was cancelled. Emitted by `cancelScheduledMultiplier`, | |
There was a problem hiding this comment.
UIMultiplierUpdated(uint256,uint256,uint256) is missing from this index. It's declared in IScaledUIAmount.sol (inherited by IB20Asset) and is the primary event emitted on multiplier changes — MultiplierUpdateCancelled is listed, but the update event itself is not.
| | Transfer receiver | `keccak256("TRANSFER_RECEIVER_POLICY")` | | ||
| | Transfer executor | `keccak256("TRANSFER_EXECUTOR_POLICY")` | | ||
| | Mint receiver | `keccak256("MINT_RECEIVER_POLICY")` | | ||
| | Seize holder | `keccak256("SEIZE_HOLDER_POLICY")` | |
There was a problem hiding this comment.
Missing the 6th policy scope: SEIZE_RECEIVER_POLICY (keccak256("SEIZE_RECEIVER_POLICY")) is defined in B20Constants.sol but absent from this table, which claims to list the B20Constants.sol values.
| | `TRANSFER_RECEIVER_POLICY` | `to` | `transfer`, `transferFrom`, and memo variants | | ||
| | `TRANSFER_EXECUTOR_POLICY` | `msg.sender` | `transferFrom` when `msg.sender != from` | | ||
| | `MINT_RECEIVER_POLICY` | `to` | `mint`, `mintWithMemo` | | ||
| | `SEIZE_HOLDER_POLICY` | `from` | `seizeWithMemo`; holder is seizable only when not authorized | |
There was a problem hiding this comment.
The Policy Integration table is missing SEIZE_RECEIVER_POLICY (6th scope), and the Seize section (~line 118) says seizeWithMemo only requires from to be denied by SEIZE_HOLDER_POLICY, it omits that to is gated by SEIZE_RECEIVER_POLICY (IB20.sol:460–467).
What changed? Why?
Added b20 reference using b20 spec