Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/abstract/ERC4626Extern.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ uint256 constant OPCODE_ERC4626_CONVERT_TO_ASSETS = 0;
uint256 constant OPCODE_ERC4626_CONVERT_TO_SHARES = 1;

uint256 constant OPCODE_FUNCTION_POINTERS_LENGTH = 2;
uint256 constant INTEGRITY_FUNCTION_POINTERS_LENGTH = 2;

/// @dev Wires the ERC-4626 convertToAssets/convertToShares words into a
/// Rainlang extern by providing the precomputed opcode and integrity function
Expand Down Expand Up @@ -44,7 +45,7 @@ abstract contract ERC4626Extern is BaseRainlangExtern {
function buildIntegrityFunctionPointers() external pure returns (bytes memory) {
function(OperandV2, uint256, uint256) internal pure returns (uint256, uint256)[] memory fs = new function(OperandV2, uint256, uint256)
internal
pure returns (uint256, uint256)[](OPCODE_FUNCTION_POINTERS_LENGTH);
pure returns (uint256, uint256)[](INTEGRITY_FUNCTION_POINTERS_LENGTH);
fs[OPCODE_ERC4626_CONVERT_TO_ASSETS] = LibOpERC4626ConvertToAssets.integrity;
fs[OPCODE_ERC4626_CONVERT_TO_SHARES] = LibOpERC4626ConvertToShares.integrity;

Expand Down
33 changes: 31 additions & 2 deletions test/src/concrete/ERC4626Words.indexAlignment.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {Test} from "forge-std-1.16.1/src/Test.sol";
import {
OPCODE_ERC4626_CONVERT_TO_ASSETS,
OPCODE_ERC4626_CONVERT_TO_SHARES,
OPCODE_FUNCTION_POINTERS_LENGTH
OPCODE_FUNCTION_POINTERS_LENGTH,
INTEGRITY_FUNCTION_POINTERS_LENGTH
} from "../../../src/abstract/ERC4626Extern.sol";
import {
SUB_PARSER_WORD_ERC4626_CONVERT_TO_ASSETS,
Expand Down Expand Up @@ -66,11 +67,39 @@ contract ERC4626WordsIndexAlignmentTest is Test {
function testIntegrityFunctionPointersByteLengthMatchesCount() external pure {
assertEq(
INTEGRITY_FUNCTION_POINTERS.length,
OPCODE_FUNCTION_POINTERS_LENGTH * 2,
INTEGRITY_FUNCTION_POINTERS_LENGTH * 2,
"INTEGRITY_FUNCTION_POINTERS must be exactly 2 bytes per opcode"
);
}

function testOpcodeTableSlotsNonZero() external pure {
bytes memory ptrs = OPCODE_FUNCTION_POINTERS;
uint256 assetsIdx = OPCODE_ERC4626_CONVERT_TO_ASSETS;
uint256 sharesIdx = OPCODE_ERC4626_CONVERT_TO_SHARES;
assertTrue(
ptrs[assetsIdx * 2] != 0 || ptrs[assetsIdx * 2 + 1] != 0,
"convert-to-assets opcode slot must have non-zero function pointer"
);
assertTrue(
ptrs[sharesIdx * 2] != 0 || ptrs[sharesIdx * 2 + 1] != 0,
"convert-to-shares opcode slot must have non-zero function pointer"
);
}

function testIntegrityTableSlotsNonZero() external pure {
bytes memory ptrs = INTEGRITY_FUNCTION_POINTERS;
uint256 assetsIdx = OPCODE_ERC4626_CONVERT_TO_ASSETS;
uint256 sharesIdx = OPCODE_ERC4626_CONVERT_TO_SHARES;
assertTrue(
ptrs[assetsIdx * 2] != 0 || ptrs[assetsIdx * 2 + 1] != 0,
"convert-to-assets integrity slot must have non-zero function pointer"
);
assertTrue(
ptrs[sharesIdx * 2] != 0 || ptrs[sharesIdx * 2 + 1] != 0,
"convert-to-shares integrity slot must have non-zero function pointer"
);
}

function testSubParserWordParsersByteLengthMatchesCount() external pure {
assertEq(
SUB_PARSER_WORD_PARSERS.length,
Expand Down
Loading