Skip to content
This repository was archived by the owner on Mar 14, 2025. It is now read-only.

Commit 9350c6b

Browse files
authored
Merge a0dfd3a into 75b1a6f
2 parents 75b1a6f + a0dfd3a commit 9350c6b

File tree

20 files changed

+372
-50
lines changed

20 files changed

+372
-50
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@chainlink/contracts': patch
3+
---
4+
5+
#feature adds OZ AccessControl support to the registry module
6+
7+
8+
PR issue: CCIP-4105
9+
10+
Solidity Review issue: CCIP-3966
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@chainlink/contracts': patch
3+
---
4+
5+
Refactor MockCCIPRouter to support EVMExtraArgsV2
6+
7+
PR issue : CCIP-4288

contracts/foundry.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ test = 'src/v0.8/transmission/test'
9595
optimizer_runs = 1_000_000
9696
src = 'src/v0.8/shared'
9797
test = 'src/v0.8/shared/test'
98-
solc_version = '0.8.19'
98+
solc_version = '0.8.24'
9999

100100

101101
# See more config options https://github.com/foundry-rs/foundry/tree/master/config

contracts/gas-snapshots/ccip.gas-snapshot

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,14 @@ MerkleMultiProofTest:test_EmptyLeaf_Revert() (gas: 3585)
482482
MerkleMultiProofTest:test_MerkleRoot256() (gas: 394891)
483483
MerkleMultiProofTest:test_MerkleRootSingleLeaf_Success() (gas: 3661)
484484
MerkleMultiProofTest:test_SpecSync_gas() (gas: 34129)
485+
MockRouterTest:test_ccipSendWithEVMExtraArgsV1_Success() (gas: 110073)
486+
MockRouterTest:test_ccipSendWithEVMExtraArgsV2_Success() (gas: 132614)
485487
MockRouterTest:test_ccipSendWithInsufficientNativeTokens_Revert() (gas: 34037)
486-
MockRouterTest:test_ccipSendWithInvalidMsgValue_Revert() (gas: 60842)
487-
MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126576)
488-
MockRouterTest:test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() (gas: 63455)
489-
MockRouterTest:test_ccipSendWithSufficientNativeFeeTokens_Success() (gas: 44012)
488+
MockRouterTest:test_ccipSendWithInvalidEVMExtraArgs_Revert() (gas: 106684)
489+
MockRouterTest:test_ccipSendWithInvalidMsgValue_Revert() (gas: 60886)
490+
MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126640)
491+
MockRouterTest:test_ccipSendWithLinkFeeTokenButInsufficientAllowance_Revert() (gas: 63478)
492+
MockRouterTest:test_ccipSendWithSufficientNativeFeeTokens_Success() (gas: 44048)
490493
MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigsBothLanes_Success() (gas: 133528)
491494
MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_MultipleConfigs_Success() (gas: 315630)
492495
MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_OnlyCallableByOwner_Revert() (gas: 17864)
@@ -917,11 +920,13 @@ RateLimiter_consume:test_TokenRateLimitReached_Revert() (gas: 24886)
917920
RateLimiter_currentTokenBucketState:test_CurrentTokenBucketState_Success() (gas: 38944)
918921
RateLimiter_currentTokenBucketState:test_Refill_Success() (gas: 46849)
919922
RateLimiter_setTokenBucketConfig:test_SetRateLimiterConfig_Success() (gas: 38506)
920-
RegistryModuleOwnerCustom_constructor:test_constructor_Revert() (gas: 36033)
921-
RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Revert() (gas: 19739)
922-
RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Success() (gas: 130086)
923-
RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Revert() (gas: 19559)
924-
RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Success() (gas: 129905)
923+
RegistryModuleOwnerCustom_constructor:test_constructor_Revert() (gas: 36107)
924+
RegistryModuleOwnerCustom_registerAccessControlDefaultAdmin:test_registerAccessControlDefaultAdmin_Revert() (gas: 20206)
925+
RegistryModuleOwnerCustom_registerAccessControlDefaultAdmin:test_registerAccessControlDefaultAdmin_Success() (gas: 130628)
926+
RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Revert() (gas: 19773)
927+
RegistryModuleOwnerCustom_registerAdminViaGetCCIPAdmin:test_registerAdminViaGetCCIPAdmin_Success() (gas: 130108)
928+
RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Revert() (gas: 19593)
929+
RegistryModuleOwnerCustom_registerAdminViaOwner:test_registerAdminViaOwner_Success() (gas: 129927)
925930
Router_applyRampUpdates:test_OffRampMismatch_Revert() (gas: 89366)
926931
Router_applyRampUpdates:test_OffRampUpdatesWithRouting() (gas: 10662612)
927932
Router_applyRampUpdates:test_OnRampDisable() (gas: 56007)

contracts/gas-snapshots/shared.gas-snapshot

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_AddAndRemove_Success() (gas: 125205)
2-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyAdd_Success() (gas: 133100)
3-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyCallableByOwner_Revert() (gas: 12350)
4-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyRemove_Success() (gas: 45064)
5-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_RemoveThenAdd_Success() (gas: 57241)
6-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_SkipRemove_Success() (gas: 32121)
7-
AuthorizedCallers_applyAuthorizedCallerUpdates:test_ZeroAddressNotAllowed_Revert() (gas: 64473)
8-
AuthorizedCallers_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 64473)
9-
AuthorizedCallers_constructor:test_constructor_Success() (gas: 720513)
1+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_AddAndRemove_Success() (gas: 125022)
2+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyAdd_Success() (gas: 132980)
3+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyCallableByOwner_Revert() (gas: 12356)
4+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_OnlyRemove_Success() (gas: 45007)
5+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_RemoveThenAdd_Success() (gas: 57121)
6+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_SkipRemove_Success() (gas: 32064)
7+
AuthorizedCallers_applyAuthorizedCallerUpdates:test_ZeroAddressNotAllowed_Revert() (gas: 64440)
8+
AuthorizedCallers_constructor:test_ZeroAddressNotAllowed_Revert() (gas: 64440)
9+
AuthorizedCallers_constructor:test_constructor_Success() (gas: 704809)
1010
BurnMintERC677_approve:testApproveSuccess() (gas: 55512)
1111
BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10663)
12-
BurnMintERC677_burn:testBasicBurnSuccess() (gas: 173939)
12+
BurnMintERC677_burn:testBasicBurnSuccess() (gas: 172100)
1313
BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 47201)
1414
BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 21841)
1515
BurnMintERC677_burn:testSenderNotBurnerReverts() (gas: 13359)
@@ -21,7 +21,7 @@ BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 57949)
2121
BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 35880)
2222
BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 21869)
2323
BurnMintERC677_burnFromAlias:testSenderNotBurnerReverts() (gas: 13379)
24-
BurnMintERC677_constructor:testConstructorSuccess() (gas: 1672809)
24+
BurnMintERC677_constructor:testConstructorSuccess() (gas: 1672812)
2525
BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 31069)
2626
BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 121324)
2727
BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 53460)
@@ -34,14 +34,14 @@ BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11195)
3434
BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 12476)
3535
BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10639)
3636
BurnMintERC677_transfer:testTransferSuccess() (gas: 42299)
37-
CallWithExactGas__callWithExactGas:test_CallWithExactGasReceiverErrorSuccess() (gas: 67209)
37+
CallWithExactGas__callWithExactGas:test_CallWithExactGasReceiverErrorSuccess() (gas: 65949)
3838
CallWithExactGas__callWithExactGas:test_CallWithExactGasSafeReturnDataExactGas() (gas: 18324)
3939
CallWithExactGas__callWithExactGas:test_NoContractReverts() (gas: 11559)
4040
CallWithExactGas__callWithExactGas:test_NoGasForCallExactCheckReverts() (gas: 15788)
4141
CallWithExactGas__callWithExactGas:test_NotEnoughGasForCallReverts() (gas: 16241)
4242
CallWithExactGas__callWithExactGas:test_callWithExactGasSuccess(bytes,bytes4) (runs: 256, μ: 15766, ~: 15719)
4343
CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractExactGasSuccess() (gas: 20116)
44-
CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 67721)
44+
CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractReceiverErrorSuccess() (gas: 66461)
4545
CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_CallWithExactGasEvenIfTargetIsNoContractSuccess(bytes,bytes4) (runs: 256, μ: 16276, ~: 16229)
4646
CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoContractSuccess() (gas: 12962)
4747
CallWithExactGas__callWithExactGasEvenIfTargetIsNoContract:test_NoGasForCallExactCheckReturnFalseSuccess() (gas: 13005)
@@ -75,20 +75,28 @@ EnumerableMapAddresses_tryGet:testBytes32TryGetSuccess() (gas: 94622)
7575
EnumerableMapAddresses_tryGet:testBytesTryGetSuccess() (gas: 96279)
7676
EnumerableMapAddresses_tryGet:testTryGetSuccess() (gas: 94893)
7777
OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1743649)
78-
OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 298649)
78+
OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 291393)
7979
OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957)
8080
OpStackBurnMintERC677_interfaceCompatibility:testStaticFunctionsCompatibility() (gas: 13781)
8181
OpStackBurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 12752)
82-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySubset_Reverts() (gas: 5460)
83-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySuperset_Reverts() (gas: 4661)
84-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_HasDuplicates_Reverts() (gas: 8265)
85-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_NotASubset_Reverts() (gas: 12487)
86-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubset() (gas: 4489)
82+
Ownable2Step_acceptOwnership:test_acceptOwnership_MustBeProposedOwner_reverts() (gas: 10360)
83+
Ownable2Step_acceptOwnership:test_acceptOwnership_success() (gas: 31088)
84+
Ownable2Step_constructor:test_constructor_OwnerCannotBeZero_reverts() (gas: 35858)
85+
Ownable2Step_constructor:test_constructor_success() (gas: 10428)
86+
Ownable2Step_onlyOwner:test_onlyOwner_OnlyCallableByOwner_reverts() (gas: 10754)
87+
Ownable2Step_onlyOwner:test_onlyOwner_success() (gas: 7506)
88+
Ownable2Step_transferOwnership:test_transferOwnership_CannotTransferToSelf_reverts() (gas: 10501)
89+
Ownable2Step_transferOwnership:test_transferOwnership_success() (gas: 30140)
90+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySubset_Reverts() (gas: 5208)
91+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_EmptySuperset_Reverts() (gas: 4535)
92+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_HasDuplicates_Reverts() (gas: 7761)
93+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_NotASubset_Reverts() (gas: 11668)
94+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubset() (gas: 3922)
8795
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_Equal() (gas: 1464)
8896
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SingleElementSubsetAndSuperset_NotEqual_Reverts() (gas: 6172)
89-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetEqualsSuperset_NoRevert() (gas: 8867)
90-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetLargerThanSuperset_Reverts() (gas: 16544)
91-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SupersetHasDuplicates_Reverts() (gas: 9420)
92-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSubset_Reverts() (gas: 7380)
93-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSuperset_Reverts() (gas: 9600)
94-
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_ValidSubset_Success() (gas: 6490)
97+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetEqualsSuperset_NoRevert() (gas: 7859)
98+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SubsetLargerThanSuperset_Reverts() (gas: 15410)
99+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_SupersetHasDuplicates_Reverts() (gas: 8790)
100+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSubset_Reverts() (gas: 7128)
101+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_UnsortedSuperset_Reverts() (gas: 8970)
102+
SortedSetValidationUtil_CheckIsValidUniqueSubsetTest:test__checkIsValidUniqueSubset_ValidSubset_Success() (gas: 5671)

contracts/src/v0.8/ccip/test/mocks/MockRouter.sol

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,21 @@ contract MockCCIPRouter is IRouter, IRouterClient {
119119
return mockMsgId;
120120
}
121121

122-
function _fromBytes(bytes calldata extraArgs) internal pure returns (Client.EVMExtraArgsV1 memory) {
122+
function _fromBytes(
123+
bytes calldata extraArgs
124+
) internal pure returns (Client.EVMExtraArgsV2 memory) {
123125
if (extraArgs.length == 0) {
124-
return Client.EVMExtraArgsV1({gasLimit: DEFAULT_GAS_LIMIT});
126+
return Client.EVMExtraArgsV2({gasLimit: DEFAULT_GAS_LIMIT, allowOutOfOrderExecution: false});
125127
}
126-
if (bytes4(extraArgs) != Client.EVM_EXTRA_ARGS_V1_TAG) revert InvalidExtraArgsTag();
127-
return abi.decode(extraArgs[4:], (Client.EVMExtraArgsV1));
128+
129+
bytes4 extraArgsTag = bytes4(extraArgs);
130+
if (extraArgsTag == Client.EVM_EXTRA_ARGS_V2_TAG) {
131+
return abi.decode(extraArgs[4:], (Client.EVMExtraArgsV2));
132+
} else if (extraArgsTag == Client.EVM_EXTRA_ARGS_V1_TAG) {
133+
return Client.EVMExtraArgsV2({gasLimit: abi.decode(extraArgs[4:], (uint256)), allowOutOfOrderExecution: false});
134+
}
135+
136+
revert InvalidExtraArgsTag();
128137
}
129138

130139
/// @notice Always returns true to make sure this check can be performed on any chain.

contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ contract MockRouterTest is TokenSetup {
4949
mockRouter.ccipSend{value: 0.1 ether}(mockChainSelector, message);
5050
}
5151

52-
function test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() public {
52+
function test_ccipSendWithLinkFeeTokenButInsufficientAllowance_Revert() public {
5353
message.feeToken = s_sourceFeeToken;
5454

5555
vm.expectRevert(bytes("ERC20: insufficient allowance"));
@@ -65,4 +65,24 @@ contract MockRouterTest is TokenSetup {
6565

6666
mockRouter.ccipSend(mockChainSelector, message);
6767
}
68+
69+
function test_ccipSendWithEVMExtraArgsV1_Success() public {
70+
Client.EVMExtraArgsV1 memory extraArgs = Client.EVMExtraArgsV1({gasLimit: 500_000});
71+
message.extraArgs = Client._argsToBytes(extraArgs);
72+
mockRouter.ccipSend{value: 0.1 ether}(mockChainSelector, message);
73+
}
74+
75+
function test_ccipSendWithEVMExtraArgsV2_Success() public {
76+
Client.EVMExtraArgsV2 memory extraArgs = Client.EVMExtraArgsV2({gasLimit: 500_000, allowOutOfOrderExecution: true});
77+
message.extraArgs = Client._argsToBytes(extraArgs);
78+
mockRouter.ccipSend{value: 0.1 ether}(mockChainSelector, message);
79+
}
80+
81+
function test_ccipSendWithInvalidEVMExtraArgs_Revert() public {
82+
uint256 gasLimit = 500_000;
83+
bytes4 invalidExtraArgsTag = bytes4(keccak256("CCIP EVMExtraArgsInvalid"));
84+
message.extraArgs = abi.encodeWithSelector(invalidExtraArgsTag, gasLimit);
85+
vm.expectRevert(MockCCIPRouter.InvalidExtraArgsTag.selector);
86+
mockRouter.ccipSend{value: 0.1 ether}(mockChainSelector, message);
87+
}
6888
}

contracts/src/v0.8/ccip/test/tokenAdminRegistry/RegistryModuleOwnerCustom.t.sol

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {RegistryModuleOwnerCustom} from "../../tokenAdminRegistry/RegistryModule
88
import {TokenAdminRegistry} from "../../tokenAdminRegistry/TokenAdminRegistry.sol";
99
import {BurnMintERC677Helper} from "../helpers/BurnMintERC677Helper.sol";
1010

11+
import {AccessControl} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/access/AccessControl.sol";
1112
import {Test} from "forge-std/Test.sol";
1213

1314
contract RegistryModuleOwnerCustomSetup is Test {
@@ -102,3 +103,54 @@ contract RegistryModuleOwnerCustom_registerAdminViaOwner is RegistryModuleOwnerC
102103
s_registryModuleOwnerCustom.registerAdminViaOwner(s_token);
103104
}
104105
}
106+
107+
contract AccessController is AccessControl {
108+
constructor(
109+
address admin
110+
) {
111+
_grantRole(DEFAULT_ADMIN_ROLE, admin);
112+
}
113+
}
114+
115+
contract RegistryModuleOwnerCustom_registerAccessControlDefaultAdmin is RegistryModuleOwnerCustomSetup {
116+
function setUp() public override {
117+
super.setUp();
118+
119+
s_token = address(new AccessController(OWNER));
120+
}
121+
122+
function test_registerAccessControlDefaultAdmin_Success() public {
123+
assertEq(s_tokenAdminRegistry.getTokenConfig(s_token).administrator, address(0));
124+
125+
bytes32 defaultAdminRole = AccessController(s_token).DEFAULT_ADMIN_ROLE();
126+
127+
vm.expectCall(address(s_token), abi.encodeWithSelector(AccessControl.hasRole.selector, defaultAdminRole, OWNER), 1);
128+
vm.expectCall(
129+
address(s_tokenAdminRegistry),
130+
abi.encodeWithSelector(TokenAdminRegistry.proposeAdministrator.selector, s_token, OWNER),
131+
1
132+
);
133+
134+
vm.expectEmit();
135+
emit RegistryModuleOwnerCustom.AdministratorRegistered(s_token, OWNER);
136+
137+
s_registryModuleOwnerCustom.registerAccessControlDefaultAdmin(s_token);
138+
139+
assertEq(s_tokenAdminRegistry.getTokenConfig(s_token).pendingAdministrator, OWNER);
140+
}
141+
142+
function test_registerAccessControlDefaultAdmin_Revert() public {
143+
bytes32 defaultAdminRole = AccessController(s_token).DEFAULT_ADMIN_ROLE();
144+
145+
address wrongSender = makeAddr("Not_expected_owner");
146+
vm.startPrank(wrongSender);
147+
148+
vm.expectRevert(
149+
abi.encodeWithSelector(
150+
RegistryModuleOwnerCustom.RequiredRoleNotFound.selector, wrongSender, defaultAdminRole, s_token
151+
)
152+
);
153+
154+
s_registryModuleOwnerCustom.registerAccessControlDefaultAdmin(s_token);
155+
}
156+
}

contracts/src/v0.8/ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ import {IGetCCIPAdmin} from "../interfaces/IGetCCIPAdmin.sol";
66
import {IOwner} from "../interfaces/IOwner.sol";
77
import {ITokenAdminRegistry} from "../interfaces/ITokenAdminRegistry.sol";
88

9+
import {AccessControl} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/access/AccessControl.sol";
10+
911
contract RegistryModuleOwnerCustom is ITypeAndVersion {
1012
error CanOnlySelfRegister(address admin, address token);
13+
error RequiredRoleNotFound(address msgSender, bytes32 role, address token);
1114
error AddressZero();
1215

1316
event AdministratorRegistered(address indexed token, address indexed administrator);
1417

15-
string public constant override typeAndVersion = "RegistryModuleOwnerCustom 1.5.0";
18+
string public constant override typeAndVersion = "RegistryModuleOwnerCustom 1.6.0";
1619

1720
// The TokenAdminRegistry contract
1821
ITokenAdminRegistry internal immutable i_tokenAdminRegistry;
@@ -38,6 +41,20 @@ contract RegistryModuleOwnerCustom is ITypeAndVersion {
3841
_registerAdmin(token, IOwner(token).owner());
3942
}
4043

44+
/// @notice Registers the admin of the token using OZ's AccessControl DEFAULT_ADMIN_ROLE.
45+
/// @param token The token to register the admin for.
46+
/// @dev The caller must have the DEFAULT_ADMIN_ROLE as defined by the contract itself.
47+
function registerAccessControlDefaultAdmin(
48+
address token
49+
) external {
50+
bytes32 defaultAdminRole = AccessControl(token).DEFAULT_ADMIN_ROLE();
51+
if (!AccessControl(token).hasRole(defaultAdminRole, msg.sender)) {
52+
revert RequiredRoleNotFound(msg.sender, defaultAdminRole, token);
53+
}
54+
55+
_registerAdmin(token, msg.sender);
56+
}
57+
4158
/// @notice Registers the admin of the token to msg.sender given that the
4259
/// admin is equal to msg.sender.
4360
/// @param token The token to register the admin for.

contracts/src/v0.8/shared/access/AuthorizedCallers.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: BUSL-1.1
2-
pragma solidity ^0.8.0;
2+
pragma solidity ^0.8.4;
33

44
import {OwnerIsCreator} from "./OwnerIsCreator.sol";
55
import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol";

0 commit comments

Comments
 (0)