# Multicalls

Build and execute multicalls using SDK service helpers.

> For Solidity multicall encoding, see [Multicalls](https://docs.gearbox.finance/dev/solidity-guide/multicalls).

## Service Multicall Helpers

The SDK provides structured multicall builders via `createCreditAccountService`:

```typescript
import { GearboxSDK, createCreditAccountService } from '@gearbox-protocol/sdk';

const sdk = await GearboxSDK.attach({ client, marketConfigurators: [] });
const service = createCreditAccountService(sdk, 310);
```

## Available Service Methods

| Method                                         | Operation                  |
| ---------------------------------------------- | -------------------------- |
| `prepareAddCollateral(token, amount)`          | Add collateral from wallet |
| `prepareIncreaseDebt(amount)`                  | Borrow from pool           |
| `prepareDecreaseDebt(amount)`                  | Repay debt                 |
| `prepareUpdateQuota(token, change, minQuota)`  | Adjust token quota         |
| `prepareWithdrawCollateral(token, amount, to)` | Remove collateral          |

## Detailed Operation Guides

For comprehensive documentation of each operation:

**SDK Helper Operations:**

* [Adding Collateral](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/adding-collateral) - Transfer tokens with approval patterns
* [Debt Management](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/debt-management) - Borrowing, repayment, and constraints
* [Updating Quotas](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/updating-quotas) - Quota mechanics and limits
* [Withdrawing Collateral](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/withdrawing-collateral) - Safe pricing and health impact

**Manual Encoding Operations:**

* [Controlling Slippage](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/controlling-slippage) - Balance delta protection
* [Making External Calls](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/making-external-calls) - Adapter interaction patterns
* [Enabling/Disabling Tokens](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/enabling-disabling-tokens) - Token mask management
* [Updating Price Feeds](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/updating-price-feeds) - On-demand oracle data
* [Collateral Check Params](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/collateral-check-params) - Health check optimization
* [Revoke Allowances](https://docs.gearbox.finance/dev/sdk-guide-typescript/multicalls/multicalls/revoke-allowances) - Security cleanup

## Building a Multicall

```typescript
// Build multicall with SDK helpers
const calls = [
  // Add 10,000 USDC as collateral
  service.prepareAddCollateral(usdcAddress, 10_000n * 10n ** 6n),

  // Borrow 40,000 USDC (5x leverage)
  service.prepareIncreaseDebt(40_000n * 10n ** 6n),

  // Set quota for destination token
  service.prepareUpdateQuota(wethAddress, 50_000n * 10n ** 6n, 50_000n * 10n ** 6n),
];
```

## Executing Multicalls

### On Existing Account

```typescript
const market = sdk.marketRegister.findByCreditManager(cmAddress);

await market.creditFacade.write.multicall([
  creditAccountAddress,
  calls,
]);
```

### Opening with Multicall

```typescript
const hash = await market.creditFacade.write.openCreditAccount([
  ownerAddress,
  calls,
  0n, // referralCode
]);
```

## Combining SDK Helpers with Raw Encoding

For adapter calls or custom operations, combine SDK helpers with manual encoding:

```typescript
import { encodeFunctionData } from 'viem';
import { iCreditFacadeV300MulticallAbi } from '@gearbox-protocol/sdk';

const calls = [
  // SDK helpers for standard operations
  service.prepareAddCollateral(usdcAddress, 10_000n * 10n ** 6n),
  service.prepareIncreaseDebt(40_000n * 10n ** 6n),

  // Manual encoding for adapter calls
  {
    target: uniswapV3Adapter,
    callData: encodeFunctionData({
      abi: uniswapV3AdapterAbi,
      functionName: 'exactInputSingle',
      args: [{
        tokenIn: usdcAddress,
        tokenOut: wethAddress,
        fee: 500,
        recipient: '0x0000000000000000000000000000000000000000', // Adapter overrides
        deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
        amountIn: 50_000n * 10n ** 6n,
        amountOutMinimum: 0n,
        sqrtPriceLimitX96: 0n,
      }],
    }),
  },

  // SDK helper for quota
  service.prepareUpdateQuota(wethAddress, 50_000n * 10n ** 6n, 50_000n * 10n ** 6n),
];
```

## Slippage Protection

Add slippage checks around external calls:

```typescript
const calls = [
  // Store expected balances before swap
  {
    target: creditFacadeAddress,
    callData: encodeFunctionData({
      abi: iCreditFacadeV300MulticallAbi,
      functionName: 'storeExpectedBalances',
      args: [[{ token: wethAddress, amount: minExpectedWeth }]],
    }),
  },

  // Swap operation
  {
    target: uniswapV3Adapter,
    callData: encodeFunctionData({
      abi: uniswapV3AdapterAbi,
      functionName: 'exactInputSingle',
      args: [swapParams],
    }),
  },

  // Compare balances after swap
  {
    target: creditFacadeAddress,
    callData: encodeFunctionData({
      abi: iCreditFacadeV300MulticallAbi,
      functionName: 'compareBalances',
      args: [],
    }),
  },
];
```

## On-Demand Price Updates

If using pull-based oracles, add price updates first:

```typescript
const calls = [
  // Price updates must be first
  {
    target: creditFacadeAddress,
    callData: encodeFunctionData({
      abi: iCreditFacadeV300MulticallAbi,
      functionName: 'onDemandPriceUpdates',
      args: [[{ token: wethAddress, reserve: false, data: priceData }]],
    }),
  },

  // Then standard operations
  service.prepareAddCollateral(usdcAddress, amount),
  service.prepareIncreaseDebt(debtAmount),
];
```

## Getting Adapter Addresses

Retrieve adapter addresses from the Credit Manager:

```typescript
import { getContract } from 'viem';
import { creditManagerAbi } from '@gearbox-protocol/sdk';

const creditManager = getContract({
  address: cmAddress,
  abi: creditManagerAbi,
  client: publicClient,
});

// Get adapter for a protocol (e.g., Uniswap V3 Router)
const uniswapV3Adapter = await creditManager.read.contractToAdapter([
  UNISWAP_V3_ROUTER,
]);
```

## Complete Example

```typescript
import {
  GearboxSDK,
  createCreditAccountService,
  iCreditFacadeV300MulticallAbi,
} from '@gearbox-protocol/sdk';
import { encodeFunctionData, createPublicClient, createWalletClient, http } from 'viem';
import { mainnet } from 'viem/chains';

async function leveragePosition() {
  const publicClient = createPublicClient({
    chain: mainnet,
    transport: http(),
  });

  const sdk = await GearboxSDK.attach({
    client: publicClient,
    marketConfigurators: [],
  });

  const service = createCreditAccountService(sdk, 310);

  // Find market
  const market = sdk.marketRegister.findByCreditManager(cmAddress);

  // Build multicall
  const calls = [
    // Add collateral
    service.prepareAddCollateral(usdcAddress, 10_000n * 10n ** 6n),

    // Borrow
    service.prepareIncreaseDebt(40_000n * 10n ** 6n),

    // Set quota for final token
    service.prepareUpdateQuota(targetToken, 50_000n * 10n ** 6n, 50_000n * 10n ** 6n),
  ];

  // Execute
  const walletClient = createWalletClient({
    chain: mainnet,
    transport: http(),
    account: myAccount,
  });

  const hash = await walletClient.writeContract({
    address: market.creditFacade.address,
    abi: creditFacadeAbi,
    functionName: 'openCreditAccount',
    args: [myAccount.address, calls, 0n],
  });

  console.log(`Transaction: ${hash}`);
}
```

## Best Practices

1. **Always use slippage protection** when performing swaps
2. **Price updates first** if using pull-based oracles
3. **Set quotas** for tokens you'll hold as collateral
4. **Approve collateral** to Credit Manager (not Facade) before adding

For architectural background, see [Multicall System](https://docs.gearbox.finance/dev/concepts/multicall-system).
