diff --git a/docs/base-chain/specs/reference/b20/changelog/03-denim-b20-transfer-executor-enforcement.mdx b/docs/base-chain/specs/reference/b20/changelog/03-denim-b20-transfer-executor-enforcement.mdx index 498869141..2efaa64e7 100644 --- a/docs/base-chain/specs/reference/b20/changelog/03-denim-b20-transfer-executor-enforcement.mdx +++ b/docs/base-chain/specs/reference/b20/changelog/03-denim-b20-transfer-executor-enforcement.mdx @@ -45,7 +45,9 @@ All three transfer-side scopes now run inside the shared `_transfer` helper that | `TRANSFER_EXECUTOR_POLICY` | `msg.sender` | `transferFrom` paths, only when `msg.sender != from` | Every transfer path | All three scopes are still bypassed during the factory bootstrap window (`_isPrivileged()`), so a -token's `initCalls` can move newly minted supply without pre-authorizing the factory. +token's `initCalls` can move newly minted supply without pre-authorizing the factory. Allowance +accounting on `transferFrom` and `transferFromWithMemo` is unconditional, including during the +bootstrap window, and is unchanged. ### Revert Order @@ -69,7 +71,9 @@ On `transferFrom`, this removes the second (warm) read the entrypoint used to ma On `transfer`, the executor lookup is new. When `TRANSFER_EXECUTOR_POLICY` equals `TRANSFER_SENDER_POLICY` and `from == msg.sender` (including both slots unset, `ALWAYS_ALLOW_ID`), `_transfer` reuses the executor result and skips the sender `isAuthorized` call. A default -`transfer` therefore still makes two `isAuthorized` calls. +`transfer` therefore still makes two `isAuthorized` calls. Distinct policy IDs, or a `transferFrom` +where `msg.sender != from`, still make both the executor and sender calls. Receiver checks are +unchanged. ## Examples diff --git a/docs/specifications/b20/reference/interfaces.mdx b/docs/specifications/b20/reference/interfaces.mdx index 648a9d3aa..cee5cf11d 100644 --- a/docs/specifications/b20/reference/interfaces.mdx +++ b/docs/specifications/b20/reference/interfaces.mdx @@ -15,6 +15,7 @@ B20 interfaces describe the token, factory, and registry precompile surfaces. Us | `IB20Factory` | [IB20Factory reference](/specifications/b20/reference/interfaces/ib20-factory) | [IB20Factory.sol](https://github.com/base/base-std/blob/main/src/interfaces/IB20Factory.sol) | | `IPolicyRegistry` | [IPolicyRegistry reference](/specifications/b20/reference/interfaces/i-policy-registry) | [IPolicyRegistry.sol](https://github.com/base/base-std/blob/main/src/interfaces/IPolicyRegistry.sol) | | `IActivationRegistry` | [IActivationRegistry reference](/specifications/b20/reference/interfaces/i-activation-registry) | [IActivationRegistry.sol](https://github.com/base/base-std/blob/main/src/interfaces/IActivationRegistry.sol) | +| `IBaseTime` | BaseTime predeploy (millisecond block timestamp, read-only) | [IBaseTime.sol](https://github.com/base/base-std/blob/main/src/interfaces/IBaseTime.sol) | | `IERC8056` | Asset multiplier interfaces | [IERC8056.sol](https://github.com/base/base-std/blob/main/src/interfaces/IERC8056.sol) | | `IERC165` | Asset interface detection | [IERC165.sol](https://github.com/base/base-std/blob/main/src/interfaces/IERC165.sol) | @@ -58,6 +59,12 @@ import {IPolicyRegistry} from "base-std/interfaces/IPolicyRegistry.sol"; import {IActivationRegistry} from "base-std/interfaces/IActivationRegistry.sol"; ``` +### IBaseTime + +```solidity filename="IBaseTime.sol" +import {IBaseTime} from "base-std/interfaces/IBaseTime.sol"; +``` + ### IERC8056 ```solidity filename="IERC8056.sol" @@ -75,4 +82,4 @@ import { import {IERC165} from "base-std/interfaces/IERC165.sol"; ``` -See [`StdPrecompiles`](https://github.com/base/base-std/blob/main/src/StdPrecompiles.sol) for canonical precompile addresses. +See [`StdPrecompiles`](https://github.com/base/base-std/blob/main/src/StdPrecompiles.sol) for canonical precompile addresses and [`StdPredeploys`](https://github.com/base/base-std/blob/main/src/StdPredeploys.sol) for predeploy addresses.