# Zapping Assets

<pre class="language-solidity"><code class="lang-solidity"><strong>library AccountBalanceLib {
</strong><strong>    enum BalanceCheckFlag {
</strong><strong>        Both,
</strong><strong>        From,
</strong><strong>        To,
</strong><strong>        None
</strong><strong>    }
</strong><strong>}
</strong><strong>
</strong><strong>interface IDolomiteStructs {
</strong><strong>    struct AccountInfo {
</strong><strong>        address owner;
</strong><strong>        uint256 number;
</strong><strong>    }
</strong><strong>}
</strong><strong>
</strong><strong>interface IGenericTraderBase {  
</strong>    enum TraderType {
        ExternalLiquidity,
        InternalLiquidiy,
        IsolationModeUnwrapper,
        IsolationModeWrapper
    }
    
    struct TraderParam {
        TraderType traderType;
        uint256 makerAccountIndex;
        address trader;
        bytes tradeData;
    }
}

interface IGenericTraderProxyV2 {
    enum EventEmissionType {
        None,
        BorrowPosition,
        MarginPosition
    }
    
    struct TransferAmount {
        uint256 marketId;
        uint256 amountWei;
    }

    struct TransferCollateralParam {
        uint256 fromAccountNumber;
        uint256 toAccountNumber;
        TransferAmount[] transferAmounts;
    }
    
    struct UserConfig {
        uint256 deadline;
        AccountBalanceLib.BalanceCheckFlag balanceCheckFlag;
        EventEmissionType eventType;
    }
    
    struct ExpiryParam {
        uint256 marketId;
        uint32 expiryTimeDelta;
    }
    
    struct SwapExactInputForOutputParams {
        uint256 accountNumber;
        uint256[] marketIdsPath;
        uint256 inputAmountWei;
        uint256 minOutputAmountWei;
        TraderParam[] tradersPath;
        IDolomiteMargin.AccountInfo[] makerAccounts;
        UserConfig userConfig;
    }
    
    struct SwapExactInputForOutputAndModifyPositionParams {
        uint256 accountNumber;
        uint256[] marketIdsPath;
        uint256 inputAmountWei;
        uint256 minOutputAmountWei;
        TraderParam[] tradersPath;
        IDolomiteStructs.AccountInfo[] makerAccounts;
        TransferCollateralParam transferCollateralParams;
        ExpiryParam expiryParams;
        UserConfig userConfig;
    }
}

interface IGenericTraderRouter {
    /**
     * @param _isolationModeMarketId Market ID of isolation mode token (0 if not using isolation mode)
     * @param _params                Trading parameters including:
     *                              - accountNumber: Account to trade from
     *                              - marketIdsPath: Array of market IDs for trading path
     *                              - inputAmountWei: Amount to swap (uint(-1) for entire balance)
     *                              - minOutputAmountWei: Minimum output amount
     *                              - tradersPath: Array of traders to use
     *                              - makerAccounts: Accounts for internal liquidity trades
     *                              - userConfig: Deadline, balance checks, and event config
     */
    function swapExactInputForOutput(
        uint256 _isolationModeMarketId,
        SwapExactInputForOutputParams memory _params
    ) external;
    
    /**
     * @param _isolationModeMarketId Market ID of isolation mode token (0 if not using isolation mode)
     * @param _params                Trading parameters including:
     *                              - All parameters from SwapExactInputForOutputParams
     *                              - transferCollateralParams: Collateral transfer config
     *                              - expiryParams: Position expiry settings
     */
    function swapExactInputForOutputAndModifyPosition(
        uint256 _isolationModeMarketId,
        SwapExactInputForOutputAndModifyPositionParams memory _params
    ) external;

}
</code></pre>

### Examples

{% hint style="info" %}
For these examples, we are creating the structs and arrays directly inline to make it more readable. This would result in a compile error in normal solidity.\
\
Also, the tradeData is dependent on which trader you are using.
{% endhint %}

Depositing 1,000 USDC into the default account number and then swapping for WETH.

```solidity
uint256 usdcAmount = 1000e6;
usdc.safeApprove(address(DepositWithdrawalRouter), usdcAmount);

uint256 usdcMarketId = DOLOMITE_MARGIN.getMarketIdByTokenAddress(address(usdc));
DepositWithdrawalRouter.depositWei(
    /* isolationModeMarketId = */ 0,
    /* toAccountNumber = */ 0,
    /* marketId = */ usdcMarketId,
    /* amountWei = */ usdcAmount,
    EventFlag.None
);

uint256 wethMarketId = DOLOMITE_MARGIN.getMarketIdByTokenAddress(address(weth));
uint256 minAmountOut = 0.25 ether;
bytes memory odosOrderData = '0x1234';
GenericTraderRouter.swapExactInputForOutput(
    /* isolationModeMarketId = */ 0,
    /* SwapExactInputForOutputParams */ {
        /* accountNumber = */ 0,
        /* marketIdsPath = */ [usdcMarketId, wethMarketId],
        /* inputAmountWei = */ usdcAmount,
        /* minOutputAmountWei = */ minAmountOut,
        /* tradersPath = */ [{
            /* trader = */ odosExchangeRouterAddress,
            /* traderType = */ GenericTraderType.ExternalLiquidity,
            /* tradeData = */ abi.encode(minAmountOut, odosOrderData),
            /* makerAccountIndex = */ 0
        }],
        /* makerAccounts = */ [],
        /* userConfig = */ {
            /* deadline = */ block.timestamp,
            /* balanceCheckFlag = */ BalanceCheckFlag.From,
            /* eventType = */ GenericEventEmissionType.None
        }
    }
);
```

Depositing 1,000 USDC into the user's default account and swapping into GLP, an isolation mode asset. Swapping into an isolation mode asset requires using a whitelisted wrapper trader and swapping out of an isolation mode asset requires using a whitelisted unwrapper trader.

{% hint style="info" %}
tradeData is in the format of (uint256 minAmountOut, bytes memory extraOrderData) = abi.decode(tradeData, (uint256, bytes)). The GLP wrapper requires no extra order data, but many traders require extra information.
{% endhint %}

```solidity
uint256 usdcAmount = 1000e6;
usdc.safeApprove(address(DepositWithdrawalRouter), usdcAmount);

uint256 usdcMarketId = DOLOMITE_MARGIN.getMarketIdByTokenAddress(address(usdc));
DepositWithdrawalRouter.depositWei(
    /* isolationModeMarketId = */ 0,
    /* toAccountNumber = */ 0,
    usdcMarketId,
    /* amountWei = */ usdcAmount,
    EventFlag.None
);

address dfsGlp = 0x34DF4E8062A8C8Ae97E3382B452bd7BF60542698;
uint256 glpMarketId = DOLOMITE_MARGIN.getMarketIdByTokenAddress(dfsGlp);
uint256 minAmountOut = 0.25 ether;
GenericTraderRouter.swapExactInputForOutput(
    /* isolationModeMarketId = */ glpMarketId,
    /* SwapExactInputForOutputParams */ {
        /* accountNumber = */ 0,
        /* marketIdsPath = */ [usdcMarketId, glpMarketId],
        /* inputAmountWei = */ usdcAmount,
        /* minOutputAmountWei = */ minAmountOut,
        /* tradersPath = */ [{
            /* trader = */ glpWrapperTraderAddress,
            /* traderType = */ GenericTraderType.IsolationModeWrapper,
            /* tradeData = */ abi.encode(minAmountOut, bytes("")),
            /* makerAccountIndex = */ 0
        }],
        /* makerAccounts = */ [],
        /* userConfig = */ {
            /* deadline = */ block.timestamp,
            /* balanceCheckFlag = */ BalanceCheckFlag.From,
            /* eventType = */ GenericEventEmissionType.None
        }
    }
);
```
