Skip to content

Commit

Permalink
Fix packing?
Browse files Browse the repository at this point in the history
  • Loading branch information
ernestognw committed Jun 10, 2024
1 parent 905cc40 commit 038e2dc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 35 deletions.
42 changes: 17 additions & 25 deletions scripts/generate/templates/Packing.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ pragma solidity ^0.8.20;
/**
* @dev Helper library packing and unpacking multiple values into bytesXX.
*
*
* Example usage:
*
*
* \`\`\`solidity
* library MyPacker {
* type MyType is bytes32;
Expand All @@ -36,40 +36,32 @@ pragma solidity ^0.8.20;
`;

const errors = `\
error OutOfRangeAccess();
`;
error OutOfRangeAccess();`;

const pack = (left, right) => `\
function pack_${left}_${right}(bytes${left} left, bytes${right} right) internal pure returns (bytes${
left + right
} result) {
const pack = (left, right) => `
function pack_${left}_${right}(bytes${left} left, bytes${right} right) internal pure returns (bytes${
left + right
} result) {
assembly ("memory-safe") {
result := or(left, shr(${8 * left}, right))
result := or(left, shr(${8 * left}, right))
}
}
`;
}`;

const extract = (outer, inner) => `\
function extract_${outer}_${inner}(bytes${outer} self, uint8 offset) internal pure returns (bytes${inner} result) {
const extract = (outer, inner) => `
function extract_${outer}_${inner}(bytes${outer} self, uint8 offset) internal pure returns (bytes${inner} result) {
if (offset > ${outer - inner}) revert OutOfRangeAccess();
assembly ("memory-safe") {
result := and(shl(mul(8, offset), self), shl(${256 - 8 * inner}, not(0)))
result := and(shl(mul(8, offset), self), shl(${256 - 8 * inner}, not(0)))
}
}
`;
}`;

const replace = (outer, inner) => `\
function replace_${outer}_${inner}(
bytes${outer} self,
bytes${inner} value,
uint8 offset
) internal pure returns (bytes${outer} result) {
const replace = (outer, inner) => `
function replace_${outer}_${inner}(bytes${outer} self, bytes${inner} value, uint8 offset) internal pure returns (bytes${outer} result) {
bytes${inner} oldValue = extract_${outer}_${inner}(self, offset);
assembly ("memory-safe") {
result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
result := xor(self, shr(mul(8, offset), xor(oldValue, value)))
}
}
`;
}`;

// GENERATE
module.exports = format(
Expand Down
18 changes: 8 additions & 10 deletions scripts/generate/templates/Packing.t.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,28 @@ import {Test} from "forge-std/Test.sol";
import {Packing} from "@openzeppelin/contracts/utils/Packing.sol";
`;

const testPack = (left, right) => `\
function testPack(bytes${left} left, bytes${right} right) external {
const testPack = (left, right) => `
function testPack(bytes${left} left, bytes${right} right) external {
assertEq(left, Packing.pack_${left}_${right}(left, right).extract_${left + right}_${left}(0));
assertEq(right, Packing.pack_${left}_${right}(left, right).extract_${left + right}_${right}(${left}));
}
`;
}`;

const testReplace = (outer, inner) => `\
function testReplace(bytes${outer} container, bytes${inner} newValue, uint8 offset) external {
const testReplace = (outer, inner) => `
function testReplace(bytes${outer} container, bytes${inner} newValue, uint8 offset) external {
offset = uint8(bound(offset, 0, ${outer - inner}));
bytes${inner} oldValue = container.extract_${outer}_${inner}(offset);
assertEq(newValue, container.replace_${outer}_${inner}(newValue, offset).extract_${outer}_${inner}(offset));
assertEq(container, container.replace_${outer}_${inner}(newValue, offset).replace_${outer}_${inner}(oldValue, offset));
}
`;
}`;

// GENERATE
module.exports = format(
header.trimEnd(),
'contract PackingTest is Test {',
'using Packing for *;',
'',
'contract PackingTest is Test {',
' using Packing for *;',
product(SIZES, SIZES)
.filter(([left, right]) => SIZES.includes(left + right))
.map(([left, right]) => testPack(left, right)),
Expand Down

0 comments on commit 038e2dc

Please sign in to comment.