@@ -69,16 +69,15 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
6969 /// keccak256(abi.encode(uint256(keccak256("ethscriptions.storage.ERC404NullOwnerCapped")) - 1)) & ~bytes32(uint256(0xff))
7070 bytes32 private constant STORAGE_LOCATION = 0x8a0c9d8e5f7b3a2c1d4e6f8a9b7c5d3e2f1a4b6c8d9e7f5a3b2c1d4e6f8a9b00 ;
7171
72- /// @dev Constant for token id encoding
73- uint256 public constant ID_ENCODING_PREFIX = 1 << 255 ;
74-
7572 // =============================================================
7673 // EVENTS
7774 // =============================================================
7875
7976 // ERC20 Events are inherited from IERC20 (Transfer, Approval)
8077
8178 // ERC721 Events (using different names to avoid conflicts with ERC20)
79+ // event Transfer(address indexed from, address indexed to, uint256 value);
80+ event ERC20Transfer (address indexed from , address indexed to , uint256 value );
8281 event ERC721Transfer (address indexed from , address indexed to , uint256 indexed id );
8382 event ERC721Approval (address indexed owner , address indexed spender , uint256 indexed id );
8483 event ApprovalForAll (address indexed owner , address indexed operator , bool approved );
@@ -125,14 +124,9 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
125124 ) internal onlyInitializing {
126125 TokenStorage storage $ = _getS ();
127126
128- if (cap_ == 0 || cap_ > ID_ENCODING_PREFIX - 1 ) {
129- revert ERC20InvalidCap (cap_);
130- }
131-
127+ if (cap_ == 0 ) revert ERC20InvalidCap (cap_);
132128 uint256 base = 10 ** decimals ();
133- if (units_ == 0 || units_ % base != 0 ) {
134- revert InvalidUnits (units_);
135- }
129+ if (units_ == 0 || units_ % base != 0 ) revert InvalidUnits (units_);
136130
137131 $.name = name_;
138132 $.symbol = symbol_;
@@ -173,6 +167,17 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
173167 TokenStorage storage $ = _getS ();
174168 return $.balances[account];
175169 }
170+
171+ function balanceOf (address owner_ , uint256 id_ )
172+ public
173+ view
174+ returns (uint256 )
175+ {
176+ TokenStorage storage $ = _getS ();
177+ TokenData storage t = $.tokens[id_];
178+ if (! t.exists) return 0 ;
179+ return t.owner == owner_ ? 1 : 0 ;
180+ }
176181
177182 function allowance (address owner , address spender ) public view virtual override (IERC404 , IERC20 ) returns (uint256 ) {
178183 TokenStorage storage $ = _getS ();
@@ -202,16 +207,11 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
202207 }
203208
204209 function ownerOf (uint256 id_ ) public view virtual override (IERC404 ) returns (address ) {
205- if (! _isValidTokenId (id_)) {
206- revert InvalidTokenId ();
207- }
208-
210+ _validateTokenId (id_);
209211 TokenStorage storage $ = _getS ();
210212 TokenData storage t = $.tokens[id_];
211213
212- if (! t.exists) {
213- revert NotFound ();
214- }
214+ if (! t.exists) revert NotFound ();
215215
216216 return t.owner;
217217 }
@@ -222,7 +222,10 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
222222 }
223223
224224 function getApproved (uint256 id_ ) public view virtual returns (address ) {
225+ _validateTokenId (id_);
225226 TokenStorage storage $ = _getS ();
227+ if (! $.tokens[id_].exists) revert NotFound ();
228+
226229 return $.getApproved[id_];
227230 }
228231
@@ -347,9 +350,6 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
347350 if (newSupply > $.cap) {
348351 revert ERC20ExceededCap (newSupply, $.cap);
349352 }
350- if (newSupply > ID_ENCODING_PREFIX) {
351- revert MintLimitReached ();
352- }
353353 $.totalSupply = newSupply;
354354 } else {
355355 // Transfer
@@ -367,16 +367,16 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
367367 }
368368
369369 emit Transfer (from_, to_, value_);
370+ // emit ERC20Transfer(from_, to_, value_);
370371 }
371372
372373 /// @notice Transfer an ERC721 token
373374 function _transferERC721 (address from_ , address to_ , uint256 id_ ) internal virtual {
374375 TokenStorage storage $ = _getS ();
375376 TokenData storage t = $.tokens[id_];
376-
377- if (from_ != ownerOf (id_)) {
378- revert Unauthorized ();
379- }
377+
378+ if (! t.exists) revert NotFound ();
379+ if (from_ != t.owner) revert Unauthorized ();
380380
381381 if (from_ != address (0 )) {
382382 // Clear approval
@@ -417,24 +417,19 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
417417 if (to_ == address (0 )) {
418418 revert InvalidRecipient ();
419419 }
420- if (nftId_ == 0 || nftId_ >= ID_ENCODING_PREFIX - 1 ) {
421- revert InvalidTokenId ();
422- }
420+ _validateTokenId (nftId_);
423421
424422 TokenStorage storage $ = _getS ();
425423
426- // Add the ID_ENCODING_PREFIX to the provided ID
427- uint256 id = ID_ENCODING_PREFIX + nftId_;
428-
429- TokenData storage t = $.tokens[id];
424+ TokenData storage t = $.tokens[nftId_];
430425
431426 // Check if this NFT already exists (including null-owner)
432427 if (t.exists) {
433428 revert AlreadyExists ();
434429 }
435430
436431 t.exists = true ;
437- _transferERC721 (address (0 ), to_, id );
432+ _transferERC721 (address (0 ), to_, nftId_ );
438433
439434 // Increment minted supply counter
440435 $.minted++ ;
@@ -444,8 +439,11 @@ abstract contract ERC404NullOwnerCappedUpgradeable is
444439 // HELPER FUNCTIONS
445440 // =============================================================
446441
447- function _isValidTokenId (uint256 id_ ) internal pure returns (bool ) {
448- return id_ > ID_ENCODING_PREFIX && id_ != type (uint256 ).max;
442+ /// @dev Simple tokenId validation: nonzero and not max uint256.
443+ function _validateTokenId (uint256 id_ ) internal pure {
444+ if (id_ == 0 || id_ == type (uint256 ).max) {
445+ revert InvalidTokenId ();
446+ }
449447 }
450448
451449 // =============================================================
0 commit comments