const { ethers } = require("hardhat")
require('dotenv').config()
// Initiate token names
const NAME = "TestBridge"
const SYMBOL = "TESTBRIDGE"
const SHARED_DECIMALS = 5
const firstEndpoint = '0x93f54D755A063cE7bB9e6Ac47Eccc8e33411d706'
const secondEndpoint = '0xbfD2135BFfbb0B5378b56643c2Df8a87552Bfa23'
const firstLZId = 10106
const secondLZId = 10121
// Initiate two ethers instances 1 for each chain
const firstProvider = new ethers.JsonRpcProvider(process.env.FUJI_RPC_URL)
const secondProvider = new ethers.JsonRpcProvider(process.env.GOERLI_RPC_URL)
const firstWallet = new ethers.Wallet(process.env.PRIVATE_KEY, firstProvider)
const secondWallet = new ethers.Wallet(process.env.PRIVATE_KEY, secondProvider)
const initialAmount = ethers.parseEther("1.00000001").toString() // 1 ether
const amount = ethers.parseEther("1.00000000")
const dust = ethers.parseEther("0.00000001")
const abiCoder = ethers.AbiCoder.defaultAbiCoder()
const walletAddressBytes32 = abiCoder.encode(["address"], [firstWallet.address])
async function main() {
await deployContracts()
}
main()
// Get contract factories
async function deployContracts() {
console.log('Getting contract factories...\n')
const ERC20 = await ethers.getContractFactory("ERC20Mock", firstWallet)
const ProxyOFTV2 = await ethers.getContractFactory("ProxyOFTV2", firstWallet)
const OFTV2 = await ethers.getContractFactory("OFTV2", secondWallet)
// const erc20Address = "0xF49c606621280Ec3Be5861c2eb0e919C8d171F54"
// const localOFTAddress = "0xBa8a5316744A3Cb4C07f9bEb428447b8Af4448a6"
// const remoteOFTAddress = "0x6B50f3dA64742dE3cAC38c818f528A4F90988eCF"
// const erc20 = ERC20.attach(erc20Address)
// const localOFT = ProxyOFTV2.attach(localOFTAddress)
// const remoteOFT = OFTV2.attach(remoteOFTAddress)
// Deploy ERC20 on Fuji chain
// Deploy proxy on Fuji chain
// Deploy OFTV2 on Mumbai chain
console.log('Deploying Contracts...\n')
const erc20ConstructorArgs = [NAME, SYMBOL]
const erc20 = await ERC20.deploy(...erc20ConstructorArgs) // Deploy token
await erc20.waitForDeployment()
const erc20Address = await erc20.getAddress()
console.log("ERC20: ", erc20Address)
const localOFTConstructorArgs = [erc20Address, SHARED_DECIMALS, firstEndpoint]
const localOFT = await ProxyOFTV2.deploy(...localOFTConstructorArgs) // Deploy proxy to token with token address and local endpoint address
await localOFT.waitForDeployment()
const localOFTAddress = await localOFT.getAddress()
console.log("Fuji OFT: ", localOFTAddress)
const remoteOFTConstructructorArgs = [NAME, SYMBOL, SHARED_DECIMALS, secondEndpoint]
const remoteOFT = await OFTV2.deploy(...remoteOFTConstructructorArgs) // Deploy remote token with remote endpoint address
await remoteOFT.waitForDeployment()
const remoteOFTAddress = await remoteOFT.getAddress()
console.log("Remote OFT: ", remoteOFTAddress)
// Set paths
console.log('Setting Paths...\n')
firstPath = ethers.solidityPacked(["address", "address"], [secondEndpoint, firstEndpoint])
secondPath = ethers.solidityPacked(["address", "address"], [firstEndpoint, secondEndpoint])
await localOFT.setTrustedRemote(secondLZId, firstPath) // for A, set B
console.log('Set path for first')
await remoteOFT.setTrustedRemote(firstLZId, secondPath) // for B, set A
console.log('Set path for second')
// Mint tokens
console.log('Minting Tokens...\n')
let tx = await erc20.mint(firstWallet, initialAmount)
await tx.wait()
// SWAP TOKENS FROM ALICE TO BOB
// 1. Approve the proxy to swap your tokens
console.log('Approving Tokens...\n')
tx = await erc20.approve(localOFTAddress, initialAmount)
await tx.wait()
// Set min gas fee
console.log('Setting min dst gas...\n')
tx = await localOFT.setMinDstGas(secondLZId, 0, 200000)
await tx.wait()
tx = await localOFT.setMinDstGas(secondLZId, 1, 200000)
await tx.wait()
tx = await remoteOFT.setMinDstGas(firstLZId, 0, 200000)
await tx.wait()
tx = await remoteOFT.setMinDstGas(firstLZId, 1, 200000)
await tx.wait()
// 3. Estimate gas
console.log('Estimating Fee...\n')
let nativeFee = (await localOFT.estimateSendFee(
secondLZId, // layezero chain id
walletAddressBytes32,
initialAmount,
false,
"0x"
)).nativeFee
let adapterParams = ethers.solidityPacked(["uint16", "uint256"], [0, 200000]) // 0 for sendFrom
// 4. Send to end chain
console.log('Sending Transaction...\n')
tx = await localOFT.sendFrom(
firstWallet.address, // from address to send from
secondLZId, // layerzero chain id
walletAddressBytes32, // bytes of to address
initialAmount, // amount to send
[
firstWallet.address,
ethers.ZeroAddress,
adapterParams
],
{ value: nativeFee }
)
const receipt = await tx.wait()
console.log(receipt)
console.log('\n\n\nSwap has been made \n\n\n')
// SEND TOKENS BACK TO START CHAIN
const halfAmount = amount.div(2)
// 1. Create bytes32 of alice's address
const aliceAddressBytes32 = abiCoder.encode(["address"], [firstWallet.address])
// 2. Estimate gas fee
nativeFee = (await remoteOFT.estimateSendFee(firstLZId, aliceAddressBytes32, halfAmount, false, "0x")).nativeFee
// 3. Send to alice
tx = await remoteOFT.sendFrom(
firstWallet.address,
firstLZId,
aliceAddressBytes32,
halfAmount,
[firstWallet.address, ethers.ZeroAddress, "0x"],
{ value: nativeFee }
)
const receipt2 = await tx.wait()
console.log(receipt2)
// TOKENS HAVE BEEN SWAPPED
console.log('\n\n\nSwapped back\n\n\n')
}