Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit aae76b37e0397728ebd1a529a265da4f1dec23bc
Author: Ryan Hall <[email protected]>
Date:   Mon Sep 16 12:46:32 2024 -0400

    fix rebase issues

commit a74b43a8f7ccd3d49cb1dc93e3ba69e2e5343d57
Author: Rens Rooimans <[email protected]>
Date:   Mon Sep 16 11:57:15 2024 +0200

    rm VersionedConfig & emit version and config separate

commit db534f9ff05c150633ac7e94362120bd920f1506
Author: Rens Rooimans <[email protected]>
Date:   Mon Sep 16 11:39:04 2024 +0200

    update some tests

commit 3e86f2149229f7634c35224935dcb08b5ccbf945
Author: Rens Rooimans <[email protected]>
Date:   Mon Sep 16 10:57:45 2024 +0200

    use rawVs from report & fix tests

commit fbe12de74e142cff71c47109ee96be27de168cc4
Author: Rens Rooimans <[email protected]>
Date:   Fri Sep 13 12:55:27 2024 +0200

    demo
  • Loading branch information
RyanRHall committed Sep 16, 2024
1 parent cc636d4 commit f3454c4
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 157 deletions.
5 changes: 3 additions & 2 deletions contracts/src/v0.8/ccip/interfaces/IRMNV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ interface IRMNV2 {
function verify(
address offRampAddress,
Internal.MerkleRoot[] memory merkleRoots,
Signature[] memory signatures
Signature[] memory signatures,
uint256 rawVs
) external view;

/// @notice gets the current set of cursed subjects
Expand All @@ -32,6 +33,6 @@ interface IRMNV2 {

/// @notice If there is an active global curse, or an active curse for `subject`, this function returns true.
/// @param subject To check whether a particular chain is cursed, set to bytes16(uint128(chainSelector)).
/// @return bool true if the profived subject is cured *or* if there is an active global curse
/// @return bool true if the provided subject is cured *or* if there is an active global curse
function isCursed(bytes16 subject) external view returns (bool);
}
5 changes: 3 additions & 2 deletions contracts/src/v0.8/ccip/offRamp/OffRamp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base {
Internal.PriceUpdates priceUpdates; // Collection of gas and price updates to commit
Internal.MerkleRoot[] merkleRoots; // Collection of merkle roots per source chain to commit
IRMNV2.Signature[] rmnSignatures; // RMN signatures on the merkle roots
uint256 rmnRawVs; // Raw v values of the RMN signatures
}

struct GasLimitOverride {
Expand Down Expand Up @@ -778,13 +779,13 @@ contract OffRamp is ITypeAndVersion, MultiOCR3Base {
bytes calldata report,
bytes32[] calldata rs,
bytes32[] calldata ss,
bytes32 rawVs // signatures
bytes32 rawVs
) external {
CommitReport memory commitReport = abi.decode(report, (CommitReport));

// Verify RMN signatures
if (commitReport.merkleRoots.length > 0) {
i_rmn.verify(address(this), commitReport.merkleRoots, commitReport.rmnSignatures);
i_rmn.verify(address(this), commitReport.merkleRoots, commitReport.rmnSignatures, commitReport.rmnRawVs);
}

// Check if the report contains price updates
Expand Down
35 changes: 17 additions & 18 deletions contracts/src/v0.8/ccip/rmn/RMNRemote.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 {
error UnexpectedSigner();
error ZeroValueNotAllowed();

event ConfigSet(VersionedConfig versionedConfig);
event ConfigSet(uint32 indexed version, Config config);
event Cursed(bytes16[] subjects);
event Uncursed(bytes16[] subjects);

Expand All @@ -52,12 +52,6 @@ contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 {
uint64 minSigners; // Threshold for the number of signers required to verify a report
}

/// @dev the contract config + a version number
struct VersionedConfig {
uint32 version; // For tracking the version of the config
Config config; // The config
}

/// @dev part of the payload that RMN nodes sign: keccak256(abi.encode(RMN_V1_6_ANY2EVM_REPORT, report))
/// @dev this struct is only ever abi-encoded and hashed; it is never stored
struct Report {
Expand All @@ -69,15 +63,16 @@ contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 {
Internal.MerkleRoot[] merkleRoots; // The dest lane updates
}

Config s_config;
uint32 s_configCount;

string public constant override typeAndVersion = "RMNRemote 1.6.0-dev";
uint64 internal immutable i_localChainSelector;

/// @dev the set of cursed subjects
bytes16[] private s_cursedSubjects;
/// @dev the index+1 is stored to easily distinguish b/t noncursed and cursed at the 0 index

Config private s_config;
uint32 private s_configCount;

/// @dev the index+1 is stored to easily distinguish b/t non-cursed and cursed at the 0 index
mapping(bytes16 subject => uint256 indexPlusOne) private s_cursedSubjectsIndexPlusOne;
mapping(address signer => bool exists) private s_signers; // for more gas efficient verify

Expand All @@ -95,11 +90,13 @@ contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 {
function verify(
address offrampAddress,
Internal.MerkleRoot[] memory merkleRoots,
Signature[] memory signatures
Signature[] memory signatures,
uint256 rawVs
) external view {
if (s_configCount == 0) {
revert ConfigNotSet();
}
if (signatures.length < s_config.minSigners) revert ThresholdNotMet();

if (signatures.length < s_config.minSigners) revert ThresholdNotMet();

Expand All @@ -121,7 +118,8 @@ contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 {
address signerAddress;
for (uint256 i = 0; i < signatures.length; ++i) {
Signature memory sig = signatures[i];
signerAddress = ecrecover(digest, 27, sig.r, sig.s);
// The v value is bit-encoded into rawVs
signerAddress = ecrecover(digest, 27 + uint8(rawVs & 0x01 << i), sig.r, sig.s);
if (signerAddress == address(0)) revert InvalidSignature();
if (prevAddress >= signerAddress) revert OutOfOrderSignatures();
if (!s_signers[signerAddress]) revert UnexpectedSigner();
Expand Down Expand Up @@ -173,13 +171,14 @@ contract RMNRemote is OwnerIsCreator, ITypeAndVersion, IRMNV2 {

s_config = newConfig;
uint32 newConfigCount = ++s_configCount;
emit ConfigSet(VersionedConfig({version: newConfigCount, config: newConfig}));
emit ConfigSet(newConfigCount, newConfig);
}

/// @notice Returns the current configuration of the contract + a version number
/// @return versionedConfig the current configuration + version
function getVersionedConfig() external view returns (VersionedConfig memory) {
return VersionedConfig({version: s_configCount, config: s_config});
/// @notice Returns the current configuration of the contract and a version number
/// @return version the current configs version
/// @return config the current config
function getVersionedConfig() external view returns (uint32 version, Config memory config) {
return (s_configCount, s_config);
}

/// @notice Returns the chain selector configured at deployment time
Expand Down
9 changes: 7 additions & 2 deletions contracts/src/v0.8/ccip/test/e2e/MultiRampsEnd2End.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,12 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup {
merkleRoot: merkleRoots[1]
});

OffRamp.CommitReport memory report =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: rmnSignatures});
OffRamp.CommitReport memory report = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: rmnSignatures,
rmnRawVs: 0
});

vm.resumeGasMetering();
_commit(report, ++s_latestSequenceNumber);
Expand Down Expand Up @@ -269,6 +273,7 @@ contract MultiRampsE2E is OnRampSetup, OffRampSetup {

Internal.Any2EVMTokenTransfer[] memory any2EVMTokenTransfer =
new Internal.Any2EVMTokenTransfer[](message.tokenAmounts.length);

for (uint256 i = 0; i < msgEvent.tokenAmounts.length; ++i) {
any2EVMTokenTransfer[i] = Internal.Any2EVMTokenTransfer({
sourcePoolAddress: abi.encode(msgEvent.tokenAmounts[i].sourcePoolAddress),
Expand Down
91 changes: 66 additions & 25 deletions contracts/src/v0.8/ccip/test/offRamp/OffRamp.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,8 @@ contract OffRamp_executeSingleReport is OffRampSetup {
return OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});
}
}
Expand Down Expand Up @@ -3243,7 +3244,8 @@ contract OffRamp_applySourceChainConfigUpdates is OffRampSetup {
OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
}),
s_latestSequenceNumber
);
Expand Down Expand Up @@ -3296,8 +3298,12 @@ contract OffRamp_commit is OffRampSetup {
merkleRoot: root
});

OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
emit OffRamp.CommitReportAccepted(commitReport.merkleRoots, commitReport.priceUpdates);
Expand All @@ -3324,8 +3330,12 @@ contract OffRamp_commit is OffRampSetup {
maxSeqNr: maxSeq,
merkleRoot: "stale report 1"
});
OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
emit OffRamp.CommitReportAccepted(commitReport.merkleRoots, commitReport.priceUpdates);
Expand Down Expand Up @@ -3363,7 +3373,8 @@ contract OffRamp_commit is OffRampSetup {
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
Expand All @@ -3385,7 +3396,8 @@ contract OffRamp_commit is OffRampSetup {
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
Expand All @@ -3403,7 +3415,8 @@ contract OffRamp_commit is OffRampSetup {
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
Expand Down Expand Up @@ -3455,7 +3468,8 @@ contract OffRamp_commit is OffRampSetup {
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
Expand Down Expand Up @@ -3565,8 +3579,12 @@ contract OffRamp_commit is OffRampSetup {
onRampAddress: abi.encode(ON_RAMP_ADDRESS_1)
});

OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectRevert(abi.encodeWithSelector(OffRamp.CursedByRMN.selector, roots[0].sourceChainSelector));
_commit(commitReport, s_latestSequenceNumber);
Expand All @@ -3581,8 +3599,12 @@ contract OffRamp_commit is OffRampSetup {
maxSeqNr: 4,
merkleRoot: bytes32(0)
});
OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectRevert(OffRamp.InvalidRoot.selector);
_commit(commitReport, s_latestSequenceNumber);
Expand All @@ -3597,8 +3619,12 @@ contract OffRamp_commit is OffRampSetup {
maxSeqNr: 2,
merkleRoot: bytes32(0)
});
OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectRevert(
abi.encodeWithSelector(
Expand All @@ -3618,8 +3644,12 @@ contract OffRamp_commit is OffRampSetup {
maxSeqNr: 0,
merkleRoot: bytes32(0)
});
OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectRevert(
abi.encodeWithSelector(
Expand All @@ -3634,7 +3664,8 @@ contract OffRamp_commit is OffRampSetup {
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectRevert(OffRamp.StaleCommitReport.selector);
Expand All @@ -3646,7 +3677,8 @@ contract OffRamp_commit is OffRampSetup {
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectEmit();
Expand All @@ -3667,8 +3699,12 @@ contract OffRamp_commit is OffRampSetup {
merkleRoot: "Only a single root"
});

OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

vm.expectRevert(abi.encodeWithSelector(OffRamp.SourceChainNotEnabled.selector, 0));
_commit(commitReport, s_latestSequenceNumber);
Expand All @@ -3683,8 +3719,12 @@ contract OffRamp_commit is OffRampSetup {
maxSeqNr: 2,
merkleRoot: "Only a single root"
});
OffRamp.CommitReport memory commitReport =
OffRamp.CommitReport({priceUpdates: _getEmptyPriceUpdates(), merkleRoots: roots, rmnSignatures: s_rmnSignatures});
OffRamp.CommitReport memory commitReport = OffRamp.CommitReport({
priceUpdates: _getEmptyPriceUpdates(),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});

_commit(commitReport, s_latestSequenceNumber);
commitReport.merkleRoots[0].minSeqNr = 3;
Expand Down Expand Up @@ -3718,7 +3758,8 @@ contract OffRamp_commit is OffRampSetup {
return OffRamp.CommitReport({
priceUpdates: _getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18),
merkleRoots: roots,
rmnSignatures: s_rmnSignatures
rmnSignatures: s_rmnSignatures,
rmnRawVs: 0
});
}
}
Expand Down
Loading

0 comments on commit f3454c4

Please sign in to comment.