Lending / Wrapping

Note: WrapModule is not available for Optimism.

What is the WrapModule:

The WrapModule is a module that enables the wrapping of ERC20 and Ether positions via third party protocols, provided that an ERC20 token representing the wrapped token is returned. This includes lending assets on Aave and Compound, staking Sushi in xSushi and more. For lending and other activities that do not return an ERC20 asset representation, you can use the StakingModule (coming soon).

Initializing the WrapModule:

All modules need to be added to the SetToken as the first step. Learn how to add a module to your SetToken in this section.

Once you have added the WrapModule to the SetToken, you must initialize the SetToken on the WrapModule:

/**
 * Initializes this module to the SetToken. Only callable by the SetToken's manager.
 *
 * @param _setToken        Instance of the SetToken to initialize
 */
function initialize(ISetToken _setToken);

Simply input the SetToken address in the WrapModule.

Wrapping:

In order to wrap components, you must be operating as the manager of your SetToken. Call the wrap or (wrapWithEtherfor transacting with ETH) function with inputs as follows:

/**
 * MANAGER-ONLY: Instructs the SetToken to wrap an underlying asset into a wrappedToken via a specified adapter.
 *
 * @param _setToken             Instance of the SetToken
 * @param _underlyingToken      Address of the component to be wrapped
 * @param _wrappedToken         Address of the desired wrapped token
 * @param _underlyingUnits      Quantity of underlying units in Position units
 * @param _integrationName      Name of wrap module integration (mapping on integration registry)
 */
function wrap(
    ISetToken _setToken,
    address _underlyingToken,
    address _wrappedToken,
    uint256 _underlyingUnits,
    string calldata _integrationName
);

/**
 * MANAGER-ONLY: Instructs the SetToken to wrap Ether into a wrappedToken via a specified adapter. Since SetTokens
 * only hold WETH, in order to support protocols that collateralize with Ether the SetToken's WETH must be unwrapped
 * first before sending to the external protocol.
 *
 * @param _setToken             Instance of the SetToken
 * @param _wrappedToken         Address of the desired wrapped token
 * @param _underlyingUnits      Quantity of underlying units in Position units
 * @param _integrationName      Name of wrap module integration (mapping on integration registry)
 */
function wrapWithEther(
    ISetToken _setToken,
    address _wrappedToken,
    uint256 _underlyingUnits,
    string calldata _integrationName
);

It is important to not that units passed into the wrap function are in position units (NOT the total notional quantity). For example, if 1 SetToken contains 1 WETH, and there are 10 supply of SetTokens (10 WETH locked in total), trading 100% of the ETH to DAI requires passing in 1 (more accurately 1 * 10^18) into the _underlyingUnits.

To retrieve the position units in 1 SetToken, call getPositions on your SetToken contract.

The _integrationName is a string specifying which protocol to execute the wrap. The _integrationName is registered in the IntegrationRegistry. Wrap adapters supported by the TradeModule are:

Contract

Wrap Adapter Name

AaveWrapAdapter

"AaveWrapAdapter"

CompoundWrapAdapter

"CompoundWrapAdapter"

YearnWrapAdapter

"YearnWrapAdapter"

Unwrapping:

In order to unwrap components, you must be operating as the manager of your SetToken. Call the unwrap or (unwrapWithEtherfor transacting with ETH) function with inputs as follows:

/**
 * MANAGER-ONLY: Instructs the SetToken to unwrap a wrapped asset into its underlying via a specified adapter.
 *
 * @param _setToken             Instance of the SetToken
 * @param _underlyingToken      Address of the underlying asset
 * @param _wrappedToken         Address of the component to be unwrapped
 * @param _wrappedUnits         Quantity of wrapped tokens in Position units
 * @param _integrationName      ID of wrap module integration (mapping on integration registry)
 */
function unwrap(
    ISetToken _setToken,
    address _underlyingToken,
    address _wrappedToken,
    uint256 _wrappedUnits,
    string calldata _integrationName
);

/**
 * MANAGER-ONLY: Instructs the SetToken to unwrap a wrapped asset collateralized by Ether into Wrapped Ether. Since
 * external protocol will send back Ether that Ether must be Wrapped into WETH in order to be accounted for by SetToken.
 *
 * @param _setToken                 Instance of the SetToken
 * @param _wrappedToken             Address of the component to be unwrapped
 * @param _wrappedUnits             Quantity of wrapped tokens in Position units
 * @param _integrationName          ID of wrap module integration (mapping on integration registry)
 */
function unwrapWithEther(
    ISetToken _setToken,
    address _wrappedToken,
    uint256 _wrappedUnits,
    string calldata _integrationName
);

This is simply the opposite flow of wrapping. Similarly, wrappedUnits is the position units of the wrapped token (e.g. aDAI, cUSDC). To retrieve the position units in 1 SetToken, call getPositions on your SetToken contract.

Unwrapping uses the same wrap adapters as wrap in the table above.

Last updated