-
Notifications
You must be signed in to change notification settings - Fork 0
feat: prepare mainnet #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
950e2f6
6d1eda3
6774976
7ea4c73
3756bdd
111d3ef
4142ea8
2492ff8
376ee66
8e0487e
468ec90
cbf938a
1463754
fbaa270
02fee6b
583fba5
a276c24
6359848
61694ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,39 @@ | ||
| CI=false # Set to true if you want to run the make file commands in CI mode (will use --private-key instead of --account option) | ||
| # =========================================== | ||
| # CI/CD CONFIGURATION | ||
| # =========================================== | ||
| # Set to true in CI environments | ||
| CI=false | ||
|
|
||
| # =========================================== | ||
| # DEPLOYMENT CONFIGURATION | ||
| # =========================================== | ||
| # Account name in your Foundry wallet for deployment | ||
| ACCOUNT=default | ||
|
|
||
| # =========================================== | ||
| # RPC_URL CONFIGURATION | ||
| # =========================================== | ||
| ETHEREUM_RPC_URL="https://gateway.tenderly.co/public/mainnet" | ||
| ARBITRUM_RPC_URL="https://arbitrum.gateway.tenderly.co" | ||
| SEPOLIA_RPC_URL="https://gateway.tenderly.co/public/sepolia" | ||
| ARBITRUM_SEPOLIA_RPC_URL="https://arbitrum-sepolia.gateway.tenderly.co" | ||
|
|
||
| # =========================================== | ||
| # ANVIL LOCAL TESTING CONFIGURATION | ||
| # =========================================== | ||
| ANVIL_SEPOLIA_RPC_URL=http://localhost:8545 | ||
| ANVIL_ARBITRUM_SEPOLIA_RPC_URL=http://localhost:8546 | ||
|
|
||
| # =========================================== | ||
| # VERIFICATION CONFIGURATION | ||
| # =========================================== | ||
| # Etherscan v2 uses a single API key for all networks. | ||
| ETHERSCAN_API_URL=https://api.etherscan.io/v2/api | ||
| # Etherscan API key for contract verification | ||
| ETHERSCAN_API_KEY= | ||
|
|
||
| # Local dev config. | ||
| ANVIL_SEPOLIA_RPC_URL=http://localhost:8545 | ||
| ANVIL_ARBITRUM_SEPOLIA_RPC_URL=http://localhost:8546 | ||
|
|
||
| # Account to be used for script execution. | ||
| # Account name in Foundry keystore | ||
| ACCOUNT=<your-account-name> | ||
| RECIPIENT_ADDRESS=<recipient-address> # for cross-chain transfers scripts | ||
| # =========================================== | ||
| # TRANSFER CONFIGURATION | ||
| # =========================================== | ||
| # Recipient address for cross-chain transfers | ||
| RECIPIENT_ADDRESS= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,8 @@ | ||
| { | ||
| "createxFactory": "0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed", | ||
| "initialAdmin": "0x9990cfb1Feb7f47297F54bef4d4EbeDf6c5463a3", | ||
| "initialUpgrader": "0x9990cfb1Feb7f47297F54bef4d4EbeDf6c5463a3", | ||
| "initialPauser": "0x9990cfb1Feb7f47297F54bef4d4EbeDf6c5463a3", | ||
| "initialAdmin": "0x111165a109feca14e4ad4d805f6460c7d206ead1", | ||
zguesmi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "initialUpgrader": "0x111121e2ec2557f484f65d5b1ad2b6b07b8acd23", | ||
| "initialPauser": "0x11113fe3513787f5a4f5f19690700e2736b3056e", | ||
|
Comment on lines
+3
to
+5
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we add a TODO for that in the readme ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you mean |
||
| "chains": { | ||
| "sepolia": { | ||
| "approvalRequired": true, | ||
|
|
@@ -22,6 +22,25 @@ | |
| "iexecLayerZeroBridgeCreatexSalt": "0x4f2784ad07b2be2a5c5e466c91d758133f4aa33bd4cf09ddba1a1e1035e57875", | ||
| "lzEndpointAddress": "0x6EDCE65403992e310A62460808c4b910D972f10f", | ||
| "lzChainId": 40231 | ||
| }, | ||
| "ethereum": { | ||
| "approvalRequired": true, | ||
| "rlcAddress": "0x607F4C5BB672230e8672085532f7e901544a7375", | ||
| "rlcLiquidityUnifierAddress": "0x0000000000000000000000000000000000000000", | ||
| "rlcLiquidityUnifierCreatexSalt": "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| "iexecLayerZeroBridgeAddress": "0x0000000000000000000000000000000000000000", | ||
| "iexecLayerZeroBridgeCreatexSalt": "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| "lzEndpointAddress": "0x1a44076050125825900e736c501f859c50fE728c", | ||
| "lzChainId": 30101 | ||
| }, | ||
| "arbitrum": { | ||
| "approvalRequired": false, | ||
| "rlcCrosschainTokenAddress": "0x0000000000000000000000000000000000000000", | ||
| "rlcCrosschainTokenCreatexSalt": "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| "iexecLayerZeroBridgeAddress": "0x0000000000000000000000000000000000000000", | ||
| "iexecLayerZeroBridgeCreatexSalt": "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
| "lzEndpointAddress": "0x1a44076050125825900e736c501f859c50fE728c", | ||
| "lzChainId": 30110 | ||
| } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need two scripts? Can’t we have a single contract script that handles the transfer in both directions?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could yes
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,12 +3,20 @@ | |
| pragma solidity ^0.8.22; | ||
|
|
||
| import {Script, console} from "forge-std/Script.sol"; | ||
|
Comment on lines
3
to
5
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No important change just cleaning |
||
| import {ConfigLib} from "./lib/ConfigLib.sol"; | ||
| import {IexecLayerZeroBridge} from "../src/bridges/layerZero/IexecLayerZeroBridge.sol"; | ||
| import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
| import {SendParam} from "@layerzerolabs/oft-evm/contracts/interfaces/IOFT.sol"; | ||
| import {MessagingFee} from "@layerzerolabs/oapp-evm/contracts/oapp/OApp.sol"; | ||
| import {IexecLayerZeroBridge} from "../src/bridges/layerZero/IexecLayerZeroBridge.sol"; | ||
| import {ConfigLib} from "./lib/ConfigLib.sol"; | ||
|
|
||
| /** | ||
| * Script to send tokens from Arbitrum Mainnet to Ethereum Mainnet. | ||
| * This script demonstrates cross-chain token transfers using LayerZero bridge. | ||
| */ | ||
| // TODO: fusion SendTokensFromArbitrumToEthereum and SendTokensFromEthereumToArbitrum into a single script with dynamic chain handling | ||
| contract SendTokensFromArbitrumToEthereum is Script { | ||
| uint256 private constant TRANSFER_AMOUNT = 10 * 10 ** 9; // 10 RLC tokens with 9 decimals | ||
|
|
||
| /** | ||
| * @dev Converts an address to bytes32. | ||
| * @param _addr The address to convert. | ||
|
|
@@ -18,45 +26,59 @@ contract SendTokensFromArbitrumToEthereum is Script { | |
| return bytes32(uint256(uint160(_addr))); | ||
| } | ||
|
|
||
| /** | ||
| * Main function to execute the cross-chain transfer. | ||
| * Reads configuration and sends tokens from Arbitrum to Ethereum. | ||
| */ | ||
| function run() external { | ||
| string memory sourceChain = vm.envString("SOURCE_CHAIN"); | ||
| string memory targetChain = vm.envString("TARGET_CHAIN"); | ||
|
|
||
| ConfigLib.CommonConfigParams memory sourceParams = ConfigLib.readCommonConfig(sourceChain); | ||
| ConfigLib.CommonConfigParams memory targetParams = ConfigLib.readCommonConfig(targetChain); | ||
|
|
||
| // Contract addresses | ||
| address iexecLayerZeroBridgeAddress = sourceParams.iexecLayerZeroBridgeAddress; | ||
|
|
||
| // Transfer parameters | ||
| uint16 destinationChainId = uint16(targetParams.lzChainId); // LayerZero chain ID for Ethereum Sepolia | ||
| address recipientAddress = vm.envAddress("RECIPIENT_ADDRESS"); | ||
| console.log("Recipient: %s", recipientAddress); | ||
| IexecLayerZeroBridge sourceBridge = IexecLayerZeroBridge(sourceParams.iexecLayerZeroBridgeAddress); | ||
| IERC20 rlcToken = IERC20(sourceParams.rlcCrosschainTokenAddress); | ||
|
|
||
| uint256 amount = 5 * 10 ** 9; // RLC tokens (adjust the amount as needed) | ||
| address sender = vm.envAddress("RECIPIENT_ADDRESS"); | ||
| address recipient = vm.envAddress("RECIPIENT_ADDRESS"); | ||
|
|
||
| // Send tokens cross-chain | ||
| IexecLayerZeroBridge iexecLayerZeroBridge = IexecLayerZeroBridge(iexecLayerZeroBridgeAddress); | ||
| console.log("Sending %s RLC to Ethereum Sepolia", amount / 10 ** 9); | ||
| // Check sender's balance | ||
| uint256 senderBalance = rlcToken.balanceOf(sender); | ||
| require(senderBalance >= TRANSFER_AMOUNT, "Insufficient RLC balance"); | ||
|
|
||
| // Prepare send parameters | ||
| SendParam memory sendParam = SendParam( | ||
| destinationChainId, // Destination endpoint ID. | ||
| addressToBytes32(recipientAddress), // Recipient address. | ||
| amount, // amount (in local decimals, e.g., 5 RLC = 5 * 10 ** 9) | ||
| amount * 99 / 100, // minAmount (allowing 1% slippage) | ||
| "", // Extra options, not used in this case, already setup using `setEnforcedOptions` | ||
| "", // Composed message, not used in this case | ||
| "" // OFT command to be executed, unused in default OFT implementations. | ||
| uint16(targetParams.lzChainId), // Destination endpoint ID | ||
| addressToBytes32(recipient), // Recipient address | ||
| TRANSFER_AMOUNT, // Amount to send in local decimals | ||
| TRANSFER_AMOUNT * 99 / 100, // Minimum amount to send (allowing 1% slippage) | ||
| "", // Extra options, already set via setEnforcedOptions | ||
| "", // Composed message for send() operation (unused) | ||
| "" // OFT command to be executed (unused in default OFT) | ||
| ); | ||
|
|
||
| // Get the fee for the transfer | ||
| MessagingFee memory fee = iexecLayerZeroBridge.quoteSend(sendParam, false); | ||
| console.log("Fee amount: ", fee.nativeFee); | ||
| // Get quote for the transfer | ||
| MessagingFee memory fee = sourceBridge.quoteSend(sendParam, false); | ||
|
|
||
| console.log("=== Cross-Chain Transfer Details ==="); | ||
| console.log("From: Arbitrum Mainnet"); | ||
| console.log("To: Ethereum Mainnet"); | ||
| console.log("Amount: %d RLC", TRANSFER_AMOUNT / 10 ** 9); | ||
| console.log("Fee: %d wei", fee.nativeFee); | ||
| console.log("Sender: %s", sender); | ||
| console.log("Recipient: %s", recipient); | ||
| console.log("Sender Balance: %d RLC", senderBalance / 10 ** 9); | ||
|
|
||
| vm.startBroadcast(); | ||
| // Execute the cross-chain transfer | ||
| iexecLayerZeroBridge.send{value: fee.nativeFee}(sendParam, fee, msg.sender); | ||
|
|
||
| console.log("Cross-chain transfer from Arbitrum to Ethereum initiated!"); | ||
| // Note: For crosschain tokens, no approval is needed as the bridge can burn directly | ||
| console.log("Initiating cross-chain transfer..."); | ||
| sourceBridge.send{value: fee.nativeFee}(sendParam, fee, payable(sender)); | ||
|
|
||
| vm.stopBroadcast(); | ||
|
|
||
| console.log("Transfer initiated successfully!"); | ||
| console.log("Monitor the destination chain for token receipt."); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.