diff --git a/.gitignore b/.gitignore index eb8d6cc39b7..cded8f7c19b 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ typechain-types/ .tmp .cache +.idea diff --git a/.solhint.json b/.solhint.json index 36f9346be3b..906ebb3dcaf 100644 --- a/.solhint.json +++ b/.solhint.json @@ -1,9 +1,22 @@ { "extends": "solhint:recommended", - "plugins": ["prettier"], + "plugins": ["prettier", "chainlink-solidity"], "rules": { "prettier/prettier": "error", - "compiler-version": ["error", ">=0.4.0"], - "func-visibility": ["warn", { "ignoreConstructors": true }] + "compiler-version": ["error", ">=0.4.24"], + "const-name-snakecase": "off", + "constructor-syntax": "error", + "var-name-mixedcase": "off", + "func-named-parameters": "off", + "immutable-vars-naming": "off", + "no-inline-assembly": "off", + "no-unused-import": "error", + "func-visibility": ["error", { "ignoreConstructors": true }], + "quotes": ["error", "double"], + "reason-string": ["warn", { "maxLength": 64 }], + "chainlink-solidity/prefix-internal-functions-with-underscore": "warn", + "chainlink-solidity/prefix-private-functions-with-underscore": "warn", + "chainlink-solidity/prefix-storage-variables-with-s-underscore": "warn", + "chainlink-solidity/prefix-immutable-variables-with-i": "warn" } } diff --git a/package-lock.json b/package-lock.json index 8529da29e8a..0d126ec9739 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,6 +67,7 @@ "prettier-plugin-solidity": "^1.1.3", "rehype-autolink-headings": "^6.1.1", "solhint": "^3.6.2", + "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git", "solhint-plugin-prettier": "^0.0.5", "ts-jest": "^29.1.1", "tsconfig-paths": "^4.2.0", @@ -21838,6 +21839,12 @@ "prettier": "^2.8.3" } }, + "node_modules/solhint-plugin-chainlink-solidity": { + "name": "@chainlink/solhint-plugin-chainlink-solidity", + "version": "1.0.1", + "resolved": "git+ssh://git@github.com/smartcontractkit/chainlink-solhint-rules.git#6229ce5d3cc3e4a2454411bebc887c5ca240dcf2", + "dev": true + }, "node_modules/solhint-plugin-prettier": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz", @@ -41032,6 +41039,11 @@ } } }, + "solhint-plugin-chainlink-solidity": { + "version": "git+ssh://git@github.com/smartcontractkit/chainlink-solhint-rules.git#6229ce5d3cc3e4a2454411bebc887c5ca240dcf2", + "dev": true, + "from": "solhint-plugin-chainlink-solidity@git+https://github.com/smartcontractkit/chainlink-solhint-rules.git" + }, "solhint-plugin-prettier": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/solhint-plugin-prettier/-/solhint-plugin-prettier-0.0.5.tgz", diff --git a/package.json b/package.json index 7b05b046960..dbf62caf2df 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "lint:fix": "eslint --fix . ", "lint-ts": "eslint --ext ts .", "lint-ts:fix": "eslint --ext ts .", - "lint-solc": "solhint 'public/samples/**/*.sol'", + "lint-solc": "solhint --max-warnings 266 'public/samples/**/*.sol'", "prepare": "husky install", "test": "jest", "typecheck": "tsc --noEmit" @@ -87,6 +87,7 @@ "rehype-autolink-headings": "^6.1.1", "solhint": "^3.6.2", "solhint-plugin-prettier": "^0.0.5", + "solhint-plugin-chainlink-solidity": "git+https://github.com/smartcontractkit/chainlink-solhint-rules.git", "ts-jest": "^29.1.1", "tsconfig-paths": "^4.2.0", "typescript": "^5.2.2" diff --git a/public/samples/Automation/UpkeepIDConsumerExamplev1.sol b/public/samples/Automation/UpkeepIDConsumerExamplev1.sol index 08cc01cdbf7..077507343f4 100644 --- a/public/samples/Automation/UpkeepIDConsumerExamplev1.sol +++ b/public/samples/Automation/UpkeepIDConsumerExamplev1.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.6; // UpkeepIDConsumerExamplev1.sol imports functions from both ./AutomationRegistryInterface1_2.sol and // ./interfaces/LinkTokenInterface.sol -import {AutomationRegistryInterface, State, Config} from "@chainlink/contracts/src/v0.8/automation/interfaces/v1_2/AutomationRegistryInterface1_2.sol"; +import {AutomationRegistryInterface, State} from "@chainlink/contracts/src/v0.8/automation/interfaces/v1_2/AutomationRegistryInterface1_2.sol"; import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; /** diff --git a/public/samples/CCIP/Messenger.sol b/public/samples/CCIP/Messenger.sol index e428a451810..fce999697e4 100644 --- a/public/samples/CCIP/Messenger.sol +++ b/public/samples/CCIP/Messenger.sol @@ -6,7 +6,6 @@ import {OwnerIsCreator} from "@chainlink/contracts-ccip/src/v0.8/shared/access/O import {Client} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol"; import {CCIPReceiver} from "@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol"; import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; -import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. @@ -20,9 +19,9 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { error NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees); // Used to make sure contract has enough balance. error NothingToWithdraw(); // Used when trying to withdraw Ether but there's nothing to withdraw. error FailedToWithdrawEth(address owner, address target, uint256 value); // Used when the withdrawal of Ether fails. - error DestinationChainNotWhitelisted(uint64 destinationChainSelector); // Used when the destination chain has not been whitelisted by the contract owner. - error SourceChainNotWhitelisted(uint64 sourceChainSelector); // Used when the source chain has not been whitelisted by the contract owner. - error SenderNotWhitelisted(address sender); // Used when the sender has not been whitelisted by the contract owner. + error DestinationChainNotAllowlisted(uint64 destinationChainSelector); // Used when the destination chain has not been allowlisted by the contract owner. + error SourceChainNotAllowlisted(uint64 sourceChainSelector); // Used when the source chain has not been allowlisted by the contract owner. + error SenderNotAllowlisted(address sender); // Used when the sender has not been allowlisted by the contract owner. // Event emitted when a message is sent to another chain. event MessageSent( @@ -42,98 +41,64 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { string text // The text that was received. ); - bytes32 private lastReceivedMessageId; // Store the last received messageId. - string private lastReceivedText; // Store the last received text. + bytes32 private s_lastReceivedMessageId; // Store the last received messageId. + string private s_lastReceivedText; // Store the last received text. - // Mapping to keep track of whitelisted destination chains. - mapping(uint64 => bool) public whitelistedDestinationChains; + // Mapping to keep track of allowlisted destination chains. + mapping(uint64 => bool) public allowlistedDestinationChains; - // Mapping to keep track of whitelisted source chains. - mapping(uint64 => bool) public whitelistedSourceChains; + // Mapping to keep track of allowlisted source chains. + mapping(uint64 => bool) public allowlistedSourceChains; - // Mapping to keep track of whitelisted senders. - mapping(address => bool) public whitelistedSenders; + // Mapping to keep track of allowlisted senders. + mapping(address => bool) public allowlistedSenders; - LinkTokenInterface linkToken; + IERC20 private s_linkToken; /// @notice Constructor initializes the contract with the router address. /// @param _router The address of the router contract. /// @param _link The address of the link contract. constructor(address _router, address _link) CCIPReceiver(_router) { - linkToken = LinkTokenInterface(_link); + s_linkToken = IERC20(_link); } - /// @dev Modifier that checks if the chain with the given destinationChainSelector is whitelisted. + /// @dev Modifier that checks if the chain with the given destinationChainSelector is allowlisted. /// @param _destinationChainSelector The selector of the destination chain. - modifier onlyWhitelistedDestinationChain(uint64 _destinationChainSelector) { - if (!whitelistedDestinationChains[_destinationChainSelector]) - revert DestinationChainNotWhitelisted(_destinationChainSelector); + modifier onlyAllowlistedDestinationChain(uint64 _destinationChainSelector) { + if (!allowlistedDestinationChains[_destinationChainSelector]) + revert DestinationChainNotAllowlisted(_destinationChainSelector); _; } - /// @dev Modifier that checks if the chain with the given sourceChainSelector is whitelisted. + /// @dev Modifier that checks if the chain with the given sourceChainSelector is allowlisted and if the sender is allowlisted. /// @param _sourceChainSelector The selector of the destination chain. - modifier onlyWhitelistedSourceChain(uint64 _sourceChainSelector) { - if (!whitelistedSourceChains[_sourceChainSelector]) - revert SourceChainNotWhitelisted(_sourceChainSelector); - _; - } - - /// @dev Modifier that checks if the chain with the given sourceChainSelector is whitelisted. /// @param _sender The address of the sender. - modifier onlyWhitelistedSenders(address _sender) { - if (!whitelistedSenders[_sender]) revert SenderNotWhitelisted(_sender); + modifier onlyAllowlisted(uint64 _sourceChainSelector, address _sender) { + if (!allowlistedSourceChains[_sourceChainSelector]) + revert SourceChainNotAllowlisted(_sourceChainSelector); + if (!allowlistedSenders[_sender]) revert SenderNotAllowlisted(_sender); _; } - /// @dev Whitelists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _destinationChainSelector The selector of the destination chain to be whitelisted. - function whitelistDestinationChain( - uint64 _destinationChainSelector - ) external onlyOwner { - whitelistedDestinationChains[_destinationChainSelector] = true; - } - - /// @dev Denylists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _destinationChainSelector The selector of the destination chain to be denylisted. - function denylistDestinationChain( - uint64 _destinationChainSelector - ) external onlyOwner { - whitelistedDestinationChains[_destinationChainSelector] = false; - } - - /// @dev Whitelists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _sourceChainSelector The selector of the source chain to be whitelisted. - function whitelistSourceChain( - uint64 _sourceChainSelector + /// @dev Updates the allowlist status of a destination chain for transactions. + function allowlistDestinationChain( + uint64 _destinationChainSelector, + bool allowed ) external onlyOwner { - whitelistedSourceChains[_sourceChainSelector] = true; + allowlistedDestinationChains[_destinationChainSelector] = allowed; } - /// @dev Denylists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _sourceChainSelector The selector of the source chain to be denylisted. - function denylistSourceChain( - uint64 _sourceChainSelector + /// @dev Updates the allowlist status of a source chain for transactions. + function allowlistSourceChain( + uint64 _sourceChainSelector, + bool allowed ) external onlyOwner { - whitelistedSourceChains[_sourceChainSelector] = false; + allowlistedSourceChains[_sourceChainSelector] = allowed; } - /// @dev Whitelists a sender. - /// @notice This function can only be called by the owner. - /// @param _sender The address of the sender. - function whitelistSender(address _sender) external onlyOwner { - whitelistedSenders[_sender] = true; - } - - /// @dev Denylists a sender. - /// @notice This function can only be called by the owner. - /// @param _sender The address of the sender. - function denySender(address _sender) external onlyOwner { - whitelistedSenders[_sender] = false; + /// @dev Updates the allowlist status of a sender for transactions. + function allowlistSender(address _sender, bool allowed) external onlyOwner { + allowlistedSenders[_sender] = allowed; } /// @notice Sends data to receiver on the destination chain. @@ -150,14 +115,14 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { ) external onlyOwner - onlyWhitelistedDestinationChain(_destinationChainSelector) + onlyAllowlistedDestinationChain(_destinationChainSelector) returns (bytes32 messageId) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message Client.EVM2AnyMessage memory evm2AnyMessage = _buildCCIPMessage( _receiver, _text, - address(linkToken) + address(s_linkToken) ); // Initialize a router client instance to interact with cross-chain router @@ -166,11 +131,11 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { // Get the fee required to send the CCIP message uint256 fees = router.getFee(_destinationChainSelector, evm2AnyMessage); - if (fees > linkToken.balanceOf(address(this))) - revert NotEnoughBalance(linkToken.balanceOf(address(this)), fees); + if (fees > s_linkToken.balanceOf(address(this))) + revert NotEnoughBalance(s_linkToken.balanceOf(address(this)), fees); // approve the Router to transfer LINK tokens on contract's behalf. It will spend the fees in LINK - linkToken.approve(address(router), fees); + s_linkToken.approve(address(router), fees); // Send the CCIP message through the router and store the returned CCIP message ID messageId = router.ccipSend(_destinationChainSelector, evm2AnyMessage); @@ -181,7 +146,7 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { _destinationChainSelector, _receiver, _text, - address(linkToken), + address(s_linkToken), fees ); @@ -203,7 +168,7 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { ) external onlyOwner - onlyWhitelistedDestinationChain(_destinationChainSelector) + onlyAllowlistedDestinationChain(_destinationChainSelector) returns (bytes32 messageId) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message @@ -248,11 +213,13 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { ) internal override - onlyWhitelistedSourceChain(any2EvmMessage.sourceChainSelector) // Make sure source chain is whitelisted - onlyWhitelistedSenders(abi.decode(any2EvmMessage.sender, (address))) // Make sure the sender is whitelisted + onlyAllowlisted( + any2EvmMessage.sourceChainSelector, + abi.decode(any2EvmMessage.sender, (address)) + ) // Make sure source chain and sender are allowlisted { - lastReceivedMessageId = any2EvmMessage.messageId; // fetch the messageId - lastReceivedText = abi.decode(any2EvmMessage.data, (string)); // abi-decoding of the sent text + s_lastReceivedMessageId = any2EvmMessage.messageId; // fetch the messageId + s_lastReceivedText = abi.decode(any2EvmMessage.data, (string)); // abi-decoding of the sent text emit MessageReceived( any2EvmMessage.messageId, @@ -274,18 +241,18 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { address _feeTokenAddress ) internal pure returns (Client.EVM2AnyMessage memory) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message - Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({ - receiver: abi.encode(_receiver), // ABI-encoded receiver address - data: abi.encode(_text), // ABI-encoded string - tokenAmounts: new Client.EVMTokenAmount[](0), // Empty array aas no tokens are transferred - extraArgs: Client._argsToBytes( - // Additional arguments, setting gas limit and non-strict sequencing mode - Client.EVMExtraArgsV1({gasLimit: 200_000, strict: false}) - ), - // Set the feeToken to a feeTokenAddress, indicating specific asset will be used for fees - feeToken: _feeTokenAddress - }); - return evm2AnyMessage; + return + Client.EVM2AnyMessage({ + receiver: abi.encode(_receiver), // ABI-encoded receiver address + data: abi.encode(_text), // ABI-encoded string + tokenAmounts: new Client.EVMTokenAmount[](0), // Empty array aas no tokens are transferred + extraArgs: Client._argsToBytes( + // Additional arguments, setting gas limit and non-strict sequencing mode + Client.EVMExtraArgsV1({gasLimit: 200_000, strict: false}) + ), + // Set the feeToken to a feeTokenAddress, indicating specific asset will be used for fees + feeToken: _feeTokenAddress + }); } /// @notice Fetches the details of the last received message. @@ -296,7 +263,7 @@ contract Messenger is CCIPReceiver, OwnerIsCreator { view returns (bytes32 messageId, string memory text) { - return (lastReceivedMessageId, lastReceivedText); + return (s_lastReceivedMessageId, s_lastReceivedText); } /// @notice Fallback function to allow the contract to receive Ether. diff --git a/public/samples/CCIP/ProgrammableTokenTransfers.sol b/public/samples/CCIP/ProgrammableTokenTransfers.sol index 29292156900..3a027af95ec 100644 --- a/public/samples/CCIP/ProgrammableTokenTransfers.sol +++ b/public/samples/CCIP/ProgrammableTokenTransfers.sol @@ -6,7 +6,6 @@ import {OwnerIsCreator} from "@chainlink/contracts-ccip/src/v0.8/shared/access/O import {Client} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol"; import {CCIPReceiver} from "@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol"; import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; -import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. @@ -20,9 +19,9 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { error NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees); // Used to make sure contract has enough balance to cover the fees. error NothingToWithdraw(); // Used when trying to withdraw Ether but there's nothing to withdraw. error FailedToWithdrawEth(address owner, address target, uint256 value); // Used when the withdrawal of Ether fails. - error DestinationChainNotWhitelisted(uint64 destinationChainSelector); // Used when the destination chain has not been whitelisted by the contract owner. - error SourceChainNotWhitelisted(uint64 sourceChainSelector); // Used when the source chain has not been whitelisted by the contract owner. - error SenderNotWhitelisted(address sender); // Used when the sender has not been whitelisted by the contract owner. + error DestinationChainNotAllowed(uint64 destinationChainSelector); // Used when the destination chain has not been allowlisted by the contract owner. + error SourceChainNotAllowed(uint64 sourceChainSelector); // Used when the source chain has not been allowlisted by the contract owner. + error SenderNotAllowed(address sender); // Used when the sender has not been allowlisted by the contract owner. // Event emitted when a message is sent to another chain. event MessageSent( @@ -46,100 +45,75 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { uint256 tokenAmount // The token amount that was transferred. ); - bytes32 private lastReceivedMessageId; // Store the last received messageId. - address private lastReceivedTokenAddress; // Store the last received token address. - uint256 private lastReceivedTokenAmount; // Store the last received amount. - string private lastReceivedText; // Store the last received text. + bytes32 private s_lastReceivedMessageId; // Store the last received messageId. + address private s_lastReceivedTokenAddress; // Store the last received token address. + uint256 private s_lastReceivedTokenAmount; // Store the last received amount. + string private s_lastReceivedText; // Store the last received text. - // Mapping to keep track of whitelisted destination chains. - mapping(uint64 => bool) public whitelistedDestinationChains; + // Mapping to keep track of allowlisted destination chains. + mapping(uint64 => bool) public allowlistedDestinationChains; - // Mapping to keep track of whitelisted source chains. - mapping(uint64 => bool) public whitelistedSourceChains; + // Mapping to keep track of allowlisted source chains. + mapping(uint64 => bool) public allowlistedSourceChains; - // Mapping to keep track of whitelisted senders. - mapping(address => bool) public whitelistedSenders; + // Mapping to keep track of allowlisted senders. + mapping(address => bool) public allowlistedSenders; - LinkTokenInterface linkToken; + IERC20 private s_linkToken; /// @notice Constructor initializes the contract with the router address. /// @param _router The address of the router contract. /// @param _link The address of the link contract. constructor(address _router, address _link) CCIPReceiver(_router) { - linkToken = LinkTokenInterface(_link); + s_linkToken = IERC20(_link); } - /// @dev Modifier that checks if the chain with the given destinationChainSelector is whitelisted. + /// @dev Modifier that checks if the chain with the given destinationChainSelector is allowlisted. /// @param _destinationChainSelector The selector of the destination chain. - modifier onlyWhitelistedDestinationChain(uint64 _destinationChainSelector) { - if (!whitelistedDestinationChains[_destinationChainSelector]) - revert DestinationChainNotWhitelisted(_destinationChainSelector); + modifier onlyAllowlistedDestinationChain(uint64 _destinationChainSelector) { + if (!allowlistedDestinationChains[_destinationChainSelector]) + revert DestinationChainNotAllowed(_destinationChainSelector); _; } - /// @dev Modifier that checks if the chain with the given sourceChainSelector is whitelisted. + /// @dev Modifier that checks if the chain with the given sourceChainSelector is allowlisted and if the sender is allowlisted. /// @param _sourceChainSelector The selector of the destination chain. - modifier onlyWhitelistedSourceChain(uint64 _sourceChainSelector) { - if (!whitelistedSourceChains[_sourceChainSelector]) - revert SourceChainNotWhitelisted(_sourceChainSelector); - _; - } - - /// @dev Modifier that checks if the chain with the given sourceChainSelector is whitelisted. /// @param _sender The address of the sender. - modifier onlyWhitelistedSenders(address _sender) { - if (!whitelistedSenders[_sender]) revert SenderNotWhitelisted(_sender); + modifier onlyAllowlisted(uint64 _sourceChainSelector, address _sender) { + if (!allowlistedSourceChains[_sourceChainSelector]) + revert SourceChainNotAllowed(_sourceChainSelector); + if (!allowlistedSenders[_sender]) revert SenderNotAllowed(_sender); _; } - /// @dev Whitelists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _destinationChainSelector The selector of the destination chain to be whitelisted. - function whitelistDestinationChain( - uint64 _destinationChainSelector - ) external onlyOwner { - whitelistedDestinationChains[_destinationChainSelector] = true; - } - - /// @dev Denylists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _destinationChainSelector The selector of the destination chain to be denylisted. - function denylistDestinationChain( - uint64 _destinationChainSelector - ) external onlyOwner { - whitelistedDestinationChains[_destinationChainSelector] = false; - } - - /// @dev Whitelists a chain for transactions. + /// @dev Updates the allowlist status of a destination chain for transactions. /// @notice This function can only be called by the owner. - /// @param _sourceChainSelector The selector of the source chain to be whitelisted. - function whitelistSourceChain( - uint64 _sourceChainSelector + /// @param _destinationChainSelector The selector of the destination chain to be updated. + /// @param allowed The allowlist status to be set for the destination chain. + function allowlistDestinationChain( + uint64 _destinationChainSelector, + bool allowed ) external onlyOwner { - whitelistedSourceChains[_sourceChainSelector] = true; + allowlistedDestinationChains[_destinationChainSelector] = allowed; } - /// @dev Denylists a chain for transactions. + /// @dev Updates the allowlist status of a source chain /// @notice This function can only be called by the owner. - /// @param _sourceChainSelector The selector of the source chain to be denylisted. - function denylistSourceChain( - uint64 _sourceChainSelector + /// @param _sourceChainSelector The selector of the source chain to be updated. + /// @param allowed The allowlist status to be set for the source chain. + function allowlistSourceChain( + uint64 _sourceChainSelector, + bool allowed ) external onlyOwner { - whitelistedSourceChains[_sourceChainSelector] = false; + allowlistedSourceChains[_sourceChainSelector] = allowed; } - /// @dev Whitelists a sender. + /// @dev Updates the allowlist status of a sender for transactions. /// @notice This function can only be called by the owner. - /// @param _sender The address of the sender. - function whitelistSender(address _sender) external onlyOwner { - whitelistedSenders[_sender] = true; - } - - /// @dev Denylists a sender. - /// @notice This function can only be called by the owner. - /// @param _sender The address of the sender. - function denySender(address _sender) external onlyOwner { - whitelistedSenders[_sender] = false; + /// @param _sender The address of the sender to be updated. + /// @param allowed The allowlist status to be set for the sender. + function allowlistSender(address _sender, bool allowed) external onlyOwner { + allowlistedSenders[_sender] = allowed; } /// @notice Sends data and transfer tokens to receiver on the destination chain. @@ -160,7 +134,7 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { ) external onlyOwner - onlyWhitelistedDestinationChain(_destinationChainSelector) + onlyAllowlistedDestinationChain(_destinationChainSelector) returns (bytes32 messageId) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message @@ -170,7 +144,7 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { _text, _token, _amount, - address(linkToken) + address(s_linkToken) ); // Initialize a router client instance to interact with cross-chain router @@ -179,11 +153,11 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { // Get the fee required to send the CCIP message uint256 fees = router.getFee(_destinationChainSelector, evm2AnyMessage); - if (fees > linkToken.balanceOf(address(this))) - revert NotEnoughBalance(linkToken.balanceOf(address(this)), fees); + if (fees > s_linkToken.balanceOf(address(this))) + revert NotEnoughBalance(s_linkToken.balanceOf(address(this)), fees); // approve the Router to transfer LINK tokens on contract's behalf. It will spend the fees in LINK - linkToken.approve(address(router), fees); + s_linkToken.approve(address(router), fees); // approve the Router to spend tokens on contract's behalf. It will spend the amount of the given token IERC20(_token).approve(address(router), _amount); @@ -199,7 +173,7 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { _text, _token, _amount, - address(linkToken), + address(s_linkToken), fees ); @@ -225,7 +199,7 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { ) external onlyOwner - onlyWhitelistedDestinationChain(_destinationChainSelector) + onlyAllowlistedDestinationChain(_destinationChainSelector) returns (bytes32 messageId) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message @@ -291,10 +265,10 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { ) { return ( - lastReceivedMessageId, - lastReceivedText, - lastReceivedTokenAddress, - lastReceivedTokenAmount + s_lastReceivedMessageId, + s_lastReceivedText, + s_lastReceivedTokenAddress, + s_lastReceivedTokenAmount ); } @@ -304,14 +278,16 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { ) internal override - onlyWhitelistedSourceChain(any2EvmMessage.sourceChainSelector) // Make sure source chain is whitelisted - onlyWhitelistedSenders(abi.decode(any2EvmMessage.sender, (address))) // Make sure the sender is whitelisted + onlyAllowlisted( + any2EvmMessage.sourceChainSelector, + abi.decode(any2EvmMessage.sender, (address)) + ) // Make sure source chain and sender are allowlisted { - lastReceivedMessageId = any2EvmMessage.messageId; // fetch the messageId - lastReceivedText = abi.decode(any2EvmMessage.data, (string)); // abi-decoding of the sent text + s_lastReceivedMessageId = any2EvmMessage.messageId; // fetch the messageId + s_lastReceivedText = abi.decode(any2EvmMessage.data, (string)); // abi-decoding of the sent text // Expect one token to be transferred at once, but you can transfer several tokens. - lastReceivedTokenAddress = any2EvmMessage.destTokenAmounts[0].token; - lastReceivedTokenAmount = any2EvmMessage.destTokenAmounts[0].amount; + s_lastReceivedTokenAddress = any2EvmMessage.destTokenAmounts[0].token; + s_lastReceivedTokenAmount = any2EvmMessage.destTokenAmounts[0].amount; emit MessageReceived( any2EvmMessage.messageId, @@ -341,24 +317,23 @@ contract ProgrammableTokenTransfers is CCIPReceiver, OwnerIsCreator { // Set the token amounts Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); - Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({ + tokenAmounts[0] = Client.EVMTokenAmount({ token: _token, amount: _amount }); - tokenAmounts[0] = tokenAmount; // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message - Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({ - receiver: abi.encode(_receiver), // ABI-encoded receiver address - data: abi.encode(_text), // ABI-encoded string - tokenAmounts: tokenAmounts, // The amount and type of token being transferred - extraArgs: Client._argsToBytes( - // Additional arguments, setting gas limit and non-strict sequencing mode - Client.EVMExtraArgsV1({gasLimit: 200_000, strict: false}) - ), - // Set the feeToken to a feeTokenAddress, indicating specific asset will be used for fees - feeToken: _feeTokenAddress - }); - return evm2AnyMessage; + return + Client.EVM2AnyMessage({ + receiver: abi.encode(_receiver), // ABI-encoded receiver address + data: abi.encode(_text), // ABI-encoded string + tokenAmounts: tokenAmounts, // The amount and type of token being transferred + extraArgs: Client._argsToBytes( + // Additional arguments, setting gas limit and non-strict sequencing mode + Client.EVMExtraArgsV1({gasLimit: 200_000, strict: false}) + ), + // Set the feeToken to a feeTokenAddress, indicating specific asset will be used for fees + feeToken: _feeTokenAddress + }); } /// @notice Fallback function to allow the contract to receive Ether. diff --git a/public/samples/CCIP/Receiver.sol b/public/samples/CCIP/Receiver.sol index 1c75204c65a..e5017b79114 100644 --- a/public/samples/CCIP/Receiver.sol +++ b/public/samples/CCIP/Receiver.sol @@ -20,8 +20,8 @@ contract Receiver is CCIPReceiver { string text // The text that was received. ); - bytes32 private lastReceivedMessageId; // Store the last received messageId. - string private lastReceivedText; // Store the last received text. + bytes32 private s_lastReceivedMessageId; // Store the last received messageId. + string private s_lastReceivedText; // Store the last received text. /// @notice Constructor initializes the contract with the router address. /// @param router The address of the router contract. @@ -31,8 +31,8 @@ contract Receiver is CCIPReceiver { function _ccipReceive( Client.Any2EVMMessage memory any2EvmMessage ) internal override { - lastReceivedMessageId = any2EvmMessage.messageId; // fetch the messageId - lastReceivedText = abi.decode(any2EvmMessage.data, (string)); // abi-decoding of the sent text + s_lastReceivedMessageId = any2EvmMessage.messageId; // fetch the messageId + s_lastReceivedText = abi.decode(any2EvmMessage.data, (string)); // abi-decoding of the sent text emit MessageReceived( any2EvmMessage.messageId, @@ -50,6 +50,6 @@ contract Receiver is CCIPReceiver { view returns (bytes32 messageId, string memory text) { - return (lastReceivedMessageId, lastReceivedText); + return (s_lastReceivedMessageId, s_lastReceivedText); } } diff --git a/public/samples/CCIP/Sender.sol b/public/samples/CCIP/Sender.sol index 402b4dce852..b6f8c2a3871 100644 --- a/public/samples/CCIP/Sender.sol +++ b/public/samples/CCIP/Sender.sol @@ -27,16 +27,16 @@ contract Sender is OwnerIsCreator { uint256 fees // The fees paid for sending the CCIP message. ); - IRouterClient router; + IRouterClient private s_router; - LinkTokenInterface linkToken; + LinkTokenInterface private s_linkToken; /// @notice Constructor initializes the contract with the router address. /// @param _router The address of the router contract. /// @param _link The address of the link contract. constructor(address _router, address _link) { - router = IRouterClient(_router); - linkToken = LinkTokenInterface(_link); + s_router = IRouterClient(_router); + s_linkToken = LinkTokenInterface(_link); } /// @notice Sends data to receiver on the destination chain. @@ -60,20 +60,23 @@ contract Sender is OwnerIsCreator { Client.EVMExtraArgsV1({gasLimit: 200_000, strict: false}) ), // Set the feeToken address, indicating LINK will be used for fees - feeToken: address(linkToken) + feeToken: address(s_linkToken) }); // Get the fee required to send the message - uint256 fees = router.getFee(destinationChainSelector, evm2AnyMessage); + uint256 fees = s_router.getFee( + destinationChainSelector, + evm2AnyMessage + ); - if (fees > linkToken.balanceOf(address(this))) - revert NotEnoughBalance(linkToken.balanceOf(address(this)), fees); + if (fees > s_linkToken.balanceOf(address(this))) + revert NotEnoughBalance(s_linkToken.balanceOf(address(this)), fees); // approve the Router to transfer LINK tokens on contract's behalf. It will spend the fees in LINK - linkToken.approve(address(router), fees); + s_linkToken.approve(address(s_router), fees); // Send the message through the router and store the returned message ID - messageId = router.ccipSend(destinationChainSelector, evm2AnyMessage); + messageId = s_router.ccipSend(destinationChainSelector, evm2AnyMessage); // Emit an event with message details emit MessageSent( @@ -81,7 +84,7 @@ contract Sender is OwnerIsCreator { destinationChainSelector, receiver, text, - address(linkToken), + address(s_linkToken), fees ); diff --git a/public/samples/CCIP/TokenTransferor.sol b/public/samples/CCIP/TokenTransferor.sol index a751e13e3f1..e66dc5ddae5 100644 --- a/public/samples/CCIP/TokenTransferor.sol +++ b/public/samples/CCIP/TokenTransferor.sol @@ -5,7 +5,6 @@ import {IRouterClient} from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/ import {OwnerIsCreator} from "@chainlink/contracts-ccip/src/v0.8/shared/access/OwnerIsCreator.sol"; import {Client} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol"; import {IERC20} from "@chainlink/contracts-ccip/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/token/ERC20/IERC20.sol"; -import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY. @@ -19,7 +18,7 @@ contract TokenTransferor is OwnerIsCreator { error NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees); // Used to make sure contract has enough balance to cover the fees. error NothingToWithdraw(); // Used when trying to withdraw Ether but there's nothing to withdraw. error FailedToWithdrawEth(address owner, address target, uint256 value); // Used when the withdrawal of Ether fails. - error DestinationChainNotWhitelisted(uint64 destinationChainSelector); // Used when the destination chain has not been whitelisted by the contract owner. + error DestinationChainNotAllowlisted(uint64 destinationChainSelector); // Used when the destination chain has not been allowlisted by the contract owner. // Event emitted when the tokens are transferred to an account on another chain. event TokensTransferred( bytes32 indexed messageId, // The unique ID of the message. @@ -31,45 +30,38 @@ contract TokenTransferor is OwnerIsCreator { uint256 fees // The fees paid for sending the message. ); - // Mapping to keep track of whitelisted destination chains. - mapping(uint64 => bool) public whitelistedChains; + // Mapping to keep track of allowlisted destination chains. + mapping(uint64 => bool) public allowlistedChains; - IRouterClient router; + IRouterClient private s_router; - LinkTokenInterface linkToken; + IERC20 private s_linkToken; /// @notice Constructor initializes the contract with the router address. /// @param _router The address of the router contract. /// @param _link The address of the link contract. constructor(address _router, address _link) { - router = IRouterClient(_router); - linkToken = LinkTokenInterface(_link); + s_router = IRouterClient(_router); + s_linkToken = IERC20(_link); } - /// @dev Modifier that checks if the chain with the given destinationChainSelector is whitelisted. + /// @dev Modifier that checks if the chain with the given destinationChainSelector is allowlisted. /// @param _destinationChainSelector The selector of the destination chain. - modifier onlyWhitelistedChain(uint64 _destinationChainSelector) { - if (!whitelistedChains[_destinationChainSelector]) - revert DestinationChainNotWhitelisted(_destinationChainSelector); + modifier onlyAllowlistedChain(uint64 _destinationChainSelector) { + if (!allowlistedChains[_destinationChainSelector]) + revert DestinationChainNotAllowlisted(_destinationChainSelector); _; } - /// @dev Whitelists a chain for transactions. + /// @dev Updates the allowlist status of a destination chain for transactions. /// @notice This function can only be called by the owner. - /// @param _destinationChainSelector The selector of the destination chain to be whitelisted. - function whitelistChain( - uint64 _destinationChainSelector - ) external onlyOwner { - whitelistedChains[_destinationChainSelector] = true; - } - - /// @dev Denylists a chain for transactions. - /// @notice This function can only be called by the owner. - /// @param _destinationChainSelector The selector of the destination chain to be denylisted. - function denylistChain( - uint64 _destinationChainSelector + /// @param _destinationChainSelector The selector of the destination chain to be updated. + /// @param allowed The allowlist status to be set for the destination chain. + function allowlistDestinationChain( + uint64 _destinationChainSelector, + bool allowed ) external onlyOwner { - whitelistedChains[_destinationChainSelector] = false; + allowlistedChains[_destinationChainSelector] = allowed; } /// @notice Transfer tokens to receiver on the destination chain. @@ -90,7 +82,7 @@ contract TokenTransferor is OwnerIsCreator { ) external onlyOwner - onlyWhitelistedChain(_destinationChainSelector) + onlyAllowlistedChain(_destinationChainSelector) returns (bytes32 messageId) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message @@ -99,23 +91,29 @@ contract TokenTransferor is OwnerIsCreator { _receiver, _token, _amount, - address(linkToken) + address(s_linkToken) ); // Get the fee required to send the message - uint256 fees = router.getFee(_destinationChainSelector, evm2AnyMessage); + uint256 fees = s_router.getFee( + _destinationChainSelector, + evm2AnyMessage + ); - if (fees > linkToken.balanceOf(address(this))) - revert NotEnoughBalance(linkToken.balanceOf(address(this)), fees); + if (fees > s_linkToken.balanceOf(address(this))) + revert NotEnoughBalance(s_linkToken.balanceOf(address(this)), fees); // approve the Router to transfer LINK tokens on contract's behalf. It will spend the fees in LINK - linkToken.approve(address(router), fees); + s_linkToken.approve(address(s_router), fees); // approve the Router to spend tokens on contract's behalf. It will spend the amount of the given token - IERC20(_token).approve(address(router), _amount); + IERC20(_token).approve(address(s_router), _amount); // Send the message through the router and store the returned message ID - messageId = router.ccipSend(_destinationChainSelector, evm2AnyMessage); + messageId = s_router.ccipSend( + _destinationChainSelector, + evm2AnyMessage + ); // Emit an event with message details emit TokensTransferred( @@ -124,7 +122,7 @@ contract TokenTransferor is OwnerIsCreator { _receiver, _token, _amount, - address(linkToken), + address(s_linkToken), fees ); @@ -150,7 +148,7 @@ contract TokenTransferor is OwnerIsCreator { ) external onlyOwner - onlyWhitelistedChain(_destinationChainSelector) + onlyAllowlistedChain(_destinationChainSelector) returns (bytes32 messageId) { // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message @@ -163,16 +161,19 @@ contract TokenTransferor is OwnerIsCreator { ); // Get the fee required to send the message - uint256 fees = router.getFee(_destinationChainSelector, evm2AnyMessage); + uint256 fees = s_router.getFee( + _destinationChainSelector, + evm2AnyMessage + ); if (fees > address(this).balance) revert NotEnoughBalance(address(this).balance, fees); // approve the Router to spend tokens on contract's behalf. It will spend the amount of the given token - IERC20(_token).approve(address(router), _amount); + IERC20(_token).approve(address(s_router), _amount); // Send the message through the router and store the returned message ID - messageId = router.ccipSend{value: fees}( + messageId = s_router.ccipSend{value: fees}( _destinationChainSelector, evm2AnyMessage ); @@ -208,24 +209,24 @@ contract TokenTransferor is OwnerIsCreator { // Set the token amounts Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1); - Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({ + tokenAmounts[0] = Client.EVMTokenAmount({ token: _token, amount: _amount }); - tokenAmounts[0] = tokenAmount; + // Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message - Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({ - receiver: abi.encode(_receiver), // ABI-encoded receiver address - data: "", // No data - tokenAmounts: tokenAmounts, // The amount and type of token being transferred - extraArgs: Client._argsToBytes( - // Additional arguments, setting gas limit to 0 as we are not sending any data and non-strict sequencing mode - Client.EVMExtraArgsV1({gasLimit: 0, strict: false}) - ), - // Set the feeToken to a feeTokenAddress, indicating specific asset will be used for fees - feeToken: _feeTokenAddress - }); - return evm2AnyMessage; + return + Client.EVM2AnyMessage({ + receiver: abi.encode(_receiver), // ABI-encoded receiver address + data: "", // No data + tokenAmounts: tokenAmounts, // The amount and type of token being transferred + extraArgs: Client._argsToBytes( + // Additional arguments, setting gas limit to 0 as we are not sending any data and non-strict sequencing mode + Client.EVMExtraArgsV1({gasLimit: 0, strict: false}) + ), + // Set the feeToken to a feeTokenAddress, indicating specific asset will be used for fees + feeToken: _feeTokenAddress + }); } /// @notice Fallback function to allow the contract to receive Ether. diff --git a/src/content/ccip/api-reference/errors.mdx b/src/content/ccip/api-reference/errors.mdx index 311a0c503bf..e1b62dbc0ba 100644 --- a/src/content/ccip/api-reference/errors.mdx +++ b/src/content/ccip/api-reference/errors.mdx @@ -37,7 +37,7 @@ When invoking the `ccipSend` [function](/ccip/api-reference/i-router-client#ccip | MustBeCalledByRouter | - | This error should never be thrown as the router always makes the call. | | MessageGasLimitTooHigh | - | Thrown when the gas limit is too high. | | UnsupportedNumberOfTokens | - | Thrown when too many tokens are involved in the transfer. | -| SenderNotAllowed | | Thrown when the sender is not whitelisted. | +| SenderNotAllowed | | Thrown when the sender is not allowlisted. | | MaxFeeBalanceReached | - | Thrown when the onRamp has reached its maximum fee storage capacity. If it is full, it cannot process new transactions. | ## RateLimiter diff --git a/src/content/ccip/tutorials/cross-chain-tokens.mdx b/src/content/ccip/tutorials/cross-chain-tokens.mdx index ef2b6b05d8f..f37408f313a 100644 --- a/src/content/ccip/tutorials/cross-chain-tokens.mdx +++ b/src/content/ccip/tutorials/cross-chain-tokens.mdx @@ -60,7 +60,7 @@ To use this contract: 1. Enable your contract to transfer tokens to _Polygon Mumbai_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of functions for your smart contract deployed on _Ethereum Sepolia_. - 1. Call the `whitelistChain` function with as the destination chain selector. Each chain selector is found on the [supported networks page](/ccip/supported-networks). + 1. Call the `allowlistDestinationChain` function with as the destination chain selector, and as allowed. Each chain selector is found on the [supported networks page](/ccip/supported-networks). ### Transfer tokens and pay in LINK @@ -212,7 +212,7 @@ The `transferTokensPayLINK` function undertakes six primary operations: 1. Grants the router contract permission to deduct the amount from the contract's _CCIP-BnM_ balance. 1. Dispatches the CCIP message to the destination chain by executing the router's `ccipSend` [function](/ccip/api-reference/i-router-client#ccipsend). -**Note**: As a security measure, the `transferTokensPayLINK` function is protected by the `onlyWhitelistedChain` to ensure the contract owner has whitelisted a destination chain. +**Note**: As a security measure, the `transferTokensPayLINK` function is protected by the `onlyAllowlistedChain` to ensure the contract owner has allowlisted a destination chain. ### Transferring tokens and pay in native @@ -236,4 +236,4 @@ The `transferTokensPayNative` function undertakes five primary operations: 1. Grants the router contract permission to deduct the amount from the contract's _CCIP-BnM_ balance. 1. Dispatches the CCIP message to the destination chain by executing the router's `ccipSend` [function](/ccip/api-reference/i-router-client#ccipsend). **Note**: `msg.value` is set because you pay in native gas. -**Note**: As a security measure, the `transferTokensPayNative` function is protected by the `onlyWhitelistedChain`, ensuring the contract owner has whitelisted a destination chain. +**Note**: As a security measure, the `transferTokensPayNative` function is protected by the `onlyAllowlistedChain`, ensuring the contract owner has allowlisted a destination chain. diff --git a/src/content/ccip/tutorials/programmable-token-transfers.mdx b/src/content/ccip/tutorials/programmable-token-transfers.mdx index fb0005221f0..8c4f551d8db 100644 --- a/src/content/ccip/tutorials/programmable-token-transfers.mdx +++ b/src/content/ccip/tutorials/programmable-token-transfers.mdx @@ -59,7 +59,7 @@ To use this contract: 1. Open MetaMask and fund your contract with CCIP-BnM tokens. You can transfer _CCIP-BnM_ to your contract. 1. Enable your contract to send CCIP messages to _Polygon Mumbai_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of transactions of your smart contract deployed on _Ethereum Sepolia_. - 1. Call the `whitelistDestinationChain` with as the destination chain selector. Each chain selector is found on the [supported networks page](/ccip/supported-networks). + 1. Call the `allowlistDestinationChain` with as the destination chain selector, and as allowed. Each chain selector is found on the [supported networks page](/ccip/supported-networks). 1. Deploy your receiver contract on _Polygon Mumbai_: @@ -70,10 +70,10 @@ To use this contract: Note your contract address. 1. Enable your contract to receive CCIP messages from _Ethereum Sepolia_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of transactions of your smart contract deployed on _Polygon Mumbai_. - 1. Call the `whitelistSourceChain` with as the source chain selector. Each chain selector is found on the [supported networks page](/ccip/supported-networks). + 1. Call the `allowlistSourceChain` with as the source chain selector, and as allowed. Each chain selector is found on the [supported networks page](/ccip/supported-networks). 1. Enable your contract to receive CCIP messages from the contract that you deployed on _Ethereum Sepolia_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of transactions of your smart contract deployed on _Polygon Mumbai_. - 1. Call the `whitelistSender` with the contract address of the contract that you deployed on _Ethereum Sepolia_. + 1. Call the `allowlistSender` with the contract address of the contract that you deployed on _Ethereum Sepolia_, and as allowed. 1. At this point, you have one _sender_ contract on _Ethereum Sepolia_ and one _receiver_ contract on _Polygon Mumbai_. As security measures, you enabled the sender contract to send CCIP messages to _Polygon Mumbai_ and the receiver contract to receive CCIP messages from the sender and _Ethereum Sepolia_. @@ -242,7 +242,7 @@ The `sendMessagePayLINK` function undertakes six primary operations: 1. Grants the router contract permission to deduct the amount from the contract's _CCIP-BnM_ balance. 1. Dispatches the CCIP message to the destination chain by executing the router's `ccipSend` [function](/ccip/api-reference/i-router-client#ccipsend). -**Note**: As a security measure, the `sendMessagePayLINK` function is protected by the `onlyWhitelistedDestinationChain`, ensuring the contract owner has whitelisted a destination chain. +**Note**: As a security measure, the `sendMessagePayLINK` function is protected by the `onlyAllowlistedDestinationChain`, ensuring the contract owner has allowlisted a destination chain. ### Transferring tokens and data and pay in native @@ -265,7 +265,7 @@ The `sendMessagePayNative` function undertakes five primary operations: 1. Grants the router contract permission to deduct the amount from the contract's _CCIP-BnM_ balance. 1. Dispatches the CCIP message to the destination chain by executing the router's `ccipSend` [function](/ccip/api-reference/i-router-client#ccipsend). **Note**: `msg.value` is set because you pay in native gas. -**Note**: As a security measure, the `sendMessagePayNative` function is protected by the `onlyWhitelistedDestinationChain`, ensuring the contract owner has whitelisted a destination chain. +**Note**: As a security measure, the `sendMessagePayNative` function is protected by the `onlyAllowlistedDestinationChain`, ensuring the contract owner has allowlisted a destination chain. ### Receiving messages @@ -280,5 +280,4 @@ On the destination blockchain, the router invokes the `_ccipReceive` [function]( **Note**: Three important security measures are applied: - `_ccipReceive` is called by the `ccipReceive` [function](/ccip/api-reference/ccip-receiver#ccipreceive), which ensures that only the router can deliver CCIP messages to the receiver contract. See the `onlyRouter` [modifier](/ccip/api-reference/ccip-receiver#onlyrouter) for more information. -- The modifier `onlyWhitelistedSourceChain` ensures that only a call from a whitelisted source chain is accepted. -- The modifier `onlyWhitelistedSenders` ensures that only a call from a whitelisted sender is accepted. +- The modifier `onlyAllowlisted` ensures that only a call from an allowlisted source chain and sender is accepted. diff --git a/src/content/ccip/tutorials/send-arbitrary-data.mdx b/src/content/ccip/tutorials/send-arbitrary-data.mdx index c1c49ead6d0..15b6a8121af 100644 --- a/src/content/ccip/tutorials/send-arbitrary-data.mdx +++ b/src/content/ccip/tutorials/send-arbitrary-data.mdx @@ -48,7 +48,7 @@ To use this contract: Note your contract address. 1. Enable your contract to send CCIP messages to _Polygon Mumbai_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of transactions of your smart contract deployed on _Ethereum Sepolia_. - 1. Call the `whitelistDestinationChain` with as the destination chain selector. Each chain selector is found on the [supported networks page](/ccip/supported-networks). + 1. Call the `allowlistDestinationChain` with as the destination chain selector, and as allowed. Each chain selector is found on the [supported networks page](/ccip/supported-networks). 1. Deploy your receiver contract on _Polygon Mumbai_: @@ -59,10 +59,10 @@ To use this contract: Note your contract address. 1. Enable your contract to receive CCIP messages from _Ethereum Sepolia_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of transactions of your smart contract deployed on _Polygon Mumbai_. - 1. Call the `whitelistSourceChain` with as the source chain selector. Each chain selector is found on the [supported networks page](/ccip/supported-networks). + 1. Call the `allowlistSourceChain` with as the source chain selector, and as allowed. Each chain selector is found on the [supported networks page](/ccip/supported-networks). 1. Enable your contract to receive CCIP messages from the contract that you deployed on _Ethereum Sepolia_: 1. In Remix IDE, under _Deploy & Run Transactions_, open the list of transactions of your smart contract deployed on _Polygon Mumbai_. - 1. Call the `whitelistSender` with the contract address of the contract that you deployed on _Ethereum Sepolia_. + 1. Call the `allowlistSender` with the contract address of the contract that you deployed on _Ethereum Sepolia_, and as allowed. 1. At this point, you have one _sender_ contract on _Ethereum Sepolia_ and one _receiver_ contract on _Polygon Mumbai_. As security measures, you enabled the sender contract to send CCIP messages to _Polygon Mumbai_ and the receiver contract to receive CCIP messages from the sender and _Ethereum Sepolia_. **Note**: Another security measure enforces that only the router can call the `_ccipReceive` function. Read the [explanation](#explanation) section for more details. @@ -224,7 +224,7 @@ The `sendMessagePayLINK` function undertakes five primary operations: 1. Grants the router contract permission to deduct the fees from the contract's LINK balance. 1. Dispatches the CCIP message to the destination chain by executing the router's `ccipSend` [function](/ccip/api-reference/i-router-client#ccipsend). -**Note**: As a security measure, the `sendMessagePayLINK` function is protected by the `onlyWhitelistedDestinationChain`, ensuring the contract owner has whitelisted a destination chain. +**Note**: As a security measure, the `sendMessagePayLINK` function is protected by the `onlyAllowlistedDestinationChain`, ensuring the contract owner has allowlisted a destination chain. ### Sending data and pay in native @@ -246,7 +246,7 @@ The `sendMessagePayNative` function undertakes four primary operations: 1. Ensures your contract balance in native gas is enough to cover the fees. 1. Dispatches the CCIP message to the destination chain by executing the router's `ccipSend` [function](/ccip/api-reference/i-router-client#ccipsend). **Note**: `msg.value` is set because you pay in native gas. -**Note**: As a security measure, the `sendMessagePayNative` function is protected by the `onlyWhitelistedDestinationChain`, ensuring the contract owner has whitelisted a destination chain. +**Note**: As a security measure, the `sendMessagePayNative` function is protected by the `onlyAllowlistedDestinationChain`, ensuring the contract owner has allowlisted a destination chain. ### Receiving data @@ -260,5 +260,4 @@ On the destination blockchain, the router invokes the `ccipReceive` [function](/ This example applies three important security measures: - `_ccipReceive` is called by the `ccipReceive` [function](/ccip/api-reference/ccip-receiver#ccipreceive), which ensures that only the router can deliver CCIP messages to the receiver contract. See the `onlyRouter` [modifier](/ccip/api-reference/ccip-receiver#onlyrouter) for more information. -- The modifier `onlyWhitelistedSourceChain` ensures that only a call from a whitelisted source chain is accepted. -- The modifier `onlyWhitelistedSenders` ensures that only a call from a whitelisted sender is accepted. +- The modifier `onlyAllowlisted` ensures that only a call from an allowlisted source chain and sender is accepted.