Skip to main content

Interactions

Settlement interactions enable CoW Protocol settlements to execute arbitrary smart contract calls at specific execution stages.

Interaction Interface

interface Interaction {
  target: string;       // Smart contract address
  value: BigNumberish;  // ETH value to send
  callData: string;     // Encoded function call data
}

InteractionLike

A flexible partial type with optional fields:
interface InteractionLike {
  target: string;
  value?: BigNumberish;  // Defaults to 0
  callData?: string;     // Defaults to "0x"
}

Execution Stages

enum InteractionStage {
  PRE = 0,   // Before token transfers
  INTRA = 1, // During trading (after sells, before buys)
  POST = 2,  // After all trading
}

PRE Stage

Executes before token transfers. Useful for:
  • EIP-2612 permit calls
  • Token wrapping (e.g., ETH to WETH)
  • Setting up approvals
encoder.encodeInteraction({
  target: tokenAddress,
  callData: token.interface.encodeFunctionData("permit", [
    owner, spender, value, deadline, v, r, s
  ]),
}, InteractionStage.PRE);

INTRA Stage

Executes during trading, after sell tokens arrive but before buy tokens are distributed. Default stage if none specified.
// Uniswap swap for liquidity sourcing
encoder.encodeInteraction({
  target: uniswapRouter,
  callData: router.interface.encodeFunctionData("exactInputSingle", [params]),
}, InteractionStage.INTRA);

POST Stage

Executes after all trading concludes. Used for cleanup:
// WETH unwrapping
encoder.encodeInteraction({
  target: wethAddress,
  callData: weth.interface.encodeFunctionData("withdraw", [amount]),
}, InteractionStage.POST);

Helper Functions

normalizeInteraction

Converts an InteractionLike into a complete Interaction with default values:
import { normalizeInteraction } from "@cowprotocol/contracts";

const interaction = normalizeInteraction({
  target: contractAddress,
  // value defaults to 0
  // callData defaults to "0x"
});

normalizeInteractions

Handles arrays of interactions:
import { normalizeInteractions } from "@cowprotocol/contracts";

const interactions = normalizeInteractions([
  { target: addr1, callData: data1 },
  { target: addr2, callData: data2 },
]);

Integration with SettlementEncoder

The encodeInteraction() method adds interactions to settlements. If no stage is specified, InteractionStage.INTRA is the default.
const encoder = new SettlementEncoder(domain);

// Pre-settlement permit
encoder.encodeInteraction(permitInteraction, InteractionStage.PRE);

// Intra-settlement swap (default stage)
encoder.encodeInteraction(swapInteraction);

// Post-settlement cleanup
encoder.encodeInteraction(unwrapInteraction, InteractionStage.POST);

Common Use Cases

  • EIP-2612 permit calls for gasless approvals
  • Uniswap/Curve swaps for liquidity sourcing
  • WETH wrapping/unwrapping
  • Post-settlement fee distributions

Best Practices

  • Select appropriate stages based on token balance availability
  • Minimize interactions for gas efficiency
  • Ensure all calls will succeed (failures cause the entire settlement to revert)
  • Be cautious with reentrancy risks
Last modified on March 4, 2026