-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(world-modules): properly concat baseURI and tokenURI in ERC721 mo…
…dule (#2686) Co-authored-by: Fraser Scott <[email protected]> Co-authored-by: Kevin Ingersoll <[email protected]>
- Loading branch information
1 parent
08c5099
commit 78a94d7
Showing
4 changed files
with
100 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@latticexyz/world-modules": patch | ||
--- | ||
|
||
Fixed ERC721 module to properly encode token ID as part of token URI. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
packages/world-modules/src/modules/erc721-puppet/libraries/LibString.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.8.0; | ||
|
||
/// @notice Efficient library for creating string representations of integers. | ||
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) | ||
/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) | ||
library LibString { | ||
function toString(int256 value) internal pure returns (string memory str) { | ||
if (value >= 0) return toString(uint256(value)); | ||
|
||
unchecked { | ||
str = toString(uint256(-value)); | ||
|
||
/// @solidity memory-safe-assembly | ||
assembly { | ||
// Note: This is only safe because we over-allocate memory | ||
// and write the string from right to left in toString(uint256), | ||
// and thus can be sure that sub(str, 1) is an unused memory location. | ||
|
||
let length := mload(str) // Load the string length. | ||
// Put the - character at the start of the string contents. | ||
mstore(str, 45) // 45 is the ASCII code for the - character. | ||
str := sub(str, 1) // Move back the string pointer by a byte. | ||
mstore(str, add(length, 1)) // Update the string length. | ||
} | ||
} | ||
} | ||
|
||
function toString(uint256 value) internal pure returns (string memory str) { | ||
/// @solidity memory-safe-assembly | ||
assembly { | ||
// The maximum value of a uint256 contains 78 digits (1 byte per digit), but we allocate 160 bytes | ||
// to keep the free memory pointer word aligned. We'll need 1 word for the length, 1 word for the | ||
// trailing zeros padding, and 3 other words for a max of 78 digits. In total: 5 * 32 = 160 bytes. | ||
let newFreeMemoryPointer := add(mload(0x40), 160) | ||
|
||
// Update the free memory pointer to avoid overriding our string. | ||
mstore(0x40, newFreeMemoryPointer) | ||
|
||
// Assign str to the end of the zone of newly allocated memory. | ||
str := sub(newFreeMemoryPointer, 32) | ||
|
||
// Clean the last word of memory it may not be overwritten. | ||
mstore(str, 0) | ||
|
||
// Cache the end of the memory to calculate the length later. | ||
let end := str | ||
|
||
// We write the string from rightmost digit to leftmost digit. | ||
// The following is essentially a do-while loop that also handles the zero case. | ||
// prettier-ignore | ||
for { let temp := value } 1 {} { | ||
// Move the pointer 1 byte to the left. | ||
str := sub(str, 1) | ||
|
||
// Write the character to the pointer. | ||
// The ASCII index of the '0' character is 48. | ||
mstore8(str, add(48, mod(temp, 10))) | ||
|
||
// Keep dividing temp until zero. | ||
temp := div(temp, 10) | ||
|
||
// prettier-ignore | ||
if iszero(temp) { break } | ||
} | ||
|
||
// Compute and cache the final total length of the string. | ||
let length := sub(end, str) | ||
|
||
// Move the pointer 32 bytes leftwards to make room for the length. | ||
str := sub(str, 32) | ||
|
||
// Store the string's length at the start of memory allocated for our string. | ||
mstore(str, length) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters