๐ŸŒพKey Function - harvest

In-depth descriptions of key functions

harvest

    /**
     * @notice  harvest the strategy. This involves accruing profits from the strategy and depositing
     *          user funds to the strategy. The funds are split into their constituents and then distributed
     *          to their appropriate location.
     *          For the shortPosition a perpetual position is opened, for the long position funds are swapped
     *          to the long asset. For the buffer position the funds are deposited to the margin account idle.
     * @dev     only callable by the owner
     */
    function harvest() public onlyOwner {
        uint256 shortPosition;
        uint256 longPosition;
        uint256 bufferPosition;
        isUnwind = false;

        mcLiquidityPool.forceToSyncState();
        // determine the profit since the last harvest and remove profits from the margin
        // account to be redistributed
        uint256 amount;
        bool loss;
        if (positions.unitAccumulativeFunding != 0) {
            (amount, loss) = _determineFee();
        }
        // update the vault with profits/losses accrued and receive deposits
        uint256 newFunds = vault.update(amount, loss);
        // combine the funds and check that they are larger than 0
        uint256 toActivate = IERC20(want).balanceOf(address(this));

        if (toActivate > 0) {
            // determine the split of the funds and trade for the spot position of long
            (shortPosition, longPosition, bufferPosition) = _calculateSplit(
                toActivate
            );
            // deposit the bufferPosition to the margin account
            _depositToMarginAccount(bufferPosition);
            // open a short perpetual position and store the number of perp contracts
            positions.perpContracts += _openPerpPosition(shortPosition, true);
        }
        // record incremented positions
        positions.margin = getMargin();
        positions.unitAccumulativeFunding = getUnitAccumulativeFunding();
        emit Harvest(
            positions.perpContracts,
            IERC20(long).balanceOf(address(this)),
            positions.margin
        );
    }

The harvest function is the strategy's "work" function. It is responsible for running the strategy.

The harvest will begin by determining the profit/loss since the previous harvest. It will do this by getting the unitAccumulativeFunding and getting the difference from the last harvest's unitAccumulativeFunding. If the difference is positive then the profits will be withdrawn from the margin account. If the difference is negative then the loss will be determined.

Next, the harvest will update the vault of the profit/loss. The vault will update its totalLent which is the funds it has lent to the vault; if there is a profit then totalLent will increase and the protocol fees will be determined. If there is a loss then totalLent will decrease. Finally, funds that have been deposited after the previous harvest will be recorded and transferred to the strategy contract.

The harvest will then calculate the split of the gains (deposits and/or profits) and split them first into the buffer position, then the long position, then the short position. The long position is swapped from the deposit asset to the long asset using a Uniswap v2 or Uniswap v3 interfaced AMM.

The harvest will then deposit the short position and buffer position deposit asset into the strategy's MCDEX margin account.

The harvest will then open a short perpetual position on MCDEX using the short position collateral. The MCDEX internal oracle is used to determine the number of short contracts to open.

Finally, a few parameters are updated and a harvest event is emitted. Fin.

Last updated