Skip to content
Open
35 changes: 35 additions & 0 deletions test/src/concrete/FlareFtsoWords.pointers.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ import {
} from "src/concrete/FlareFtsoWords.sol";
import {LibGenParseMeta} from "rain-interpreter-interface-0.1.0/src/lib/codegen/LibGenParseMeta.sol";
import {LibFlareFtsoSubParser} from "src/lib/parse/LibFlareFtsoSubParser.sol";
import {BYTECODE_HASH} from "src/generated/FlareFtsoWords.pointers.sol";
import {
SUB_PARSER_WORD_FTSO_CURRENT_PRICE_USD,
SUB_PARSER_WORD_FTSO_CURRENT_PRICE_PAIR,
SUB_PARSER_WORD_SFLR_EXCHANGE_RATE,
SUB_PARSER_WORD_PARSERS_LENGTH
} from "src/lib/parse/LibFlareFtsoSubParser.sol";
import {
OPCODE_FTSO_CURRENT_PRICE_USD,
OPCODE_FTSO_CURRENT_PRICE_PAIR,
OPCODE_SLFR_CURRENT_EXCHANGE_RATE,
OPCODE_FUNCTION_POINTERS_LENGTH
} from "src/abstract/FlareFtsoExtern.sol";

contract FlareFtsoWordsPointersTest is Test {
function testIntegrityPointers() external {
Expand Down Expand Up @@ -42,4 +55,26 @@ contract FlareFtsoWordsPointersTest is Test {
bytes memory expected = LibGenParseMeta.buildParseMetaV2(authoringMeta, 2);
assertEq(SUB_PARSER_PARSE_META, expected);
}

/// #63 — committed BYTECODE_HASH is verified against the actual compiled contract
/// so any bytecode drift (optimizer change, solc bump, library edit) fires CI red.
function testBytecodeHash() external {
FlareFtsoWords flareFtsoWords = new FlareFtsoWords();
assertEq(address(flareFtsoWords).codehash, BYTECODE_HASH, "BYTECODE_HASH drifted from compiled bytecode");
}

/// #64 — both index-constant sets must agree element-for-element; any reorder
/// in either file that breaks the pairing is caught without a fork or RPC.
function testWordOpcodeIndicesAligned() external pure {
assertEq(SUB_PARSER_WORD_FTSO_CURRENT_PRICE_USD, OPCODE_FTSO_CURRENT_PRICE_USD);
assertEq(SUB_PARSER_WORD_FTSO_CURRENT_PRICE_PAIR, OPCODE_FTSO_CURRENT_PRICE_PAIR);
assertEq(SUB_PARSER_WORD_SFLR_EXCHANGE_RATE, OPCODE_SLFR_CURRENT_EXCHANGE_RATE);
assertEq(SUB_PARSER_WORD_PARSERS_LENGTH, OPCODE_FUNCTION_POINTERS_LENGTH);

bytes memory authoringMetaBytes = LibFlareFtsoSubParser.authoringMetaV2();
AuthoringMetaV2[] memory meta = abi.decode(authoringMetaBytes, (AuthoringMetaV2[]));
assertEq(meta[OPCODE_FTSO_CURRENT_PRICE_USD].word, bytes32("ftso-current-price-usd"));
assertEq(meta[OPCODE_FTSO_CURRENT_PRICE_PAIR].word, bytes32("ftso-current-price-pair"));
assertEq(meta[OPCODE_SLFR_CURRENT_EXCHANGE_RATE].word, bytes32("sflr-exchange-rate"));
}
}
9 changes: 9 additions & 0 deletions test/src/lib/flreth/LibDineroFlrEth.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@ contract LibDineroFlrEthTest is Test {
uint256 rate18 = LibDineroFlrEth.getFLRETHPerETH18();
assertEq(rate18, 0.989103076939285809e18);
}

/// #62 — asserts getETHPerFLRETH18 and getFLRETHPerETH18 are reciprocals of each
/// other within 0.1%. An inverted direction mapping between LSTPerToken /
/// tokensPerLST and the wrappers would produce a product far from 1e36.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
function testRatesAreReciprocal() external view {
uint256 ethPerFlreth = LibDineroFlrEth.getETHPerFLRETH18();
uint256 flrethPerEth = LibDineroFlrEth.getFLRETHPerETH18();
assertApproxEqRel(ethPerFlreth * flrethPerEth, 1e36, 1e15);
}
}
Loading