Skip to content

Commit

Permalink
bridging task
Browse files Browse the repository at this point in the history
  • Loading branch information
0xCalibur committed Dec 16, 2024
1 parent b008497 commit 62320ca
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 19 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import 'hardhat-deploy-ethers'
import 'hardhat-contract-sizer'
import '@nomiclabs/hardhat-ethers'
import '@layerzerolabs/toolbox-hardhat'
import './tasks'

import { HardhatUserConfig, HttpNetworkAccountsUserConfig } from 'hardhat/types'

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"ethers": "^5.7.2",
"hardhat-deploy": "^0.12.1"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.23.9",
"@layerzerolabs/devtools-evm-hardhat": "^2.0.3",
Expand All @@ -35,6 +36,7 @@
"@layerzerolabs/test-devtools-evm-foundry": "~5.1.0",
"@layerzerolabs/toolbox-foundry": "~0.1.9",
"@layerzerolabs/toolbox-hardhat": "~0.6.2",
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-waffle": "^2.0.6",
"@openzeppelin/contracts": "^5.0.2",
Expand All @@ -54,6 +56,7 @@
"hardhat-contract-sizer": "^2.10.0",
"hardhat-deploy": "^0.12.1",
"hardhat-deploy-ethers": "^0.3.0-beta.13",
"inquirer": "^12.2.0",
"mocha": "^10.2.0",
"prettier": "^3.2.5",
"solhint": "^4.1.1",
Expand Down
19 changes: 0 additions & 19 deletions script/Counter.s.sol

This file was deleted.

138 changes: 138 additions & 0 deletions tasks/bridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import inquirer from 'inquirer';
import { formatEther } from "ethers/lib/utils";
import { Options } from '@layerzerolabs/lz-v2-utilities';
import { addressToBytes32 } from '@layerzerolabs/lz-v2-utilities';

/**
Usage:
bunx hardhat bridge \
--token SPELL \
--network ethereum-mainnet \
--dst-chain arbitrum-mainnet \
--to 0xRecipientAddress \
--amount 1.5
*/

// Token configurations
const TOKEN_CONFIGS = {
SPELL: {
symbol: 'SPELL',
decimals: 18,
networks: {
'ethereum-mainnet': {
type: 'adapter',
contractName: 'AbraOFTAdapterUpgradeable',
underlying: '0x090185f2135308BaD17527004364eBcC2D37e5F6',
deploymentName: 'SpellOFT',
},
'arbitrum-mainnet': {
type: 'oft',
contractName: 'AbraOFTUpgradeable',
deploymentName: 'SpellOFT',
}
}
}
};

task("bridge", "Bridge tokens from one chain to another")
.addParam("token", "The token symbol to bridge (e.g., SPELL, bSPELL)")
.addParam("dstChain", "The destination chain name (e.g., 'arbitrum-mainnet')")
.addParam("to", "The recipient address")
.addParam("amount", "Amount of tokens to send (in human readable format)")
.setAction(async (taskArgs, hre: HardhatRuntimeEnvironment) => {
const { token: tokenSymbol, dstChain, to, amount } = taskArgs;

// Get destination chain endpoint ID from config
const dstEid = hre.config.networks[dstChain]?.eid;
if (!dstEid) {
throw new Error(`Destination chain ${dstChain} not configured or missing endpoint ID`);
}

const tokenConfig = TOKEN_CONFIGS[tokenSymbol as keyof typeof TOKEN_CONFIGS];
if (!tokenConfig) throw new Error(`Unknown token symbol: ${tokenSymbol}`);

const networkConfig = tokenConfig.networks[hre.network.name as keyof typeof tokenConfig.networks];
if (!networkConfig) throw new Error(`Token ${tokenSymbol} not configured for network ${hre.network.name}`);

const [sender] = await hre.ethers.getSigners();
const oftContract = await hre.ethers.getContract(networkConfig.deploymentName);
const underlyingToken = await hre.ethers.getContractAt("IERC20", oftContract.address);
const decimals = tokenConfig.decimals;
const amountInWei = hre.ethers.utils.parseUnits(amount, decimals);

//console.log(`decimals: ${decimals}`);
//console.log(`amount (wei): ${amountInWei}`);

// Handle approvals for adapter
if (networkConfig.type === 'adapter') {
const adapterConfig = networkConfig as { type: 'adapter', underlying: string };
const underlyingToken = await hre.ethers.getContractAt("IERC20", adapterConfig.underlying);
const allowance = await underlyingToken.allowance(sender.address, underlyingToken.address);
//console.log(`allowance: ${allowance}`);

if (allowance.lt(amountInWei)) {
console.log(`Approving ${tokenSymbol} tokens to OFT adapter...`);
const approveTx = await underlyingToken.approve(underlyingToken.address, amountInWei);
await approveTx.wait();
console.log("Approval successful!");
}
}

// Prepare send parameters with optimized gas settings
const options = Options.newOptions().addExecutorLzReceiveOption(65000, 0).toBytes();
const sendParam = {
dstEid,
to: addressToBytes32(to),
amountLD: amountInWei,
minAmountLD: amountInWei,
extraOptions: options,
composeMsg: "0x",
oftCmd: "0x"
};

// Get quote for the bridge transaction
const quote = await oftContract.quoteSend(sendParam, false);

// Show confirmation prompt with enhanced details
const answers = await inquirer.prompt([{
type: 'confirm',
name: 'proceed',
message: `
Bridge Details:
- From: ${hre.network.name} (EID: ${hre.config.networks[hre.network.name]?.eid})
- To: ${dstChain} (EID: ${dstEid})
- Token: ${tokenSymbol}
- Amount: ${amount} ${tokenSymbol}
- Recipient: ${to}
- Bridge Fee: ${formatEther(quote.nativeFee)} ${hre.network.name.includes('ethereum') ? 'ETH' : 'native token'}
- OFT Contract: ${oftContract.address}
Do you want to proceed?`,
default: false
}]);

if (!answers.proceed) {
console.log("Bridge operation cancelled");
return;
}

try {
const tx = await oftContract.send(
sendParam,
{ nativeFee: quote.nativeFee, lzTokenFee: 0 },
sender.address,
{ value: quote.nativeFee }
);
await tx.wait();

console.log(`Bridge transaction successful!`);
console.log(`Transaction: https://layerzeroscan.com/tx/${tx.hash}`);
console.log(`Native fee paid: ${formatEther(quote.nativeFee)}`);
} catch (error) {
console.error("Error bridging tokens:", error);
throw error;
}
});
1 change: 1 addition & 0 deletions tasks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "./bridge";

0 comments on commit 62320ca

Please sign in to comment.