diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol index 6136f4cf1..e9c330a3b 100644 --- a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol +++ b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721.sol @@ -15,7 +15,6 @@ import { import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; // modules import { @@ -103,14 +102,26 @@ abstract contract LSP8CompatibleERC721 is ) public view virtual returns (string memory) { bytes memory data = _getData(_LSP4_METADATA_KEY); - // offset = bytes4(hashSig) + bytes32(contentHash) -> 4 + 32 = 36 - uint256 offset = 36; + if (data.length <= 36) { + return ""; + } - bytes memory uriBytes = BytesLib.slice( - data, - offset, - data.length - offset - ); + uint256 requiredLength = data.length - 36; + bytes memory uriBytes; + // solhint-disable-next-line no-inline-assembly + assembly { + uriBytes := mload(0x40) + mstore(uriBytes, requiredLength) + for { + let i := 0 + } lt(i, requiredLength) { + i := add(i, 32) + } { + mstore(add(uriBytes, add(i, 32)), mload(add(data, add(i, 68)))) + } + // Update the free memory pointer + mstore(0x40, add(uriBytes, add(32, requiredLength))) + } return string(uriBytes); } diff --git a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol index 851a0e361..305d678e0 100644 --- a/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol +++ b/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CompatibleERC721InitAbstract.sol @@ -15,7 +15,6 @@ import { import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; // modules import { @@ -111,14 +110,26 @@ abstract contract LSP8CompatibleERC721InitAbstract is ) public view virtual returns (string memory) { bytes memory data = _getData(_LSP4_METADATA_KEY); - // offset = bytes4(hashSig) + bytes32(contentHash) -> 4 + 32 = 36 - uint256 offset = 36; + if (data.length <= 36) { + return ""; + } - bytes memory uriBytes = BytesLib.slice( - data, - offset, - data.length - offset - ); + uint256 requiredLength = data.length - 36; + bytes memory uriBytes; + // solhint-disable-next-line no-inline-assembly + assembly { + uriBytes := mload(0x40) + mstore(uriBytes, requiredLength) + for { + let i := 0 + } lt(i, requiredLength) { + i := add(i, 32) + } { + mstore(add(uriBytes, add(i, 32)), mload(add(data, add(i, 68)))) + } + // Update the free memory pointer + mstore(0x40, add(uriBytes, add(32, requiredLength))) + } return string(uriBytes); }