-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathIB20Factory.sol
More file actions
175 lines (154 loc) · 8.76 KB
/
IB20Factory.sol
File metadata and controls
175 lines (154 loc) · 8.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.20 <0.9.0;
/// @title IB20Factory
///
/// @notice Singleton factory precompile for creating B-20 tokens of any variant. A single
/// entry point `createB20` dispatches on a `B20Variant` discriminator; variant-specific
/// arguments are ABI-encoded into `params` with a leading `version` byte.
interface IB20Factory {
/*//////////////////////////////////////////////////////////////
TYPES
//////////////////////////////////////////////////////////////*/
/// @notice Variant of a B-20 token. Encoded in address byte `[10]`.
///
/// @param ASSET Asset variant (configurable `decimals`, multiplier, announcements, batched issuance / clawback).
/// @param STABLECOIN Stablecoin variant (fixed `6` decimals, immutable `currency`).
enum B20Variant {
ASSET,
STABLECOIN
}
/// @notice Creation parameters for a Stablecoin-variant B-20 token. ABI-encoded into `params`.
struct B20StablecoinCreateParams {
/// @dev Encoding version. Currently `1`.
uint8 version;
/// @dev ERC-20 token name.
string name;
/// @dev ERC-20 token symbol.
string symbol;
/// @dev Initial holder of `DEFAULT_ADMIN_ROLE`, or `address(0)` to deploy admin-less.
address initialAdmin;
/// @dev Immutable self-declared currency code; uppercase ASCII `A`-`Z` only.
string currency;
}
/// @notice Creation parameters for an Asset-variant B-20 token. ABI-encoded into `params`.
struct B20AssetCreateParams {
/// @dev Encoding version. Currently `1`.
uint8 version;
/// @dev ERC-20 token name.
string name;
/// @dev ERC-20 token symbol.
string symbol;
/// @dev Initial holder of `DEFAULT_ADMIN_ROLE`, or `address(0)` to deploy admin-less.
address initialAdmin;
/// @dev ERC-20 `decimals` value. Immutable post-creation. Must be in the inclusive
/// range `[B20Constants.MIN_ASSET_DECIMALS, B20Constants.MAX_ASSET_DECIMALS]`
/// (`[6, 18]`); out-of-range values revert with `InvalidDecimals`.
uint8 decimals;
}
/// @notice Event payload carried in the `variantEventParams` field of `B20Created` for
/// STABLECOIN-variant tokens. ABI-encoded and prefixed with a version byte.
struct B20StablecoinEventParams {
/// @dev Event-encoding version. Currently `1`. Independent of `B20StablecoinCreateParams.version`.
uint8 version;
/// @dev Stablecoin currency code, identical to the value passed in
/// `B20StablecoinCreateParams.currency`.
string currency;
}
/*//////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice A token already exists at the deterministic address derived from
/// `(variant, msg.sender, salt)`. Caller must use a different salt.
error TokenAlreadyExists(address token);
/// @notice `variant` is not a recognized `B20Variant`.
error InvalidVariant();
/// @notice The leading `version` byte in `params` does not match any known encoding for the requested variant.
error UnsupportedVersion(uint8 version, B20Variant variant);
/// @notice A required string argument was the empty string.
///
/// @param field Name of the missing field (e.g. `"currency"`).
error MissingRequiredField(string field);
/// @notice The stablecoin `currency` was non-empty but contained a non-`A`-`Z` byte.
error InvalidCurrency(string code);
/// @notice The asset `decimals` was outside the allowed inclusive range
/// `[B20Constants.MIN_ASSET_DECIMALS, B20Constants.MAX_ASSET_DECIMALS]`.
///
/// @param decimals Offending decimals value.
error InvalidDecimals(uint8 decimals);
/// @notice One of the `initCalls` reverted. The factory bubbles the underlying revert reason
/// where the call returns one; this error wraps empty reverts.
error InitCallFailed(uint256 index);
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
/// @notice Emitted once per `createB20` invocation, after the token's identity is sealed
/// and before any `initCalls` are dispatched.
///
/// @dev `variantEventParams` carries variant-specific immutable identity data, ABI-encoded
/// and prefixed with a version byte. Empty for ASSET; for STABLECOIN,
/// `abi.encode(B20StablecoinEventParams)` with `currency`.
/// @dev `decimals` mirrors the value chosen at creation: configurable in
/// `[B20Constants.MIN_ASSET_DECIMALS, B20Constants.MAX_ASSET_DECIMALS]` for ASSET
/// (from `B20AssetCreateParams.decimals`); hardcoded to `6` for STABLECOIN.
event B20Created(
address indexed token,
B20Variant indexed variant,
string name,
string symbol,
uint8 decimals,
bytes variantEventParams
);
/*//////////////////////////////////////////////////////////////
CREATE
//////////////////////////////////////////////////////////////*/
/// @notice Creates a B-20 token of the given `variant` at the deterministic address derived
/// from `(variant, msg.sender, salt)`, then dispatches each entry in `initCalls` on
/// the new token. Emits `B20Created`.
///
/// @dev Reverts with IActivationRegistry.FeatureNotActivated when the variant feature is not activated.
/// @dev Reverts with `InvalidVariant` when `variant` is outside the `B20Variant` range.
/// @dev Reverts with `UnsupportedVersion` when the leading `version` byte in `params` is unrecognized for `variant`.
/// @dev Reverts with `MissingRequiredField` when a required string field is empty (e.g. stablecoin `currency`).
/// @dev Reverts with `InvalidCurrency` when a stablecoin `currency` is non-empty but contains a non-`A`-`Z` byte.
/// @dev Reverts with `InvalidDecimals` when an asset `decimals` is outside `[B20Constants.MIN_ASSET_DECIMALS, B20Constants.MAX_ASSET_DECIMALS]`.
/// @dev Reverts with `TokenAlreadyExists` when a token already exists at the derived address.
/// @dev Reverts with `InitCallFailed` (or the bubbled inner reason) when any entry in `initCalls` reverts.
/// @dev Each `initCall` executes on the new token within the creation (bootstrap) window, during which the
/// token's role / policy / pause authorization gates are bypassed for factory-originated calls — so
/// admin-gated setup (e.g. `grantRole`, `updatePolicy`, `updateSupplyCap`) succeeds without the factory
/// holding any role. The window closes when `createB20` returns; the factory retains no persisted access.
///
/// @param variant Which variant struct `params` decodes as.
/// @param salt Caller-chosen salt for deterministic address derivation.
/// @param params ABI-encoded variant-specific creation struct, leading with the version byte.
/// @param initCalls Bootstrap calls invoked on the new token after identity is sealed.
///
/// @return token The address of the newly created token.
function createB20(B20Variant variant, bytes32 salt, bytes calldata params, bytes[] calldata initCalls)
external
returns (address token);
/*//////////////////////////////////////////////////////////////
ADDRESS QUERIES
//////////////////////////////////////////////////////////////*/
/// @notice Returns the deterministic address `createB20` would assign for `(variant, sender, salt)`. Never reverts.
///
/// @param variant Variant of the token whose address is being predicted.
/// @param sender Account that would call `createB20`.
/// @param salt Caller-chosen salt.
///
/// @return The deterministic token address.
function getB20Address(B20Variant variant, address sender, bytes32 salt) external view returns (address);
/// @notice Returns whether `token` was created by this factory, recovered from the address prefix. Never reverts.
///
/// @param token Address to check.
///
/// @return Whether `token` matches the B-20 address prefix.
function isB20(address token) external view returns (bool);
/// @notice Returns whether `createB20` has run to completion at `token`. Flips exactly once,
/// the moment the creating `createB20` call returns. Never reverts.
///
/// @param token Address to check.
///
/// @return Whether `token` is an initialized B-20.
function isB20Initialized(address token) external view returns (bool);
}