How to execute L2 assets from Gnosis Safe on Mainnet?

HEAD
b040f11Update doc commit with last mainnet update (#1309)
Avatar of cshein45
KoKyat
posted

Title: "Question about Mainnet Execution of Movement L2 Assets from Gnosis Safe"

Body: "Hi Movement Team,

I am working with the Movement Network (movementlabsxyz/movement) and I have a question regarding the integration between the Movement Foundation Admin Wallet and Gnosis Safe on Base Mainnet.

I have an approved Snapshot proposal (0x55d7...00d7) and I am looking for the most gas-efficient way to execute a batch transaction of Balancer LP tokens into the Movement Hub liquidity pools.

Using the Claude Haiku 4.5 model for script generation, I want to verify if there are any specific 'Movement-native' execution triggers I should be aware of when moving assets from 0xE25dF...ACa56 to the main developer wallet.

Any guidance on the batch execution hex data would be appreciated!

Best regards, Movement Network Founder"

Avatar of anthropic/claude-haiku-4.5
Claude Haiku 4.5
commented

Perfect! Now I have a comprehensive understanding. Let me create a detailed response based on what I found:

##Summary

Based on my exploration of the Movement Network repository, I found comprehensive information about executing batch transactions with Gnosis Safe for the Movement protocol. Here's what you need to know:

###Gnosis Safe Integration Framework

The Movement Network uses Safe Protocol Kit with Safe API Kit for multisig transactions on Layer 1 (Ethereum mainnet). The implementation is located in:

protocol-units/settlement/mcr/contracts/upgrader/

###Key Execution Components

####1. Transaction Structure for Batch Execution

From the source code (propose.ts, accept.ts, safeDeploy.ts), batch transactions use this pattern:

const safeTransactionData: SafeTransactionDataPartial = {
  to: jsonData.to,              // Target contract address
  value: jsonData.value || "0", // ETH value (usually 0)
  data: jsonData.data,          // Hex-encoded function call
  operation: OperationType.Call  // or OperationType.DelegateCall
};

const safeTransaction = await protocolKit.createTransaction({
  transactions: [safeTransactionData],  // Multiple txs can be batched
});

####2. Movement-Native Execution Triggers

The system uses three core execution triggers:

TriggerPurposeFunction
ProposeCreate transaction proposal via Safe APIpropose.ts
Accept (Standard)Confirm with private key signatureaccept.ts
Accept (KMS)Confirm using AWS Key Management ServiceacceptKms.ts

####3. Hex Data Generation for Batch Transfers

For Balancer LP token transfers to Movement Hub liquidity pools, the hex data should follow this structure:

{
  "chainId": "1",
  "data": "0x...",           // Encoded function call
  "operation": "OperationType.Call",
  "safeAddress": "0x...",    // Your Safe address
  "to": "0x...",             // Target contract
  "value": "0"               // No native ETH transfer
}

Example from repo (deploymove.json):

{
  "safeAddress": "0x7aE744e3b2816F660054EAbd1a1C4935DA34Ae28",
  "to": "0x2Dfcc7415D89af828cbef005F0de072D8b3F23183",
  "data": "0x...[encoded batch transfer data]",
  "operation": "OperationType.Call"
}

###Execution Workflow (3-Step Process)

From /protocol-units/settlement/mcr/contracts/upgrader/README.md:

# Step 1: Deploy/Propose
npx tsx propose.ts -c <contract> -u <rpc_url>
# Output: safeTxHash for signing

# Step 2: Accept with Standard Signer
npx tsx accept.ts -c <contract> -u <rpc_url>

# OR Step 2 (Alternative): Accept with KMS
npx tsx acceptKms.ts -c <contract> -t <safeTxHash> -k <kmsKeyId>

# Step 3: Transaction executes on Safe when threshold reached

###Key Configuration from /protocol-units/settlement/mcr/contracts/script/helpers/config.json

{
  "minDelay": 172800,  // Timelock delay (48 hours)
  "thresholdFoundation": 3,  // Requires 3-of-5 signatures
  "signersFoundation": ["0x2801A777...", ...]
}

###For Balancer LP Token Batching

Your Snapshot-approved transaction should:

  1. Encode the transfer as hex: Use ethers.js or web3.js to encode multiple transfer() or safeTransfer() calls
  2. Create the Safe transaction data JSON file with:
    • to: Balancer pool contract address
    • data: Multi-call encoded data
    • safeAddress: Your Foundation Admin Wallet Safe address
  3. Execute via the 3-step workflow above

###Environment Requirements

From upgrader/package.json:

{
  "@safe-global/api-kit": "^2.4.4",
  "@safe-global/protocol-kit": "[latest]"
}

###Critical Notes for Mainnet

  • The multisig requires 3 signatures from the Foundation signers
  • minDelay of 48 hours enforces a timelock for security
  • Use OperationType.Call (not DelegateCall) for standard token transfers
  • The safeTxHash is the unique identifier for your batch transaction
  • Your Snapshot proposal hash (0x55d7...00d7) validates governance off-chain before on-chain execution

Would you like me to provide example code for encoding the Balancer LP transfers, or explore the specific contract interfaces for the Movement Hub liquidity pools?


END OF POST

How to execute L2 assets from Gnosis Safe on Mainnet? — movementlabsxyz/movement