SlotFactory
Deploys slots as BeaconProxies sharing one implementation. A slot's address is assigned at deploy time, not derived from its config, so a slot is identified by its address.
function createSlot(SlotInit calldata init) external returns (address slot);One call, one struct. There is no batch variant and no separate
recipient / currency / config argument list — everything a slot needs is
in SlotInit.
SlotInit
struct SlotInit {
address recipient; // where tax goes; never zero
IERC20 currency; // token for tax and price; address(0) = native ETH
address manager; // may change what is mutable; zero on an immutable slot
address hook; // the single extension point; zero for none
bytes32 hookData; // that hook's configuration; must be 0 when hook is
uint256 taxBps; // basis points per 30 days (100 = 1%), 1..10000
uint256 minDepositSeconds; // deposit a buy must fund; zero = no minimum
bool mutableTax;
bool mutableHook;
}hookData is 32 bytes the slot stores and hands its hook on every callback — a
minimum-tenure window, say. It is what lets one hook deployment serve every
configuration, and it is refused unless there is a hook to interpret it. The hook
validates it at creation, so a configuration it will reject fails there rather
than vetoing every buy afterwards.
Two mutability flags, not three. A slot has one hook, so it has one promise about that hook — separate from the promise about its tax rate. A slot can offer a swappable hook on a tax rate that never changes, or the reverse.
minDepositSeconds guards against a buyer declaring a huge price with no means
to pay: the deposit must cover that many seconds of tax at the declared price. It
rounds up — a truncating client-side copy lands one unit short and reverts.
Admin
function transferAdmin(address next) external; // hand over the role
function upgradeBeacon(address implementation) external; // move every slot at once
function implementation() external view returns (address);upgradeBeacon moves every slot to a new implementation in one call — they all
share one beacon. Storage is strictly append-only for that reason.