Skip to content

Commit 5bea0d5

Browse files
Merge pull request #127 from ethscriptions-protocol/rename
Big rename
2 parents a308e2c + 83e4f49 commit 5bea0d5

27 files changed

Lines changed: 458 additions & 606 deletions

app/models/token_params_extractor.rb renamed to app/models/fixed_fungible_token_params_extractor.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
# Extracts token parameters from content URIs using strict regex validation
1+
# Extracts fixed-fungible token parameters from content URIs using strict regex validation
22
# Protocol uniqueness is based on exact text matching, so we validate the exact format
3-
class TokenParamsExtractor
3+
class FixedFungibleTokenParamsExtractor
44
# Constants
55
DEFAULT_PARAMS = [''.b, ''.b, ''.b, 0, 0, 0].freeze
66
UINT256_MAX = 2**256 - 1
7-
7+
88
# Exact regex patterns for valid formats
9-
# Protocol must be "erc-20" (not captured since it's fixed)
9+
# Protocol must be "erc-20" or "fixed-fungible" (case-sensitive)
1010
# Tick must be lowercase letters/numbers, max 28 chars
1111
# Numbers must be positive decimals without leading zeros
12-
DEPLOY_REGEX = /\Adata:,\{"p":"erc-20","op":"deploy","tick":"([a-z0-9]{1,28})","max":"(0|[1-9][0-9]*)","lim":"(0|[1-9][0-9]*)"\}\z/
13-
MINT_REGEX = /\Adata:,\{"p":"erc-20","op":"mint","tick":"([a-z0-9]{1,28})","id":"(0|[1-9][0-9]*)","amt":"(0|[1-9][0-9]*)"\}\z/
12+
PROTOCOL_PATTERN = '(?:erc-20|fixed-fungible)'
13+
DEPLOY_REGEX = /\Adata:,\{"p":"#{PROTOCOL_PATTERN}","op":"deploy","tick":"([a-z0-9]{1,28})","max":"(0|[1-9][0-9]*)","lim":"(0|[1-9][0-9]*)"\}\z/
14+
MINT_REGEX = /\Adata:,\{"p":"#{PROTOCOL_PATTERN}","op":"mint","tick":"([a-z0-9]{1,28})","id":"(0|[1-9][0-9]*)","amt":"(0|[1-9][0-9]*)"\}\z/
1415

1516
def self.extract(content_uri)
1617
return DEFAULT_PARAMS unless content_uri.is_a?(String)
@@ -24,7 +25,7 @@ def self.extract(content_uri)
2425
# Validate uint256 bounds
2526
return DEFAULT_PARAMS if max > UINT256_MAX || lim > UINT256_MAX
2627

27-
return ['deploy'.b, 'erc-20'.b, tick.b, max, lim, 0]
28+
return ['deploy'.b, 'fixed-fungible'.b, tick.b, max, lim, 0]
2829
end
2930

3031
# Try mint format
@@ -36,7 +37,7 @@ def self.extract(content_uri)
3637
# Validate uint256 bounds
3738
return DEFAULT_PARAMS if id > UINT256_MAX || amt > UINT256_MAX
3839

39-
return ['mint'.b, 'erc-20'.b, tick.b, id, 0, amt]
40+
return ['mint'.b, 'fixed-fungible'.b, tick.b, id, 0, amt]
4041
end
4142

4243
# No match - return default

app/models/generic_protocol_extractor.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,9 @@ def handle_bytes_hint(type_hint, value)
572572
[type_hint, [hex_part.downcase].pack('H*')]
573573
end
574574

575-
# Helper method for legacy token protocol (maintains compatibility)
575+
# Helper method for fixed-fungible protocol parsing (shared with protocol extractor)
576576
def self.extract_token_params(content_uri)
577577
# Use the strict regex-based extractor for token protocol
578-
TokenParamsExtractor.extract(content_uri)
578+
FixedFungibleTokenParamsExtractor.extract(content_uri)
579579
end
580580
end

app/models/protocol_extractor.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Unified protocol extractor that delegates to appropriate extractors
22
class ProtocolExtractor
33
# Default return values to check if extraction succeeded
4-
TOKEN_DEFAULT_PARAMS = TokenParamsExtractor::DEFAULT_PARAMS
4+
TOKEN_DEFAULT_PARAMS = FixedFungibleTokenParamsExtractor::DEFAULT_PARAMS
55
COLLECTIONS_DEFAULT_PARAMS = CollectionsParamsExtractor::DEFAULT_PARAMS
66
GENERIC_DEFAULT_PARAMS = GenericProtocolExtractor::DEFAULT_PARAMS
77

@@ -45,15 +45,15 @@ def self.extract(content_uri)
4545
private
4646

4747
def self.try_token_extractor(content_uri)
48-
# TokenParamsExtractor uses strict regex and returns DEFAULT_PARAMS if no match
48+
# FixedFungibleTokenParamsExtractor uses strict regex and returns DEFAULT_PARAMS if no match
4949
# This enforces non-ESIP6 and exact JSON formatting implicitly.
50-
params = TokenParamsExtractor.extract(content_uri)
50+
params = FixedFungibleTokenParamsExtractor.extract(content_uri)
5151

5252
# Check if extraction succeeded (returns non-default params)
5353
if params != TOKEN_DEFAULT_PARAMS
5454
{
55-
type: :token,
56-
protocol: 'erc-20',
55+
type: :fixed_fungible,
56+
protocol: 'fixed-fungible',
5757
operation: params[0], # 'deploy' or 'mint'
5858
params: params,
5959
encoded_params: encode_token_params(params)
@@ -135,8 +135,8 @@ def self.for_calldata(content_uri)
135135
if result.nil?
136136
# No protocol detected - return empty protocol params
137137
[''.b, ''.b, ''.b]
138-
elsif result[:type] == :token
139-
# Token protocol - return in new format
138+
elsif result[:type] == :fixed_fungible
139+
# Fixed-fungible protocol - return in ABI-ready format
140140
protocol = result[:protocol].b
141141
operation = result[:operation]
142142
# For tokens, encode the params properly
@@ -158,7 +158,7 @@ def self.encode_token_data(params)
158158

159159
# Encode based on operation type (operation is passed separately now)
160160
# Use tuple encoding for struct compatibility with contracts
161-
# IMPORTANT: Field order must match TokenManager's struct definitions!
161+
# IMPORTANT: Field order must match FixedFungibleProtocolHandler's struct definitions!
162162
if op == 'deploy'.b
163163
# DeployOperation struct: tick, maxSupply, mintAmount
164164
# Our params: tick, max (val1), lim (val2)

contracts/script/L2Genesis.s.sol

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -198,22 +198,22 @@ contract L2Genesis is Script {
198198

199199
// Wire up implementations for the Ethscriptions predeploys that use proxies
200200
bool isProxiedContract = addr == Predeploys.ETHSCRIPTIONS ||
201-
addr == Predeploys.TOKEN_MANAGER ||
201+
addr == Predeploys.FIXED_FUNGIBLE_HANDLER ||
202202
addr == Predeploys.ETHSCRIPTIONS_PROVER ||
203-
addr == Predeploys.COLLECTIONS_MANAGER;
203+
addr == Predeploys.COLLECTIONS_PROTOCOL_HANDLER;
204204
if (isProxiedContract) {
205205
address impl = Predeploys.predeployToCodeNamespace(addr);
206206
setImplementation(addr, impl);
207207
}
208208
}
209209

210210
// Set implementation code for non-ETHSCRIPTIONS contracts now
211-
_setImplementationCodeNamed(Predeploys.TOKEN_MANAGER, "TokenManager");
212-
_setImplementationCodeNamed(Predeploys.COLLECTIONS_MANAGER, "CollectionsManager");
211+
_setImplementationCodeNamed(Predeploys.FIXED_FUNGIBLE_HANDLER, "FixedFungibleProtocolHandler");
212+
_setImplementationCodeNamed(Predeploys.COLLECTIONS_PROTOCOL_HANDLER, "CollectionsProtocolHandler");
213213
_setImplementationCodeNamed(Predeploys.ETHSCRIPTIONS_PROVER, "EthscriptionsProver");
214214
// Templates live directly at their implementation addresses (no proxy wrapping)
215-
_setCodeAt(Predeploys.ERC20_TEMPLATE_IMPLEMENTATION, "EthscriptionsERC20");
216-
_setCodeAt(Predeploys.ERC721_TEMPLATE_IMPLEMENTATION, "EthscriptionERC721");
215+
_setCodeAt(Predeploys.FIXED_FUNGIBLE_TEMPLATE_IMPLEMENTATION, "FixedFungibleERC20");
216+
_setCodeAt(Predeploys.COLLECTIONS_TEMPLATE_IMPLEMENTATION, "CollectionsERC721");
217217

218218
// Create genesis Ethscriptions (writes via proxy to proxy storage)
219219
createGenesisEthscriptions();
@@ -226,18 +226,18 @@ contract L2Genesis is Script {
226226
function registerProtocolHandlers() internal {
227227
Ethscriptions ethscriptions = Ethscriptions(Predeploys.ETHSCRIPTIONS);
228228

229-
ethscriptions.registerProtocol("erc-20", Predeploys.TOKEN_MANAGER);
230-
console.log("Registered erc-20 protocol handler:", Predeploys.TOKEN_MANAGER);
229+
ethscriptions.registerProtocol("fixed-fungible", Predeploys.FIXED_FUNGIBLE_HANDLER);
230+
console.log("Registered fixed-fungible protocol handler:", Predeploys.FIXED_FUNGIBLE_HANDLER);
231231

232232
// Check environment variable for collections
233233
// Default to true so forge tests work (they don't go through genesis_generator.rb)
234234
// Production explicitly sets ENABLE_COLLECTIONS=false
235235
bool enableCollections = vm.envOr("ENABLE_COLLECTIONS", true);
236236

237237
if (enableCollections) {
238-
// Register the CollectionsManager as the handler for collections protocol
239-
ethscriptions.registerProtocol("collections", Predeploys.COLLECTIONS_MANAGER);
240-
console.log("Registered collections protocol handler:", Predeploys.COLLECTIONS_MANAGER);
238+
// Register the collections protocol handler for collections operations
239+
ethscriptions.registerProtocol("collections", Predeploys.COLLECTIONS_PROTOCOL_HANDLER);
240+
console.log("Registered collections protocol handler:", Predeploys.COLLECTIONS_PROTOCOL_HANDLER);
241241
} else {
242242
console.log("Collections protocol not registered (ENABLE_COLLECTIONS=false)");
243243
}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import "./ERC721EthscriptionsUpgradeable.sol";
88
import "./Ethscriptions.sol";
99
import {LibString} from "solady/utils/LibString.sol";
1010
import {Base64} from "solady/utils/Base64.sol";
11-
import "./CollectionsManager.sol";
11+
import "./CollectionsProtocolHandler.sol";
1212

13-
/// @title EthscriptionERC721
13+
/// @title CollectionsERC721
1414
/// @notice ERC-721 contract for an Ethscription collection
1515
/// @dev Maintains internal state but overrides ownerOf to delegate to Ethscriptions contract
16-
contract EthscriptionERC721 is ERC721EthscriptionsUpgradeable {
16+
contract CollectionsERC721 is ERC721EthscriptionsUpgradeable {
1717
using LibString for *;
1818

1919
/// @notice The main Ethscriptions contract
@@ -125,8 +125,8 @@ contract EthscriptionERC721 is ERC721EthscriptionsUpgradeable {
125125
}
126126

127127
// Get ethscription ID from manager
128-
CollectionsManager manager = CollectionsManager(factory);
129-
CollectionsManager.CollectionItem memory item = manager.getCollectionItem(collectionId, tokenId);
128+
CollectionsProtocolHandler manager = CollectionsProtocolHandler(factory);
129+
CollectionsProtocolHandler.CollectionItem memory item = manager.getCollectionItem(collectionId, tokenId);
130130

131131
if (item.ethscriptionId == bytes32(0)) {
132132
revert("Token not in collection");
@@ -142,9 +142,9 @@ contract EthscriptionERC721 is ERC721EthscriptionsUpgradeable {
142142
revert("Token does not exist");
143143
}
144144

145-
// Get collection metadata and item data from CollectionsManager
146-
CollectionsManager manager = CollectionsManager(factory);
147-
CollectionsManager.CollectionItem memory item = manager.getCollectionItem(collectionId, tokenId);
145+
// Get collection metadata and item data from CollectionsProtocolHandler
146+
CollectionsProtocolHandler manager = CollectionsProtocolHandler(factory);
147+
CollectionsProtocolHandler.CollectionItem memory item = manager.getCollectionItem(collectionId, tokenId);
148148

149149
if (item.ethscriptionId == bytes32(0)) {
150150
revert("Token not in collection");

contracts/src/CollectionsManager.sol renamed to contracts/src/CollectionsProtocolHandler.sol

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ pragma solidity 0.8.24;
33

44
import "@openzeppelin/contracts/proxy/Clones.sol";
55
import {LibString} from "solady/utils/LibString.sol";
6-
import "./EthscriptionERC721.sol";
6+
import "./CollectionsERC721.sol";
77
import "./Ethscriptions.sol";
88
import "./libraries/Predeploys.sol";
99
import "./interfaces/IProtocolHandler.sol";
1010

11-
contract CollectionsManager is IProtocolHandler {
11+
contract CollectionsProtocolHandler is IProtocolHandler {
1212
using Clones for address;
1313
using LibString for string;
1414

@@ -96,7 +96,7 @@ contract CollectionsManager is IProtocolHandler {
9696
// Note: Similar to ItemData but without ethscriptionId (can't change)
9797
}
9898

99-
address public constant erc721Template = Predeploys.ERC721_TEMPLATE_IMPLEMENTATION;
99+
address public constant collectionsTemplate = Predeploys.COLLECTIONS_TEMPLATE_IMPLEMENTATION;
100100
address public constant ethscriptions = Predeploys.ETHSCRIPTIONS;
101101

102102
// Track deployed collections by ID
@@ -157,10 +157,10 @@ contract CollectionsManager is IProtocolHandler {
157157
uint256 totalSupply = metadata.totalSupply;
158158

159159
// Deploy ERC721 clone with CREATE2 using collectionId as salt for deterministic address
160-
address collectionContract = erc721Template.cloneDeterministic(collectionId);
160+
address collectionContract = collectionsTemplate.cloneDeterministic(collectionId);
161161

162162
// Initialize the clone with basic info
163-
EthscriptionERC721(collectionContract).initialize(
163+
CollectionsERC721(collectionContract).initialize(
164164
metadata.name,
165165
metadata.symbol,
166166
collectionId
@@ -211,7 +211,7 @@ contract CollectionsManager is IProtocolHandler {
211211
}
212212

213213
// Add each item with full metadata
214-
EthscriptionERC721 collectionContract = EthscriptionERC721(collection.collectionContract);
214+
CollectionsERC721 collectionContract = CollectionsERC721(collection.collectionContract);
215215

216216
for (uint256 i = 0; i < addOp.items.length; i++) {
217217
ItemData memory itemData = addOp.items[i];
@@ -271,7 +271,7 @@ contract CollectionsManager is IProtocolHandler {
271271
require(currentOwner == sender, "Only collection owner can remove items");
272272

273273
// Remove each ethscription from the collection
274-
EthscriptionERC721 collectionContract = EthscriptionERC721(collection.collectionContract);
274+
CollectionsERC721 collectionContract = CollectionsERC721(collection.collectionContract);
275275
for (uint256 i = 0; i < removeOp.ethscriptionIds.length; i++) {
276276
bytes32 ethscriptionId = removeOp.ethscriptionIds[i];
277277

@@ -374,7 +374,7 @@ contract CollectionsManager is IProtocolHandler {
374374
require(currentOwner == sender, "Only collection owner can lock");
375375

376376
collection.locked = true;
377-
EthscriptionERC721(collection.collectionContract).lockCollection();
377+
CollectionsERC721(collection.collectionContract).lockCollection();
378378
emit CollectionLocked(collectionId);
379379
emit ProtocolHandlerSuccess(txHash, protocolName());
380380
}
@@ -389,7 +389,7 @@ contract CollectionsManager is IProtocolHandler {
389389
CollectionState memory collection = collectionState[collectionId];
390390
require(collection.collectionContract != address(0), "Collection does not exist");
391391

392-
EthscriptionERC721 collectionContract = EthscriptionERC721(collection.collectionContract);
392+
CollectionsERC721 collectionContract = CollectionsERC721(collection.collectionContract);
393393

394394
// Sync ownership for specified ethscriptions in this collection
395395
for (uint256 i = 0; i < ethscriptionIds.length; i++) {
@@ -419,7 +419,7 @@ contract CollectionsManager is IProtocolHandler {
419419
// CollectionState memory collection = collectionState[item.collectionId];
420420
// if (collection.collectionContract != address(0)) {
421421
// // Sync the ownership in the ERC721 contract
422-
// EthscriptionERC721(collection.collectionContract).syncOwnership(item.tokenId);
422+
// CollectionsERC721(collection.collectionContract).syncOwnership(item.tokenId);
423423
// }
424424
// }
425425
}
@@ -459,7 +459,7 @@ contract CollectionsManager is IProtocolHandler {
459459
}
460460

461461
// Predict using CREATE2
462-
return Clones.predictDeterministicAddress(erc721Template, collectionId, address(this));
462+
return Clones.predictDeterministicAddress(collectionsTemplate, collectionId, address(this));
463463
}
464464

465465
function getAllCollections() external view returns (bytes32[] memory) {
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ pragma solidity 0.8.24;
44
import "./ERC20NullOwnerCappedUpgradeable.sol";
55
import "./libraries/Predeploys.sol";
66

7-
/// @title EthscriptionsERC20
8-
/// @notice ERC20 with cap that supports null address ownership
9-
/// @dev Only TokenManager can mint/transfer. User-initiated transfers are disabled.
10-
contract EthscriptionsERC20 is ERC20NullOwnerCappedUpgradeable {
7+
/// @title FixedFungibleERC20
8+
/// @notice ERC-20 clone whose balances are controlled by the FixedFungible protocol handler
9+
/// @dev User-initiated transfers/approvals are disabled; only the handler can mutate balances.
10+
contract FixedFungibleERC20 is ERC20NullOwnerCappedUpgradeable {
1111

1212
// =============================================================
1313
// CONSTANTS
1414
// =============================================================
1515

16-
/// @notice The TokenManager contract that controls this token
17-
address public constant tokenManager = Predeploys.TOKEN_MANAGER;
16+
/// @notice The FixedFungible protocol handler that controls this token
17+
address public constant protocolHandler = Predeploys.FIXED_FUNGIBLE_HANDLER;
1818

1919
// =============================================================
2020
// STATE VARIABLES
@@ -27,16 +27,16 @@ contract EthscriptionsERC20 is ERC20NullOwnerCappedUpgradeable {
2727
// CUSTOM ERRORS
2828
// =============================================================
2929

30-
error OnlyTokenManager();
30+
error OnlyProtocolHandler();
3131
error TransfersOnlyViaEthscriptions();
3232
error ApprovalsNotAllowed();
3333

3434
// =============================================================
3535
// MODIFIERS
3636
// =============================================================
3737

38-
modifier onlyTokenManager() {
39-
if (msg.sender != tokenManager) revert OnlyTokenManager();
38+
modifier onlyProtocolHandler() {
39+
if (msg.sender != protocolHandler) revert OnlyProtocolHandler();
4040
_;
4141
}
4242

@@ -60,20 +60,20 @@ contract EthscriptionsERC20 is ERC20NullOwnerCappedUpgradeable {
6060
deployEthscriptionId = deployEthscriptionId_;
6161
}
6262

63-
/// @notice Mint tokens (TokenManager only)
63+
/// @notice Mint tokens (protocol handler only)
6464
/// @dev Allows minting to address(0) for null ownership
6565
/// @param to The recipient address (can be address(0))
6666
/// @param amount The amount to mint (in 18 decimals)
67-
function mint(address to, uint256 amount) external onlyTokenManager {
67+
function mint(address to, uint256 amount) external onlyProtocolHandler {
6868
_mint(to, amount);
6969
}
7070

71-
/// @notice Force transfer tokens (TokenManager only)
71+
/// @notice Force transfer tokens (protocol handler only)
7272
/// @dev Allows transfers to/from address(0) for null ownership
7373
/// @param from The sender address (can be address(0))
7474
/// @param to The recipient address (can be address(0))
7575
/// @param amount The amount to transfer (in 18 decimals)
76-
function forceTransfer(address from, address to, uint256 amount) external onlyTokenManager {
76+
function forceTransfer(address from, address to, uint256 amount) external onlyProtocolHandler {
7777
_update(from, to, amount);
7878
}
7979

@@ -94,7 +94,7 @@ contract EthscriptionsERC20 is ERC20NullOwnerCappedUpgradeable {
9494
}
9595

9696
/// @notice Approvals are disabled
97-
/// @dev All transfers are controlled by the TokenManager
97+
/// @dev All transfers are controlled by the FixedFungibleProtocolHandler
9898
function approve(address, uint256) public pure override returns (bool) {
9999
revert ApprovalsNotAllowed();
100100
}

0 commit comments

Comments
 (0)