// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.15;
import {DSTestPlus} from "./utils/DSTestPlus.sol";
import {SSTORE2} from "../utils/SSTORE2.sol";
contract SSTORE2Test is DSTestPlus {
function testWriteRead() public {
bytes memory testBytes = abi.encode("this is a test");
address pointer = SSTORE2.write(testBytes);
assertBytesEq(SSTORE2.read(pointer), testBytes);
}
function testWriteReadFullStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 0), hex"11223344");
}
function testWriteReadCustomStartBound() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1), hex"223344");
}
function testWriteReadFullBoundedRead() public {
bytes memory testBytes = abi.encode("this is a test");
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), 0, testBytes.length), testBytes);
}
function testWriteReadCustomBounds() public {
assertBytesEq(SSTORE2.read(SSTORE2.write(hex"11223344"), 1, 3), hex"2233");
}
function testWriteReadEmptyBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 3, 3);
}
function testFailReadInvalidPointer() public view {
SSTORE2.read(DEAD_ADDRESS);
}
function testFailReadInvalidPointerCustomStartBound() public view {
SSTORE2.read(DEAD_ADDRESS, 1);
}
function testFailReadInvalidPointerCustomBounds() public view {
SSTORE2.read(DEAD_ADDRESS, 2, 4);
}
function testFailWriteReadOutOfStartBound() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000);
}
function testFailWriteReadEmptyOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 42000, 42000);
}
function testFailWriteReadOutOfBounds() public {
SSTORE2.read(SSTORE2.write(hex"11223344"), 41000, 42000);
}
function testWriteRead(bytes calldata testBytes, bytes calldata brutalizeWith)
public
brutalizeMemory(brutalizeWith)
{
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes)), testBytes);
}
function testWriteReadCustomStartBound(
bytes calldata testBytes,
uint256 startIndex,
bytes calldata brutalizeWith
) public brutalizeMemory(brutalizeWith) {
if (testBytes.length == 0) return;
startIndex = bound(startIndex, 0, testBytes.length);
assertBytesEq(SSTORE2.read(SSTORE2.write(testBytes), startIndex), bytes(testBytes[startIndex:]));
}
function testWriteReadCustomBounds(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex,
bytes calldata brutalizeWith
) public brutalizeMemory(brutalizeWith) {
if (testBytes.length == 0) return;
endIndex = bound(endIndex, 0, testBytes.length);
startIndex = bound(startIndex, 0, testBytes.length);
if (startIndex > endIndex) return;
assertBytesEq(
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex),
bytes(testBytes[startIndex:endIndex])
);
}
function testFailReadInvalidPointer(address pointer, bytes calldata brutalizeWith)
public
view
brutalizeMemory(brutalizeWith)
{
if (pointer.code.length > 0) revert();
SSTORE2.read(pointer);
}
function testFailReadInvalidPointerCustomStartBound(
address pointer,
uint256 startIndex,
bytes calldata brutalizeWith
) public view brutalizeMemory(brutalizeWith) {
if (pointer.code.length > 0) revert();
SSTORE2.read(pointer, startIndex);
}
function testFailReadInvalidPointerCustomBounds(
address pointer,
uint256 startIndex,
uint256 endIndex,
bytes calldata brutalizeWith
) public view brutalizeMemory(brutalizeWith) {
if (pointer.code.length > 0) revert();
SSTORE2.read(pointer, startIndex, endIndex);
}
function testFailWriteReadCustomStartBoundOutOfRange(
bytes calldata testBytes,
uint256 startIndex,
bytes calldata brutalizeWith
) public brutalizeMemory(brutalizeWith) {
startIndex = bound(startIndex, testBytes.length + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex);
}
function testFailWriteReadCustomBoundsOutOfRange(
bytes calldata testBytes,
uint256 startIndex,
uint256 endIndex,
bytes calldata brutalizeWith
) public brutalizeMemory(brutalizeWith) {
endIndex = bound(endIndex, testBytes.length + 1, type(uint256).max);
SSTORE2.read(SSTORE2.write(testBytes), startIndex, endIndex);
}
}