hoodquidity/packages/contracts/lib/openzeppelin-contracts/test/utils/Memory.t.sol
Денис Зефиров dba2811447 Hoodquidity: liquidity campaigns for Robinhood Chain stock token markets
Full build: Vite/React acid-terminal frontend (BEARER design system,
Panchang/Sentient/Fragment Mono, neon layer, palette audit script),
HoodquidityVaults Foundry contracts (single+dual deposits via Chainlink-style
feeds, hybrid exit, 10% platform fee, boost, Genesis LP), Reown AppKit wallet
connect with Robinhood Chain testnet (46630), live data from Dexscreener and
onchain reads, partner portal, design-sync setup for claude.ai/design.

Deploy: static via Forgejo Actions platform, BUILD_DIR=apps/web/dist (.env).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 08:32:28 +04:00

90 lines
3.1 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Test} from "forge-std/Test.sol";
import {Bytes} from "@openzeppelin/contracts/utils/Bytes.sol";
import {Memory} from "@openzeppelin/contracts/utils/Memory.sol";
contract MemoryTest is Test {
using Bytes for *;
using Memory for *;
// - first 0x80 bytes are reserved (scratch + FMP + zero)
uint256 constant START_PTR = 0x80;
// - moving the free memory pointer to far causes OOG errors
uint256 constant END_PTR = type(uint24).max;
function testGetSetFreeMemoryPointer(uint256 seed) public pure {
bytes32 ptr = bytes32(bound(seed, START_PTR, END_PTR));
Memory.Pointer.wrap(ptr).unsafeSetFreeMemoryPointer();
assertEq(Memory.Pointer.unwrap(Memory.getFreeMemoryPointer()), ptr);
}
function testAsSliceToBytes(bytes memory input) public pure {
Memory.Slice slice = input.asSlice();
assertEq(slice.toBytes(), input);
assertTrue(slice.isReserved());
}
function testSlice(bytes memory input, uint256 offset) public pure {
offset = bound(offset, 0, input.length);
Memory.Slice slice = input.asSlice().slice(offset);
assertEq(slice.toBytes(), input.slice(offset));
assertTrue(slice.isReserved());
}
function testSlice(bytes memory input, uint256 offset, uint256 length) public pure {
offset = bound(offset, 0, input.length);
length = bound(length, 0, input.length - offset);
Memory.Slice slice = input.asSlice().slice(offset, length);
assertEq(slice.toBytes(), input.slice(offset, offset + length));
assertTrue(slice.isReserved());
}
function testInvalidSliceOutOfBound() public pure {
bytes memory input = new bytes(256);
Memory.Slice slice = input.asSlice();
assertTrue(slice.isReserved());
Memory.Slice sliceMoved;
assembly ("memory-safe") {
sliceMoved := add(slice, 0x01) // add 1 to the ptr part
}
assertFalse(sliceMoved.isReserved());
Memory.Slice sliceExtended;
assembly ("memory-safe") {
sliceExtended := add(slice, shl(128, 0x01)) // add 1 to the length part
}
assertFalse(sliceExtended.isReserved());
}
function testSymbolicEqual(bytes memory a, bytes memory b) public pure {
Memory.Slice sliceA = a.asSlice();
Memory.Slice sliceB = b.asSlice();
bool expected = keccak256(a) == keccak256(b);
assertEq(Memory.equal(sliceA, sliceB), expected);
}
function testEqual(
bytes memory a,
uint256 offsetA,
uint256 lengthA,
bytes memory b,
uint256 offsetB,
uint256 lengthB
) public pure {
offsetA = bound(offsetA, 0, a.length);
offsetB = bound(offsetB, 0, b.length);
lengthA = bound(lengthA, 0, a.length - offsetA);
lengthB = bound(lengthB, 0, b.length - offsetB);
assertEq(
a.asSlice().slice(offsetA, lengthA).equal(b.asSlice().slice(offsetB, lengthB)),
keccak256(a.slice(offsetA, offsetA + lengthA)) == keccak256(b.slice(offsetB, offsetB + lengthB))
);
}
}