@@ -5,24 +5,25 @@ import {IAny2EVMMessageReceiver} from "../interfaces/IAny2EVMMessageReceiver.sol
55import {IAny2EVMMessageReceiverV2} from "../interfaces/IAny2EVMMessageReceiverV2.sol " ;
66import {ICrossChainVerifierResolver} from "../interfaces/ICrossChainVerifierResolver.sol " ;
77import {ICrossChainVerifierV1} from "../interfaces/ICrossChainVerifierV1.sol " ;
8+ import {CCVConfigValidation} from "../libraries/CCVConfigValidation.sol " ;
9+ import {Client} from "../libraries/Client.sol " ;
10+ import {ERC165CheckerReverting } from "../libraries/ERC165CheckerReverting.sol " ;
11+ import "../libraries/FinalityCodec.sol " ;
12+ import {IERC20 } from "@openzeppelin/contracts@5.3.0/token/ERC20/IERC20.sol " ;
13+ import {EnumerableSet} from "@openzeppelin/contracts@5.3.0/utils/structs/EnumerableSet.sol " ;
14+
815import {IPoolV1} from "../interfaces/IPool.sol " ;
916import {IPoolV2} from "../interfaces/IPoolV2.sol " ;
1017import {IRMNRemote} from "../interfaces/IRMNRemote.sol " ;
1118import {IRouter} from "../interfaces/IRouter.sol " ;
1219import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol " ;
20+ import {Internal} from "../libraries/Internal.sol " ;
1321import {ITypeAndVersion} from "@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol " ;
1422
15- import {CCVConfigValidation} from "../libraries/CCVConfigValidation.sol " ;
16- import {Client} from "../libraries/Client.sol " ;
17- import {ERC165CheckerReverting } from "../libraries/ERC165CheckerReverting.sol " ;
18- import {Internal} from "../libraries/Internal.sol " ;
1923import {MessageV1Codec} from "../libraries/MessageV1Codec.sol " ;
2024import {Pool} from "../libraries/Pool.sol " ;
2125import {Ownable2StepMsgSender} from "@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol " ;
2226
23- import {IERC20 } from "@openzeppelin/contracts@5.3.0/token/ERC20/IERC20.sol " ;
24- import {EnumerableSet} from "@openzeppelin/contracts@5.3.0/utils/structs/EnumerableSet.sol " ;
25-
2627contract OffRamp is ITypeAndVersion , Ownable2StepMsgSender {
2728 using ERC165CheckerReverting for address ;
2829 using EnumerableSet for EnumerableSet.UintSet;
@@ -44,7 +45,6 @@ contract OffRamp is ITypeAndVersion, Ownable2StepMsgSender {
4445 error SkippedAlreadyExecutedMessage (bytes32 messageId , uint64 sourceChainSelector , uint64 messageNumber );
4546 error ReentrancyGuardReentrantCall ();
4647 error RequiredCCVMissing (address requiredCCV );
47- error InvalidFinalityForReceiver (address receiver , uint16 msgBlockDepth , uint16 requiredBlockDepth );
4848 error InvalidNumberOfTokens (uint256 numTokens );
4949 error InvalidOnRamp (bytes got );
5050 error InvalidOffRamp (address expected , bytes got );
@@ -693,16 +693,16 @@ contract OffRamp is ITypeAndVersion, Ownable2StepMsgSender {
693693 bytes memory sender ,
694694 bytes2 messageRequestedFinality
695695 ) internal view returns (address [] memory requiredCCV , address [] memory optionalCCVs , uint8 optionalThreshold ) {
696- // Default block confirmations requirement is 0, which means "wait for finality". A receiver implementing
697- // IAny2EVMMessageReceiverV2 can return a different value.
696+ // Default finality config is 0, which means "wait for finality". A receiver implementing IAny2EVMMessageReceiverV2
697+ // can return a different value.
698698 // If the receiver does not support the V2 interface it cannot support FTF. This is to protect anyone not
699699 // explicitly opting in to support FTF from accidentally allowing messages with FTF finality to be executed.
700- uint16 minBlockConfirmations ;
700+ bytes2 receiverFinalityConfig = bytes2 ( 0 ) ;
701701
702702 // Only query for custom CCVs if the receiver supports the interface.
703703 if (receiver._supportsInterfaceReverting (type (IAny2EVMMessageReceiverV2).interfaceId)) {
704- (requiredCCV, optionalCCVs, optionalThreshold, minBlockConfirmations ) =
705- IAny2EVMMessageReceiverV2 (receiver).getCCVsAndMinBlockConfirmations (sourceChainSelector, sender);
704+ (requiredCCV, optionalCCVs, optionalThreshold, receiverFinalityConfig ) =
705+ IAny2EVMMessageReceiverV2 (receiver).getCCVsAndFinalityConfig (sourceChainSelector, sender);
706706
707707 CCVConfigValidation._assertNoDuplicates (requiredCCV);
708708 CCVConfigValidation._assertNoDuplicates (optionalCCVs);
@@ -713,18 +713,8 @@ contract OffRamp is ITypeAndVersion, Ownable2StepMsgSender {
713713 }
714714 }
715715
716- // If non-zero it means FTF is enabled. Ensure it follows the min requirements from the receiver.
717- uint16 requestedWire = uint16 (messageRequestedFinality);
718- if (requestedWire != 0 ) {
719- // If the receiver requires finality, but the msg is FTF, revert.
720- if (minBlockConfirmations == 0 ) {
721- revert InvalidFinalityForReceiver (receiver, requestedWire, minBlockConfirmations);
722- }
723- // If the receiver specified a minBlockConfirmations that is higher than the message requested block confirmations, revert.
724- if (minBlockConfirmations > requestedWire) {
725- revert InvalidFinalityForReceiver (receiver, requestedWire, minBlockConfirmations);
726- }
727- }
716+ // Check the finality requirement of the message against the allowed finality for the receiver.
717+ FinalityCodec._ensureRequestedFinalityAllowed (messageRequestedFinality, receiverFinalityConfig);
728718
729719 // If the receiver specified empty required and optional CCVs, we fall back to the default CCVs.
730720 // If they did specify something, we use what they specified.
@@ -742,6 +732,7 @@ contract OffRamp is ITypeAndVersion, Ownable2StepMsgSender {
742732 /// @param localToken The local token address.
743733 /// @param sourceChainSelector The source chain selector.
744734 /// @param amount The amount of the token to be released/minted.
735+ /// @param finality The finality requirement of the message (see `FinalityCodec`).
745736 /// @param extraData The extra data for the pool.
746737 /// @return requiredCCV The required CCVs.
747738 function _getCCVsFromPool (
0 commit comments