Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions script/demoScripts/CallPolymerCCTP.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/bin/bash

# Exit on error
set -e

# Color codes for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# Function to display usage
usage() {
echo "Usage: $0 <RPC_URL> <PRIVATE_KEY> <DESTINATION_DOMAIN> <ADDRESSES_FILE>"
echo ""
echo "Required arguments:"
echo " RPC_URL RPC endpoint URL"
echo " PRIVATE_KEY Private key for deployment"
echo " DESTINATION_DOMAIN Destination domain for CCTP bridge"
echo " ADDRESSES_FILE Path to addresses json"
echo ""
echo "Example:"
echo " $0 https://arb-sepolia.g.alchemy.com/v2/KEY 0xYOURKEY 3 ./testnet-addresses.json"
exit 1
}

# Check if we have the required number of arguments
if [ $# -lt 4 ]; then
echo -e "${RED}Error: Missing required arguments${NC}\n"
usage
fi

# Parse positional arguments
RPC_URL="$1"
PRIVATE_KEY="$2"
DESTINATION_DOMAIN="$3"
ADDRESSES_FILE="$4"

# Get chain ID from RPC
echo -e "${BLUE}Fetching chain ID from RPC...${NC}"
if ! CHAIN_ID=$(cast chain-id -r "$RPC_URL" 2>&1); then
echo -e "${RED}Error: cast chain-id failed for $RPC_URL${NC}"
echo "$CHAIN_ID"
exit 1
fi
if [ -z "$CHAIN_ID" ]; then
echo -e "${RED}Error: Could not fetch chain ID from RPC${NC}"
exit 1
fi
echo -e "${GREEN}Chain ID: $CHAIN_ID${NC}"

# Read DIAMOND_ADDRESS and USDC from addresses.json
DIAMOND_ADDRESS=$(jq -r --arg chainId "$CHAIN_ID" '.[$chainId].diamondProxy // empty' "$ADDRESSES_FILE")
if [ -z "$DIAMOND_ADDRESS" ]; then
echo -e "${RED}Error: DIAMOND_ADDRESS not found in $ADDRESSES_FILE for chain $CHAIN_ID${NC}"
echo "Please deploy the diamond first using DeployPolymerContracts.sh"
exit 1
fi
echo -e "${BLUE}Using DIAMOND_ADDRESS from $ADDRESSES_FILE: $DIAMOND_ADDRESS${NC}"

if [ -z "$USDC" ]; then
USDC=$(jq -r --arg chainId "$CHAIN_ID" '.[$chainId].usdc // empty' "$ADDRESSES_FILE")
if [ -z "$USDC" ]; then
echo -e "${RED}Error: USDC not found in $ADDRESSES_FILE for chain $CHAIN_ID and not set in environment${NC}"
echo "Please either:"
echo " 1. Set USDC environment variable, or"
echo " 2. Add it to $ADDRESSES_FILE under \"$CHAIN_ID\": { \"usdc\": \"0x...\" }"
exit 1
fi
echo -e "${BLUE}Using USDC from $ADDRESSES_FILE: $USDC${NC}"
fi

# Export all variables for forge scripts
export RPC_URL
export CHAIN_ID
export PRIVATE_KEY
export DESTINATION_DOMAIN
export DIAMOND_ADDRESS
export USDC

echo -e "${BLUE}Calling PolymerCCTPFacet on chain $CHAIN_ID...${NC}"

# Run the call script
forge script ./script/demoScripts/PolymerCCTP.s.sol \
--rpc-url "$RPC_URL" \
--broadcast \
--verify

echo -e "${GREEN}PolymerCCTP call complete!${NC}"
69 changes: 69 additions & 0 deletions script/demoScripts/PolymerCCTP.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import {Script, console2} from "forge-std/Script.sol";
import {LiFiDiamond} from "lifi/LiFiDiamond.sol";
import {PolymerCCTPFacet, PolymerCCTPData} from "lifi/Facets/PolymerCCTPFacet.sol";
import {ILiFi} from "lifi/Interfaces/ILiFi.sol";
import {LibSwap} from "lifi/Libraries/LibSwap.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract CallPolymerCCTPFacet is Script {
function run() external payable {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address diamondAddress = vm.envAddress("DIAMOND_ADDRESS");
uint32 destinationDomain = uint32(vm.envUint("DESTINATION_DOMAIN"));
address receiver = vm.addr(deployerPrivateKey);
uint256 amount = uint256(1000);
uint256 polymerTokenFee = uint256(10);
uint32 maxCCTPFee = uint32(vm.envOr("MAX_CCTP_FEE", uint256(100)));
uint32 minFinalityThreshold = uint32(vm.envOr("MIN_FINALITY_THRESHOLD", uint256(0)));

console2.log("Diamond Proxy address:", diamondAddress);
// Cast diamond to PolymerCCTPFacet to call its functions
PolymerCCTPFacet polymerFacet = PolymerCCTPFacet(diamondAddress);
address usdcAddress = vm.envAddress("USDC");

// Get USDC address from the PolymerCCTPFacet
console2.log("USDC address:", usdcAddress);

vm.startBroadcast(deployerPrivateKey);

// Approve USDC spending
IERC20(usdcAddress).approve(diamondAddress, amount + polymerTokenFee);

// Prepare bridge data
ILiFi.BridgeData memory bridgeData = ILiFi.BridgeData({
transactionId: bytes32(uint256(1)), // Simple transaction ID
bridge: "PolymerCCTP",
integrator: "LiFi",
referrer: address(0),
sendingAssetId: usdcAddress,
receiver: receiver,
minAmount: amount,
destinationChainId: uint256(destinationDomain), // Using domain as chain ID to avoid SLOAD to read from a mapping - this seems like it can just directly be passed via calldata.
hasSourceSwaps: false,
hasDestinationCall: false
});

// Prepare Polymer-specific data
PolymerCCTPData memory polymerData = PolymerCCTPData({
polymerTokenFee: polymerTokenFee,
maxCCTPFee: maxCCTPFee,
minFinalityThreshold: minFinalityThreshold,
nonEvmAddress: bytes32(0)
});

console2.log("Calling startBridgeTokensViaPolymerCCTP...");
console2.log("Amount:", amount);
console2.log("Destination Domain:", destinationDomain);
console2.log("Receiver:", receiver);

// Call the bridge function
polymerFacet.startBridgeTokensViaPolymerCCTP(bridgeData, polymerData);

console2.log("Bridge transaction initiated successfully");

vm.stopBroadcast();
}
}
Loading