BasisOS
  • INTRODUCTION
    • What is BasisOS
    • Key Concepts in Basis Trading
    • Vision and Value Proposition
  • Basis Vaults
    • Architecture Overview
    • Components and Interactions
    • Managed Approach
    • Execution Flow
  • BASISOS AGENT
    • Overview
    • Core Components
    • System Design and Interactions
    • Agentic Roadmap
      • Stage 0: Assistant
      • Stage 1: Maintainer
      • Stage 2: Curator
      • Stage 3: Sovereign
  • TOKENOMICS
    • Token Distribution
    • Liquidity Mining
      • Distribution Mechanics
      • Rewards Schedule
    • Mindshare Mining
      • Distribution Mechanics
      • Rewards Schedule
  • CORE PROTOCOL
    • LogarithmVault
    • BasisStrategy
    • SpotManager
    • OffchainPositionManager
    • GmxV2PositionManager
    • LogarithmOracle
      • Oracle Provider
    • Contract Addresses
  • RISK MANAGEMENT
    • Funding Risk
    • Liquidity Risk
    • Risk Framework
      • Margin Treasury
      • Maximum Leverage
      • Asset Clustering
      • Strategy Capacity
    • Backtests
Powered by GitBook
On this page
  • State Variables
  • Functions
  • Events
  • Structs
  • Enums
  1. CORE PROTOCOL

BasisStrategy

Inherits: Initializable, PausableUpgradeable, OwnableUpgradeable, IBasisStrategy, AutomationCompatibleInterface

Author: Logarithm Labs

BasisStrategy implements a delta-neutral basis trading strategy. By simultaneously buying a spot asset and selling a perpetual contract, the strategy seeks to hedge the price risk of the spot position while generating revenue from funding payments. The contract allows depositors to provide capital through the connected vault, which is then deployed across both the spot and perpetual markets. Profits are derived from the funding payments collected from the short perpetual position, aiming for yield independent of price direction.

SpotManager and HedgeManager are connected as separated smart contracts to manage spot and hedge positions. BasisStrategy is an upgradeable smart contract, deployed through a beacon proxy pattern.

State Variables

BasisStrategyStorageLocation

bytes32 private constant BasisStrategyStorageLocation =
    0x3176332e209c21f110843843692adc742ac2f78c16c19930ebc0f9f8747e5200;

Functions

_getBasisStrategyStorage

function _getBasisStrategyStorage() private pure returns (BasisStrategyStorage storage $);

authCaller

Authorize caller if it is authorized one.

modifier authCaller(address authorized);

onlyOwnerOrVault

Authorize caller if it is owner and vault.

modifier onlyOwnerOrVault();

whenIdle

Validates if strategy is in IDLE status, otherwise reverts calling.

modifier whenIdle();

initialize

function initialize(
    address _config,
    address _product,
    address _vault,
    address _oracle,
    address _operator,
    uint256 _targetLeverage,
    uint256 _minLeverage,
    uint256 _maxLeverage,
    uint256 _safeMarginLeverage
) external initializer;

_setLeverages

function _setLeverages(uint256 _targetLeverage, uint256 _minLeverage, uint256 _maxLeverage, uint256 _safeMarginLeverage)
    internal;

_setOperator

function _setOperator(address newOperator) internal;

setSpotManager

Sets the spot manager.

function setSpotManager(address newSpotManager) external onlyOwner;

setHedgeManager

Sets the hedge manager.

function setHedgeManager(address newHedgeManager) external onlyOwner;

setOperator

Sets the operator.

function setOperator(address newOperator) external onlyOwner;

setLeverages

Sets the leverages.

function setLeverages(uint256 _targetLeverage, uint256 _minLeverage, uint256 _maxLeverage, uint256 _safeMarginLeverage)
    external
    onlyOwner;

pause

Pauses strategy, disabling utilizing and deutilizing for withdraw requests, while all logics related to keeping are still available.

function pause() external onlyOwnerOrVault whenNotPaused;

unpause

Unpauses strategy.

function unpause() external onlyOwnerOrVault whenPaused;

stop

Pauses strategy while swapping all products back to assets and closing the hedge position.

function stop() external onlyOwnerOrVault whenNotPaused;

utilize

Utilizes assets to increase the spot size. Right after the increase, the hedge position is also increased as the same amount as the spot size increased.

Uses assets in vault. Callable only by the operator.

function utilize(uint256 amount, ISpotManager.SwapType swapType, bytes calldata swapData)
    external
    virtual
    authCaller(operator())
    whenIdle;

Parameters

Name
Type
Description

amount

uint256

The underlying asset amount to be utilized.

swapType

ISpotManager.SwapType

The swap type in which the underlying asset is swapped.

swapData

bytes

The data used in swapping.

deutilize

Deutilizes products to decrease the spot size. Right after the decrease, the hedge position is also decreased as the same amount as the spot size decreased.

Called when processing withdraw requests, when deleveraging the position, and when there are funding risks. Callable only by the operator.

function deutilize(uint256 amount, ISpotManager.SwapType swapType, bytes calldata swapData)
    external
    authCaller(operator())
    whenIdle;

Parameters

Name
Type
Description

amount

uint256

The product amount to be deutilized.

swapType

ISpotManager.SwapType

The swap type in which the product is swapped.

swapData

bytes

The data used in swapping.

processAssetsToWithdraw

Processes assets in Strategy for the withdraw requests.

Callable by anyone and only when strategy is in the IDLE status.

function processAssetsToWithdraw() public whenIdle;

checkUpkeep

method that is simulated by the keepers to see if any work actually needs to be performed. This method does does not actually need to be executable, and since it is only ever simulated it can consume lots of gas.

To ensure that it is never called, you may want to add the cannotExecute modifier from KeeperBase to your implementation of this method.

function checkUpkeep(bytes memory) public view returns (bool upkeepNeeded, bytes memory performData);

Parameters

Name
Type
Description

<none>

bytes

Returns

Name
Type
Description

upkeepNeeded

bool

boolean to indicate whether the keeper should call performUpkeep or not.

performData

bytes

bytes that the keeper should call performUpkeep with, if upkeep is needed. If you would like to encode data to decode later, try abi.encode.

performUpkeep

method that is actually executed by the keepers, via the registry. The data returned by the checkUpkeep simulation will be passed into this method to actually be executed.

The input to this method should not be trusted, and the caller of the method should not even be restricted to any single registry. Anyone should be able call it, and the input should be validated, there is no guarantee that the data passed in is the performData returned from checkUpkeep. This could happen due to malicious keepers, racing keepers, or simply a state change while the performUpkeep transaction is waiting for confirmation. Always validate the data passed in.

function performUpkeep(bytes calldata) external whenIdle;

Parameters

Name
Type
Description

<none>

bytes

spotBuyCallback

Called after product is bought. Increases the hedge position size if the swap operation is for utilizing.

function spotBuyCallback(uint256 assetDelta, uint256 productDelta) external authCaller(spotManager());

spotSellCallback

Called after product is sold. Decreases the hedge position if the swap operation is not for reverting.

function spotSellCallback(uint256 assetDelta, uint256 productDelta) external authCaller(spotManager());

afterAdjustPosition

Callback function dispatcher of the hedge position adjustment.

function afterAdjustPosition(IHedgeManager.AdjustPositionPayload calldata params) external authCaller(hedgeManager());

pendingUtilizations

Returns available pending utilization and deutilization amounts.

The operator uses these values on offchain side to decide the parameters for calling utilize or deutilize functions. Both of those values can’t be none-zero at the same time.

function pendingUtilizations()
    public
    view
    returns (uint256 pendingUtilizationInAsset, uint256 pendingDeutilizationInProduct);

Returns

Name
Type
Description

pendingUtilizationInAsset

uint256

The available pending utilization amount in asset.

pendingDeutilizationInProduct

uint256

The available pending deutilzation amount in product. The calculation of this amount depends on the goal of deutilizing whether it is for processing withdraw requests or for rebalancing down.

utilizedAssets

The total underlying asset amount that has been utilized by this strategy.

Includes the product balance, the position net balance, and the asset balance of this strategy.

function utilizedAssets() public view returns (uint256);

assetsToWithdraw

The asset balance of this strategy.

This value should be transferred to the vault after finishing strategy operations.

function assetsToWithdraw() public view returns (uint256);

assetsToDeutilize

The total asset amount that is needed to be withdrawn from strategy to vault to process withdraw requests.

function assetsToDeutilize() public view returns (uint256);

_adjustPosition

Validate the position adjustment parameters before requesting.

function _adjustPosition(uint256 sizeDeltaInTokens, uint256 collateralDeltaAmount, bool isIncrease)
    internal
    virtual
    returns (bool);

_checkUpkeep

Common function of checkUpkeep and performUpkeep.

function _checkUpkeep() private view returns (InternalCheckUpkeepResult memory result);

_afterIncreasePosition

Called after the hedge position is increased.

function _afterIncreasePosition(IHedgeManager.AdjustPositionPayload calldata responseParams)
    private
    returns (bool shouldPause);

_afterDecreasePosition

Called after the hedge position is decreased.

function _afterDecreasePosition(IHedgeManager.AdjustPositionPayload calldata responseParams)
    private
    returns (bool shouldPause);

_processAssetsToWithdraw

Processes assetsToWithdraw for the withdraw requests

function _processAssetsToWithdraw(address _asset) private;

_pendingUtilization

This return value should be 0 when rebalancing down or when paused or when the totalSupply is 0.

function _pendingUtilization(
    uint256 totalSupply,
    uint256 idleAssets,
    uint256 _targetLeverage,
    bool _processingRebalanceDown,
    bool _paused
) private pure returns (uint256);

_pendingDeutilization

This return value should be 0 when paused and not processing rebalance down.

function _pendingDeutilization(InternalPendingDeutilization memory params) private view returns (uint256);

_clamp

function _clamp(uint256 min, uint256 value, uint256 max) internal pure returns (uint256 result);

_checkDeviation

Should be called under the condition that denominator != 0. Note: check if response of position adjustment is in the allowed deviation

function _checkDeviation(uint256 numerator, uint256 denominator, uint256 deviationThreshold)
    internal
    pure
    returns (bool exceedsThreshold, int256 deviation);

_checkNeedRebalance

Checks if current leverage is not near to the target leverage

function _checkNeedRebalance(uint256 _currentLeverage, uint256 _targetLeverage, uint256 _rebalanceDeviationThreshold)
    internal
    pure
    returns (bool rebalanceUpNeeded, bool rebalanceDownNeeded);

_checkRebalance

Checks if current leverage is out of the min and max leverage

function _checkRebalance(
    uint256 currentLeverage,
    uint256 _minLeverage,
    uint256 _maxLeverage,
    uint256 _safeMarginLeverage
) internal pure returns (bool rebalanceUpNeeded, bool rebalanceDownNeeded, bool deleverageNeeded);

_checkHedgeDeviation

Checks the difference between spot and hedge sizes if it is over the configured threshold.

function _checkHedgeDeviation(IHedgeManager _hedgeManager, uint256 _hedgeDeviationThreshold)
    internal
    view
    returns (int256);

_calculateDeltaCollateralForRebalance

collateral adjustment for rebalancing currentLeverage = notional / collateral notional = currentLeverage collateral targetLeverage = notional / targetCollateral targetCollateral = notional / targetLeverage targetCollateral = collateral * currentLeverage / targetLeverage*

function _calculateDeltaCollateralForRebalance(
    uint256 positionNetBalance,
    uint256 _currentLeverage,
    uint256 _targetLeverage
) internal pure returns (uint256);

_validateStrategyStatus

Validates the strategy status if it is desired one.

function _validateStrategyStatus(StrategyStatus targetStatus) private view;

_setStrategyStatus

Sets the strategy status.

function _setStrategyStatus(StrategyStatus newStatus) private;

vault

The address of connected vault.

function vault() public view returns (address);

spotManager

The address of the spot manager which buys and sells product in spot markets.

function spotManager() public view returns (address);

hedgeManager

The address of the position manager which hedges the spot by opening perpetual positions.

function hedgeManager() public view returns (address);

oracle

The address of system oracle.

function oracle() public view returns (address);

operator

The address of operator which is responsible for calling utilize/deutilize.

function operator() public view returns (address);

asset

The address of underlying asset.

function asset() public view returns (address);

product

The address of product.

function product() public view returns (address);

config

The address of Config smart contract that is used throughout all strategies for their configurations.

function config() public view returns (IStrategyConfig);

strategyStatus

The strategy status.

function strategyStatus() public view returns (StrategyStatus);

targetLeverage

The target leverage at which the hedge position is increased.

function targetLeverage() public view returns (uint256);

minLeverage

The minimum leverage value to which the hedge position can be reached down.

function minLeverage() public view returns (uint256);

maxLeverage

The maximum leverage value to which the hedge position can be reached up.

function maxLeverage() public view returns (uint256);

safeMarginLeverage

The maximum leverage value where normal rebalancing down is applied. If the leverage overshoots it, emergency rebalancing down is executed.

function safeMarginLeverage() public view returns (uint256);

pendingDecreaseCollateral

The value that couldn’t be decreased due to size limits. Accumulated overtime and executed to decrease collateral by keeping logic once the size satisfies the conditions.

function pendingDecreaseCollateral() public view returns (uint256);

processingRebalanceDown

Tells if strategy is in rebalancing down.

function processingRebalanceDown() public view returns (bool);

Events

Utilize

Emitted when assets are utilized.

event Utilize(address indexed caller, uint256 assetDelta, uint256 productDelta);

Deutilize

Emitted when assets are deutilized.

event Deutilize(address indexed caller, uint256 productDelta, uint256 assetDelta);

PositionAdjusted

Emitted when the hedge position gets adjusted.

event PositionAdjusted(uint256 sizeDeltaInTokens, uint256 collateralDeltaAmount, bool isIncrease);

LeverageConfigUpdated

Emitted when leverage config gets changed.

event LeverageConfigUpdated(
    address indexed account,
    uint256 targetLeverage,
    uint256 minLeverage,
    uint256 maxLeverage,
    uint256 safeMarginLeverage
);

SpotManagerUpdated

Emitted when the spot manager is changed.

event SpotManagerUpdated(address indexed account, address indexed newSpotManager);

HedgeManagerUpdated

Emitted when the position manager is changed.

event HedgeManagerUpdated(address indexed account, address indexed newPositionManager);

OperatorUpdated

Emitted when the operator is changed.

event OperatorUpdated(address indexed account, address indexed newOperator);

Stopped

Emitted when strategy is stopped.

event Stopped(address indexed account);

Structs

InternalPendingDeutilization

Used internally to optimize params of deutilization.

struct InternalPendingDeutilization {
    IHedgeManager hedgeManager;
    address asset;
    address product;
    uint256 totalSupply;
    bool processingRebalanceDown;
    bool paused;
}

InternalCheckUpkeepResult

Used internally as a result of checkUpkeep function.

struct InternalCheckUpkeepResult {
    uint256 emergencyDeutilizationAmount;
    uint256 deltaCollateralToIncrease;
    bool clearProcessingRebalanceDown;
    int256 hedgeDeviationInTokens;
    bool hedgeManagerNeedKeep;
    bool processPendingDecreaseCollateral;
    uint256 deltaCollateralToDecrease;
}

BasisStrategyStorage

struct BasisStrategyStorage {
    IERC20 product;
    IERC20 asset;
    ILogarithmVault vault;
    ISpotManager spotManager;
    IHedgeManager hedgeManager;
    IOracle oracle;
    address operator;
    address config;
    uint256 targetLeverage;
    uint256 minLeverage;
    uint256 maxLeverage;
    uint256 safeMarginLeverage;
    uint256 pendingDeutilizedAssets;
    uint256 pendingDecreaseCollateral;
    StrategyStatus strategyStatus;
    bool processingRebalanceDown;
    IHedgeManager.AdjustPositionPayload requestParams;
}

Enums

StrategyStatus

Used to specify strategy’s operations.

enum StrategyStatus {
    IDLE,
    KEEPING,
    UTILIZING,
    PARTIAL_DEUTILIZING,
    FULL_DEUTILIZING
}
PreviousLogarithmVaultNextSpotManager

Last updated 3 months ago