Skip to content

Instantly share code, notes, and snippets.

@Philogy
Last active October 28, 2022 11:21
Show Gist options
  • Select an option

  • Save Philogy/3eefd64904116d695eb4ea1d47f7a5f9 to your computer and use it in GitHub Desktop.

Select an option

Save Philogy/3eefd64904116d695eb4ea1d47f7a5f9 to your computer and use it in GitHub Desktop.
Load dynamically sized string / byte-string from storage into memory
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import {Test} from "forge-std/Test.sol";
/// @author Philippe Dumonet <https://github.com/philogy>
contract StringTest is Test {
bytes str;
function testBytesLikeStorage(bytes memory _inputStr) public {
str = _inputStr;
bytes memory strInMem;
assembly {
let slot := sload(str.slot)
let len := shr(1, and(slot, 0xff))
strInMem := mload(0x40)
mstore(strInMem, len)
let initialStrOffset := add(strInMem, 0x20)
let paddedLen := and(add(len, 0x1f), 0xffffffffffffffe0)
mstore(0x40, add(initialStrOffset, paddedLen))
switch gt(len, 31)
case 0 {
mstore(
initialStrOffset,
and(not(shr(shl(3, len), not(0))), slot)
)
}
case 1 {
mstore(0x00, str.slot)
let strDataSlot := keccak256(0x00, 0x20)
for {
let i := 0
} lt(i, paddedLen) {
i := add(i, 0x20)
} {
mstore(
add(i, initialStrOffset),
sload(add(strDataSlot, shr(5, i)))
)
}
}
}
assertEq(strInMem.length, str.length);
assertEq(strInMem, str);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment