diff --git a/public/changelog.json b/public/changelog.json index 096c7af4b1a..903c22444eb 100644 --- a/public/changelog.json +++ b/public/changelog.json @@ -1,4 +1,16 @@ [ + { + "category": "integration", + "changes": [], + "date": "2024-12-16", + "description": "Chainlink Data Feeds is available on Hedera mainnet. View the available price feed information on the [Price Feed Addresses](https://docs.chain.link/data-feeds/price-feeds/addresses?network=hedera&page=1) page.", + "relatedNetworks": ["hedera"], + "relatedTokens": [], + "title": "Data Feeds on Hedera", + "topic": "data", + "subTopic": "data-feeds", + "urls": [] + }, { "category": "integration", "changes": [], diff --git a/src/config/data/chains.json b/src/config/data/chains.json index 4fa31104384..bc246aac269 100644 --- a/src/config/data/chains.json +++ b/src/config/data/chains.json @@ -155,7 +155,7 @@ }, "FANTOM_TESTNET": { "chainId": 4002, - "title": "Fantom testnet", + "title": "Fantom Testnet", "explorer": "https://testnet.ftmscan.com", "nativeCurrency": { "name": "Fantom", @@ -585,13 +585,13 @@ "chains": { "ZIRCUIT_MAINNET": { "chainId": 48900, - "title": "Zircuit mainnet", + "title": "Zircuit", "explorer": "https://explorer.zircuit.com", "nativeCurrency": { "name": "ETH", "symbol": "ETH", "decimals": 18 } }, "ZIRCUIT_TESTNET": { "chainId": 48899, - "title": "Zircuit testnet", + "title": "Zircuit Testnet", "explorer": "https://explorer.testnet.zircuit.com", "nativeCurrency": { "name": "ETH", "symbol": "ETH", "decimals": 18 } } diff --git a/src/config/sidebar.ts b/src/config/sidebar.ts index 04af39711a1..3329eca2e17 100644 --- a/src/config/sidebar.ts +++ b/src/config/sidebar.ts @@ -1031,7 +1031,7 @@ export const SIDEBAR: Partial> = { url: "ccip/tutorials/cross-chain-tokens", children: [ { - title: "Deploy and RegisterUsing Remix IDE", + title: "Deploy and Register Using Remix IDE", url: "ccip/tutorials/cross-chain-tokens/register-from-eoa-remix", }, { diff --git a/src/content/chainlink-local/build/ccip/foundry/cct-burn-and-mint-fork.mdx b/src/content/chainlink-local/build/ccip/foundry/cct-burn-and-mint-fork.mdx index 1bf73d166f3..99f4210b002 100644 --- a/src/content/chainlink-local/build/ccip/foundry/cct-burn-and-mint-fork.mdx +++ b/src/content/chainlink-local/build/ccip/foundry/cct-burn-and-mint-fork.mdx @@ -167,7 +167,10 @@ contract CCIPv1_5BurnMintPoolFork is Test { CCIPLocalSimulatorFork public ccipLocalSimulatorFork; MockERC20BurnAndMintToken public mockERC20TokenEthSepolia; MockERC20BurnAndMintToken public mockERC20TokenBaseSepolia; + BurnMintTokenPool public burnMintTokenPoolEthSepolia; + BurnMintTokenPool public burnMintTokenPoolBaseSepolia; + Register.NetworkDetails ethSepoliaNetworkDetails; Register.NetworkDetails baseSepoliaNetworkDetails; uint256 ethSepoliaFork; @@ -230,12 +233,14 @@ contract CCIPv1_5BurnMintPoolFork is Test { function test_forkSupportNewCCIPToken() public { // Step 3) Deploy BurnMintTokenPool on Ethereum Sepolia vm.selectFork(ethSepoliaFork); - Register.NetworkDetails memory ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); + ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); address[] memory allowlist = new address[](0); + uint8 localTokenDecimals = 18; vm.startPrank(alice); - BurnMintTokenPool burnMintTokenPoolEthSepolia = new BurnMintTokenPool( + burnMintTokenPoolEthSepolia = new BurnMintTokenPool( IBurnMintERC20(address(mockERC20TokenEthSepolia)), + localTokenDecimals, allowlist, ethSepoliaNetworkDetails.rmnProxyAddress, ethSepoliaNetworkDetails.routerAddress @@ -257,8 +262,9 @@ contract CCIPv1_5BurnMintPoolFork is Test { baseSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); vm.startPrank(alice); - BurnMintTokenPool burnMintTokenPoolBaseSepolia = new BurnMintTokenPool( + burnMintTokenPoolBaseSepolia = new BurnMintTokenPool( IBurnMintERC20(address(mockERC20TokenBaseSepolia)), + localTokenDecimals, allowlist, baseSepoliaNetworkDetails.rmnProxyAddress, baseSepoliaNetworkDetails.routerAddress @@ -434,15 +440,17 @@ contract CCIPv1_5BurnMintPoolFork is Test { vm.startPrank(alice); TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesEthSepolia = new bytes[](1); + remotePoolAddressesEthSepolia[0] = abi.encode(address(burnMintTokenPoolEthSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: baseSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(burnMintTokenPoolBaseSepolia)), + remotePoolAddresses: remotePoolAddressesEthSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenBaseSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }) }); - burnMintTokenPoolEthSepolia.applyChainUpdates(chains); + uint64[] memory remoteChainSelectorsToRemove = new uint64[](0); + burnMintTokenPoolEthSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); } } @@ -460,15 +468,16 @@ contract CCIPv1_5BurnMintPoolFork is Test { vm.startPrank(alice); chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesBaseSepolia = new bytes[](1); + remotePoolAddressesBaseSepolia[0] = abi.encode(address(burnMintTokenPoolEthSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: ethSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(burnMintTokenPoolEthSepolia)), + remotePoolAddresses: remotePoolAddressesBaseSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenEthSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }) }); - burnMintTokenPoolBaseSepolia.applyChainUpdates(chains); + burnMintTokenPoolBaseSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); } } @@ -590,7 +599,10 @@ contract CCIPv1_5BurnMintPoolFork is Test { CCIPLocalSimulatorFork public ccipLocalSimulatorFork; MockERC20BurnAndMintToken public mockERC20TokenEthSepolia; MockERC20BurnAndMintToken public mockERC20TokenBaseSepolia; + BurnMintTokenPool public burnMintTokenPoolEthSepolia; + BurnMintTokenPool public burnMintTokenPoolBaseSepolia; + Register.NetworkDetails ethSepoliaNetworkDetails; Register.NetworkDetails baseSepoliaNetworkDetails; uint256 ethSepoliaFork; @@ -625,12 +637,14 @@ contract CCIPv1_5BurnMintPoolFork is Test { function test_forkSupportNewCCIPToken() public { // Step 3) Deploy BurnMintTokenPool on Ethereum Sepolia vm.selectFork(ethSepoliaFork); - Register.NetworkDetails memory ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); + ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); address[] memory allowlist = new address[](0); + uint8 localTokenDecimals = 18; vm.startPrank(alice); - BurnMintTokenPool burnMintTokenPoolEthSepolia = new BurnMintTokenPool( + burnMintTokenPoolEthSepolia = new BurnMintTokenPool( IBurnMintERC20(address(mockERC20TokenEthSepolia)), + localTokenDecimals, allowlist, ethSepoliaNetworkDetails.rmnProxyAddress, ethSepoliaNetworkDetails.routerAddress @@ -642,8 +656,9 @@ contract CCIPv1_5BurnMintPoolFork is Test { baseSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); vm.startPrank(alice); - BurnMintTokenPool burnMintTokenPoolBaseSepolia = new BurnMintTokenPool( + burnMintTokenPoolBaseSepolia = new BurnMintTokenPool( IBurnMintERC20(address(mockERC20TokenBaseSepolia)), + localTokenDecimals, allowlist, baseSepoliaNetworkDetails.rmnProxyAddress, baseSepoliaNetworkDetails.routerAddress @@ -729,15 +744,17 @@ contract CCIPv1_5BurnMintPoolFork is Test { vm.startPrank(alice); TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesEthSepolia = new bytes[](1); + remotePoolAddressesEthSepolia[0] = abi.encode(address(burnMintTokenPoolEthSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: baseSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(burnMintTokenPoolBaseSepolia)), + remotePoolAddresses: remotePoolAddressesEthSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenBaseSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }) }); - burnMintTokenPoolEthSepolia.applyChainUpdates(chains); + uint64[] memory remoteChainSelectorsToRemove = new uint64[](0); + burnMintTokenPoolEthSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); // Step 14) Configure Token Pool on Base Sepolia @@ -745,15 +762,16 @@ contract CCIPv1_5BurnMintPoolFork is Test { vm.startPrank(alice); chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesBaseSepolia = new bytes[](1); + remotePoolAddressesBaseSepolia[0] = abi.encode(address(burnMintTokenPoolEthSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: ethSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(burnMintTokenPoolEthSepolia)), + remotePoolAddresses: remotePoolAddressesBaseSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenEthSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: 100_000, rate: 167 }) }); - burnMintTokenPoolBaseSepolia.applyChainUpdates(chains); + burnMintTokenPoolBaseSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); // Step 15) Mint tokens on Ethereum Sepolia and transfer them to Base Sepolia diff --git a/src/content/chainlink-local/build/ccip/foundry/cct-lock-and-release-fork.mdx b/src/content/chainlink-local/build/ccip/foundry/cct-lock-and-release-fork.mdx index 85b6a215d66..0fa001649b5 100644 --- a/src/content/chainlink-local/build/ccip/foundry/cct-lock-and-release-fork.mdx +++ b/src/content/chainlink-local/build/ccip/foundry/cct-lock-and-release-fork.mdx @@ -134,6 +134,11 @@ contract CCIPv1_5LockReleasePoolFork is Test { CCIPLocalSimulatorFork public ccipLocalSimulatorFork; MockERC20TokenOwner public mockERC20TokenEthSepolia; MockERC20TokenOwner public mockERC20TokenBaseSepolia; + LockReleaseTokenPool public lockReleaseTokenPoolEthSepolia; + LockReleaseTokenPool public lockReleaseTokenPoolBaseSepolia; + + Register.NetworkDetails ethSepoliaNetworkDetails; + Register.NetworkDetails baseSepoliaNetworkDetails; uint256 ethSepoliaFork; uint256 baseSepoliaFork; @@ -195,12 +200,14 @@ contract CCIPv1_5LockReleasePoolFork is Test { function test_forkSupportNewCCIPToken() public { // Step 3) Deploy LockReleaseTokenPool on Ethereum Sepolia vm.selectFork(ethSepoliaFork); - Register.NetworkDetails memory ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); + ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); address[] memory allowlist = new address[](0); + uint8 localTokenDecimals = 18; vm.startPrank(alice); - LockReleaseTokenPool lockReleaseTokenPoolEthSepolia = new LockReleaseTokenPool( + lockReleaseTokenPoolEthSepolia = new LockReleaseTokenPool( IERC20(address(mockERC20TokenEthSepolia)), + localTokenDecimals, allowlist, ethSepoliaNetworkDetails.rmnProxyAddress, true, // acceptLiquidity @@ -220,11 +227,12 @@ contract CCIPv1_5LockReleasePoolFork is Test { // Step 4) Deploy LockReleaseTokenPool on Base Sepolia vm.selectFork(baseSepoliaFork); - Register.NetworkDetails memory baseSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); + baseSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); vm.startPrank(alice); - LockReleaseTokenPool lockReleaseTokenPoolBaseSepolia = new LockReleaseTokenPool( + lockReleaseTokenPoolBaseSepolia = new LockReleaseTokenPool( IERC20(address(mockERC20TokenBaseSepolia)), + localTokenDecimals, allowlist, baseSepoliaNetworkDetails.rmnProxyAddress, true, // acceptLiquidity @@ -407,15 +415,17 @@ contract CCIPv1_5LockReleasePoolFork is Test { vm.startPrank(alice); TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesEthSepolia = new bytes[](1); + remotePoolAddressesEthSepolia[0] = abi.encode(address(lockReleaseTokenPoolBaseSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: baseSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(lockReleaseTokenPoolBaseSepolia)), + remotePoolAddresses: remotePoolAddressesEthSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenBaseSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }) }); - lockReleaseTokenPoolEthSepolia.applyChainUpdates(chains); + uint64[] memory remoteChainSelectorsToRemove = new uint64[](0); + lockReleaseTokenPoolEthSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); } } @@ -433,15 +443,16 @@ contract CCIPv1_5LockReleasePoolFork is Test { vm.startPrank(alice); chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesBaseSepolia = new bytes[](1); + remotePoolAddressesBaseSepolia[0] = abi.encode(address(lockReleaseTokenPoolEthSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: ethSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(lockReleaseTokenPoolEthSepolia)), + remotePoolAddresses: remotePoolAddressesBaseSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenEthSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }) }); - lockReleaseTokenPoolBaseSepolia.applyChainUpdates(chains); + lockReleaseTokenPoolBaseSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); } } @@ -534,6 +545,11 @@ contract CCIPv1_5LockReleasePoolFork is Test { CCIPLocalSimulatorFork public ccipLocalSimulatorFork; MockERC20TokenOwner public mockERC20TokenEthSepolia; MockERC20TokenOwner public mockERC20TokenBaseSepolia; + LockReleaseTokenPool public lockReleaseTokenPoolEthSepolia; + LockReleaseTokenPool public lockReleaseTokenPoolBaseSepolia; + + Register.NetworkDetails ethSepoliaNetworkDetails; + Register.NetworkDetails baseSepoliaNetworkDetails; uint256 ethSepoliaFork; uint256 baseSepoliaFork; @@ -567,12 +583,14 @@ contract CCIPv1_5LockReleasePoolFork is Test { function test_forkSupportNewCCIPToken() public { // Step 3) Deploy LockReleaseTokenPool on Ethereum Sepolia vm.selectFork(ethSepoliaFork); - Register.NetworkDetails memory ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); + ethSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); address[] memory allowlist = new address[](0); + uint8 localTokenDecimals = 18; vm.startPrank(alice); - LockReleaseTokenPool lockReleaseTokenPoolEthSepolia = new LockReleaseTokenPool( + lockReleaseTokenPoolEthSepolia = new LockReleaseTokenPool( IERC20(address(mockERC20TokenEthSepolia)), + localTokenDecimals, allowlist, ethSepoliaNetworkDetails.rmnProxyAddress, true, // acceptLiquidity @@ -582,11 +600,12 @@ contract CCIPv1_5LockReleasePoolFork is Test { // Step 4) Deploy LockReleaseTokenPool on Base Sepolia vm.selectFork(baseSepoliaFork); - Register.NetworkDetails memory baseSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); + baseSepoliaNetworkDetails = ccipLocalSimulatorFork.getNetworkDetails(block.chainid); vm.startPrank(alice); - LockReleaseTokenPool lockReleaseTokenPoolBaseSepolia = new LockReleaseTokenPool( + lockReleaseTokenPoolBaseSepolia = new LockReleaseTokenPool( IERC20(address(mockERC20TokenBaseSepolia)), + localTokenDecimals, allowlist, baseSepoliaNetworkDetails.rmnProxyAddress, true, // acceptLiquidity @@ -679,15 +698,17 @@ contract CCIPv1_5LockReleasePoolFork is Test { vm.startPrank(alice); TokenPool.ChainUpdate[] memory chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesEthSepolia = new bytes[](1); + remotePoolAddressesEthSepolia[0] = abi.encode(address(lockReleaseTokenPoolBaseSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: baseSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(lockReleaseTokenPoolBaseSepolia)), + remotePoolAddresses: remotePoolAddressesEthSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenBaseSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }) }); - lockReleaseTokenPoolEthSepolia.applyChainUpdates(chains); + uint64[] memory remoteChainSelectorsToRemove = new uint64[](0); + lockReleaseTokenPoolEthSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); // Step 14) Configure Token Pool on Base Sepolia @@ -695,15 +716,16 @@ contract CCIPv1_5LockReleasePoolFork is Test { vm.startPrank(alice); chains = new TokenPool.ChainUpdate[](1); + bytes[] memory remotePoolAddressesBaseSepolia = new bytes[](1); + remotePoolAddressesBaseSepolia[0] = abi.encode(address(lockReleaseTokenPoolEthSepolia)); chains[0] = TokenPool.ChainUpdate({ remoteChainSelector: ethSepoliaNetworkDetails.chainSelector, - allowed: true, - remotePoolAddress: abi.encode(address(lockReleaseTokenPoolEthSepolia)), + remotePoolAddresses: remotePoolAddressesBaseSepolia, remoteTokenAddress: abi.encode(address(mockERC20TokenEthSepolia)), outboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }), inboundRateLimiterConfig: RateLimiter.Config({ isEnabled: true, capacity: liquidityAmount, rate: 167 }) }); - lockReleaseTokenPoolBaseSepolia.applyChainUpdates(chains); + lockReleaseTokenPoolBaseSepolia.applyChainUpdates(remoteChainSelectorsToRemove, chains); vm.stopPrank(); // Step 15) Transfer tokens from Ethereum Sepolia to Base Sepolia diff --git a/src/features/data/chains.ts b/src/features/data/chains.ts index 033ffea65d0..d926b5b270d 100644 --- a/src/features/data/chains.ts +++ b/src/features/data/chains.ts @@ -349,7 +349,7 @@ export const CHAINS: Chain[] = [ title: "Scroll Data Feeds", img: "/assets/chains/scroll.svg", networkStatusUrl: "https://status.scroll.io/", - tags: ["default"], + tags: ["default", "smartData"], supportedFeatures: ["feeds"], l2SequencerFeed: true, networks: [ @@ -359,6 +359,7 @@ export const CHAINS: Chain[] = [ networkType: "mainnet", rddUrl: "https://reference-data-directory.vercel.app/feeds-ethereum-mainnet-scroll-1.json", queryString: "scroll-mainnet", + tags: ["smartData"], }, { name: "Scroll Sepolia testnet", @@ -514,6 +515,13 @@ export const CHAINS: Chain[] = [ tags: ["default"], supportedFeatures: ["feeds"], networks: [ + { + name: "Hedera Mainnet", + explorerUrl: "https://hashscan.io/mainnet/contract/%s", + networkType: "mainnet", + rddUrl: "https://reference-data-directory.vercel.app/feeds-hedera-mainnet.json", + queryString: "hedera-mainnet", + }, { name: "Hedera Testnet", explorerUrl: "https://hashscan.io/testnet/contract/%s",