diff --git a/app/(home)/hackathon/page.tsx b/app/(home)/hackathon/page.tsx
index 57b35f9afb4..e8f9a06b517 100644
--- a/app/(home)/hackathon/page.tsx
+++ b/app/(home)/hackathon/page.tsx
@@ -207,7 +207,8 @@ export default function HackathonPage() {
],
resources: [
{ name: 'InterChain Messaging', url: 'https://academy.avax.network/course/interchain-messaging' },
- { name: 'InterChain Token Transfer', url: 'https://academy.avax.network/course/interchain-token-transfer' },
+ { name: 'ERC20 Bridge', url: 'https://academy.avax.network/course/erc20-bridge' },
+ { name: 'Native Token Bridge', url: 'https://academy.avax.network/course/native-token-bridge' },
{ name: 'Cross-Chain Communication', url: 'https://build.avax.network/docs/build/avalanchego/cross-chain' }
]
},
diff --git a/app/(home)/hackathon_bba/page.tsx b/app/(home)/hackathon_bba/page.tsx
index 43e495e7289..b0c3225fcbb 100644
--- a/app/(home)/hackathon_bba/page.tsx
+++ b/app/(home)/hackathon_bba/page.tsx
@@ -188,7 +188,8 @@ export default function HackathonPage() {
],
resources: [
{ name: 'InterChain Messaging', url: 'https://academy.avax.network/course/interchain-messaging' },
- { name: 'InterChain Token Transfer', url: 'https://academy.avax.network/course/interchain-token-transfer' },
+ { name: 'ERC20 Bridge', url: 'https://academy.avax.network/course/erc20-bridge' },
+ { name: 'Native Token Bridge', url: 'https://academy.avax.network/course/native-token-bridge' },
{ name: 'Cross-Chain Communication', url: 'https://build.avax.network/docs/build/avalanchego/cross-chain' }
]
},
diff --git a/app/academy/[...slug]/page.tsx b/app/academy/[...slug]/page.tsx
index b6888894ef4..2cbc45a9051 100644
--- a/app/academy/[...slug]/page.tsx
+++ b/app/academy/[...slug]/page.tsx
@@ -47,7 +47,9 @@ import DeployExampleERC20 from "@/components/toolbox/console/ictt/setup/DeployEx
import DeployTokenHome from "@/components/toolbox/console/ictt/setup/DeployTokenHome";
import DeployWrappedNative from "@/components/toolbox/console/ictt/setup/DeployWrappedNative";
import DeployERC20TokenRemote from "@/components/toolbox/console/ictt/setup/DeployERC20TokenRemote";
+import DeployNativeTokenRemote from "@/components/toolbox/console/ictt/setup/DeployNativeTokenRemote";
import RegisterWithHome from "@/components/toolbox/console/ictt/setup/RegisterWithHome";
+import AddCollateral from "@/components/toolbox/console/ictt/setup/AddCollateral";
import TestSend from "@/components/toolbox/console/ictt/token-transfer/TestSend";
import TeleporterRegistry from "@/components/toolbox/console/icm/setup/TeleporterRegistry";
import ICMRelayer from "@/components/toolbox/console/icm/setup/ICMRelayer";
@@ -68,7 +70,9 @@ const toolboxComponents = {
DeployTokenHome,
DeployWrappedNative,
DeployERC20TokenRemote,
+ DeployNativeTokenRemote,
RegisterWithHome,
+ AddCollateral,
TestSend,
TeleporterRegistry,
ICMRelayer,
diff --git a/app/api/icm-flow/route.ts b/app/api/icm-flow/route.ts
index 27f906eec03..079fcb4eda0 100644
--- a/app/api/icm-flow/route.ts
+++ b/app/api/icm-flow/route.ts
@@ -1,6 +1,6 @@
import { NextResponse } from 'next/server';
import l1ChainsData from "@/constants/l1-chains.json";
-const mainnetChains = l1ChainsData.filter(c => c.isTestnet !== true);
+const mainnetChains = l1ChainsData.filter(c => (c as any).isTestnet !== true);
interface ICMFlowData {
sourceChain: string;
diff --git a/components/academy/learning-path-configs/avalanche.config.ts b/components/academy/learning-path-configs/avalanche.config.ts
index 67e7a4452de..6056aad2c68 100644
--- a/components/academy/learning-path-configs/avalanche.config.ts
+++ b/components/academy/learning-path-configs/avalanche.config.ts
@@ -20,7 +20,7 @@ export const avalancheLearningPaths: CourseNode[] = [
slug: "avalanche-l1/customizing-evm",
category: "VM Customization",
dependencies: ["avalanche-fundamentals"],
- position: { x: 87.5, y: 250 },
+ position: { x: 87.5, y: 200 },
mobileOrder: 2
},
@@ -32,7 +32,7 @@ export const avalancheLearningPaths: CourseNode[] = [
slug: "avalanche-l1/interchain-messaging",
category: "Interoperability",
dependencies: ["avalanche-fundamentals"],
- position: { x: 62.5, y: 250 },
+ position: { x: 62.5, y: 200 },
mobileOrder: 3
},
{
@@ -42,7 +42,7 @@ export const avalancheLearningPaths: CourseNode[] = [
slug: "avalanche-l1/permissioned-l1s",
category: "L1 Development",
dependencies: ["avalanche-fundamentals"],
- position: { x: 12.5, y: 250 },
+ position: { x: 12.5, y: 200 },
mobileOrder: 6
},
{
@@ -52,28 +52,28 @@ export const avalancheLearningPaths: CourseNode[] = [
slug: "avalanche-l1/l1-native-tokenomics",
category: "L1 Tokenomics",
dependencies: ["avalanche-fundamentals"],
- position: { x: 37.5, y: 250 },
+ position: { x: 37.5, y: 200 },
mobileOrder: 7
},
// Third Layer - Advanced topics
{
- id: "interchain-token-transfer",
- name: "Interchain Token Transfer",
- description: "Transfer assets between chains using Interchain Messaging",
- slug: "avalanche-l1/interchain-token-transfer",
+ id: "erc20-bridge",
+ name: "ERC20 Bridge",
+ description: "Bridge ERC20 tokens between chains using Interchain Token Transfer",
+ slug: "avalanche-l1/erc20-bridge",
category: "Interoperability",
dependencies: ["interchain-messaging"],
- position: { x: 82.5, y: 500 },
+ position: { x: 62.5, y: 375 },
mobileOrder: 4
},
{
- id: "erc20-to-erc20-bridge",
- name: "ERC20 to ERC20 Bridge",
- description: "Bridge ERC20 tokens between chains using Interchain Token Transfer",
- slug: "avalanche-l1/erc20-bridge",
+ id: "native-token-bridge",
+ name: "Native Token Bridge",
+ description: "Bridge native tokens between chains using Interchain Token Transfer",
+ slug: "avalanche-l1/native-token-bridge",
category: "Interoperability",
- dependencies: ["interchain-messaging", "l1-native-tokenomics"],
- position: { x: 52.5, y: 500 },
+ dependencies: ["erc20-bridge", "l1-native-tokenomics"],
+ position: { x: 50, y: 525 },
mobileOrder: 5
},
{
@@ -83,7 +83,7 @@ export const avalancheLearningPaths: CourseNode[] = [
slug: "avalanche-l1/permissionless-l1s",
category: "L1 Development",
dependencies: ["permissioned-l1s", "l1-native-tokenomics"],
- position: { x: 22.5, y: 500 },
+ position: { x: 25, y: 375 },
mobileOrder: 8
},
];
diff --git a/components/navigation/navigation.tsx b/components/navigation/navigation.tsx
index a296f51c0f3..ec49de3b87f 100644
--- a/components/navigation/navigation.tsx
+++ b/components/navigation/navigation.tsx
@@ -141,10 +141,10 @@ export function AcademyDropdown() {
url: "https://academy.avax.network/course/interchain-messaging",
},
{
- title: "Interchain Token Transfer",
- description: "Transfer assets between Avalanche blockchains.",
+ title: "ERC20 Bridge",
+ description: "Bridge ERC-20 tokens between Avalanche L1s.",
icon: ,
- url: "https://academy.avax.network/course/interchain-token-transfer",
+ url: "https://academy.avax.network/course/erc20-bridge",
},
{
title: "Customizing the EVM",
diff --git a/components/quizzes/quizData.json b/components/quizzes/quizData.json
index ab23b2d7e58..8f4aada9cb4 100644
--- a/components/quizzes/quizData.json
+++ b/components/quizzes/quizData.json
@@ -51,8 +51,8 @@
"215"
]
},
- "interchain-token-transfer": {
- "title": "Interchain Token Transfer",
+ "native-token-bridge": {
+ "title": "Native Token Bridge",
"quizzes": [
"118",
"119",
diff --git a/components/toolbox/console/ictt/token-transfer/TestSend.tsx b/components/toolbox/console/ictt/token-transfer/TestSend.tsx
index cac009f4478..a9355100f2e 100644
--- a/components/toolbox/console/ictt/token-transfer/TestSend.tsx
+++ b/components/toolbox/console/ictt/token-transfer/TestSend.tsx
@@ -9,6 +9,7 @@ import { Button } from "@/components/toolbox/components/Button";
import { Success } from "@/components/toolbox/components/Success";
import ERC20TokenHomeABI from "@/contracts/icm-contracts/compiled/ERC20TokenHome.json";
import NativeTokenHomeABI from "@/contracts/icm-contracts/compiled/NativeTokenHome.json";
+import NativeTokenRemoteABI from "@/contracts/icm-contracts/compiled/NativeTokenRemote.json";
import ExampleERC20ABI from "@/contracts/icm-contracts/compiled/ExampleERC20.json";
import ITeleporterMessenger from "@/contracts/example-contracts/compiled/ITeleporterMessenger.json";
import { createPublicClient, http, formatUnits, parseUnits, Address, zeroAddress, decodeEventLog, AbiEvent } from "viem";
@@ -36,6 +37,7 @@ export default function TokenBridge() {
// Contract addresses
const [sourceContractAddress, setSourceContractAddress] = useState
("");
const [sourceToken, setSourceToken] = useState(null);
+ const [sourceTransferrerType, setSourceTransferrerType] = useState<"unknown" | "home" | "nativeRemote">("unknown");
const [destinationContractAddress, setDestinationContractAddress] = useState("");
const [destinationToken, setDestinationToken] = useState(null);
@@ -136,6 +138,21 @@ export default function TokenBridge() {
useEffect(() => {
const fetchSuggestions = async () => {
const suggestions: Suggestion[] = [];
+ // If the destination chain has a TokenHome deployed, it's also a valid destination transferrer
+ if (destToolboxStore?.nativeTokenHomeAddress) {
+ suggestions.push({
+ title: destToolboxStore.nativeTokenHomeAddress,
+ value: destToolboxStore.nativeTokenHomeAddress,
+ description: `NativeTokenHome on ${destL1?.name}`,
+ });
+ }
+ if (destToolboxStore?.erc20TokenHomeAddress) {
+ suggestions.push({
+ title: destToolboxStore.erc20TokenHomeAddress,
+ value: destToolboxStore.erc20TokenHomeAddress,
+ description: `ERC20TokenHome on ${destL1?.name}`,
+ });
+ }
if (destToolboxStore?.erc20TokenRemoteAddress) {
suggestions.push({
title: destToolboxStore.erc20TokenRemoteAddress,
@@ -157,7 +174,7 @@ export default function TokenBridge() {
if (!destL1) return;
fetchSuggestions();
- }, [destToolboxStore?.erc20TokenRemoteAddress, destToolboxStore?.nativeTokenRemoteAddress, destL1?.id]);
+ }, [destToolboxStore?.erc20TokenRemoteAddress, destToolboxStore?.nativeTokenRemoteAddress, destToolboxStore?.nativeTokenHomeAddress, destToolboxStore?.erc20TokenHomeAddress, destL1?.id]);
// Fetch token info from bridge contract on current chain
const fetchTokenInfoFromBridgeContract = useCallback(async (address: Address, direction: "source" | "destination", updateState: boolean = true) => {
@@ -176,38 +193,66 @@ export default function TokenBridge() {
let tokenAddress = address;
+ let detectedSourceType: "unknown" | "home" | "nativeRemote" = "unknown";
+ let forceNativeBalance = false;
+ let tokenName: string | null = null;
+ let tokenSymbol: string | null = null;
+ let tokenDecimalsLocal: number | null = null;
if (direction === "source") {
- // Try to get the token address from the bridge contract
+ // 1) Home transferrers expose getTokenAddress()
const fetchedTokenAddress = await publicClient.readContract({
address: address,
abi: ERC20TokenHomeABI.abi,
functionName: 'getTokenAddress',
}).catch(() => null) as Address | null;
- if (!fetchedTokenAddress) {
- throw new Error("Could not determine token address from bridge contract");
+ if (fetchedTokenAddress) {
+ tokenAddress = fetchedTokenAddress;
+ detectedSourceType = "home";
+ } else {
+ // 2) NativeTokenRemote doesn't expose getTokenAddress(), but does expose getTokenHomeAddress() + ERC20-like metadata.
+ const tokenHomeAddr = await publicClient.readContract({
+ address: address,
+ abi: NativeTokenRemoteABI.abi,
+ functionName: 'getTokenHomeAddress',
+ }).catch(() => null) as Address | null;
+
+ if (tokenHomeAddr) {
+ detectedSourceType = "nativeRemote";
+ forceNativeBalance = true;
+ const [d, n, s] = await Promise.all([
+ publicClient.readContract({ address, abi: NativeTokenRemoteABI.abi, functionName: 'decimals' }).catch(() => null),
+ publicClient.readContract({ address, abi: NativeTokenRemoteABI.abi, functionName: 'name' }).catch(() => null),
+ publicClient.readContract({ address, abi: NativeTokenRemoteABI.abi, functionName: 'symbol' }).catch(() => null),
+ ]);
+ tokenDecimalsLocal = d !== null ? Number(d as number) : 18;
+ tokenName = (n as string | null) ?? selectedL1?.coinName ?? "Native Token";
+ tokenSymbol = (s as string | null) ?? selectedL1?.coinName ?? "NATIVE";
+ // Use a non-empty address so the UI enables inputs; for native balance we won't use ERC20 reads.
+ tokenAddress = zeroAddress;
+ } else {
+ detectedSourceType = "unknown";
+ }
}
-
- tokenAddress = fetchedTokenAddress;
}
const code = await publicClient.getCode({ address: tokenAddress });
- const isWrapped = code?.includes('d0e30db0') && code.includes('2e1a7d4d');
+ const isWrapped = forceNativeBalance ? true : (code?.includes('d0e30db0') && code.includes('2e1a7d4d'));
const [fetchedDecimals, fetchedName, fetchedSymbol, fetchedBalance, fetchedAllowance] = await Promise.all([
- publicClient.readContract({
+ tokenDecimalsLocal !== null ? Promise.resolve(BigInt(tokenDecimalsLocal)) : publicClient.readContract({
address: tokenAddress,
abi: ExampleERC20ABI.abi,
functionName: 'decimals'
}),
- publicClient.readContract({
+ tokenName !== null ? Promise.resolve(tokenName) : publicClient.readContract({
address: tokenAddress,
abi: ExampleERC20ABI.abi,
functionName: 'name'
}),
- publicClient.readContract({
+ tokenSymbol !== null ? Promise.resolve(tokenSymbol) : publicClient.readContract({
address: tokenAddress,
abi: ExampleERC20ABI.abi,
functionName: 'symbol'
@@ -220,7 +265,8 @@ export default function TokenBridge() {
functionName: 'balanceOf',
args: [walletEVMAddress === "" ? zeroAddress : walletEVMAddress as Address]
}),
- publicClient.readContract({
+ // Allowance is only meaningful for ERC20-style tokens; for native value transfers treat as unlimited.
+ isWrapped === true ? Promise.resolve(0n) : publicClient.readContract({
address: tokenAddress,
abi: ExampleERC20ABI.abi,
functionName: 'allowance',
@@ -230,12 +276,12 @@ export default function TokenBridge() {
const token: Token = {
address: tokenAddress,
- name: (isWrapped === true ? selectedL1?.coinName : fetchedName) as string,
- symbol: (isWrapped === true ? selectedL1?.coinName : fetchedSymbol) as string,
+ name: (isWrapped === true && detectedSourceType !== "nativeRemote" ? selectedL1?.coinName : fetchedName) as string,
+ symbol: (isWrapped === true && detectedSourceType !== "nativeRemote" ? selectedL1?.coinName : fetchedSymbol) as string,
decimals: Number(fetchedDecimals as bigint),
balance: fetchedBalance as bigint,
allowance: fetchedAllowance as bigint,
- isNative: isWrapped || false,
+ isNative: forceNativeBalance ? true : (isWrapped || false),
chain: {
name: direction === "source" ? selectedL1!.name : destL1!.name,
id: direction === "source" ? selectedL1!.id : destL1!.id,
@@ -246,6 +292,7 @@ export default function TokenBridge() {
if (updateState) {
if (direction === "source") {
setSourceToken(token);
+ setSourceTransferrerType(detectedSourceType);
setTokenAddress(tokenAddress);
setTokenDecimals(token?.decimals);
setTokenSymbol(token?.symbol);
@@ -367,12 +414,17 @@ export default function TokenBridge() {
multiHopFallback: zeroAddress,
};
+ const isNativeValueTransfer = sourceToken.isNative === true;
const { request } = await publicClient.simulateContract({
address: sourceContractAddress as Address,
- abi: sourceToken.isNative === true ? NativeTokenHomeABI.abi : ERC20TokenHomeABI.abi,
+ abi: sourceTransferrerType === "nativeRemote"
+ ? NativeTokenRemoteABI.abi
+ : (isNativeValueTransfer ? NativeTokenHomeABI.abi : ERC20TokenHomeABI.abi),
functionName: 'send',
- args: sourceToken.isNative === true ? [sendInput] : [sendInput, amountParsed],
- value: sourceToken.isNative === true ? amountParsed : 0n,
+ args: sourceTransferrerType === "nativeRemote"
+ ? [sendInput]
+ : (isNativeValueTransfer ? [sendInput] : [sendInput, amountParsed]),
+ value: (sourceTransferrerType === "nativeRemote" || isNativeValueTransfer) ? amountParsed : 0n,
account: coreWalletClient.account,
chain: viemChain,
});
diff --git a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token.mdx b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token.mdx
index f6bf8e29d56..cb9192571dd 100644
--- a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token.mdx
@@ -13,7 +13,7 @@ import { Step, Steps } from 'fumadocs-ui/components/steps';
### Deploy an ERC-20 Token
-We've already deployed an ERC-20 token in the [Transfer an ERC-20 Token](/academy/interchain-token-transfer/03-tokens/08-transfer-an-erc-20-token) section. If you've completed that step, you can use the same token for this bridge.
+We've already deployed an ERC-20 token in the [Transfer an ERC-20 Token](/academy/avalanche-l1/l1-native-tokenomics/01-tokens-fundamentals/05-transfer-an-erc-20-token) section. If you've completed that step, you can use the same token for this bridge.
If you haven't deployed a token yet, make sure you're connected to the Fuji testnet since we're covering this guide from Fuji to Echo. You can deploy the original ERC-20 token below:
diff --git a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home.mdx b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home.mdx
index f86be4cd886..5b4903bfb62 100644
--- a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home.mdx
@@ -17,7 +17,7 @@ Since we're covering an ERC20 > ERC20 bridge, make sure to set the Transferrer t
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
2. Have enough test AVAX for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote.mdx b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote.mdx
index 92e180c573f..86e75eb3567 100644
--- a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote.mdx
@@ -28,8 +28,8 @@ Now we'll deploy the ERC20TokenRemote contract to the Echo chain. Use our toolbo
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
-2. Deployed your ERC20Home contract (from [Deploy Home](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/03-deploy-home))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+2. Deployed your ERC20Home contract (from [Deploy Home](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home))
3. Have enough test ECH for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/05-register-remote.mdx b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/05-register-remote.mdx
index 6295a2f683a..825c58306c4 100644
--- a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/05-register-remote.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/05-register-remote.mdx
@@ -18,9 +18,9 @@ To register your remote bridge with the home bridge, use our toolbox:
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
-2. Deployed your ERC20Home contract (from [Deploy Home](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/03-deploy-home))
-3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/04-deploy-remote))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+2. Deployed your ERC20Home contract (from [Deploy Home](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home))
+3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote))
4. Have enough test ECH for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/06-transfer-tokens.mdx b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/06-transfer-tokens.mdx
index c8aa6f4e4f8..73b4c613c44 100644
--- a/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/06-transfer-tokens.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/06-transfer-tokens.mdx
@@ -16,10 +16,10 @@ Now that all the bridge contracts have been deployed and registered, you can tra
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
-2. Deployed your ERC20Home contract (from [Deploy Home](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/03-deploy-home))
-3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/04-deploy-remote))
-4. Registered your remote bridge with the home bridge (from [Register Remote](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/05-register-remote))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+2. Deployed your ERC20Home contract (from [Deploy Home](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home))
+3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote))
+4. Registered your remote bridge with the home bridge (from [Register Remote](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/05-register-remote))
5. Have enough test AVAX for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/02-deploy-token-remote.mdx b/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/02-deploy-token-remote.mdx
index a7dcb872df2..b49f02ce98c 100644
--- a/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/02-deploy-token-remote.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/02-deploy-token-remote.mdx
@@ -27,8 +27,8 @@ Now we'll deploy the ERC20TokenRemote contract to the Echo chain. Use our toolbo
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
-2. Deployed your ERC20Home contract (from [Deploy Home](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/03-deploy-home))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+2. Deployed your ERC20Home contract (from [Deploy Home](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home))
3. Have enough test ECH for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/03-register-remote.mdx b/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/03-register-remote.mdx
index 1a31e5a7349..feb39b94783 100644
--- a/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/03-register-remote.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/03-register-remote.mdx
@@ -18,9 +18,9 @@ To register your remote bridge with the home bridge, use our toolbox:
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
-2. Deployed your ERC20Home contract (from [Deploy Home](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/03-deploy-home))
-3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/interchain-token-transfer/07-tokens-on-multiple-chains/02-deploy-token-remote))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+2. Deployed your ERC20Home contract (from [Deploy Home](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home))
+3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/02-deploy-token-remote))
4. Have enough test DIS for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/04-multihop.mdx b/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/04-multihop.mdx
index 8f4c0e84adb..77edc887f3f 100644
--- a/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/04-multihop.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/04-tokens-on-multiple-chains/04-multihop.mdx
@@ -16,11 +16,11 @@ Now that all the bridge contracts have been deployed and registered, you can tra
Make sure you have:
-1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
-2. Deployed your ERC20Home contract (from [Deploy Home](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/03-deploy-home))
-3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/04-deploy-remote))
-4. Registered your remote bridge with the home bridge (from [Register Remote](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/05-register-remote))
-5. Have enough ERC-20 tokens on the _Ra_ chain: `Echo` (you can transfer tokens from the _H_ chain to the _Ra_ chain first) (from [Transfer Tokens](/academy/interchain-token-transfer/06-erc-20-to-erc-20-bridge/06-transfer-tokens))
+1. Deployed your ERC-20 token (from [Deploy ERC-20 Token](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/02-deploy-erc-20-token))
+2. Deployed your ERC20Home contract (from [Deploy Home](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/03-deploy-home))
+3. Deployed your ERC20TokenRemote contract (from [Deploy Remote](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/04-deploy-remote))
+4. Registered your remote bridge with the home bridge (from [Register Remote](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/05-register-remote))
+5. Have enough ERC-20 tokens on the _Ra_ chain: `Echo` (you can transfer tokens from the _H_ chain to the _Ra_ chain first) (from [Transfer Tokens](/academy/avalanche-l1/erc20-bridge/03-erc-20-to-erc-20-bridge/06-transfer-tokens))
6. Have enough test ECH for gas fees
diff --git a/content/academy/avalanche-l1/erc20-bridge/index.mdx b/content/academy/avalanche-l1/erc20-bridge/index.mdx
index 23d595a7417..dc316535fec 100644
--- a/content/academy/avalanche-l1/erc20-bridge/index.mdx
+++ b/content/academy/avalanche-l1/erc20-bridge/index.mdx
@@ -6,9 +6,9 @@ authors: [nicolasarnedo]
icon: Smile
---
-## ERC-20 to ERC-20 Bridge
+## ERC20 Bridge
-Welcome to the **ERC-20 to ERC-20 Bridge** course! This course is designed to give you a deep understanding of bridging ERC-20 tokens between Avalanche L1s using Avalanche Interchain Token Transfer (ICTT).
+Welcome to the **ERC20 Bridge** course! This course is designed to give you a deep understanding of bridging ERC-20 tokens between Avalanche L1s using Avalanche Interchain Token Transfer (ICTT).
By the end of this course, you will have practical skills in deploying token bridges, understanding bridge security, and implementing multi-chain token transfers using Avalanche's native interoperability features.
@@ -16,7 +16,6 @@ By the end of this course, you will have practical skills in deploying token bri
Before starting this course, we recommend completing:
- [Interchain Messaging](/academy/avalanche-l1/interchain-messaging) - Foundation in cross-chain communication with ICM
-- [L1 Native Tokenomics](/academy/avalanche-l1/l1-native-tokenomics) - Understanding tokens fundamentals
### What You'll Learn
diff --git a/content/academy/avalanche-l1/erc20-bridge/meta.json b/content/academy/avalanche-l1/erc20-bridge/meta.json
index 1633e1a5455..d5f74e293b5 100644
--- a/content/academy/avalanche-l1/erc20-bridge/meta.json
+++ b/content/academy/avalanche-l1/erc20-bridge/meta.json
@@ -1,9 +1,9 @@
{
- "title": "ERC-20 to ERC-20 Bridge",
+ "title": "ERC20 Bridge",
"icon": "ArrowLeftRight",
"root": true,
"pages": [
- "---ERC-20 to ERC-20 Bridge---",
+ "---ERC20 Bridge---",
"index",
"---Token Bridging---",
"...01-token-bridging",
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/02-getting-started/01-introduction.mdx b/content/academy/avalanche-l1/interchain-token-transfer/02-getting-started/01-introduction.mdx
deleted file mode 100644
index 946a2c3f9b5..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/02-getting-started/01-introduction.mdx
+++ /dev/null
@@ -1,101 +0,0 @@
----
-title: Getting Started with Interchain Token Transfer
-description: Learn how to use our Interchain Token Transfer toolbox to transfer assets across Avalanche chains.
-updated: 2024-05-31
-authors: [ashucoder9, 0xstt]
-icon: Smile
----
-
-# Getting Started with Interchain Token Transfer
-
-In this section, we'll help you get started with our Interchain Token Transfer toolbox. We've made it easier than ever to transfer assets across Avalanche chains by providing a user-friendly interface that handles all the complexity for you.
-
-## Prerequisites
-
-Before you begin, make sure you have:
-
-1. A modern web browser with Core Wallet installed
- - Download Core Wallet from [core.app](https://core.app)
- - Create or import your wallet
- - Add the following testnet chains to your wallet:
- - Fuji C-Chain****
- - Echo
- - Dispatch
-
-2. Test tokens for development
- - **Recommended:** Create a [Builder Hub account](https://build.avax.network/login) and connect your wallet to receive testnet tokens automatically
- - **Alternative:** Get test AVAX from external faucets like [core.app/tools/testnet-faucet](https://core.app/tools/testnet-faucet/?subnet=c&token=c) with code `avalanche-academy`
-
-3. Basic understanding of how to use Core Wallet
- - Adding networks
- - Managing accounts
- - Approving transactions
-
-4. An understanding of Avalanche networks and how to connect to them
-
-
-This course focuses on using the existing testnet chains (Fuji C-Chain, Echo, and Dispatch). If you want to create your own L1 blockchain, please refer to the [Creating an L1](/academy/avalanche-l1/avalanche-fundamentals/04-creating-an-l1/01-creating-an-l1) course.
-
-Since Interchain Token Transfer relies on Interchain Messaging (ICM), you must run your own relayer to enable cross-chain communication. Follow the [Running a Relayer](/academy/interchain-messaging/10-running-a-relayer/01-running-a-relayer) course to set up your relayer.
-
-
-## Using the Interchain Token Transfer Toolbox
-
-Our Interchain Token Transfer toolbox is a comprehensive web application that provides a complete suite of tools for cross-chain operations. Here's how to get started:
-
-1. Visit the [Interchain Token Transfer Toolbox](https://toolbox.avax.network/interchain-transfer)
-
-2. Connect your wallet:
- - Click the "Connect Wallet" button
- - Select Core Wallet
- - Approve the connection request
-
-3. Explore the toolbox features:
-
- a. Deploy Contracts:
- - Deploy new ERC-20 tokens
- - Create bridge contracts
- - Set up token bridges
-
- b. Transfer Assets:
- - Select the source and destination chains (Fuji C-Chain, Echo, or Dispatch)
- - Choose the token and amount
- - Execute cross-chain transfers
-
- c. Test Transfers:
- - Use the test transfer feature to verify your setup
- - Monitor transfer status
- - View transaction history
-
-## Features
-
-Our toolbox provides several features to help you with cross-chain operations:
-
-- Contract Deployment:
- - ERC-20 token deployment
- - Bridge contract creation
- - Token bridge setup
-
-- Asset Transfers:
- - Support for testnet chains (Fuji C-Chain, Echo, Dispatch)
- - ERC-20 token transfers
- - Native token transfers
- - Cross-chain token swaps
-
-- Testing and Monitoring:
- - Test transfer functionality
- - Transaction history
- - Real-time status updates
- - Cross-chain transaction tracking
-
-## Next Steps
-
-Now that you know how to use the Interchain Token Transfer toolbox, you can:
-
-1. Learn about different token types in the next section
-2. Explore token bridging concepts
-3. Try out different types of cross-chain transfers
-4. Deploy your own tokens and bridges
-5. Test your cross-chain setup
-
-Remember that our toolbox handles all the complex interactions with the Interchain Token Transfer protocol, so you can focus on your cross-chain operations without worrying about the technical details.
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/01-native-to-erc-20-bridge.mdx b/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/01-native-to-erc-20-bridge.mdx
deleted file mode 100644
index a6ed6bd03c5..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/01-native-to-erc-20-bridge.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: Native to ERC-20 Token Bridge Overview
-description: Learn how to transfer native Avalanche L1 tokens to the C-Chain as ERC-20 tokens.
-updated: 2024-09-09
-authors: [owenwahlgren]
-icon: Book
----
-
-ICTT is also capable of bridging native tokens between any Avalanche L1s as ERC-20 tokens. This process involves using a `NativeTokenHome` contract on the source L1, and a `ERC20TokenRemote` contract on the destination L1. The `NativeTokenHome` contract will be used to bridge the native token to the destination L1 as an ERC-20 token.
-
-This example will cover native to ERC-20 token bridging between Avalanche C-Chain and Echo, where we'll bridge the native asset, `AVAX`, to Echo as an ERC-20 token.
-
-### What we will do
-1. Deploy `NativeTokenHome` on Avalanche C-Chain
-2. Deploy `ERC20TokenRemote` on Echo
-3. Register `ERC20TokenRemote` on Echo with `NativeTokenHome` on Avalanche
-4. Perform a transfer of the native token on Avalanche to Echo as an ERC-20 token
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/02-deploy-native-token-home.mdx b/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/02-deploy-native-token-home.mdx
deleted file mode 100644
index 1c96ba7e9bc..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/02-deploy-native-token-home.mdx
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: Deploy Native Token Home
-description: Deploy the NativeTokenHome contract on the Avalanche L1 blockchain.
-updated: 2024-05-31
-authors: [owenwahlgren]
-icon: Book
----
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-
-
-For this guide, we'll be using the Avalanche Fuji testnet, which already has a wrapped native asset (WAVAX). If you're creating your own L1 blockchain, you'll need to deploy your own wrapped native asset first.
-
-
-
-
-### Deploy NativeTokenHome
-
-Use our toolbox to deploy the NativeTokenHome contract:
-
-
-Make sure you have:
-1. Connected your Core Wallet to the Fuji testnet
-2. Have enough test AVAX for gas fees
-3. Select "Native Token" as the transferrer type in the toolbox
-
-
-
-
-
-
-
-### Save the Native Token Home Address
-
-After deployment, you'll need to save the contract address for future steps. You can find it in the deployment confirmation in the toolbox.
-
-
-Keep this address handy as you'll need it for the next steps in the bridging process.
-
-
-
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/03-deploy-erc20-token-remote.mdx b/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/03-deploy-erc20-token-remote.mdx
deleted file mode 100644
index 08b8bb93cbf..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/03-deploy-erc20-token-remote.mdx
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: Deploy ERC20 Token Remote
-description: Deploy the ERC20TokenRemote contract to the Echo chain.
-updated: 2024-05-31
-authors: [owenwahlgren]
-icon: Book
----
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-
-
-
-### Deploy ERC20TokenRemote
-
-Use our toolbox to deploy the ERC20TokenRemote contract:
-
-
-Make sure you have:
-1. Connected your Core Wallet to the Fuji testnet
-2. Have enough test ECH for gas fees
-3. Select the NativeTokenHome contract you deployed in the previous step from the suggestions
-4. If you don't see your NativeTokenHome contract in the suggestions, you'll need to manually enter its address
-
-
-
-
-
-
-
-
-
-### Save the ERC20 Token Remote Address
-
-After deployment, you'll need to save the contract address for future steps. You can find it in the deployment confirmation in the toolbox.
-
-
-Keep this address handy as you'll need it for the next steps in the bridging process.
-
-
-
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/04-register-remote.mdx b/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/04-register-remote.mdx
deleted file mode 100644
index 2a1abff8df3..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/04-register-remote.mdx
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: Register Remote Bridge
-description: Register the ERC20TokenRemote contract with the NativeTokenHome contract.
-updated: 2024-05-31
-authors: [owenwahlgren]
-icon: Book
----
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-
-
-
-### Register Remote Bridge
-
-After deploying the bridge contracts, you need to register the remote bridge with the home bridge. Use our toolbox to complete the registration:
-
-
-Make sure you have:
-1. Successfully deployed your ERC20TokenRemote contract
-2. Have enough test ECH for gas fees
-
-
-
-
-
-
-
-
-
-### Verify Registration
-
-After registration, you can verify the process was successful by looking for the registration event in the transaction logs. You can find the registration confirmation in the toolbox.
-
-
-The registration process is a one-time setup that establishes the connection between your home and remote bridges. Once completed, you can proceed with token transfers.
-
-
-
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/05-bridge-tokens.mdx b/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/05-bridge-tokens.mdx
deleted file mode 100644
index a65727f74d9..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/08-native-to-erc-20-bridge/05-bridge-tokens.mdx
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: Native Token Bridge Transfer
-description: Perform a transfer of a native Avalanche L1 token to the C-Chain as an ERC-20 token.
-updated: 2024-05-31
-authors: [ashucoder9, owenwahlgren]
-icon: Book
----
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-
-
-
-### Transfer the L1's Native Token to the C-Chain
-
-Now that all the bridge contracts have been deployed and configured, you can transfer native tokens from your C-Chain to Echo using our toolbox:
-
-
-Make sure you have:
-1. Successfully registered your remote bridge
-2. Have enough native tokens in your C-Chain wallet for the transfer
-3. Have enough test AVAX for gas fees
-
-
-
-
-
-
-
-
-
-
-### Verify the Transfer
-
-After initiating the transfer, you can verify it was successful by:
-
-1. Checking the transaction status in the toolbox
-2. Checking the transaction status in Core Wallet
-3. Viewing the transaction details on the [Fuji Explorer](https://testnet.snowtrace.io)
-4. Checking your token balance in Core Wallet on the destination chain
-
-
-The transfer process may take a few moments to complete as it involves cross-chain communication. You can track the progress through the transaction hash.
-
-
-
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/01-intro.mdx b/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/01-intro.mdx
deleted file mode 100644
index 57baaa31b6e..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/01-intro.mdx
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: Introduction
-description: Learn how to call another contract function after send tokens to another L1s.
-updated: 2024-08-23
-authors: [0xstt]
-icon: Book
----
-
-In addition to supporting basic token transfers, the token transferrer contracts offer a
-`sendAndCall` interface for bridging tokens and using them in a smart contract interaction all
-within a single Interchain Messaging message. If the call to the recipient smart contract fails, the
-transferred tokens are sent to a fallback recipient address on the destination chain of the
-transfer. The `sendAndCall` interface enables the direct use of transferred tokens in dApps on other
-chains, such as performing swaps, using the tokens to pay for fees when invoking services, etc.
-
-
-
-Teleporter Messenger has the ability to receive cross-chain messages on the destination chain and casts related messages to the `TeleporterMessage` struct. It then sends these messages to the Home/Remote Transferrer contract, and handles them as `SEND` or `CALL`, as implemented in `TokenHome.sol` or `TokenRemote.sol`.
-
-In this section we will cover the usage of the `CALL` message type with an example implementation.
-
-When `sendAndCall` function is triggered, the following actions are taken;
-
-- The Transferrer Contract grants an allowance to spend tokens on the destination contract.
-- The Transferrer Contract encodes the received message as parameters for the `receiveToken` function, as defined in the `IERC20SendAndCallReceiver` or `INativeSendAndCallReceiver` interface.
-- The Transferrer Contract checks whether the destination contract's function execution is successfull.
-- The Transferrer Contract retrieves the remaining allowance to check if there are any unspent tokens exists.
-- The Transferrer Contract removes the allowance for the destination contract.
-- The Transferrer Contract sends the remaining tokens to the fallback recipient. If the destination contract fails to execute the function, the full amount will be sent to the fallback recipient.
-
-## Prerequisites
-
-The following prerequisites were covered in previous sections, so you should have already deployed the following contracts before starting this chapter:
-
-- Base ERC20 Token on L1
-- Home Transferrer Contract on L1
-- Remote Transferrer Contract on Fuji
-- A Running AWM-relayer from your L1 to Fuji
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/03-send-and-call-receivers.mdx b/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/03-send-and-call-receivers.mdx
deleted file mode 100644
index 0c3073efc5f..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/03-send-and-call-receivers.mdx
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: Send and Call Receivers
-description: Learn how tokens are received by the receivers.
-updated: 2024-08-23
-authors: [0xstt]
-icon: BookOpen
----
-
-The interfaces `IERC20SendAndCallReceiver` or `INativeSendAndCallReceiver` are used for contracts that handle receiving ERC20 or native tokens of the Interchain Token Transfer protocol. They are similar to the `ITeleporterReceiver` interface, but they are specifically designed to handle token transfers.
-
-### IERC20SendAndCallReceiver
-
-The `receiveTokens` function will be called by the Transferrer bridge contract. The contract must implement this function to receive the tokens and can retrieve all the information about the origin of the tokens, the token, the bridge used, and the amount of tokens transferred from the parameters.
-
-```solidity title="lib/icm-contracts/contracts/ictt/interfaces/IERC20SendAndCallReceiver.sol"
-/**
- * @notice Interface for contracts that are called to receive token transfers.
- */
-interface IERC20SendAndCallReceiver {
- /**
- * @notice Called to receive the amount of the given token
- * @param sourceBlockchainID Blockchain ID that the transfer originated from
- * @param originTokenTransferrerAddress Address of the token transferrer that initiated the Teleporter message
- * @param originSenderAddress Address of the sender that sent the transfer. This value
- * should only be trusted if {originTokenTransferrerAddress} is verified and known.
- * @param token Address of the token to be received
- * @param amount Amount of the token to be received
- * @param payload Arbitrary data provided by the caller
- */
- function receiveTokens(
- bytes32 sourceBlockchainID,
- address originTokenTransferrerAddress,
- address originSenderAddress,
- address token,
- uint256 amount,
- bytes calldata payload
- ) external;
-}
-```
-
-### INativeSendAndCallReceiver
-
-The `INativeSendAndCallReceiver` interface is used for contracts that handle receiving native tokens of the Interchain Token Transfer protocol. It is similar to the `IERC20SendAndCallReceiver` interface, but does not include the `token` and `amount` parameters. The `receiveTokens` is now `payable`. There is only a single native token on each chain, so the address is not needed. The amount can be determined from calling `msg.value`.
-
-```solidity title="lib/icm-contracts/contracts/ictt/interfaces/INativeSendAndCallReceiver.sol"
-/**
- * @notice Interface for a contracts that are called to receive native tokens.
- */
-interface INativeSendAndCallReceiver {
- /**
- * @notice Called to receive the amount of the native token. Implementations
- * must properly handle the msg.value of the call in order to ensure it doesn't
- * become improperly made inaccessible.
- * @param sourceBlockchainID Blockchain ID that the transfer originated from
- * @param originTokenTransferrerAddress Address of the token transferrer that initiated the Teleporter message
- * @param originSenderAddress Address of the sender that sent the transfer. This value
- * should only be trusted if {originTokenTransferrerAddress} is verified and known.
- * @param payload Arbitrary data provided by the caller
- */
- function receiveTokens(
- bytes32 sourceBlockchainID,
- address originTokenTransferrerAddress,
- address originSenderAddress,
- bytes calldata payload
- ) external payable;
-}
-```
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/04-mock-receivers.mdx b/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/04-mock-receivers.mdx
deleted file mode 100644
index 02a80b59d29..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/04-mock-receivers.mdx
+++ /dev/null
@@ -1,93 +0,0 @@
----
-title: Mock Receivers
-description: A brief overview of the mock ERC20 and native token receivers used for testing in sendAndCall functions.
-updated: 2024-08-23
-authors: [0xstt]
-icon: BookOpen
----
-
-The primary purpose of these mock contracts is to test cross-chain token transfers and execute contract logic. These contracts implement the `IERC20SendAndCallReceiver` and `INativeSendAndCallReceiver` interfaces to handle token transfers, either for ERC20 tokens or native tokens, across Avalanche L1s.
-
-This contract only performs the following actions:
-
-- Checks if the message was received from a blocked sender.
-- Emits a TokensReceived event.
-- Checks if the payload is empty.
-- Receives tokens to itself.
-
-```solidity title="lib/icm-contracts/contracts/ictt/mocks/MockERC20SendAndCallReceiver.sol"
-pragma solidity 0.8.25;
-
-import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol";
-import {SafeERC20TransferFrom} from "../utils/SafeERC20TransferFrom.sol";
-import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol";
-import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol";
-import {Context} from "@openzeppelin/contracts@5.0.2/utils/Context.sol";
-
-/**
- * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
- * DO NOT USE THIS CODE IN PRODUCTION.
- */
-
-/**
- * @notice This is mock implementation of {receiveTokens} to be used in tests.
- * This contract DOES NOT provide a mechanism for accessing the tokens transfered to it.
- * Real implementations must ensure that tokens are properly handled and not incorrectly locked.
- */
-contract MockERC20SendAndCallReceiver is Context, IERC20SendAndCallReceiver {
- using SafeERC20 for IERC20;
-
- mapping(bytes32 blockchainID => mapping(address senderAddress => bool blocked)) public
- blockedSenders;
-
- /**
- * @dev Emitted when receiveTokens is called.
- */
- event TokensReceived(
- bytes32 indexed sourceBlockchainID,
- address indexed originTokenTransferrerAddress,
- address indexed originSenderAddress,
- address token,
- uint256 amount,
- bytes payload
- );
-
- /** // [!code highlight:28]
- * @dev See {IERC20SendAndCallReceiver-receiveTokens}
- */
- function receiveTokens(
- bytes32 sourceBlockchainID,
- address originTokenTransferrerAddress,
- address originSenderAddress,
- address token,
- uint256 amount,
- bytes calldata payload
- ) external {
- require(
- !blockedSenders[sourceBlockchainID][originSenderAddress],
- "MockERC20SendAndCallReceiver: sender blocked"
- );
- emit TokensReceived({
- sourceBlockchainID: sourceBlockchainID,
- originTokenTransferrerAddress: originTokenTransferrerAddress,
- originSenderAddress: originSenderAddress,
- token: token,
- amount: amount,
- payload: payload
- });
-
- require(payload.length > 0, "MockERC20SendAndCallReceiver: empty payload");
-
- SafeERC20TransferFrom.safeTransferFrom(IERC20(token), _msgSender(), amount);
- }
-
- /**
- * @notice Block a sender from sending tokens to this contract.
- * @param blockchainID The blockchain ID of the sender.
- * @param senderAddress The address of the sender.
- */
- function blockSender(bytes32 blockchainID, address senderAddress) external {
- blockedSenders[blockchainID][senderAddress] = true;
- }
-}
-```
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/05-mock-receiver.mdx b/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/05-mock-receiver.mdx
deleted file mode 100644
index 1c7b86d40fd..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/12-send-and-call/05-mock-receiver.mdx
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: Deploy a Mock Receiver
-description: Learn how to deploy a mock receiver contract.
-updated: 2024-08-23
-authors: [0xstt]
-icon: Terminal
----
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-
-In this section, you will deploy mock receiver contracts on the Avalanche L1.
-
-
-
-
-### Receiver Deployment
-
-You can choose to deploy either the `MockERC20SendAndCallReceiver` or the `MockNativeSendAndCallReceiver` contract depending your token type.
-
-```bash
-forge create --rpc-url myblockchain --private-key $PK lib/icm-contracts/contracts/ictt/mocks/MockERC20SendAndCallReceiver.sol:MockERC20SendAndCallReceiver --broadcast
-```
-
-
-
-
-### Save Receiver Address
-
-After deployment, save the `Deployed to` address in an environment variable for future use.
-
-```bash
-export MOCK_RECEIVER_ADDRESS=
-```
-
-
-
-
-### Send Tokens
-
-Use the following command to send tokens to the mock receiver contract:
-
-```bash
-cast send --rpc-url myblockchain --private-key $PK $ERC20_HOME_C_CHAIN \
-"sendAndCall((bytes32, address, address, bytes, uint256, uint256, address, address, address, uint256, uint256), uint256)" \
-"(${C_CHAIN_BLOCKCHAIN_ID_HEX}, ${ERC20_TOKEN_REMOTE_L1}, ${MOCK_RECEIVER_ADDRESS}, 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 2500000, 2000000, 0x0000000000000000000000000000000000000000, ${FUNDED_ADDRESS}, ${ERC20_HOME_C_CHAIN}, 0, 0)" 100000000000000000000
-```
-
-
-
-
-### Verify the Results
-
-Check the logs and emitted events to verify that the tokens were received correctly.
-
-TBD: Provide instructions
-
-
-
-
-After successfully deploying the contract, move on to testing the mock receivers.
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/13-cross-chain-token-swaps/07-exchange-contract.mdx b/content/academy/avalanche-l1/interchain-token-transfer/13-cross-chain-token-swaps/07-exchange-contract.mdx
deleted file mode 100644
index d1b5a20ed5d..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/13-cross-chain-token-swaps/07-exchange-contract.mdx
+++ /dev/null
@@ -1,165 +0,0 @@
----
-title: Wrap Exchange Contract
-description: Wrap the exchange contract to execute cross-chain swap operations.
-updated: 2024-08-23
-authors: [0xstt]
-icon: Book
----
-
-In this example, we will wrap Trader Joe's Factory contract to execute swap operations on the destination chain. Trader Joe's exchange contracts are already deployed on Fuji, which why we are choosing Fuji as the destination chain.
-
-An example of the exchange wrapper code is provided below. This contract only allows swap operations on Trader Joe V1 pools or any other Uniswap V2-like contracts.
-
-**Walkthrough**:
-
-- The wrapper contract receives the payload via the `receiveTokens` function.
-- The wrapper contract transfers the tokens to itself.
-- The wrapper contract gets a quote from the exchange.
-- The wrapper contract casts `payload` into `SwapOptions` struct.
-- The wrapper contract checks if the received `amountOut` is greater than the `minAmountOut` requested when the contract was called from the source chain.
-- The wrapper contract executes the swap operation and transfers the received asset to caller, depending on the preferred asset (wrapped token or native token).
-
-_Disclaimer: The avalanche-interchain-token-transfer contracts used in this tutorial are under active development and are not yet intended for production deployments. Use at your own risk._
-
-```solidity title="src/interchain-token-transfer/4-send-and-call/DexERC20Wrapper.sol"
-// (c) 2024, Ava Labs, Inc. All rights reserved.
-// See the file LICENSE for licensing terms.
-
-// SPDX-License-Identifier: Ecosystem
-
-pragma solidity 0.8.18;
-
-import {IERC20SendAndCallReceiver} from "../interfaces/IERC20SendAndCallReceiver.sol";
-import {SafeERC20TransferFrom} from "../utils/SafeERC20TransferFrom.sol";
-import {SafeERC20} from "@openzeppelin/contracts@4.8.1/token/ERC20/utils/SafeERC20.sol";
-import {IERC20} from "@openzeppelin/contracts@4.8.1/token/ERC20/IERC20.sol";
-import {Context} from "@openzeppelin/contracts@4.8.1/utils/Context.sol";
-
-import {IWAVAX} from "./interface/IWAVAX.sol";
-import {IUniswapFactory} from "./interface/IUniswapFactory.sol";
-import {IUniswapPair} from "./interface/IUniswapPair.sol";
-
-/**
- * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
- * DO NOT USE THIS CODE IN PRODUCTION.
- */
-
-contract DexERC20Wrapper is Context, IERC20SendAndCallReceiver {
- using SafeERC20 for IERC20;
-
- address public immutable WNATIVE;
- address public immutable factory;
-
- struct SwapOptions {
- address tokenOut;
- uint256 minAmountOut;
- }
-
- constructor(
- address wrappedNativeAddress,
- address dexFactoryAddress
- ) {
- WNATIVE = wrappedNativeAddress;
- factory = dexFactoryAddress;
- }
-
- event TokensReceived(
- bytes32 indexed sourceBlockchainID,
- address indexed originTokenTransferrerAddress,
- address indexed originSenderAddress,
- address token,
- uint256 amount,
- bytes payload
- );
-
- // To receive native when another contract called.
- receive() external payable {}
-
- function getAmountOut(
- uint256 amountIn,
- uint256 reserveIn,
- uint256 reserveOut
- ) internal pure returns (uint256 amountOut) {
- uint256 amountInWithFee = amountIn * 997;
- uint256 numerator = amountInWithFee * reserveOut;
- uint256 denominator = reserveIn * 1e3 + amountInWithFee;
- amountOut = numerator / denominator;
- }
-
- function query(
- uint256 amountIn,
- address tokenIn,
- address tokenOut
- ) internal view returns (uint256 amountOut) {
- if (tokenIn == tokenOut || amountIn == 0) {
- return 0;
- }
- address pair = IUniswapFactory(factory).getPair(tokenIn, tokenOut);
- if (pair == address(0)) {
- return 0;
- }
- (uint256 r0, uint256 r1, ) = IUniswapPair(pair).getReserves();
- (uint256 reserveIn, uint256 reserveOut) = tokenIn < tokenOut ? (r0, r1) : (r1, r0);
- if (reserveIn > 0 && reserveOut > 0) {
- amountOut = getAmountOut(amountIn, reserveIn, reserveOut);
- }
- }
-
- function swap(
- uint256 amountIn,
- uint256 amountOut,
- address tokenIn,
- address tokenOut,
- address to
- ) internal {
- address pair = IUniswapFactory(factory).getPair(tokenIn, tokenOut);
- (uint256 amount0Out, uint256 amount1Out) = (tokenIn < tokenOut)
- ? (uint256(0), amountOut) : (amountOut, uint256(0));
- IERC20(tokenIn).safeTransfer(pair, amountIn);
- IUniswapPair(pair).swap(amount0Out, amount1Out, to, new bytes(0));
- }
-
- function receiveTokens(
- bytes32 sourceBlockchainID,
- address originTokenTransferrerAddress,
- address originSenderAddress,
- address token,
- uint256 amount,
- bytes calldata payload
- ) external {
- emit TokensReceived({
- sourceBlockchainID: sourceBlockchainID,
- originTokenTransferrerAddress: originTokenTransferrerAddress,
- originSenderAddress: originSenderAddress,
- token: token,
- amount: amount,
- payload: payload
- });
-
- require(payload.length > 0, "DexERC20Wrapper: empty payload");
-
- IERC20 _token = IERC20(token);
- // Receives teleported assets to be used for different purposes.
- SafeERC20TransferFrom.safeTransferFrom(_token, _msgSender(), amount);
-
- // Requests a quote from the Uniswap V2-like contract.
- uint256 amountOut = query(amount, token, WNATIVE);
- require(amountOut > 0, "DexERC20Wrapper: insufficient liquidity");
-
- // Parses the payload of the message.
- SwapOptions memory swapOptions = abi.decode(payload, (SwapOptions));
- // Checks if the target swap price is still valid.
- require(amountOut >= swapOptions.minAmountOut, "DexERC20Wrapper: slippage exceeded");
-
- // Verifies if the desired tokenOut is a native or wrapped asset.
- if (swapOptions.tokenOut == address(0)) {
- swap(amount, amountOut, token, WNATIVE, address(this));
- IWAVAX(WNATIVE).withdraw(amountOut);
- payable(originSenderAddress).transfer(amountOut);
- } else {
- swap(amount, amountOut, token, WNATIVE, originSenderAddress);
- }
- }
-
-}
-```
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/13-cross-chain-token-swaps/08-deploy-wrapped-exchange-contract.mdx b/content/academy/avalanche-l1/interchain-token-transfer/13-cross-chain-token-swaps/08-deploy-wrapped-exchange-contract.mdx
deleted file mode 100644
index adfa2eff9d0..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/13-cross-chain-token-swaps/08-deploy-wrapped-exchange-contract.mdx
+++ /dev/null
@@ -1,112 +0,0 @@
----
-title: Deploy Wrapped Exchange Contract
-description: Deploy the DexERC20Wrapper on your own blockchain
-updated: 2024-08-23
-authors: [0xstt]
-icon: Terminal
----
-
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
-
-Let's deploy our wrapper for the exchange contract on your own blockchain.
-
-
-
-### Wrapper Deployment
-
-While deploying the wrapped exchange contract, you will need to send two constructor arguments to the contract.
-
-- The first argument is the wrapped native token (WAVAX) address on the destination chain (Fuji), which is: [`0xd00ae08403B9bbb9124bB305C09058E32C39A48c`](https://testnet.snowtrace.io/address/0xd00ae08403B9bbb9124bB305C09058E32C39A48c).
-- The second argument is the Trader Joe's (or any other Uniswap V2-like dapp) Factory V1 contract address on the destination chain (Fuji), which is: [`0xF5c7d9733e5f53abCC1695820c4818C59B457C2C`](https://testnet.snowtrace.io/address/0xF5c7d9733e5f53abCC1695820c4818C59B457C2C). Deployed contracts of TraderJoe can be found [here](https://docs.traderjoexyz.com/deployment-addresses/fuji).
-
-```bash
-forge create --rpc-url local-c --private-key $PK --broadcast --constructor-args 0xd00ae08403B9bbb9124bB305C09058E32C39A48c 0xF5c7d9733e5f53abCC1695820c4818C59B457C2C contracts/interchain-token-transfer/cross-chain-token-swaps/DexERC20Wrapper.sol:DexERC20Wrapper
-```
-
-```bash
-[⠊] Compiling...
-No files changed, compilation skipped
-Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC
-Deployed to: 0x4Ac1d98D9cEF99EC6546dEd4Bd550b0b287aaD6D
-Transaction hash: 0x5494b02a0278a113137f0ec9e2d31cc220d7276aa9bfd1a1438e61f2e85ca562
-```
-
-
-
-### Save the Wrapper Address
-
-The address `0x4Ac1d98D9cEF99EC6546dEd4Bd550b0b287aaD6D` is your receiver contract address.
-
-
-```bash
-export WRAPPED_EXCHANGE_ADDRESS=...
-```
-
-In case you skipped the deployment phase mentioned on the previous page, you can use a wrapper contract, that is already deployed at [`0x38B097d95B96CD17966Cf617A71b7B20F61ba85B`](https://testnet.snowtrace.io/address/0x38B097d95B96CD17966Cf617A71b7B20F61ba85B).
-
-```bash
-export WRAPPED_EXCHANGE_ADDRESS=0x38B097d95B96CD17966Cf617A71b7B20F61ba85B
-```
-
-
-
-### Initiate the Cross-Chain Swap
-
-Now that the wrapped exchange contract has been deployed, send an ERC20 token to execute a swap for WAVAX or AVAX from your Avalanche L1 to Fuji using the [`cast send`](https://book.getfoundry.sh/reference/cast/cast-send) command in foundry.
-
-```bash
-cast send --rpc-url echo --private-key $PK $ERC20_HOME_C_CHAIN "sendAndCall((bytes32, address, address, bytes, uint256, uint256, address, address, address, uint256, uint256), uint256)" "(${C_CHAIN_BLOCKCHAIN_ID_HEX}, ${ERC20_TOKEN_REMOTE_L1}, ${WRAPPED_EXCHANGE_ADDRESS}, 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, 2500000, 2000000, 0x0000000000000000000000000000000000000000, ${FUNDED_ADDRESS}, ${ERC20_HOME_C_CHAIN}, 0, 0)" 100000000000000000000
-```
-
-
-
-The ```payload``` parameter that we sent can be generated via following JavaScript file:
-
-```typescript
-const { ethers } = require("ethers");
-
-function encode() {
-
- const struct = {
- tokenOut: "0xd00ae08403B9bbb9124bB305C09058E32C39A48c",
- minAmountOut: 0
- };
-
- const types = ["address", "uint256"];
- const encoded = ethers.AbiCoder.defaultAbiCoder().encode(types, [ struct.tokenOut, struct.minAmountOut ]);
-
- console.log(encoded);
-
-}
-
-encode();
-```
-
-
-
-
-
-### Verify the Results
-
-To verify that your cross-chain swap was successful, you'll need to check the balance of your address on the destination chain (Fuji). You can use Foundry's cast command to check both native AVAX and WAVAX balances.
-
-**Check WAVAX Balance**: Since the swap involves WAVAX (the wrapped version of AVAX), use the following command to check the WAVAX token balance:
-
-```bash
-cast call --rpc-url local-c 0xd00ae08403B9bbb9124bB305C09058E32C39A48c "balanceOf(address)" ${FUNDED_ADDRESS}
-```
-
-This calls the `balanceOf` function on the WAVAX token contract to check your balance.
-
-**Check Native AVAX Balance**: If you chose to receive native AVAX instead of WAVAX, check your native balance:
-
-```bash
-cast balance --rpc-url local-c ${FUNDED_ADDRESS}
-```
-
-```bash
-cast balance --rpc-url local-c ${FUNDED_ADDRESS} --ether
-```
-
-
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/14-scaling-decimals/01-math-example.mdx b/content/academy/avalanche-l1/interchain-token-transfer/14-scaling-decimals/01-math-example.mdx
deleted file mode 100644
index 00518d36a88..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/14-scaling-decimals/01-math-example.mdx
+++ /dev/null
@@ -1,58 +0,0 @@
----
-title: Scaling with TokenRemote
-description: Learn how to handle token scaling with TokenRemote contracts when bridging assets with different decimal systems.
-updated: 2024-10-04
-authors: [owenwahlgren]
-icon: Calculator
----
-
-## Math Example
-
-Token scaling is a crucial part of cross-chain token transfers, especially when dealing with varying decimal denominations between the home and remote assets. This chapter will provide a math example to demonstrate how the scaling works with `TokenRemote` contracts.
-
-In this example, let's assume we are bridging an ERC-20 token from a home chain where the token uses 6 decimal places to a remote chain as the native token that uses 18 decimal places (e.g., USDC on Avalanche).
-
-The key variables here are:
-- `_homeTokenDecimals = 6`
-- `_tokenDecimals = 18`
-- `_tokenMultiplier` is calculated as:
-
->Remote: Calculate _tokenDecimals - _homeTokenDecimals
- Remote->>Multiplier: 18 - 6 = 12
- Multiplier-->>Multiplier: 10^12
-`} />
-
-This multiplier helps scale the token amounts when transferring between chains.
-
-### Scenario 1: Transferring from Home (6 decimals) to Remote (18 decimals)
-
-When transferring tokens from the home chain (6 decimals) to the remote chain (18 decimals), the token amount is multiplied by `_tokenMultiplier` to normalize the denomination. If `multiplyOnRemote = true`, we perform the following:
-
-For example, if we transfer **100 USDC** (which is represented as `100 × 10^6` in the 6-decimal system), it will be scaled as follows on the remote chain:
-
-```
-100 × 10^6 × 10^{12} = 100 × 10^{18}
-```
-Thus, the value on the remote chain would be 100 × 10^{18}, equivalent to 100 USDC in 18 decimals.
-
-### Scenario 2: Transferring from Remote (18 decimals) to Home (6 decimals)
-
-When transferring tokens back from the remote chain (18 decimals) to the home chain (6 decimals), the token amount is divided by `_tokenMultiplier`. If `multiplyOnRemote = true`, the reverse scaling applies:
-
-For example, transferring `100 × 10^{18}` (which is 100 USDC in the 18-decimal system) back to the home chain would scale down:
-
-```
-100 × 10^{18} ÷ 10^{12} = 100 × 10^6
-```
-
-This results in 100 × 10^6 USDC, which correctly represents 100 USDC in the 6-decimal system.
-
-By applying this multiplier, tokens retain their value across chains with different decimal systems.
-
-
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/14-scaling-decimals/02-example.mdx b/content/academy/avalanche-l1/interchain-token-transfer/14-scaling-decimals/02-example.mdx
deleted file mode 100644
index 538ba4aaa29..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/14-scaling-decimals/02-example.mdx
+++ /dev/null
@@ -1,144 +0,0 @@
----
-title: Example USDC as Native Token (DIY)
-description: Learn how to transfer USDC to a new Avalanche L1 and use it as a native token via ICTT.
-updated: 2024-09-03
-authors: [owenwahlgren]
-icon: Terminal
----
-import { Step, Steps } from 'fumadocs-ui/components/steps';
-
-In this section, you will learn how to transfer USDC from Avalanche’s C-Chain to a new Avalanche L1 using Interchain Token Transfers (ICTT) and set it up to act as the **native token** on the new L1. This guide will take you through the steps of configuring a local network environment, deploying the necessary contracts, and transferring tokens.
-
-
-
-
-### Create a new blockchain and Deploy on Local Network
-
-Use the **Avalanche CLI** to create a new blockchain where you will deploy USDC as the native token.
-
-
-```bash
-avalanche blockchain create myblockchain
-```
-```bash
-avalanche blockchain deploy myblockchain
-```
-
-
-### Acquire USDC On Fuji C-Chain
-
-The address for USDC on Fuji C-Chain is [`0x5425890298aed601595a70ab815c96711a31bc65`](https://testnet.snowtrace.io/token/0x5425890298aed601595a70ab815c96711a31bc65).
-For convience we have already deployed a `TokenHome` to the C-Chain for USDC with the address [`0x546526F786115af1FE7c11aa8Ac5682b8c181E3A`](https://testnet.snowtrace.io/address/0x546526F786115af1FE7c11aa8Ac5682b8c181E3A)
-
-You can use the [Core Faucet to get some USDC](https://core.app/en/tools/testnet-faucet/?subnet=c&token=usdcc) on Fuji.
-
-```bash
-export USDC=0x5425890298aed601595a70ab815c96711a31bc65
-export USDC_HOME_C_CHAIN=0x546526F786115af1FE7c11aa8Ac5682b8c181E3A
-```
-
-
-### Deploy Interchain Token Transfer Contracts
-Set up the remote transferer contracts for transferring tokens between the C-Chain and the newly created L1.
-
-- `NativeTokenRemote` Contract on `myblockchain`
-```bash
-forge create --rpc-url myblockchain --private-key $PK --broadcast --optimize --optimizer-runs 200 --constructor-args "($TELEPORTER_REGISTRY_L1, $FUNDED_ADDRESS, "1", $C_CHAIN_BLOCKCHAIN_ID_HEX, $USDC_HOME_C_CHAIN, 6)" "USDC" 100000000000000000000 0 lib/icm-contracts/contracts/ictt/TokenRemote/NativeTokenRemote.sol:NativeTokenRemote
-```
-
-_Note: When deploying the `NativeTokenRemote` contract on the L1, ensure that the **initial amount** matches the native token amount that was minted when the blockchain was created. This ensures consistency between the native token supply and the remote token counterpart._
-
-```
-[⠊] Compiling...
-[⠊] Compiling 34 files with Solc 0.8.25
-[⠒] Solc 0.8.25 finished in 2.00s
-Compiler run successful!
-Deployer: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC
-Deployed to: 0xe17bDC68168d07c1776c362d596adaa5d52A1De7
-Transaction hash: 0x26326b925a210e99e274739dc2ca017ff19447b6e6b1dfb875740d55d5031ad6
-```
-
-
-The address `0xe17bDC68168d07c1776c362d596adaa5d52A1De7` is your receiver contract address.
-
-
-```bash
-export NATIVE_TOKEN_REMOTE_L1=0x...
-```
-
-
-### Granting Native Minting Rights to NativeTokenRemote Contract
-To ensure that the `NativeTokenRemote` contract can mint native tokens on the L1 when USDC tokens are transferred from the `C-Chain`, the contract must be granted **minting rights**. This is done by adding the `NativeTokenRemote contract` address to the `Native Minter Precompile`.
-
-1. You will need to interact with the `Native Minter Precompile`, which resides at a fixed address on all Avalanche L1s:
-**Native Minter Precompile Address**: `0x0200000000000000000000000000000000000001`
-
-2. Use the following command to grant the `NativeTokenRemote` contract minting rights by setting it as an **enabled** address on the Native Minter Precompile:
-
-```bash
-cast send --rpc-url myblockchain --private-key $PK 0x0200000000000000000000000000000000000001 "setEnabled(address)" $NATIVE_TOKEN_REMOTE_L1
-```
-
-- `$NATIVE_TOKEN_REMOTE_L1`: The deployed address of the `NativeTokenRemote` contract on your L1.
-
-Once this step is completed, the `NativeTokenRemote` contract will have the necessary permissions to mint native tokens when USDC tokens are transferred from the C-Chain.
-
-
-### Register Remote Token with Home Transferer
-Register the remote token on the home chain so that it recognizes the transferer contracts.
-
-```bash
-cast send --rpc-url myblockchain --private-key $PK $NATIVE_TOKEN_REMOTE_L1 "registerWithHome((address, uint256))" "(0x0000000000000000000000000000000000000000, 0)"
-```
-
-
-### Collateralize and Transfer Tokens
-Add collateral to the transferer contract on the home chain, and then send the USDC tokens across chains.
-
-
-
-Collateral in this context refers to the amount of the token that is locked in the `Home Transferer contract` on the source chain (`C-Chain`) to back the value of the token on the destination chain (`myblockchain`). This ensures that for every token minted on the remote chain, there’s an equivalent token locked as collateral on the home chain.
-
-
-Collateralization ensures that the total supply of the token remains consistent across both chains. When tokens are sent from the `home chain`, they are locked as collateral, and a corresponding number of tokens is minted on the remote chain. If tokens are sent back to the home chain, the collateral is unlocked, and the minted tokens on the remote chain are burned.
-
-
-
-- **Approve Tokens for Transfer**
-Approve a certain number of tokens to be used by the Home Transferer.
-
-```bash
-cast send --rpc-url local-c --private-key $PK $USDC "approve(address, uint256)" $USDC_HOME_C_CHAIN 2000000000000000000000
-```
-
-- **Add Collateral and Send Tokens**
-Add collateral to the transferer contract.
-```bash
-cast send --rpc-url local-c --private-key $PK $USDC_HOME_C_CHAIN "addCollateral(bytes32, address, uint256)" $L1_BLOCKCHAIN_ID_HEX $NATIVE_TOKEN_REMOTE_L1 100000000000000000000
-```
-You can also confirm whether the Transferer is collateralized now by running the below command:
-
-```bash
-cast call --rpc-url myblockchain $NATIVE_TOKEN_REMOTE_L1 "isCollateralized()(bool)"
-```
-Send tokens to the L1
-```bash
-cast send --rpc-url local-c --private-key $PK $USDC_HOME_C_CHAIN "send((bytes32, address, address, address, uint256, uint256, uint256, address), uint256)" "(${L1_BLOCKCHAIN_ID_HEX}, ${NATIVE_TOKEN_REMOTE_L1}, ${FUNDED_ADDRESS}, ${USDC}, 0, 0, 250000, 0x0000000000000000000000000000000000000000)" 1000000000000000000000
-```
-
-
-
-Check Balance
-```bash
-cast balance --rpc-url myblockchain $FUNDED_ADDRESS
-```
-
-
-
----
-
-### Conclusion
-
-Follow the steps above to transfer a USDC token from the C-Chain to your custom Avalanche L1 and use it as the native token. This exercise will demonstrate how Avalanche’s **Interchain Token Transfer (ICTT)** system works, ensuring that tokens are properly locked, transferred, and minted across multiple chains.
-
-For more detailed information, refer to the [official Avalanche ICTT documentation](/academy/interchain-token-transfer).
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/index.mdx b/content/academy/avalanche-l1/interchain-token-transfer/index.mdx
deleted file mode 100644
index 753655375dd..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/index.mdx
+++ /dev/null
@@ -1,97 +0,0 @@
----
-title: Welcome to the Course
-description: Learn about sending assets to another L1s with Avalanche Interchain Token Transfer.
-updated: 2024-05-31
-authors: [ashucoder9]
-icon: Smile
----
-
-In this course, you will learn how to transfer assets across multiple Avalanche blockchains with Avalanche Interchain Token Transfer ICTT.
-
-## Why Take This Course?
-
-A significant innovation in blockchain is the development of multi-chain systems, like Avalanche, which provide a significant improvement in scalability, interoperability, and flexibility. At the core of these multi-chain systems is the ability to run multiple blockchains that communicate. Each chain's VM is optimized for specialized use cases, thereby boosting the network's overall performance.
-
-Cross-chain communication is a crucial building block of multi-chain systems. Utilizing Avalanche Interchain Messaging and Interchain Token Transfer is an incredibly easy way to build cross-Avalanche L1 dApps, since developers can build on top of an extensive, audited development framework.
-
-Transfering tokens between multiple chains is a common use case in multi-chain systems. This course will help you understand how to transfer assets between multiple Avalanche blockchains using the Avalanche Interchain Token Transfer protocol.
-
-
-This course focuses on using the existing testnet chains (Fuji C-Chain, Echo, and Dispatch). If you want to create your own L1 blockchain, please refer to the [Creating an L1](/academy/avalanche-l1/avalanche-fundamentals/04-creating-an-l1/01-creating-an-l1) course.
-
-
-
-Since Interchain Token Transfer relies on Interchain Messaging (ICM), you must run your own relayer to enable cross-chain communication. Follow the [Running a Relayer](/academy/interchain-messaging/09-running-a-relayer/01-relayer-introduction) course to set up your relayer.
-
-
-## Course Content
-
-### Getting Started with Interchain Token Transfer
-
-In this section, you will learn how to use our Interchain Token Transfer toolbox to perform cross-chain operations. We'll guide you through the process of using our user-friendly interface to deploy contracts, create bridges, and transfer assets across the testnet chains (Fuji C-Chain, Echo, and Dispatch).
-
-### Tokens and Token Types
-
-In this section, you will learn about the different types of tokens that can be transferred between Avalanche blockchains. We will cover ERC-20 and native tokens and how to deploy and transfer them using our toolbox. Furthermore, you will learn what wrapped native tokens are and how they can be used to transfer assets between chains.
-
-### Token Bridging
-
-Next we will talk about the high level concepts of token bridging and demonstrate how to use our toolbox to create and manage bridge contracts for cross-chain transfers between the testnet chains.
-
-### Interchain Token Transfer Architecture
-
-In this chapter we will look at the design of Avalanche Interchain Token Transfer. You will learn about the file structure of the contracts and the concepts of the token home and token remote.
-
-### ERC-20 to ERC-20 Bridge Implementation
-
-You will learn how to use our toolbox to deploy ERC-20 tokens and create bridges to transfer them between the testnet chains.
-
-### Multi-Chain Token Operations
-
-Here you will learn about the concept of multi-hops and how to use our toolbox to bridge tokens between multiple testnet chains.
-
-### Native to ERC-20 Bridge Implementation
-
-In this chapter you will learn how to use our toolbox to bridge a native token as an ERC-20 token to another testnet chain.
-
-### Send and Call Operations
-
-In this chapter you will learn how to use our toolbox to call smart contracts with the tokens after sending them to another testnet chain.
-
-### Cross-Chain Token Swaps
-
-In this chapter you will learn how to perform cross-chain token swaps between the testnet chains using our toolbox.
-
-## Prerequisites
-
-### Avalanche Knowledge
-
-This course is intended for people with knowledge about Cross-Chain communication protocols, and a solid understanding of the basic concepts of Avalanche. You should be familiar with these concepts:
-
-1. Avalanche Architecture: Be familiar with Avalanche blockchains.
-2. Interchain Messaging: Know how to communicate between two Avalanche blockchains with ICM.
-
-If some of this is not clear, we strongly recommend taking the Avalanche Fundamentals, Multi-Chain Architecture, and Interchain Messaging courses first.
-
-### Software Development
-
-You will need a general understanding of how to use Web3 applications. We recommend:
-
-1. Basic understanding of how to use Core Wallet
- - Download from [core.app](https://core.app)
-
-2. Test tokens for development
- - **Recommended:** Create a [Builder Hub account](https://build.avax.network/login) and connect your wallet to receive testnet tokens automatically
- - **Alternative:** Use external faucets like [core.app/tools/testnet-faucet](https://core.app/tools/testnet-faucet/?subnet=c&token=c) with code `avalanche-academy`
-
-3. Understanding of token standards (ERC-20, etc.)
-
-## Learning Outcomes
-
-By the end of this course, you will:
-
-- Understand what Avalanche Interchain Token Transfer is and when to use it.
-- Understand the different options for transferring assets between multiple chains.
-- Be able to deploy tokens and create bridges using our toolbox.
-- Be able to perform cross-chain token transfers between testnet chains using our toolbox.
-- Apply the knowledge gained in the course by enabling assets to be transferred between multiple Avalanche blockchains.
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/meta.json b/content/academy/avalanche-l1/interchain-token-transfer/meta.json
deleted file mode 100644
index 70245b17a09..00000000000
--- a/content/academy/avalanche-l1/interchain-token-transfer/meta.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "title": "Interchain Token Transfer",
- "icon": "ArrowLeftRight",
- "root": true,
- "pages": [
- "---Interchain Token Transfer---",
- "index",
- "...02-getting-started",
- "---Native to ERC-20 Token Bridge---",
- "...08-native-to-erc-20-bridge",
- "---Send and Call---",
- "...12-send-and-call",
- "---Cross-Chain Token Swaps---",
- "...13-cross-chain-token-swaps",
- "---Scaling Token Decimals---",
- "...14-scaling-decimals",
- "---Conclusion---",
- "certificate"
- ]
-}
-
diff --git a/content/academy/avalanche-l1/meta.json b/content/academy/avalanche-l1/meta.json
index a78f4e4da44..cd86a7dfa4a 100644
--- a/content/academy/avalanche-l1/meta.json
+++ b/content/academy/avalanche-l1/meta.json
@@ -5,8 +5,8 @@
"l1-native-tokenomics",
"permissionless-l1s",
"interchain-messaging",
- "interchain-token-transfer",
"erc20-bridge",
+ "native-token-bridge",
"customizing-evm"
]
}
diff --git a/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/01-native-to-erc-20-bridge.mdx b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/01-native-to-erc-20-bridge.mdx
new file mode 100644
index 00000000000..66f1ad537e6
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/01-native-to-erc-20-bridge.mdx
@@ -0,0 +1,98 @@
+---
+title: Introduction
+description: Learn how to bridge native tokens from one chain to another as ERC-20 tokens.
+updated: 2024-09-09
+authors: [nicolasarnedo]
+icon: Book
+---
+
+# Native to ERC-20 Token Bridge
+
+In this section, you'll learn how to bridge native tokens from a source chain to a destination chain, where they'll be represented as **ERC-20 tokens**.
+
+## Use Case
+
+This bridge type is ideal when:
+
+- You want to use your L1's native token on chains that **don't have the Native Minter precompile**
+- You prefer ERC-20 tokens for **DeFi integrations** (most DeFi protocols work with ERC-20)
+- You want **simpler deployment** (no precompile requirements on destination)
+
+## Architecture Overview
+
+```
+Source Chain (e.g., Fuji C-Chain) Destination Chain (e.g., Echo)
+┌──────────────────────────────┐ ┌──────────────────────────────┐
+│ │ │ │
+│ Native Token (AVAX) │ │ ERC-20 Token (bridged AVAX) │
+│ ↓ │ │ ↑ │
+│ Wrapped Token (WAVAX) │ │ │ │
+│ ↓ │ ICM │ │ │
+│ NativeTokenHome ──────────│────────▶ │ ERC20TokenRemote │
+│ │ │ │
+└──────────────────────────────┘ └──────────────────────────────┘
+```
+
+## Contracts Involved
+
+| Contract | Chain | Purpose |
+|----------|-------|---------|
+| **WrappedNativeToken** | Source | ERC-20 wrapper for native tokens |
+| **NativeTokenHome** | Source | Holds wrapped tokens as collateral, manages bridge state |
+| **ERC20TokenRemote** | Destination | Mints/burns ERC-20 tokens representing bridged assets |
+
+## Deployment Flow
+
+Here's the step-by-step process we'll follow:
+
+### Step 1: Ensure Wrapped Native Token Exists
+
+Before deploying the bridge, verify you have a wrapped native token on the source chain. On Fuji, **WAVAX** is already available.
+
+### Step 2: Deploy NativeTokenHome
+
+Deploy the `NativeTokenHome` contract on the source chain. This contract:
+- References your wrapped native token
+- Locks wrapped tokens when bridging out
+- Releases wrapped tokens when bridging back
+- Communicates with remote contracts via ICM
+
+### Step 3: Deploy ERC20TokenRemote
+
+Deploy the `ERC20TokenRemote` contract on the destination chain. This contract:
+- References the home contract's blockchain ID and address
+- Mints ERC-20 tokens when tokens are bridged in
+- Burns ERC-20 tokens when bridging back to the source
+
+### Step 4: Register Remote with Home
+
+The remote contract must register itself with the home contract. This creates a secure, bidirectional connection between the contracts.
+
+### Step 5: Bridge Tokens
+
+Once registered, you can:
+- **Send tokens**: Lock native tokens on source, mint ERC-20 on destination
+- **Receive tokens**: Burn ERC-20 on destination, unlock native tokens on source
+
+## What You'll Build
+
+In this section, we'll bridge **AVAX** from the **Fuji C-Chain** to **Echo** as an ERC-20 token:
+
+| Step | Action | Chain |
+|------|--------|-------|
+| 1 | Deploy NativeTokenHome | Fuji C-Chain |
+| 2 | Deploy ERC20TokenRemote | Echo |
+| 3 | Register Remote with Home | Echo |
+| 4 | Transfer tokens | Fuji → Echo |
+
+## Key Concepts
+
+
+**Token Backing**: Every ERC-20 token minted on the destination chain is backed 1:1 by wrapped native tokens locked in the NativeTokenHome contract.
+
+
+
+**No Collateral Required**: Unlike NativeTokenRemote, the ERC20TokenRemote doesn't require initial collateral because it only mints ERC-20 tokens, not native tokens.
+
+
+Let's get started with deploying the NativeTokenHome contract!
diff --git a/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/02-deploy-native-token-home.mdx b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/02-deploy-native-token-home.mdx
new file mode 100644
index 00000000000..2cbe1a15f6a
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/02-deploy-native-token-home.mdx
@@ -0,0 +1,107 @@
+---
+title: Deploy Native Token Home
+description: Deploy the NativeTokenHome contract on the source chain.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+
+# Deploy NativeTokenHome
+
+The `NativeTokenHome` contract is deployed on the source chain (where your native token originates). It serves as the home base for your bridge, locking wrapped native tokens when users bridge out.
+
+## Understanding NativeTokenHome
+
+The NativeTokenHome contract:
+
+- **References your wrapped native token** (e.g., WAVAX on Fuji)
+- **Locks tokens** when users bridge to remote chains
+- **Releases tokens** when users bridge back from remote chains
+- **Manages remote contract registrations** for security
+- **Communicates via ICM** (Interchain Messaging)
+
+## Deployment Parameters
+
+When deploying NativeTokenHome, you'll provide:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Teleporter Registry** | The ICM registry contract on this chain |
+| **Teleporter Manager** | Address that can manage ICM settings (usually your address) |
+| **Min Teleporter Version** | Minimum ICM version required (usually `1`) |
+| **Wrapped Token Address** | Your wrapped native token contract (e.g., WAVAX) |
+
+
+
+### Connect to Source Chain
+
+Ensure your wallet is connected to the **Fuji C-Chain** (or your source chain). The toolbox will automatically detect the chain and show relevant options.
+
+
+For Fuji C-Chain, the wrapped native token (**WAVAX**) is already deployed. The toolbox will detect it automatically.
+
+
+
+
+
+### Deploy NativeTokenHome
+
+Use the Deploy Token Home tool below. Make sure to:
+
+1. Select **"Native Token"** as the Transferrer Type
+2. Verify the **Wrapped Token Address** is populated (WAVAX on Fuji)
+3. Confirm the **Teleporter Registry** address is set
+
+
+Make sure you have:
+1. Connected your Core Wallet to the Fuji testnet
+2. Sufficient test AVAX for gas fees
+3. Selected "Native Token" as the transferrer type
+
+
+
+
+
+
+
+
+
+### Save the Contract Address
+
+After deployment, the **Token Home Address** will be displayed. Save this address—you'll need it when deploying the remote contract.
+
+
+The Token Home address is required for:
+- Deploying ERC20TokenRemote or NativeTokenRemote
+- Verifying bridge configuration
+- Troubleshooting transfer issues
+
+
+
+
+
+## What Happens During Deployment
+
+When you deploy NativeTokenHome:
+
+1. **Contract creation**: A new NativeTokenHome contract is deployed
+2. **Configuration stored**: The wrapped token address, registry, and manager are set
+3. **Ready for remotes**: The contract can now accept registrations from remote contracts
+
+## Contract State After Deployment
+
+After deployment, your NativeTokenHome:
+
+- ✅ Is linked to your wrapped native token
+- ✅ Is connected to the Teleporter Registry for ICM
+- ✅ Is ready to accept remote contract registrations
+- ❌ Has no remote contracts registered yet (we'll do this next)
+
+## Next Steps
+
+Now that you have a NativeTokenHome deployed, you need to:
+
+1. **Deploy ERC20TokenRemote** on the destination chain (Echo)
+2. **Register the remote** to establish the bridge connection
diff --git a/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/03-deploy-erc20-token-remote.mdx b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/03-deploy-erc20-token-remote.mdx
new file mode 100644
index 00000000000..c8a56afb592
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/03-deploy-erc20-token-remote.mdx
@@ -0,0 +1,141 @@
+---
+title: Deploy ERC20 Token Remote
+description: Deploy the ERC20TokenRemote contract on the destination chain.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+
+# Deploy ERC20TokenRemote
+
+The `ERC20TokenRemote` contract is deployed on the destination chain. It mints ERC-20 tokens representing your bridged native tokens.
+
+## Understanding ERC20TokenRemote
+
+The ERC20TokenRemote contract:
+
+- **Mints ERC-20 tokens** when native tokens are bridged from the source chain
+- **Burns ERC-20 tokens** when users bridge back to the source chain
+- **References the home contract** on the source chain for security
+- **Is a full ERC-20 token** that can be used in DeFi, transfers, etc.
+
+## Deployment Parameters
+
+When deploying ERC20TokenRemote, you'll provide:
+
+| Parameter | Description |
+|-----------|-------------|
+| **Teleporter Registry** | The ICM registry contract on this chain |
+| **Teleporter Manager** | Address that can manage ICM settings |
+| **Source Chain** | The blockchain where NativeTokenHome is deployed |
+| **Token Home Address** | Your NativeTokenHome contract address |
+| **Token Name** | Name for the bridged token (e.g., "Wrapped AVAX") |
+| **Token Symbol** | Symbol for the bridged token (e.g., "WAVAX.e") |
+| **Token Decimals** | Decimal precision (usually 18, auto-detected) |
+
+
+
+### Switch to Destination Chain
+
+Switch your wallet to the **Echo** chain (or your destination chain). The toolbox detects the connected chain and configures appropriately.
+
+
+Make sure you have test tokens on Echo for gas fees. You can get them from the [Builder Hub faucet](https://build.avax.network/login).
+
+
+
+
+
+### Deploy ERC20TokenRemote
+
+Use the Deploy ERC20 Token Remote tool below. The tool will:
+
+1. Ask you to select the **source chain** (Fuji C-Chain)
+2. Let you enter the **Token Home Address** (from the previous step)
+3. Auto-fill token details from the home contract
+
+
+Make sure you have:
+1. Connected your Core Wallet to Echo
+2. Sufficient test ECH for gas fees
+3. Your NativeTokenHome address from the previous step
+
+
+
+
+
+
+
+
+
+### Verify Token Details
+
+After entering the Token Home Address, the tool automatically fetches:
+
+- **Token Name**: Derived from the source token
+- **Token Symbol**: Derived from the source token
+- **Token Decimals**: Matches the source token
+
+Verify these details are correct before deploying.
+
+
+
+
+### Save the Remote Address
+
+After deployment, save the **ERC20 Token Remote Address**. You'll need it for:
+
+- Registering with the home contract
+- Adding the token to your wallet
+- Debugging transfer issues
+
+
+
+
+## What Happens During Deployment
+
+When you deploy ERC20TokenRemote:
+
+1. **Contract creation**: A new ERC-20 token contract is deployed
+2. **Home reference stored**: The source chain ID and home address are saved
+3. **Token metadata set**: Name, symbol, and decimals are configured
+4. **Ready for registration**: The contract can now register with the home
+
+## The Deployed Token
+
+Your ERC20TokenRemote is a fully-featured ERC-20 token:
+
+```solidity
+// Standard ERC-20 functions are available
+function transfer(address to, uint256 amount) external returns (bool);
+function approve(address spender, uint256 amount) external returns (bool);
+function balanceOf(address account) external view returns (uint256);
+```
+
+Users can:
+- Transfer tokens to other addresses
+- Approve tokens for DeFi protocols
+- Use tokens in any ERC-20 compatible application
+
+## Contract State After Deployment
+
+After deployment, your ERC20TokenRemote:
+
+- ✅ Is a valid ERC-20 token
+- ✅ Knows which home contract to communicate with
+- ❌ Is NOT registered with the home (transfers won't work yet)
+- ❌ Has zero total supply (no tokens minted yet)
+
+## Why Registration is Required
+
+The home contract maintains a list of authorized remote contracts. Without registration:
+
+- The home contract doesn't know this remote exists
+- Token transfers will be rejected
+- The bridge is not functional
+
+## Next Steps
+
+Now you need to **register the remote contract** with the home contract to complete the bridge setup.
diff --git a/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/04-register-remote.mdx b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/04-register-remote.mdx
new file mode 100644
index 00000000000..7ec5a42d818
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/04-register-remote.mdx
@@ -0,0 +1,172 @@
+---
+title: Register Remote Bridge
+description: Register the ERC20TokenRemote contract with the NativeTokenHome contract.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+
+# Register Remote with Home
+
+After deploying both contracts, you must **register the remote contract with the home contract**. This establishes the secure, bidirectional connection that enables token transfers.
+
+## Why Registration is Required
+
+Registration serves several critical purposes:
+
+| Purpose | Description |
+|---------|-------------|
+| **Security** | Only registered remotes can receive tokens from the home |
+| **Accounting** | The home tracks balances per registered remote |
+| **Configuration** | Token scaling and multipliers are set during registration |
+| **Trust** | Both sides cryptographically verify each other |
+
+## How Registration Works
+
+```
+Destination Chain Source Chain
+┌─────────────────────┐ ┌─────────────────────┐
+│ ERC20TokenRemote │ │ NativeTokenHome │
+│ │ 1. Register Call │ │
+│ registerWithHome() │ ───────────────────▶ │ │
+│ │ (ICM Message) │ │
+│ │ │ Stores remote info │
+│ │ │ - Blockchain ID │
+│ │ │ - Remote address │
+│ │ │ - Token settings │
+└─────────────────────┘ └─────────────────────┘
+```
+
+1. You call `registerWithHome()` on the **remote contract** (destination chain)
+2. The remote sends an ICM message to the **home contract** (source chain)
+3. The home contract stores the remote's information
+4. The bridge connection is now established
+
+
+
+### Stay on Destination Chain
+
+Keep your wallet connected to **Echo** (or your destination chain). The registration call is initiated from the remote contract.
+
+
+
+
+### Register Remote with Home
+
+Use the Register With Home tool below. You'll need to:
+
+1. Select the **source chain** (where NativeTokenHome is deployed)
+2. Enter the **Remote Contract Address** (your ERC20TokenRemote)
+
+
+The toolbox will automatically detect your deployed contracts and offer them as suggestions.
+
+
+
+Make sure you have:
+1. Successfully deployed your ERC20TokenRemote contract
+2. Sufficient test ECH for gas fees
+
+
+
+
+
+
+
+
+
+### Wait for ICM Message
+
+After submitting the registration:
+
+1. A transaction is sent on the destination chain
+2. An ICM message is relayed to the source chain
+3. The home contract processes the registration
+4. The toolbox updates to show "Registered" status
+
+
+ICM message relay typically takes a few seconds. If the status doesn't update, click the "Refresh" button in the tool.
+
+
+
+
+
+### Verify Registration
+
+The tool shows the registration status:
+
+- ✅ **Remote contract is registered with the Home contract** = Success!
+- ⚠️ **Not yet registered** = Wait for ICM message or check for errors
+
+You can also verify by checking the events on the home contract (shown in the tool).
+
+
+
+
+## What Happens During Registration
+
+When `registerWithHome()` is called:
+
+```solidity
+// On the Remote contract (simplified)
+function registerWithHome(FeeInfo calldata feeInfo) external {
+ // Send ICM message to home chain
+ ITeleporterMessenger(teleporterAddress).sendCrossChainMessage(
+ TeleporterMessageInput({
+ destinationBlockchainID: tokenHomeBlockchainID,
+ destinationAddress: tokenHomeAddress,
+ message: abi.encode(REGISTER_REMOTE_MESSAGE, ...)
+ })
+ );
+}
+```
+
+The home contract then:
+
+```solidity
+// On the Home contract (simplified)
+function _handleRegisterRemote(...) internal {
+ // Store remote contract info
+ remoteSettings[remoteBlockchainID][remoteAddress] = RemoteSettings({
+ registered: true,
+ collateralNeeded: 0, // For ERC20TokenRemote
+ tokenMultiplier: 1,
+ multiplyOnRemote: false
+ });
+}
+```
+
+## Troubleshooting
+
+### Registration Not Showing
+
+If the registration doesn't appear:
+
+1. **Wait longer**: ICM relay may take time depending on relayer configuration
+2. **Check relayer**: Ensure your relayer is running and configured for both chains
+3. **Verify addresses**: Confirm you used the correct home and remote addresses
+
+### Transaction Failed
+
+If the registration transaction fails:
+
+1. **Insufficient gas**: Ensure you have enough native tokens for fees
+2. **Wrong chain**: Verify you're on the destination chain
+3. **Already registered**: You can't register the same remote twice
+
+## Bridge State After Registration
+
+Your bridge is now configured:
+
+| Component | Status |
+|-----------|--------|
+| NativeTokenHome (Fuji) | ✅ Deployed, ✅ Knows about remote |
+| ERC20TokenRemote (Echo) | ✅ Deployed, ✅ Registered |
+| Bridge Connection | ✅ Established |
+| Token Transfers | ✅ Ready |
+
+## Next Steps
+
+With registration complete, you can now **transfer tokens** across the bridge!
diff --git a/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/05-bridge-tokens.mdx b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/05-bridge-tokens.mdx
new file mode 100644
index 00000000000..8f2ffae33bf
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/01-native-to-erc-20-bridge/05-bridge-tokens.mdx
@@ -0,0 +1,62 @@
+---
+title: Bridge Native Tokens
+description: Transfer native tokens from the source chain to the destination chain as ERC-20.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+import { Callout } from 'fumadocs-ui/components/callout';
+import ToolboxMdxWrapper from "@/components/toolbox/academy/wrapper/ToolboxMdxWrapper";
+import TestSend from "@/components/toolbox/console/ictt/token-transfer/TestSend";
+
+# Bridge Native Tokens
+
+With your bridge fully configured, you can now transfer native tokens from **Fuji C-Chain** to **Echo**, where they’ll appear as an **ERC-20**.
+
+
+
+### Step 1: Connect to Fuji C-Chain
+
+Switch your wallet to **Fuji C-Chain** (the source chain).
+
+
+You need **test AVAX** on Fuji for the amount you want to bridge **plus gas**.
+
+
+
+
+
+### Step 2: Bridge using the Console transfer tool
+
+Use the **Token Transfer** tool below to initiate the cross-chain transfer. When the transfer completes, the tool will display a **success message** (including transaction/message details).
+
+
+Make sure you have:
+1. Successfully registered your remote bridge
+2. Native tokens (AVAX) in your wallet to bridge
+3. Additional AVAX for gas fees
+
+
+
+
+
+
+
+
+
+### Step 3: Switch to Echo and confirm the bridged balance
+
+Switch your wallet to **Echo** (destination chain) and confirm your balance increased.
+
+
+Echo is already added by default in Core Wallet in this course flow, so you shouldn’t need to manually add the network.
+
+
+
+
+
+## Next Steps
+
+Next you’ll do the other native-token flow: **Native → Native**, where the bridged asset becomes the destination chain’s **native gas token** (requires collateral).
diff --git a/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/00-create-l1-with-native-minter.mdx b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/00-create-l1-with-native-minter.mdx
new file mode 100644
index 00000000000..0cf51ead282
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/00-create-l1-with-native-minter.mdx
@@ -0,0 +1,55 @@
+---
+title: Create an L1 with Native Minter (BuilderHub hosted)
+description: Create a BuilderHub-hosted L1 with the Native Minter precompile enabled (required for native-to-native bridging).
+updated: 2025-12-16
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+import { Callout } from 'fumadocs-ui/components/callout';
+import ToolboxMdxWrapper from "@/components/toolbox/academy/wrapper/ToolboxMdxWrapper.tsx";
+import CreateChain from "@/components/toolbox/console/layer-1/create/CreateChain";
+import CreateManagedTestnetNode from "@/components/toolbox/console/testnet-infra/ManagedTestnetNodes/CreateManagedTestnetNode";
+
+In Native → Native bridging, the destination chain must be able to **mint native coins**. That requires the **Native Minter precompile** to be enabled on that chain.
+
+In this chapter, we’ll use a **BuilderHub hosted node** (managed testnet infra) to quickly spin up an L1 where we can enable **Native Minter** in genesis.
+
+
+
+ ### Step 1: Create an L1 and enable Native Minter in genesis
+
+ Use the Create Chain tool below. In the **Genesis JSON / precompiles** section, enable:
+
+ - **Native Minter** (required)
+
+
+ For this native-token bridge chapter, you do **not** need Reward Manager.
+
+
+
+
+
+
+ Save your **Subnet ID**, **Blockchain ID**, and **Chain ID** after creation.
+
+
+
+ ### Step 2: Launch a BuilderHub hosted node for your L1
+
+ Start a hosted node (no Docker required):
+
+
+
+
+
+ Wait until the node is healthy and your chain is producing blocks.
+
+
+
+## Next Steps
+
+Next, you’ll deploy `NativeTokenRemote` **on this L1** (the chain with Native Minter enabled).
+
+
diff --git a/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/01-overview.mdx b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/01-overview.mdx
new file mode 100644
index 00000000000..a2e3275bdae
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/01-overview.mdx
@@ -0,0 +1,132 @@
+---
+title: Introduction
+description: Learn how to bridge native tokens that become native gas tokens on the destination chain.
+updated: 2024-09-09
+authors: [nicolasarnedo]
+icon: Book
+---
+
+# Native to Native Token Bridge (via a deployed L1)
+
+In this section, you'll bridge tokens from **Fuji C-Chain** to a **deployed L1** (BuilderHub-hosted) where the bridged asset is received as **native tokens** (usable for gas).
+
+## Use Case
+
+This bridge type is ideal when:
+
+- You want your L1's native token to be **the gas token** on another chain
+- You're building a **multi-chain ecosystem** with a shared native token
+- You want **seamless gas fee payments** across chains without token swaps
+
+## Key Difference from ERC-20 Bridge
+
+| Aspect | Native → ERC-20 | Native → Native |
+|--------|-----------------|-----------------|
+| **Destination token type** | ERC-20 | Native (gas token) |
+| **Destination contract** | ERC20TokenRemote | NativeTokenRemote |
+| **Requires Native Minter** | No | Yes |
+| **Requires Collateral** | No | Yes |
+| **Use for gas** | No (need to swap) | Yes (directly) |
+
+## Architecture Overview (high-level)
+
+```
+Source Chain (Fuji C-Chain) Destination Chain (your deployed L1)
+┌──────────────────────────────┐ ┌──────────────────────────────┐
+│ │ │ │
+│ Native Token (AVAX) │ │ Native Token (minted) │
+│ ↓ │ │ ↑ │
+│ Wrapped Token (WAVAX) │ │ Native Minter Precompile │
+│ ↓ │ ICM │ ↑ │
+│ NativeTokenHome ──────────│────────▶ │ NativeTokenRemote │
+│ │ │ │
+└──────────────────────────────┘ └──────────────────────────────┘
+```
+
+## Contracts and Components
+
+| Component | Chain | Purpose |
+|-----------|-------|---------|
+| **WrappedNativeToken** | Source | ERC-20 wrapper for native tokens |
+| **NativeTokenHome** | Source | Holds wrapped tokens, manages bridge state |
+| **NativeTokenRemote** | Destination | Calls Native Minter to create native tokens |
+| **Native Minter Precompile** | Destination | System contract that can mint native tokens |
+
+## The Native Minter Precompile (required on the L1)
+
+The `NativeTokenRemote` contract requires the **Native Minter precompile** to be enabled on the destination chain. This precompile:
+
+- Is a built-in Avalanche L1 feature
+- Allows authorized contracts to mint native tokens
+- Must be configured in the chain's genesis or via upgrade
+- Address: `0x0200000000000000000000000000000000000001`
+
+
+**Important**: This flow requires an L1 where **Native Minter is enabled**. In this chapter, you’ll create one using BuilderHub hosted nodes.
+
+
+## Collateral Requirement
+
+Unlike ERC-20 bridging, Native Token bridging requires **collateral**:
+
+### Why Collateral?
+
+When NativeTokenRemote mints native tokens, it's creating real gas tokens. The protocol requires:
+
+1. **Initial Reserve Imbalance**: Set during deployment
+2. **Collateral Deposit**: Tokens deposited to back the minted supply
+3. **Full Collateralization**: Required before minting is enabled
+
+### Collateral Flow
+
+```
+1. Deploy NativeTokenRemote (set initial reserve imbalance)
+2. Register with Home
+3. Add collateral on source chain (NativeTokenHome)
+4. Once collateralized, bridging is enabled
+```
+
+## Deployment Flow
+
+Here's the complete process:
+
+### Step 1: Deploy NativeTokenHome (Source Chain)
+
+Same as Native → ERC-20 bridge. You may already have this deployed.
+
+### Step 2: Deploy NativeTokenRemote (on your L1)
+
+Deploy on a chain with Native Minter enabled. Configure:
+- Initial reserve imbalance
+- Burned fees reporting percentage
+
+### Step 3: Register Remote with Home
+
+Establish the secure connection between contracts.
+
+### Step 4: Add Collateral
+
+On the source chain, deposit tokens to fully collateralize the bridge.
+
+### Step 5: Bridge Tokens (Fuji → L1), then optionally bridge back (L1 → Fuji)
+
+Once collateralized, users can bridge tokens that become native gas tokens.
+
+## What You'll Build
+
+In this section, we'll set up a native-to-native bridge:
+
+| Step | Action | Chain |
+|------|--------|-------|
+| 1 | Deploy/Use NativeTokenHome | Source (Fuji) |
+| 2 | Deploy NativeTokenRemote | Destination (your L1 with Native Minter) |
+| 3 | Register Remote with Home | Destination |
+| 4 | Add Collateral | Source |
+| 5 | Bridge tokens | Source → Destination (and optionally back) |
+
+
+If you already deployed NativeTokenHome in the previous section, you can reuse it! A single home contract can have multiple remote contracts registered.
+
+
+Let's get started!
+
diff --git a/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/02-deploy-native-token-remote.mdx b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/02-deploy-native-token-remote.mdx
new file mode 100644
index 00000000000..16492bd5235
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/02-deploy-native-token-remote.mdx
@@ -0,0 +1,166 @@
+---
+title: Deploy Native Token Remote
+description: Deploy the NativeTokenRemote contract on a chain with the Native Minter precompile.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+
+# Deploy NativeTokenRemote
+
+The `NativeTokenRemote` contract is deployed on your **destination L1** (the BuilderHub-hosted chain you created in the previous step) where the **Native Minter precompile** is enabled. This contract can mint native tokens (used for gas) when users bridge from the source chain (Fuji).
+
+## Prerequisites
+
+Before deploying NativeTokenRemote, ensure:
+
+1. **Your destination L1 has Native Minter precompile enabled**
+2. **NativeTokenHome is deployed** on the source chain
+3. **You have gas tokens** on the destination chain
+
+
+The Native Minter precompile must be enabled on your destination chain. This is typically configured in the chain's genesis file or via a network upgrade. Standard chains like C-Chain do NOT have this enabled.
+
+
+## Understanding NativeTokenRemote
+
+The NativeTokenRemote contract:
+
+- **Mints native tokens** by calling the Native Minter precompile
+- **Burns native tokens** when users bridge back to the source
+- **Requires collateralization** before minting is enabled
+- **Reports burned fees** back to the home contract for accounting
+
+## Deployment Parameters
+
+| Parameter | Description |
+|-----------|-------------|
+| **Teleporter Registry** | ICM registry on the destination chain |
+| **Teleporter Manager** | Address that can manage ICM settings |
+| **Source Chain** | Blockchain ID where NativeTokenHome is deployed |
+| **Token Home Address** | Your NativeTokenHome contract address |
+| **Initial Reserve Imbalance** | Amount of collateral required before minting |
+| **Burned Fees Reporting Reward** | Percentage rewarded for fee reporting (0-100) |
+
+### Initial Reserve Imbalance
+
+This is a critical parameter that determines how much collateral must be added before the bridge can mint tokens:
+
+- **Set to 0**: Bridge works immediately, no collateral needed (less secure)
+- **Set to amount**: That amount must be deposited as collateral first
+
+
+For production bridges, always set an initial reserve imbalance to ensure proper backing of minted tokens.
+
+
+### Burned Fees Reporting Reward
+
+When native tokens are used for gas and burned, this mechanism allows:
+- Reporting burned fees back to the home contract
+- Rewarding the reporter with a percentage of reported fees
+- Keeping supply accounting accurate across chains
+
+
+
+### Switch to Destination Chain
+
+Connect your wallet to a chain that has the **Native Minter precompile** enabled.
+
+The toolbox will automatically check if the precompile is active and show a warning if it's not.
+
+
+
+
+### Deploy NativeTokenRemote
+
+Use the Deploy Native Token Remote tool below:
+
+
+Make sure you have:
+1. Connected to a chain with Native Minter precompile enabled
+2. Sufficient gas tokens for deployment
+3. Your NativeTokenHome address from the source chain
+
+
+
+
+
+
+
+
+
+### Acknowledge Chain Switching
+
+The tool will ask you to confirm you're on the correct destination chain. This is important because:
+
+- The contract MUST be on the destination chain
+- You need the source chain's Token Home address
+- Deploying on the wrong chain means starting over
+
+
+
+
+### Configure Deployment
+
+Fill in the deployment parameters:
+
+1. **Source Chain**: Select where your NativeTokenHome is deployed
+2. **Token Home Address**: Enter or select your NativeTokenHome address
+3. **Initial Reserve Imbalance**: Set to `0` for testing, or a specific amount for production
+4. **Burned Fees Reporting Reward**: Usually `0` for testing
+
+
+
+
+### Save the Contract Address
+
+After deployment, save the **Native Token Remote Address** for:
+
+- Registering with the home contract
+- Adding collateral
+- Debugging issues
+
+
+
+
+## What Happens During Deployment
+
+When you deploy NativeTokenRemote:
+
+1. **Precompile Check**: Contract verifies Native Minter is available
+2. **Configuration Stored**: Home reference and settings are saved
+3. **Initial State**: Contract starts in "not collateralized" state
+4. **Ready for Registration**: Can now register with home
+
+## Contract State After Deployment
+
+| State | Value |
+|-------|-------|
+| Token Home Reference | ✅ Set |
+| Registered with Home | ❌ No (next step) |
+| Collateralized | ❌ No (requires collateral) |
+| Can Mint Tokens | ❌ No (needs collateral) |
+
+## Important Notes
+
+### Precompile Authorization
+
+The NativeTokenRemote contract needs authorization to call the Native Minter precompile. This is typically handled by:
+
+1. Adding the contract address to the precompile's allowlist
+2. Or deploying with an account that has minter permissions
+
+### Token Symbol
+
+The bridged native token will use the symbol from the source chain's wrapped token (e.g., "WAVAX" becomes the native token symbol).
+
+## Next Steps
+
+With NativeTokenRemote deployed:
+
+1. **Register with Home**: Establish the bridge connection
+2. **Add Collateral**: Enable minting by fully collateralizing
+3. **Bridge Tokens**: Start transferring native tokens
+
diff --git a/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/03-register-and-collateralize.mdx b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/03-register-and-collateralize.mdx
new file mode 100644
index 00000000000..8eb02d38bab
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/03-register-and-collateralize.mdx
@@ -0,0 +1,222 @@
+---
+title: Register and Add Collateral
+description: Register the NativeTokenRemote and add collateral to enable native token minting.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+
+# Register and Add Collateral
+
+After deploying NativeTokenRemote, you need to complete two steps before the bridge is operational:
+
+1. **Register** the remote with the home contract
+2. **Add collateral** to enable native token minting
+
+## Why Collateral is Required
+
+The NativeTokenRemote contract mints **real native tokens** that can be used for gas. To ensure the bridge is properly backed:
+
+- Collateral is locked on the source chain (in NativeTokenHome)
+- Only after full collateralization can tokens be minted
+- This ensures every minted token is backed 1:1
+
+```
+Source Chain Destination Chain
+┌─────────────────────────────┐ ┌─────────────────────────────┐
+│ │ │ │
+│ NativeTokenHome │ │ NativeTokenRemote │
+│ │ │ │
+│ Collateral: 1000 WAVAX │ backs │ Can mint up to: │
+│ (locked tokens) ────│──────────│ 1000 native tokens │
+│ │ │ │
+└─────────────────────────────┘ └─────────────────────────────┘
+```
+
+## Step 1: Register Remote
+
+
+
+### Connect to Destination Chain
+
+Stay on (or switch to) **your deployed L1** (the chain where `NativeTokenRemote` is deployed).
+
+
+
+
+### Register with Home
+
+Use the Register With Home tool. This is the same process as the ERC-20 bridge:
+
+
+
+
+
+
+
+
+### Verify Registration
+
+Wait for the ICM message to be processed. The tool will show:
+- ✅ **Registered** when complete
+- The home contract events confirming registration
+
+
+
+
+## Step 2: Add Collateral
+
+
+
+### Understand Collateral Requirements
+
+The Add Collateral tool will show you:
+
+| Information | Description |
+|-------------|-------------|
+| **Collateral Needed** | Total amount required (from Initial Reserve Imbalance) |
+| **Your Balance** | How much you have available to add |
+| **Current Allowance** | How much the home contract can spend |
+| **Collateralization Status** | Whether the bridge is fully backed |
+
+
+
+
+### Switch to Source Chain
+
+Collateral is added on the **source chain** (where NativeTokenHome is deployed), NOT the destination chain.
+
+
+This is because you're locking tokens in the NativeTokenHome contract to back the minted tokens on the destination.
+
+
+
+
+
+### Add Collateral
+
+Use the Add Collateral tool below:
+
+
+
+
+
+The tool will:
+
+1. **Fetch remote info**: Automatically get the Token Home address and source chain
+2. **Show collateral status**: Display how much is needed and current status
+3. **Auto-fill amount**: Pre-populate with the required collateral amount
+4. **Handle approval**: For ERC-20 token homes, approve spending first
+5. **Add collateral**: Lock tokens in the home contract
+
+
+
+
+### Approve Tokens (For ERC-20 Token Homes)
+
+If your Token Home uses ERC-20 tokens, you'll need to:
+
+1. Click **"Approve"** to allow the home contract to spend your tokens
+2. Wait for the approval transaction
+3. Then click **"Add Collateral"**
+
+For Native Token Homes, the collateral is sent directly as native tokens.
+
+
+
+
+### Verify Collateralization
+
+After adding collateral:
+
+- **Refresh Status** to see updated values
+- Look for ✅ **"Fully Collateralized"** status
+- The bridge is now ready for transfers
+
+
+
+
+## Understanding Collateral Flow
+
+### For Native Token Home (wrapped tokens)
+
+```
+1. You have wrapped native tokens (WAVAX)
+2. Approve NativeTokenHome to spend your WAVAX
+3. Call addCollateral() with the amount
+4. WAVAX is transferred to the home contract
+5. Remote is now collateralized
+```
+
+### For ERC-20 Token Home
+
+```
+1. You have ERC-20 tokens
+2. Approve ERC20TokenHome to spend your tokens
+3. Call addCollateral() with the amount
+4. Tokens are transferred to the home contract
+5. Remote is now collateralized
+```
+
+## Collateral Status States
+
+| Status | Meaning | Bridge Works? |
+|--------|---------|---------------|
+| **Not Collateralized** | No collateral added yet | ❌ No |
+| **Partially Collateralized** | Some collateral, not full | ❌ No |
+| **Fully Collateralized** | Required amount deposited | ✅ Yes |
+| **Over Collateralized** | More than required | ✅ Yes |
+
+## Token Type Detection
+
+The Add Collateral tool automatically detects whether your Token Home is:
+
+- **NativeTokenHome**: Uses wrapped native tokens, sends as `value`
+- **ERC20TokenHome**: Uses ERC-20 tokens, requires approval
+
+This is done by checking for specific storage locations in the contract.
+
+## Troubleshooting
+
+### "Insufficient Balance"
+
+You don't have enough tokens to add the required collateral. Options:
+- Get more tokens from a faucet
+- Use a smaller initial reserve imbalance
+- Bridge tokens from another source
+
+### "Insufficient Allowance"
+
+For ERC-20 Token Homes, you need to approve first:
+1. Click the **"Approve"** button
+2. Wait for transaction confirmation
+3. Then add collateral
+
+### Collateral Not Showing as Added
+
+Wait for:
+1. Source chain transaction to confirm
+2. ICM message to relay (if applicable)
+3. Click "Refresh Status" in the tool
+
+## Bridge State After Collateralization
+
+Your native-to-native bridge is now ready:
+
+| Component | Status |
+|-----------|--------|
+| NativeTokenHome | ✅ Deployed, ✅ Has collateral |
+| NativeTokenRemote | ✅ Deployed, ✅ Registered, ✅ Collateralized |
+| Bridge Connection | ✅ Established |
+| Native Token Minting | ✅ Enabled |
+
+## Next Steps
+
+With the bridge fully set up and collateralized, you can now:
+
+1. **Bridge tokens** that become native gas tokens
+2. **Use bridged tokens** directly for gas fees
+3. **Bridge back** to release collateral on the source chain
+
diff --git a/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/04-bridge-native-tokens.mdx b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/04-bridge-native-tokens.mdx
new file mode 100644
index 00000000000..780b69e62a0
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/02-native-to-native-bridge/04-bridge-native-tokens.mdx
@@ -0,0 +1,62 @@
+---
+title: Bridge Native Tokens
+description: Transfer native tokens that become gas tokens on the destination chain.
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Terminal
+---
+
+import { Step, Steps } from 'fumadocs-ui/components/steps';
+import { Callout } from 'fumadocs-ui/components/callout';
+import ToolboxMdxWrapper from "@/components/toolbox/academy/wrapper/ToolboxMdxWrapper";
+import TestSend from "@/components/toolbox/console/ictt/token-transfer/TestSend";
+
+# Bridge Native Tokens as Gas Tokens
+
+With your Native-to-Native bridge fully configured and **collateralized**, you can now bridge tokens that arrive as the destination chain’s **native gas token**.
+
+
+
+### Step 1: Connect to the source chain
+
+For this chapter’s “full loop” test, switch your wallet to **your L1** (the chain where `NativeTokenRemote` is deployed).
+
+
+You need enough native tokens on your L1 to bridge **plus gas** on your L1.
+
+
+
+
+
+### Step 2: Bridge using the Console transfer tool
+
+Use the **Token Transfer** tool below to initiate the cross-chain transfer. When it completes, the tool will show a **success message** (including transaction/message details).
+
+
+Make sure you have:
+1. Bridge fully collateralized (from previous step)
+2. Native tokens to bridge
+3. Additional tokens for gas fees
+
+
+
+
+
+
+
+
+
+### Step 3: Switch to the destination chain and confirm your gas balance increased
+
+Switch to **Fuji C-Chain** (destination) and confirm you received the bridged value (unlocked on the home side).
+
+
+This step is testing the “bridge back” direction (L1 → Fuji). Your `NativeTokenRemote` sends a message back to the `NativeTokenHome` on Fuji to release the backing value.
+
+
+
+
+
+## Next Steps
+
+You’ve now completed both native-token bridging patterns in this course.
diff --git a/content/academy/avalanche-l1/interchain-token-transfer/certificate.mdx b/content/academy/avalanche-l1/native-token-bridge/certificate.mdx
similarity index 80%
rename from content/academy/avalanche-l1/interchain-token-transfer/certificate.mdx
rename to content/academy/avalanche-l1/native-token-bridge/certificate.mdx
index 68af643d261..5780bc01b3f 100644
--- a/content/academy/avalanche-l1/interchain-token-transfer/certificate.mdx
+++ b/content/academy/avalanche-l1/native-token-bridge/certificate.mdx
@@ -1,7 +1,7 @@
---
title: Course Completion Certificate
updated: 2024-10-11
-authors: [owenwahlgren]
+authors: [nicolasarnedo]
icon: BadgeCheck
---
@@ -9,6 +9,6 @@ import CertificatePage from '@/components/quizzes/certificates';
You've made it to the end of the course. Let's check your progress and get your certificate.
-
+
Thank you for participating in this course. We hope you found it informative and enjoyable!
\ No newline at end of file
diff --git a/content/academy/avalanche-l1/native-token-bridge/index.mdx b/content/academy/avalanche-l1/native-token-bridge/index.mdx
new file mode 100644
index 00000000000..ca9d9e54cc6
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/index.mdx
@@ -0,0 +1,51 @@
+---
+title: Welcome to the Course
+description: Learn how to bridge native tokens between Avalanche L1s using Interchain Token Transfer (ICTT).
+updated: 2024-05-31
+authors: [nicolasarnedo]
+icon: Smile
+---
+
+Since the **ERC20 Bridge** course already covers ERC20↔ERC20, in this course we will cover the two native-token bridge patterns:
+
+- **Native token → ERC-20 token**: receive the bridged asset as an ERC-20 on the destination chain
+- **Native token → native token**: receive the bridged asset as the destination chain’s **native gas token**
+
+By the end, you’ll be able to deploy the required contracts, register remotes, collateralize when needed, and **test transfers using the console Token Transfer tool**.
+
+Native tokens are the backbone of any blockchain—they're used for gas fees, staking, and protocol operations. However, moving native tokens between chains presents unique challenges since native tokens aren't standard ERC-20 tokens.
+
+Avalanche's **Interchain Token Transfer (ICTT)** protocol solves this by providing a standardized way to bridge native tokens between Avalanche L1s. Think of it as a standardized implementation of a bridge, specifically for transfering tokens, built using Avalanche's ICM technology. The same way ERC20's is a standard implementation for a fungible token on a blockchain, but you can add more functionality in the smart contract, ICTT can be modified for additional requirements.
+
+### Prerequisites
+
+Before starting this course, we recommend completing:
+
+- [ERC20 Bridge](/academy/avalanche-l1/erc20-bridge) - ICTT mental model (TokenHome/TokenRemote), registration, and transfer basics
+- [L1 Native Tokenomics](/academy/avalanche-l1/l1-native-tokenomics) - Native vs ERC-20, wrapped tokens, and token decimals
+- [Interchain Messaging](/academy/avalanche-l1/interchain-messaging) - Cross-chain messaging and running a relayer
+
+
+This course focuses on using the existing testnet chains (Fuji C-Chain, Echo, and Dispatch). For the **Native → Native** flow, we will also spin up a **deployed L1** (BuilderHub hosted) with **Native Minter** enabled.
+
+
+
+Since Interchain Token Transfer relies on Interchain Messaging (ICM), you need a relayer running between the chains you’re bridging. Follow the [Running a Relayer](/academy/avalanche-l1/interchain-messaging/09-running-a-relayer/01-relayer-introduction) course to set one up (especially if you’re bridging to a deployed L1).
+
+
+### Key Concepts (what the console assumes you know)
+
+- **Wrapped native tokens**: native tokens are *not* ERC-20. ICTT’s native-token flows rely on a wrapped native token (e.g., WAVAX) as the ERC-20 representation used by contracts.
+- **Testing transfers**: after setup, use the console **Token Transfer** tool to send test transfers and verify balances/receipts end-to-end.
+- **Decimal scaling**: if the token representation changes decimals between chains, ICTT uses a multiplier so value is preserved. You usually don’t configure this manually, but you should recognize it when validating amounts.
+
+### What You'll Learn
+
+This course will walk you through:
+
+- **Native → ERC-20 bridge**: Deploy `NativeTokenHome` + `ERC20TokenRemote`, register the remote, then test transfers
+- **Native → native bridge**: Deploy `NativeTokenRemote`, register it, **add collateral**, then test transfers (destination tokens become gas tokens)
+
+### Let's Get Started!
+
+Each section builds upon the last, so we recommend completing the course in order.
diff --git a/content/academy/avalanche-l1/native-token-bridge/meta.json b/content/academy/avalanche-l1/native-token-bridge/meta.json
new file mode 100644
index 00000000000..a49e79d66da
--- /dev/null
+++ b/content/academy/avalanche-l1/native-token-bridge/meta.json
@@ -0,0 +1,14 @@
+{
+ "title": "Native Token Bridge",
+ "icon": "ArrowLeftRight",
+ "root": true,
+ "pages": [
+ "index",
+ "---Native to ERC-20 Bridge---",
+ "...01-native-to-erc-20-bridge",
+ "---Native to Native Bridge---",
+ "...02-native-to-native-bridge",
+ "---Course Completion---",
+ "certificate"
+ ]
+}
diff --git a/content/academy/blockchain/blockchain-fundamentals/07-independent-tokenomics/03-deploy-and-transfer-erc-20-tokens.mdx b/content/academy/blockchain/blockchain-fundamentals/07-independent-tokenomics/03-deploy-and-transfer-erc-20-tokens.mdx
index 4b097f968f1..8566b3ba9e1 100644
--- a/content/academy/blockchain/blockchain-fundamentals/07-independent-tokenomics/03-deploy-and-transfer-erc-20-tokens.mdx
+++ b/content/academy/blockchain/blockchain-fundamentals/07-independent-tokenomics/03-deploy-and-transfer-erc-20-tokens.mdx
@@ -12,6 +12,6 @@ In this section, you will follow a step-by-step guide to deploy an ERC-20 token
- Deploy an ERC-20 token smart contract.
- Interact with your token by transferring it between different accounts.
-To learn how to deploy an ERC-20 token and interact with your token on a blockchain, follow [this guide](/academy/interchain-token-transfer/03-tokens/08-transfer-an-erc-20-token) to explore the deployment process using the CLI on our Avalanche L1.
+To learn how to deploy an ERC-20 token and interact with your token on a blockchain, follow [this guide](/academy/avalanche-l1/l1-native-tokenomics/01-tokens-fundamentals/05-transfer-an-erc-20-token) to explore the deployment process using the CLI on our Avalanche L1.
diff --git a/content/courses.tsx b/content/courses.tsx
index 27dcaf63a23..a1f21e03788 100644
--- a/content/courses.tsx
+++ b/content/courses.tsx
@@ -80,7 +80,7 @@ const officialCourses: Course[] = [
certificateTemplate: "https://qizat5l3bwvomkny.public.blob.vercel-storage.com/AvalancheAcademy_Certificate.pdf"
},
{
- name: "ERC-20 to ERC-20 Bridge",
+ name: "ERC20 Bridge",
description: "Learn how to bridge ERC-20 tokens between Avalanche L1s using Interchain Token Transfer",
slug: "erc20-bridge",
icon: ,
@@ -93,15 +93,15 @@ const officialCourses: Course[] = [
certificateTemplate: "https://qizat5l3bwvomkny.public.blob.vercel-storage.com/AvalancheAcademy_Certificate.pdf"
},
{
- name: "Interchain Token Transfer",
- description: "Deploy Avalanche Interchain Token Transfer to transfer assets between Avalanche blockchains",
- slug: "interchain-token-transfer",
+ name: "Native Token Bridge",
+ description: "Bridge native tokens between Avalanche blockchains using Interchain Token Transfer",
+ slug: "native-token-bridge",
icon: ,
- status: "normal",
+ status: "featured",
duration: "2.5 hours",
tools: ["ICM", "Foundry"],
languages: ["Solidity"],
- instructors: ["Martin Eckardt", "Andrea Vargas", "Ash", "Owen Wahlgren", "Sarp"],
+ instructors: ["Martin Eckardt", "Owen Wahlgren", "Nicolas Arnedo"],
category: "Interoperability",
certificateTemplate: "https://qizat5l3bwvomkny.public.blob.vercel-storage.com/AvalancheAcademy_Certificate.pdf"
},
@@ -183,19 +183,6 @@ const officialCourses: Course[] = [
category: "Smart Contract Development",
certificateTemplate: "https://qizat5l3bwvomkny.public.blob.vercel-storage.com/AvalancheAcademy_Certificate.pdf"
},
- {
- name: "HyperSDK",
- description: "Learn how to build a high-performance blockchain using HyperSDK",
- slug: "hypersdk",
- icon: ,
- duration: "1 hour",
- status: "hidden",
- tools: ["HyperSDK"],
- languages: ["Go", "Typescript"],
- instructors: ["Aaron Buchwald", "Ilya", "Rodrigo Villar", "Martin Eckardt", "Owen Wahlgren"],
- category: "L1 Development",
- certificateTemplate: "https://qizat5l3bwvomkny.public.blob.vercel-storage.com/AvalancheAcademy_Certificate.pdf"
- },
{
name: "Chainlink on your L1 via ICM",
description: "Utilize Interchain Messaging to make Chainlink services available on any blockchain in the Avalanche Network",
diff --git a/next.config.mjs b/next.config.mjs
index 9463cc94b0f..6f01b7c79b0 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1812,6 +1812,147 @@ const config = {
destination: "/academy/avalanche-l1/permissioned-l1s/03-create-an-L1/03-genesis-breakdown",
permanent: true,
},
+ {
+ source: "/academy/avalanche-l1/interchain-token-transfer",
+ destination: "/academy/avalanche-l1/native-token-bridge",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/interchain-token-transfer/:path*",
+ destination: "/academy/avalanche-l1/native-token-bridge/:path*",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/cross-chain-l1-native-tokens",
+ destination: "/academy/avalanche-l1/native-token-bridge",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/cross-chain-l1-native-tokens/:path*",
+ destination: "/academy/avalanche-l1/native-token-bridge/:path*",
+ permanent: true,
+ },
+ // Broken links from analytics - round 8
+ {
+ source: "/docs/overview/getting-started/avalanche-consensus",
+ destination: "/docs/primary-network/avalanche-consensus",
+ permanent: true,
+ },
+ {
+ source: "/docs/quickstart/multisig-utxos-with-avalanchejs",
+ destination: "/docs/tooling/avalanche-sdk",
+ permanent: true,
+ },
+ {
+ source: "/docs/subnets/create-a-virtual-machine-vm",
+ destination: "/docs/avalanche-l1s/virtual-machines-index",
+ permanent: true,
+ },
+ {
+ source: "/docs/tooling/transactions/:path*",
+ destination: "/docs/tooling/avalanche-sdk",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalan",
+ destination: "/academy",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/avalanche-fundamentals/03-multi-chain-architecture-intro/:path*",
+ destination: "/academy/avalanche-l1/avalanche-fundamentals",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/customizing-evm/05-evm-configuration/:path*",
+ destination: "/academy/avalanche-l1/customizing-evm",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/interchain-messaging/08-securing-cross-chain-communication/:path*",
+ destination: "/academy/avalanche-l1/interchain-messaging",
+ permanent: true,
+ },
+ {
+ source: "/academy/avalanche-l1/multi-chain-architecture/02-custom-blockchains/:path*",
+ destination: "/academy/avalanche-l1/avalanche-fundamentals",
+ permanent: true,
+ },
+ {
+ source: "/docs/apis/avalanchego",
+ destination: "/docs/rpcs",
+ permanent: true,
+ },
+ {
+ source: "/docs/avalanche-l1s/subnet-evm/genesis",
+ destination: "/docs/avalanche-l1s/evm-configuration/customize-avalanche-l1",
+ permanent: true,
+ },
+ {
+ source: "/docs/avalanche-l1s/subnet-evm/permissioning/:path*",
+ destination: "/docs/avalanche-l1s/precompiles/transaction-allowlist",
+ permanent: true,
+ },
+ {
+ source: "/docs/basics/:path*",
+ destination: "/docs/primary-network",
+ permanent: true,
+ },
+ {
+ source: "/docs/builderkit/:path*",
+ destination: "/docs/tooling/avalanche-sdk",
+ permanent: true,
+ },
+ {
+ source: "/docs/learn/:path*",
+ destination: "/docs",
+ permanent: true,
+ },
+ {
+ source: "/docs/nodes/maintain/bootstrapping",
+ destination: "/docs/nodes/maintain/chain-state-management",
+ permanent: true,
+ },
+ {
+ source: "/docs/nodes/using-install-script/preparing-environment",
+ destination: "/docs/nodes/run-a-node/using-install-script/preparing-environment",
+ permanent: true,
+ },
+ {
+ source: "/docs/quickstart/avalanche-summit-fuji-quickstart",
+ destination: "/docs/primary-network",
+ permanent: true,
+ },
+ {
+ source: "/docs/quickstart/tools-list",
+ destination: "/docs/tooling",
+ permanent: true,
+ },
+ {
+ source: "/docs/quickstart/transfer-avax-between-x-chain-and-c-chain",
+ destination: "/docs/cross-chain",
+ permanent: true,
+ },
+ {
+ source: "/docs/subnets/create-a-evm-blockchain-on-subnet-with-avalanchejs",
+ destination: "/docs/tooling/avalanche-sdk",
+ permanent: true,
+ },
+ {
+ source: "/docs/subnets/create-a-vm-timestampvm",
+ destination: "/docs/avalanche-l1s/timestamp-vm/introduction",
+ permanent: true,
+ },
+ {
+ source: "/docs/subnets/introduction-to-vm",
+ destination: "/docs/primary-network/virtual-machines",
+ permanent: true,
+ },
+ {
+ source: "/docs/virtual-machines/manage-vm-binaries",
+ destination: "/docs/avalanche-l1s",
+ permanent: true,
+ },
];
},
};