Skip to content

Commit 9918898

Browse files
committed
Optimize revert bytecode size
1 parent 0369483 commit 9918898

File tree

3 files changed

+103
-64
lines changed

3 files changed

+103
-64
lines changed

src/DN404.sol

+44-29
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,10 @@ abstract contract DN404 {
251251
DN404Storage storage $ = _getDN404Storage();
252252

253253
unchecked {
254-
if (_unit() - 1 >= 2 ** 96 - 1) revert InvalidUnit();
254+
if (_unit() - 1 >= 2 ** 96 - 1) _rv(uint32(InvalidUnit.selector));
255255
}
256-
if ($.mirrorERC721 != address(0)) revert DNAlreadyInitialized();
257-
if (mirror == address(0)) revert MirrorAddressIsZero();
256+
if ($.mirrorERC721 != address(0)) _rv(uint32(DNAlreadyInitialized.selector));
257+
if (mirror == address(0)) _rv(uint32(MirrorAddressIsZero.selector));
258258

259259
/// @solidity memory-safe-assembly
260260
assembly {
@@ -278,8 +278,10 @@ abstract contract DN404 {
278278
$.mirrorERC721 = mirror;
279279

280280
if (initialTokenSupply != 0) {
281-
if (initialSupplyOwner == address(0)) revert TransferToZeroAddress();
282-
if (_totalSupplyOverflows(initialTokenSupply)) revert TotalSupplyOverflow();
281+
if (initialSupplyOwner == address(0)) _rv(uint32(TransferToZeroAddress.selector));
282+
if (_totalSupplyOverflows(initialTokenSupply)) {
283+
_rv(uint32(TotalSupplyOverflow.selector));
284+
}
283285

284286
$.totalSupply = uint96(initialTokenSupply);
285287
AddressData storage initialOwnerAddressData = $.addressData[initialSupplyOwner];
@@ -456,7 +458,7 @@ abstract contract DN404 {
456458
== uint256(0) ? type(uint256).max : a.value;
457459

458460
if (allowed != type(uint256).max) {
459-
if (amount > allowed) revert InsufficientAllowance();
461+
if (amount > allowed) _rv(uint32(InsufficientAllowance.selector));
460462
unchecked {
461463
a.value = allowed - amount;
462464
}
@@ -502,10 +504,10 @@ abstract contract DN404 {
502504
///
503505
/// Emits a {Transfer} event.
504506
function _mint(address to, uint256 amount) internal virtual {
505-
if (to == address(0)) revert TransferToZeroAddress();
507+
if (to == address(0)) _rv(uint32(TransferToZeroAddress.selector));
506508

507509
DN404Storage storage $ = _getDN404Storage();
508-
if ($.mirrorERC721 == address(0)) revert DNNotInitialized();
510+
if ($.mirrorERC721 == address(0)) _rv(uint32(DNNotInitialized.selector));
509511
AddressData storage toAddressData = $.addressData[to];
510512

511513
_DNMintTemps memory t;
@@ -520,7 +522,9 @@ abstract contract DN404 {
520522
uint256 newTotalSupply = uint256($.totalSupply) + amount;
521523
$.totalSupply = uint96(newTotalSupply);
522524
uint256 overflows = _toUint(_totalSupplyOverflows(newTotalSupply));
523-
if (overflows | _toUint(newTotalSupply < amount) != 0) revert TotalSupplyOverflow();
525+
if (overflows | _toUint(newTotalSupply < amount) != 0) {
526+
_rv(uint32(TotalSupplyOverflow.selector));
527+
}
524528
idLimit = newTotalSupply / _unit();
525529
}
526530
while (!getSkipNFT(to)) {
@@ -594,10 +598,10 @@ abstract contract DN404 {
594598
///
595599
/// Emits a {Transfer} event.
596600
function _mintNext(address to, uint256 amount) internal virtual {
597-
if (to == address(0)) revert TransferToZeroAddress();
601+
if (to == address(0)) _rv(uint32(TransferToZeroAddress.selector));
598602

599603
DN404Storage storage $ = _getDN404Storage();
600-
if ($.mirrorERC721 == address(0)) revert DNNotInitialized();
604+
if ($.mirrorERC721 == address(0)) _rv(uint32(DNNotInitialized.selector));
601605
AddressData storage toAddressData = $.addressData[to];
602606

603607
_DNMintTemps memory t;
@@ -614,7 +618,9 @@ abstract contract DN404 {
614618
uint256 newTotalSupply = uint256(preTotalSupply) + amount;
615619
$.totalSupply = uint96(newTotalSupply);
616620
uint256 overflows = _toUint(_totalSupplyOverflows(newTotalSupply));
617-
if (overflows | _toUint(newTotalSupply < amount) != 0) revert TotalSupplyOverflow();
621+
if (overflows | _toUint(newTotalSupply < amount) != 0) {
622+
_rv(uint32(TotalSupplyOverflow.selector));
623+
}
618624
idLimit = newTotalSupply / _unit();
619625
id = _wrapNFTId(preTotalSupply / _unit() + _toUint(_useOneIndexed()), idLimit);
620626
}
@@ -677,14 +683,14 @@ abstract contract DN404 {
677683
/// Emits a {Transfer} event.
678684
function _burn(address from, uint256 amount) internal virtual {
679685
DN404Storage storage $ = _getDN404Storage();
680-
if ($.mirrorERC721 == address(0)) revert DNNotInitialized();
686+
if ($.mirrorERC721 == address(0)) _rv(uint32(DNNotInitialized.selector));
681687

682688
AddressData storage fromAddressData = $.addressData[from];
683689
_DNBurnTemps memory t;
684690

685691
unchecked {
686692
t.fromBalance = fromAddressData.balance;
687-
if (amount > t.fromBalance) revert InsufficientBalance();
693+
if (amount > t.fromBalance) _rv(uint32(InsufficientBalance.selector));
688694

689695
fromAddressData.balance = uint96(t.fromBalance -= amount);
690696
t.totalSupply = uint256($.totalSupply) - amount;
@@ -755,12 +761,12 @@ abstract contract DN404 {
755761
///
756762
/// Emits a {Transfer} event.
757763
function _transfer(address from, address to, uint256 amount) internal virtual {
758-
if (to == address(0)) revert TransferToZeroAddress();
764+
if (to == address(0)) _rv(uint32(TransferToZeroAddress.selector));
759765

760766
DN404Storage storage $ = _getDN404Storage();
761767
AddressData storage fromAddressData = $.addressData[from];
762768
AddressData storage toAddressData = $.addressData[to];
763-
if ($.mirrorERC721 == address(0)) revert DNNotInitialized();
769+
if ($.mirrorERC721 == address(0)) _rv(uint32(DNNotInitialized.selector));
764770

765771
_DNTransferTemps memory t;
766772
t.fromOwnedLength = fromAddressData.ownedLength;
@@ -769,7 +775,7 @@ abstract contract DN404 {
769775
unchecked {
770776
{
771777
uint256 fromBalance = fromAddressData.balance;
772-
if (amount > fromBalance) revert InsufficientBalance();
778+
if (amount > fromBalance) _rv(uint32(InsufficientBalance.selector));
773779
fromAddressData.balance = uint96(fromBalance -= amount);
774780

775781
uint256 toBalance = uint256(toAddressData.balance) + amount;
@@ -947,21 +953,21 @@ abstract contract DN404 {
947953
internal
948954
virtual
949955
{
950-
if (to == address(0)) revert TransferToZeroAddress();
956+
if (to == address(0)) _rv(uint32(TransferToZeroAddress.selector));
951957

952958
DN404Storage storage $ = _getDN404Storage();
953-
if ($.mirrorERC721 == address(0)) revert DNNotInitialized();
959+
if ($.mirrorERC721 == address(0)) _rv(uint32(DNNotInitialized.selector));
954960

955961
Uint32Map storage oo = $.oo;
956962

957963
if (from != $.aliasToAddress[_get(oo, _ownershipIndex(_restrictNFTId(id)))]) {
958-
revert TransferFromIncorrectOwner();
964+
_rv(uint32(TransferFromIncorrectOwner.selector));
959965
}
960966

961967
if (msgSender != from) {
962968
if (!_isApprovedForAll(from, msgSender)) {
963969
if (_getApproved(id) != msgSender) {
964-
revert TransferCallerNotOwnerNorApproved();
970+
_rv(uint32(TransferCallerNotOwnerNorApproved.selector));
965971
}
966972
}
967973
}
@@ -974,7 +980,7 @@ abstract contract DN404 {
974980

975981
unchecked {
976982
uint256 fromBalance = fromAddressData.balance;
977-
if (unit > fromBalance) revert InsufficientBalance();
983+
if (unit > fromBalance) _rv(uint32(InsufficientBalance.selector));
978984
fromAddressData.balance = uint96(fromBalance - unit);
979985
toAddressData.balance += uint96(unit);
980986
}
@@ -1144,7 +1150,7 @@ abstract contract DN404 {
11441150
/// Requirements:
11451151
/// - Token `id` must exist.
11461152
function _ownerOf(uint256 id) internal view virtual returns (address) {
1147-
if (!_exists(id)) revert TokenDoesNotExist();
1153+
if (!_exists(id)) _rv(uint32(TokenDoesNotExist.selector));
11481154
return _ownerAt(id);
11491155
}
11501156

@@ -1168,7 +1174,7 @@ abstract contract DN404 {
11681174
/// Requirements:
11691175
/// - Token `id` must exist.
11701176
function _getApproved(uint256 id) internal view virtual returns (address) {
1171-
if (!_exists(id)) revert TokenDoesNotExist();
1177+
if (!_exists(id)) _rv(uint32(TokenDoesNotExist.selector));
11721178
return _getDN404Storage().nftApprovals[id];
11731179
}
11741180

@@ -1187,7 +1193,7 @@ abstract contract DN404 {
11871193

11881194
if (msgSender != owner) {
11891195
if (!_isApprovedForAll(owner, msgSender)) {
1190-
revert ApprovalCallerNotOwnerNorApproved();
1196+
_rv(uint32(ApprovalCallerNotOwnerNorApproved.selector));
11911197
}
11921198
}
11931199

@@ -1240,7 +1246,7 @@ abstract contract DN404 {
12401246

12411247
// `transferFromNFT(address,address,uint256,address)`.
12421248
if (fnSelector == 0xe5eb36c8) {
1243-
if (msg.sender != $.mirrorERC721) revert SenderNotMirror();
1249+
if (msg.sender != $.mirrorERC721) _rv(uint32(SenderNotMirror.selector));
12441250
_transferFromNFT(
12451251
address(uint160(_calldataload(0x04))), // `from`.
12461252
address(uint160(_calldataload(0x24))), // `to`.
@@ -1251,7 +1257,7 @@ abstract contract DN404 {
12511257
}
12521258
// `setApprovalForAllNFT(address,bool,address)`.
12531259
if (fnSelector == 0xf6916ddd) {
1254-
if (msg.sender != $.mirrorERC721) revert SenderNotMirror();
1260+
if (msg.sender != $.mirrorERC721) _rv(uint32(SenderNotMirror.selector));
12551261
_setApprovalForAll(
12561262
address(uint160(_calldataload(0x04))), // `spender`.
12571263
_calldataload(0x24) != 0, // `status`.
@@ -1277,7 +1283,7 @@ abstract contract DN404 {
12771283
}
12781284
// `approveNFT(address,uint256,address)`.
12791285
if (fnSelector == 0xd10b6e0c) {
1280-
if (msg.sender != $.mirrorERC721) revert SenderNotMirror();
1286+
if (msg.sender != $.mirrorERC721) _rv(uint32(SenderNotMirror.selector));
12811287
address owner = _approveNFT(
12821288
address(uint160(_calldataload(0x04))), // `spender`.
12831289
_calldataload(0x24), // `id`.
@@ -1326,7 +1332,7 @@ abstract contract DN404 {
13261332
/// fallback with utilities like Solady's `LibZip.cdFallback()`.
13271333
/// And always remember to always wrap the fallback with `dn404Fallback`.
13281334
fallback() external payable virtual dn404Fallback {
1329-
revert FnSelectorNotRecognized(); // Not mandatory. Just for quality of life.
1335+
_rv(uint32(FnSelectorNotRecognized.selector)); // Not mandatory. Just for quality of life.
13301336
}
13311337

13321338
/// @dev This is to silence the compiler warning.
@@ -1787,4 +1793,13 @@ abstract contract DN404 {
17871793
return(0x00, 0x20)
17881794
}
17891795
}
1796+
1797+
/// @dev More bytecode-efficient way to revert.
1798+
function _rv(uint32 s) private pure {
1799+
/// @solidity memory-safe-assembly
1800+
assembly {
1801+
mstore(0x00, s)
1802+
revert(0x1c, 0x04)
1803+
}
1804+
}
17901805
}

src/DN404Mirror.sol

+15-6
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ contract DN404Mirror {
353353
/// @dev Returns the address of the base DN404 contract.
354354
function baseERC20() public view virtual returns (address base) {
355355
base = _getDN404NFTStorage().baseERC20;
356-
if (base == address(0)) revert NotLinked();
356+
if (base == address(0)) _revert(uint32(NotLinked.selector));
357357
}
358358

359359
/// @dev Fallback modifier to execute calls from the base DN404 contract.
@@ -364,7 +364,7 @@ contract DN404Mirror {
364364

365365
// `logTransfer(uint256[])`.
366366
if (fnSelector == 0x263c69d6) {
367-
if (msg.sender != $.baseERC20) revert SenderNotBase();
367+
if (msg.sender != $.baseERC20) _revert(uint32(SenderNotBase.selector));
368368
/// @solidity memory-safe-assembly
369369
assembly {
370370
let o := add(0x24, calldataload(0x04)) // Packed logs offset.
@@ -388,7 +388,7 @@ contract DN404Mirror {
388388
}
389389
// `logDirectTransfer(address,address,uint256[])`.
390390
if (fnSelector == 0x144027d3) {
391-
if (msg.sender != $.baseERC20) revert SenderNotBase();
391+
if (msg.sender != $.baseERC20) _revert(uint32(SenderNotBase.selector));
392392
/// @solidity memory-safe-assembly
393393
assembly {
394394
let from := calldataload(0x04)
@@ -406,10 +406,10 @@ contract DN404Mirror {
406406
if (fnSelector == 0x0f4599e5) {
407407
if ($.deployer != address(0)) {
408408
if (address(uint160(_calldataload(0x04))) != $.deployer) {
409-
revert SenderNotDeployer();
409+
_revert(uint32(SenderNotDeployer.selector));
410410
}
411411
}
412-
if ($.baseERC20 != address(0)) revert AlreadyLinked();
412+
if ($.baseERC20 != address(0)) _revert(uint32(AlreadyLinked.selector));
413413
$.baseERC20 = msg.sender;
414414
/// @solidity memory-safe-assembly
415415
assembly {
@@ -425,7 +425,7 @@ contract DN404Mirror {
425425
/// fallback with utilities like Solady's `LibZip.cdFallback()`.
426426
/// And always remember to always wrap the fallback with `dn404NFTFallback`.
427427
fallback() external payable virtual dn404NFTFallback {
428-
revert FnSelectorNotRecognized(); // Not mandatory. Just for quality of life.
428+
_revert(uint32(FnSelectorNotRecognized.selector)); // Not mandatory. Just for quality of life.
429429
}
430430

431431
/// @dev This is to silence the compiler warning.
@@ -506,6 +506,15 @@ contract DN404Mirror {
506506
}
507507
}
508508

509+
/// @dev More bytecode-efficient way to revert.
510+
function _revert(uint32 s) private pure {
511+
/// @solidity memory-safe-assembly
512+
assembly {
513+
mstore(0x00, s)
514+
revert(0x1c, 0x04)
515+
}
516+
}
517+
509518
/// @dev Perform a call to invoke {IERC721Receiver-onERC721Received} on `to`.
510519
/// Reverts if the target does not support the function correctly.
511520
function _checkOnERC721Received(address from, address to, uint256 id, bytes memory data)

0 commit comments

Comments
 (0)