# Smart Contract Documentation

### Introduction <a href="#introduction" id="introduction"></a>

Velvet v4 protocol is a DeFi protocol enabling creation, management, and interaction with onchain portfolios. It allows portfolio managers to construct & manage bespoke portfolios across a diverse range of tokens & protocols and facilitate deposit/withdrawal process.

**Key Features:**

* **Portfolio Creation:** Portfolio managers can deploy both custodial and non-custodial portfolios setting up parameters like management fees, performance fees, entry and exit fees, token whitelists, initial token supply, and transferability options. Safe (fka Gnosis Safe) standard is used for portfolio creation.
* **Deposit and Withdrawal:** Depositors can supply multiple tokens into portfolios via single or batched transactions, with support for gasless approvals through Permit2. Withdrawals are flexible, allowing depositors to receive specific underlying assets or to repay associated debts, offering granular control over their portfolio positions.
* **Rebalancing:** Managers have the tools to update the portfolio's asset composition and adjust token weights dynamically. This enables them to rebalance portfolios in response to market movements, maintain desired asset allocations, and optimize for performance or risk management. Rebalancing includes trading and allocation into DeFi pools generating additional yield (routed using Velvet solver network).
* **External Position Management:** The protocol is also directly integrated with DeFi primitives such as Uniswap V3, Thena or similar. Portfolio managers can create and manage liquidity positions, adjust price ranges, and reinvest earned fees, enabling portfolios to participate in yield farming, liquidity provision, and other advanced DeFi strategies.
* **Debt Management:** Portfolio managers can engage in borrowing and lending activities, utilizing tokens as collateral to borrow assets from lending protocols. They can manage collateralization ratios, perform flash loans for efficient debt repayment, and adjust portfolio leverage, allowing for sophisticated debt strategies within the portfolio.
* **Portfolio Management Configuration:** Managers can propose and adjust various fees associated with the portfolio, including management, performance, entry, and exit fees. The protocol incorporates governance mechanisms such as time-locked proposals and the ability to cancel proposals, ensuring transparent and fair fee management.
* **Treasury and Whitelist Management:** The platform allows updating of treasury addresses for fee accrual and supports robust user management via whitelisting. Portfolio managers can control depositor access to their portfolios, manage permissions, and tailor depositor communities.
* **Token Exclusion Handling:** In scenarios where certain tokens need to be removed from a portfolio—such as due to liquidity issues or protocol changes—the protocol provides mechanisms for portfolio managers to exclude tokens and for depositors to claim their proportionate share of them.

Velvet v4 supports advanced portfolio management, diverse DeFi strategies, and seamless interactions with other DeFi protocols. See detailed developer documentation below.

### Velvet Core <a href="#velvet-core" id="velvet-core"></a>

The Velvet Core contracts facilitate the creation of new portfolios and provide core functionalities for portfolio management.

#### Create New Portfolio <a href="#create-new-portfolio" id="create-new-portfolio"></a>

**createPortfolioNonCustodial**

Creates a new non-custodial portfolio with specified parameters. This type of portfolio is managed directly by the asset manager without the use of a custodial wallet.

Copy

```
function createPortfolioNonCustodial(FunctionParameters.PortfolioCreationInitData memory initData) external;
```

**Parameters:**

* `initData`: A struct containing initialization data for the portfolio.

***

**createPortfolioCustodial**

Creates a new custodial portfolio managed by a Gnosis Safe, allowing for multi-signature control and enhanced security.

Copy

```
function createPortfolioCustodial(
    FunctionParameters.PortfolioCreationInitData memory initData,
    address[] memory _owners,
    uint256 _threshold
) external;
```

**Parameters:**

* `initData`: Initialization data for the portfolio.
* `_owners`: Array of addresses that will own the Gnosis Safe.
* `_threshold`: The minimum number of owner signatures required for transactions.

***

**PortfolioCreationInitData Struct**

Defines the initial configuration parameters for creating a new portfolio.

Copy

```
struct PortfolioCreationInitData {
    address _assetManagerTreasury;
    address[] _whitelistedTokens;
    uint256 _managementFee;
    uint256 _performanceFee;
    uint256 _entryFee;
    uint256 _exitFee;
    uint256 _initialPortfolioAmount;
    uint256 _minPortfolioTokenHoldingAmount;
    bool _public;
    bool _transferable;
    bool _transferableToPublic;
    bool _whitelistTokens;
    bool _externalPositionManagementWhitelisted;
    string _name;
    string _symbol;
}
```

**Fields:**

* `_assetManagerTreasury`: Address for fee accumulation.
* `_whitelistedTokens`: Tokens allowed in the portfolio.
* `_managementFee`: Annual management fee in basis points.
* `_performanceFee`: Fee on profits in basis points.
* `_entryFee`: One-time entry fee in basis points.
* `_exitFee`: Exit fee in basis points.
* `_initialPortfolioAmount`: Initial supply of portfolio tokens (>= 1e14).
* `_minPortfolioTokenHoldingAmount`: Minimum holding amount (>= 1e14).
* `_public`: Indicates if the fund is open to the public.
* `_transferable`: If tokens are transferable.
* `_transferableToPublic`: If tokens can be transferred to non-whitelisted addresses.
* `_whitelistTokens`: Restricts the fund to whitelisted tokens.
* `_externalPositionManagementWhitelisted`: Allows external position management.
* `_name`: Name of the portfolio token.
* `_symbol`: Symbol of the portfolio token.

***

**Event Emission on Portfolio Creation**

An event is emitted when a new portfolio is created, providing details about the portfolio.

Copy

```
event PortfolioInfo(
    PortfoliolInfo portfolioData,
    uint256 indexed portfolioId,
    string _name,
    string _symbol,
    address indexed _owner,
    address indexed _accessController,
    bool isPublicPortfolio
);
```

**Event Parameters:**

* `portfolioData`: Struct with portfolio-related addresses.
* `portfolioId`: Unique identifier for the portfolio.
* `_name`: Name of the portfolio token.
* `_symbol`: Symbol of the portfolio token.
* `_owner`: Address of the portfolio owner.
* `_accessController`: Access controller address.
* `isPublicPortfolio`: Indicates if the portfolio is public.

***

**PortfoliolInfo Struct**

Contains addresses of various contracts associated with the portfolio.

Copy

```
struct PortfoliolInfo {
    address portfolio;
    address tokenExclusionManager;
    address rebalancing;
    address owner;
    address borrowManager;
    address assetManagementConfig;
    address feeModule;
    address vaultAddress;
    address gnosisModule;
}
```

**Fields:**

* `portfolio`: Portfolio contract address.
* `tokenExclusionManager`: Manages token exclusions.
* `rebalancing`: Rebalancing contract address.
* `owner`: Owner's address.
* `borrowManager`: Manages borrowing operations.
* `assetManagementConfig`: Asset management configuration.
* `feeModule`: Fee module address.
* `vaultAddress`: Vault contract address.
* `gnosisModule`: Gnosis Safe module address.

***

#### Initialize Tokens <a href="#initialize-tokens" id="initialize-tokens"></a>

**initTokens**

Initializes the vault with a set of tokens, setting up the initial assets managed by the portfolio.

Copy

```
function initToken(address[] calldata _tokens) external;
```

**Parameters:**

* `_tokens`: An array of token addresses to include in the vault.

***

### Deposit <a href="#deposit" id="deposit"></a>

Users can deposit tokens into the portfolio, either directly or on behalf of another user, using multi-token deposit functions.

#### multiTokenDeposit <a href="#multitokendeposit" id="multitokendeposit"></a>

Allows users to deposit multiple tokens into the portfolio in a single transaction. Supports gasless approvals through Permit2.

Copy

```
function multiTokenDeposit(
    uint256[] calldata depositAmounts,
    uint256 _minMintAmount,
    IAllowanceTransfer.PermitBatch calldata _permit,
    bytes calldata _signature
) external;
```

**Parameters:**

* `depositAmounts`: Amounts for each token being deposited.
* `_minMintAmount`: Minimum portfolio tokens expected to receive.
* `_permit`: Batch permit data for token allowance.
* `_signature`: Signature for the permit batch.

***

**PermitBatch Struct**

Used for gasless token approvals.

Copy

```
struct PermitBatch {
    PermitDetails[] details;
    address spender;
    uint256 sigDeadline;
}
```

**Fields:**

* `details`: Array of `PermitDetails` structs.
* `spender`: Address authorized to spend tokens.
* `sigDeadline`: Signature validity deadline.

***

#### multiTokenDepositFor <a href="#multitokendepositfor" id="multitokendepositfor"></a>

Allows depositing tokens on behalf of another user.

Copy

```
function multiTokenDepositFor(
    address _depositFor,
    uint256[] calldata depositAmounts,
    uint256 _minMintAmount
) external;
```

**Parameters:**

* `_depositFor`: Address of the user for whom the deposit is made.
* `depositAmounts`: Amounts for each token being deposited.
* `_minMintAmount`: Minimum portfolio tokens expected to receive.

***

### DepositBatch <a href="#depositbatch" id="depositbatch"></a>

The `DepositBatch` contract enables users to batch multiple token swaps and deposit operations, facilitating complex deposit scenarios.

#### deposit <a href="#deposit-1" id="deposit-1"></a>

Allows depositing tokens after performing necessary swaps and transfers, especially when dealing with tokens not directly accepted by the portfolio.

Copy

```
function deposit(FunctionParameters.BatchHandler memory data) external;
```

**BatchHandler Struct**

Copy

```
struct BatchHandler {
    uint256 _minMintAmount;
    uint256 _depositAmount;
    address _target;
    address _depositToken;
    bytes[] _callData;
}
```

**Fields:**

* `_minMintAmount`: Minimum portfolio tokens expected.
* `_depositAmount`: Amount of tokens to swap.
* `_target`: Portfolio contract address.
* `_depositToken`: Initial token address to swap from.
* `_callData`: Encoded data for swap operations.

***

#### multiTokenSwapETHAndTransfer <a href="#multitokenswapethandtransfer" id="multitokenswapethandtransfer"></a>

Performs swaps for ETH deposits and transfers tokens to the portfolio.

Copy

```
function multiTokenSwapETHAndTransfer(FunctionParameters.BatchHandler memory data) external;
```

***

### DepositBatchExternalPositions <a href="#depositbatchexternalpositions" id="depositbatchexternalpositions"></a>

Extends `DepositBatch` functionalities to handle deposits into portfolios with external positions like Uniswap V3 or Thena.

#### deposit <a href="#deposit-2" id="deposit-2"></a>

Facilitates deposits involving external positions, handling swaps and liquidity operations.

Copy

```
function deposit(
    FunctionParameters.BatchHandler memory data,
    FunctionParameters.ExternalPositionDepositParams memory _params
) external;
```

**ExternalPositionDepositParams Struct**

Copy

```
struct ExternalPositionDepositParams {
    address[] _positionWrappers;
    address[] _swapTokens;
    uint256[] _positionWrapperIndex;
    uint256[] _portfolioTokenIndex;
    uint256[] _index0;
    uint256[] _index1;
    uint256[] _amount0Min;
    uint256[] _amount1Min;
    bool[] _isExternalPosition;
    address[] _tokenIn;
    address[] _tokenOut;
    uint256[] _amountIn;
}
```

**Fields:**

* `_positionWrappers`: External position wrapper addresses.
* `_swapTokens`: Tokens involved in swaps or liquidity.
* `_positionWrapperIndex`: Indices linking wrappers to portfolio tokens.
* `_portfolioTokenIndex`: Indices for tokens in the portfolio.
* `_index0`, `_index1`: Indices for liquidity pairs.
* `_amount0Min`, `_amount1Min`: Minimum amounts to prevent slippage.
* `_isExternalPosition`: Flags indicating external positions.
* `_tokenIn`, `_tokenOut`: Tokens for swap operations.
* `_amountIn`: Amounts for swaps.

***

### Withdrawal <a href="#withdrawal" id="withdrawal"></a>

Users can withdraw portfolio tokens, receiving underlying assets or swapping them into desired tokens.

#### multiTokenWithdrawal <a href="#multitokenwithdrawal" id="multitokenwithdrawal"></a>

Allows withdrawing portfolio tokens and optionally repaying debts.

Copy

```
function multiTokenWithdrawal(
    uint256 _portfolioTokenAmount,
    FunctionParameters.withdrawRepayParams calldata repayData
) external;
```

**Parameters:**

* `_portfolioTokenAmount`: Amount of portfolio tokens to withdraw.
* `repayData`: Parameters for debt repayment during withdrawal.

***

**withdrawRepayParams Struct**

Copy

```
struct withdrawRepayParams {
    address _factory;
    address _token0;
    address _token1;
    address _flashLoanToken;
    address _solverHandler;
    uint256 _bufferUnit;
    uint256[] _flashLoanAmount;
    bytes[] firstSwapData;
    bytes[] secondSwapData;
}
```

**Fields:**

* `_factory`: Thena factory contract address.
* `_token0`, `_token1`: Tokens involved in swaps.
* `_flashLoanToken`: Token for flash loan.
* `_solverHandler`: Contract handling swaps.
* `_bufferUnit`: Buffer for safety margins.
* `_flashLoanAmount`: Amounts for flash loans.
* `firstSwapData`, `secondSwapData`: Encoded swap data.

***

#### multiTokenWithdrawalFor <a href="#multitokenwithdrawalfor" id="multitokenwithdrawalfor"></a>

Allows approved users to withdraw on behalf of others.

Copy

```
function multiTokenWithdrawalFor(
    address _withdrawFor,
    address _tokenReceiver,
    uint256 _portfolioTokenAmount,
    FunctionParameters.withdrawRepayParams calldata repayData
) external;
```

**Parameters:**

* `_withdrawFor`: Address of the user whose tokens are withdrawn.
* `_tokenReceiver`: Recipient of withdrawn tokens.
* `_portfolioTokenAmount`: Amount to withdraw.
* `repayData`: Debt repayment parameters.

***

### WithdrawalBatch <a href="#withdrawalbatch" id="withdrawalbatch"></a>

Facilitates batch withdrawals involving swaps and complex operations.

#### withdraw <a href="#withdraw" id="withdraw"></a>

Withdraws portfolio tokens and executes swaps to obtain desired output tokens.

Copy

```
function withdraw(
    address _target,
    address _tokenToWithdraw,
    uint256 _portfolioTokenAmount,
    uint256 _expectedOutputAmount,
    FunctionParameters.withdrawRepayParams calldata repayData,
    bytes[] memory _callData
) external;
```

**Parameters:**

* `_target`: Portfolio contract address.
* `_tokenToWithdraw`: Token to receive after withdrawal.
* `_portfolioTokenAmount`: Amount to withdraw.
* `_expectedOutputAmount`: Minimum expected output.
* `repayData`: Debt repayment parameters.
* `_callData`: Encoded swap operations.

***

### WithdrawalBatchExternalPositions <a href="#withdrawalbatchexternalpositions" id="withdrawalbatchexternalpositions"></a>

Handles withdrawals from portfolios with external positions.

#### withdraw <a href="#withdraw-1" id="withdraw-1"></a>

Manages withdrawals involving external positions and swaps.

Copy

```
function withdraw(
    address[] memory _swapTokens,
    address _target,
    address _tokenToWithdraw,
    uint256 _portfolioTokenAmount,
    bytes[] memory _callData,
    FunctionParameters.withdrawRepayParams calldata repayData,
    FunctionParameters.ExternalPositionWithdrawParams memory _params
) external;
```

**Parameters:**

* `_swapTokens`: Tokens involved in swaps.
* `_target`: Portfolio contract address.
* `_tokenToWithdraw`: Token to receive.
* `_portfolioTokenAmount`: Amount to withdraw.
* `_callData`: Encoded swap data.
* `repayData`: Debt repayment parameters.
* `_params`: External position withdrawal parameters.

***

**ExternalPositionWithdrawParams Struct**

Copy

```
struct ExternalPositionWithdrawParams {
    address[] _positionWrappers;
    uint256[] _amountsMin0;
    uint256[] _amountsMin1;
    address[] _tokenIn;
    address[] _tokenOut;
    uint256[] _amountIn;
}
```

**Fields:**

* `_positionWrappers`: External position wrappers.
* `_amountsMin0`, `_amountsMin1`: Minimum amounts to prevent slippage.
* `_tokenIn`, `_tokenOut`: Tokens for swaps.
* `_amountIn`: Amounts for swaps.

***

### Rebalancing <a href="#rebalancing" id="rebalancing"></a>

**Note:** Functions in this section can only be called by asset managers.

Asset managers can rebalance the portfolio by updating the token list and adjusting token weights.

#### updateTokens <a href="#updatetokens" id="updatetokens"></a>

Updates the portfolio's token list and adjusts weights based on provided rebalance data.

Copy

```
function updateTokens(FunctionParameters.RebalanceIntent calldata rebalanceData) external;
```

**RebalanceIntent Struct**

Copy

```
struct RebalanceIntent {
    address[] _newTokens;
    address[] _sellTokens;
    uint256[] _sellAmounts;
    address _handler;
    bytes _callData;
}
```

**Fields:**

* `_newTokens`: Tokens to add to the portfolio.
* `_sellTokens`: Tokens to sell during rebalancing.
* `_sellAmounts`: Amounts of tokens to sell.
* `_handler`: Address of the handler executing swaps.
* `_callData`: Encoded data for rebalancing operations.

***

#### updateWeights <a href="#updateweights" id="updateweights"></a>

Adjusts the weights of existing tokens without changing the token list.

Copy

```
function updateWeights(
    address[] calldata _sellTokens,
    uint256[] calldata _sellAmounts,
    address _handler,
    bytes memory _callData
) external;
```

**Parameters:**

* `_sellTokens`: Tokens to sell.
* `_sellAmounts`: Amounts to sell.
* `_handler`: Swap handler address.
* `_callData`: Encoded swap data.

***

#### enableCollateralTokens <a href="#enablecollateraltokens" id="enablecollateraltokens"></a>

Enables specified tokens as collateral in a lending protocol.

Copy

```
function enableCollateralTokens(address[] memory _tokens, address _controller) external;
```

**Parameters:**

* `_tokens`: Tokens to enable as collateral.
* `_controller`: Lending protocol controller address.

***

#### disableCollateralTokens <a href="#disablecollateraltokens" id="disablecollateraltokens"></a>

Disables specified tokens as collateral.

Copy

```
function disableCollateralTokens(address[] memory _tokens, address _controller) external;
```

***

#### borrow <a href="#borrow" id="borrow"></a>

Executes a borrow operation using designated collateral.

Copy

```
function borrow(
    address _pool,
    address[] memory _tokens,
    address _tokenToBorrow,
    address _controller,
    uint256 _amountToBorrow
) external;
```

**Parameters:**

* `_pool`: Lending pool address.
* `_tokens`: Collateral tokens.
* `_tokenToBorrow`: Token to borrow.
* `_controller`: Lending protocol controller.
* `_amountToBorrow`: Amount to borrow.

***

#### repay <a href="#repay" id="repay"></a>

Repays debt using a flash loan and rebalances the portfolio.

Copy

```
function repay(
    address _controller,
    FunctionParameters.RepayParams calldata repayData
) external;
```

**Parameters:**

* `_controller`: Controller managing the repayment.
* `repayData`: Parameters for the repayment process.

***

**RepayParams Struct**

Refer to the `repayData` struct in the Withdrawal section for details.

***

#### directDebtRepayment <a href="#directdebtrepayment" id="directdebtrepayment"></a>

Repays debt directly by transferring debt tokens.

Copy

```
function directDebtRepayment(
    address _debtToken,
    address _protocolToken,
    uint256 _repayAmount
) external;
```

***

#### removePortfolioToken <a href="#removeportfoliotoken" id="removeportfoliotoken"></a>

Removes a token from the portfolio.

Copy

```
function removePortfolioToken(address _token) external;
```

***

#### removePortfolioTokenPartially <a href="#removeportfoliotokenpartially" id="removeportfoliotokenpartially"></a>

Removes a portion of a token from the portfolio.

Copy

```
function removePortfolioTokenPartially(address _token, uint256 _percentage) external;
```

***

#### removeNonPortfolioToken <a href="#removenonportfoliotoken" id="removenonportfoliotoken"></a>

Removes a non-portfolio token.

Copy

```
function removeNonPortfolioToken(address _token) external;
```

***

#### removeNonPortfolioTokenPartially <a href="#removenonportfoliotokenpartially" id="removenonportfoliotokenpartially"></a>

Removes a portion of a non-portfolio token.

Copy

```
function removeNonPortfolioTokenPartially(address _token, uint256 _percentage) external;
```

***

### Token Exclusion Manager <a href="#token-exclusion-manager" id="token-exclusion-manager"></a>

Manages the exclusion and removal of tokens from the portfolio due to reasons like lack of liquidity.

#### claimRemovedTokens <a href="#claimremovedtokens" id="claimremovedtokens"></a>

Allows users to claim their share of tokens that have been removed from the portfolio.

Copy

```
function claimRemovedTokens(address user, uint256 startId, uint256 endId) external;
```

***

#### claimTokenAtId <a href="#claimtokenatid" id="claimtokenatid"></a>

Claims a specific removed token by its ID.

Copy

```
function claimTokenAtId(address user, uint256 id) external;
```

***

### Position Manager <a href="#position-manager" id="position-manager"></a>

Provides functionalities to manage liquidity positions in Uniswap V3 or Thena.

**Setup:** Enable the Uniswap V3 Manager in `AssetManagementConfig`.

Copy

```
const config = await portfolio.assetManagementConfig();
assetManagementConfig = AssetManagementConfig.attach(config);
await assetManagementConfig.enableUniSwapV3Manager();
```

***

#### createNewWrapperPositionAndDeposit <a href="#createnewwrapperpositionanddeposit" id="createnewwrapperpositionanddeposit"></a>

Creates a new liquidity position and makes an initial deposit.

Copy

```
function createNewWrapperPositionAndDeposit(
    address _dustReceiver,
    address _token0,
    address _token1,
    string memory _name,
    string memory _symbol,
    WrapperFunctionParameters.PositionMintParamsThena memory params
) external;
```

**Parameters:**

* `_dustReceiver`: Address for leftover tokens.
* `_token0`, `_token1`: Tokens in the liquidity pair.
* `_name`, `_symbol`: Name and symbol for the wrapper token.
* `params`: Parameters for minting the position.

***

**PositionMintParamsThena Struct**

Copy

```
struct PositionMintParamsThena {
    uint256 _amount0Desired;
    uint256 _amount1Desired;
    uint256 _amount0Min;
    uint256 _amount1Min;
    int24 _tickLower;
    int24 _tickUpper;
}
```

**Fields:**

* `_amount0Desired`, `_amount1Desired`: Desired token amounts.
* `_amount0Min`, `_amount1Min`: Minimum amounts to prevent slippage.
* `_tickLower`, `_tickUpper`: Price range ticks.

***

#### initializePositionAndDeposit <a href="#initializepositionanddeposit" id="initializepositionanddeposit"></a>

Initializes an existing position and makes a deposit.

Copy

```
function initializePositionAndDeposit(
    address _dustReceiver,
    IPositionWrapper _positionWrapper,
    WrapperFunctionParameters.InitialMintParams memory params
) external;
```

***

#### createNewWrapperPosition <a href="#createnewwrapperposition" id="createnewwrapperposition"></a>

Creates a new wrapper position without an initial deposit.

Copy

```
function createNewWrapperPosition(
    address _token0,
    address _token1,
    string memory _name,
    string memory _symbol,
    int24 _tickLower,
    int24 _tickUpper
) public;
```

***

#### increaseLiquidity <a href="#increaseliquidity" id="increaseliquidity"></a>

Increases liquidity in an existing position.

Copy

```
function increaseLiquidity(WrapperFunctionParameters.WrapperDepositParams memory _params) external;
```

***

**WrapperDepositParams Struct**

Copy

```
struct WrapperDepositParams {
    address _dustReceiver;
    IPositionWrapper _positionWrapper;
    uint256 _amount0Desired;
    uint256 _amount1Desired;
    uint256 _amount0Min;
    uint256 _amount1Min;
    address _tokenIn;
    address _tokenOut;
    uint256 _amountIn;
}
```

***

#### decreaseLiquidity <a href="#decreaseliquidity" id="decreaseliquidity"></a>

Decreases liquidity and burns wrapper tokens.

Copy

```
function decreaseLiquidity(
    IPositionWrapper _positionWrapper,
    uint256 _withdrawalAmount,
    uint256 _amount0Min,
    uint256 _amount1Min,
    address tokenIn,
    address tokenOut,
    uint256 amountIn
) external;
```

***

#### updateRange <a href="#updaterange" id="updaterange"></a>

Updates the price range and fee tier of an existing position.

Copy

```
function updateRange(
    IPositionWrapper _positionWrapper,
    address tokenIn,
    address tokenOut,
    uint256 amountIn,
    uint256 _underlyingAmountOut0,
    uint256 _underlyingAmountOut1,
    int24 _tickLower,
    int24 _tickUpper
) external;
```

**Note:** Asset managers need to calculate swap parameters to maintain optimal ratios during liquidity adjustments. This involves determining collected fees, desired ratios, and required swaps to align with the new price range.

### Portfolio Data <a href="#portfolio-data" id="portfolio-data"></a>

The portfolio contracts provide functions to access and manage the tokens within the vault, as well as information about the portfolio tokens themselves.

#### getTokens <a href="#gettokens" id="gettokens"></a>

Copy

```
function getTokens() external view returns (address[] memory);
```

Retrieves the current list of token addresses held in the vault.

**Returns:**

* `address[] memory`: An array containing the addresses of the tokens in the vault.

#### totalSupply <a href="#totalsupply" id="totalsupply"></a>

Copy

```
function totalSupply() external view returns (uint256);
```

Returns the total supply of the portfolio tokens in circulation.

**Returns:**

* `uint256`: The total number of portfolio tokens minted.

#### balanceOf <a href="#balanceof" id="balanceof"></a>

Copy

```
function balanceOf(address account) external view returns (uint256);
```

Provides the balance of portfolio tokens held by a specific user.

**Parameters:**

* `account`: The address of the user whose balance is being queried.

**Returns:**

* `uint256`: The number of portfolio tokens owned by the specified user.

***

### Asset Management Configuration <a href="#asset-management-configuration" id="asset-management-configuration"></a>

**Note:** All functions in `AssetManagementConfig` can only be called by asset managers.

The `AssetManagementConfig` contract allows asset managers to configure various aspects of the portfolio, including external positions, fees, portfolio settings, treasury management, and user whitelist management.

#### External Position Management <a href="#external-position-management" id="external-position-management"></a>

**enableUniSwapV3Manager**

Enables the Uniswap V3 wrapper, allowing the portfolio to interact with Uniswap V3 positions. This is essential for portfolios that include external liquidity positions.

Copy

```
function enableUniSwapV3Manager() external;
```

***

#### Fee Management <a href="#fee-management" id="fee-management"></a>

The following functions allow asset managers to propose and update management, performance, entry, and exit fees. Each fee change involves a proposal followed by a waiting period before the update can be finalized.

**proposeNewManagementFee**

Starts the process of updating the management fee by proposing a new fee. A waiting period begins during which the proposed fee can be reviewed.

Copy

```
function proposeNewManagementFee(uint256 _newManagementFee) external;
```

**Parameters:**

* `_newManagementFee`: The proposed new management fee, expressed in basis points (e.g., 100 = 1%).

**Note:** The `updateManagementFee` function can be called 28 days after the proposal. The management fee cannot exceed the `maxManagementFee` set in the protocol configuration.

**deleteProposedManagementFee**

Cancels the proposed management fee, resetting the proposal and stopping the update process.

Copy

```
function deleteProposedManagementFee() external;
```

**updateManagementFee**

Finalizes the management fee update after the waiting period has elapsed, applying the previously proposed fee.

Copy

```
function updateManagementFee() external;
```

***

**proposeNewPerformanceFee**

Proposes a new performance fee, initiating a waiting period before the fee can be updated.

Copy

```
function proposeNewPerformanceFee(uint256 _newPerformanceFee) external;
```

**Parameters:**

* `_newPerformanceFee`: The proposed new performance fee, expressed in basis points.

**deleteProposedPerformanceFee**

Cancels the proposed performance fee, resetting the proposal.

Copy

```
function deleteProposedPerformanceFee() external;
```

**updatePerformanceFee**

Updates the performance fee to the previously proposed value after the waiting period has passed.

Copy

```
function updatePerformanceFee() external;
```

***

**proposeNewEntryAndExitFee**

Proposes new entry and exit fees, starting a timer before the changes can be finalized.

Copy

```
function proposeNewEntryAndExitFee(uint256 _newEntryFee, uint256 _newExitFee) external;
```

**Parameters:**

* `_newEntryFee`: The proposed new entry fee, in basis points.
* `_newExitFee`: The proposed new exit fee, in basis points.

**deleteProposedEntryAndExitFee**

Cancels the proposed entry and exit fees, resetting the proposal.

Copy

```
function deleteProposedEntryAndExitFee() external;
```

**updateEntryAndExitFee**

Finalizes the entry and exit fee updates after the waiting period.

Copy

```
function updateEntryAndExitFee() external;
```

***

#### Portfolio Settings <a href="#portfolio-settings" id="portfolio-settings"></a>

**updateTransferability**

Updates the transferability settings of the portfolio token, determining whether tokens can be transferred and whether transfers to the public are allowed.

Copy

```
function updateTransferability(bool _transferable, bool _publicTransfer) external;
```

**Parameters:**

* `_transferable`: Enables or disables the ability to transfer portfolio tokens.
* `_publicTransfer`: Allows or disallows transferring portfolio tokens to the public (non-whitelisted addresses).

***

**convertPrivateFundToPublic**

Converts a private portfolio to a public one, allowing broader access to investors.

Copy

```
function convertPrivateFundToPublic() external;
```

***

**updateMinPortfolioTokenHoldingAmount**

Sets the minimum amount of portfolio tokens that must be held or transacted, enforcing investment thresholds.

Copy

```
function updateMinPortfolioTokenHoldingAmount(uint256 _minPortfolioTokenHoldingAmount) external;
```

**Parameters:**

* `_minPortfolioTokenHoldingAmount`: The new minimum portfolio token amount required for transactions.

***

**updateInitialPortfolioAmount**

Updates the initial amount of the portfolio, setting a new starting value for the portfolio tokens.

Copy

```
function updateInitialPortfolioAmount(uint256 _newAmount) external;
```

**Parameters:**

* `_newAmount`: The new initial portfolio amount.

***

#### Treasury Management <a href="#treasury-management" id="treasury-management"></a>

**updateAssetManagerTreasury**

Changes the address where asset management fees are accumulated.

Copy

```
function updateAssetManagerTreasury(address _newAssetManagerTreasury) external;
```

**Parameters:**

* `_newAssetManagerTreasury`: The new treasury address for asset management fees.

***

#### User Whitelist Management <a href="#user-whitelist-management" id="user-whitelist-management"></a>

**whitelistUser**

Adds users to the whitelist, allowing them to deposit into the portfolio.

Copy

```
function whitelistUser(address[] calldata users) external;
```

**Parameters:**

* `users`: An array of user addresses to be whitelisted.

***

**removeWhitelistedUser**

Removes users from the whitelist, revoking their ability to deposit.

Copy

```
function removeWhitelistedUser(address[] calldata users) external;
```

**Parameters:**

* `users`: An array of user addresses to be removed from the whitelist.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.velvet.capital/for-developers/smart-contract-documentation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
