# OffchainPositionManager

**Inherits:** Initializable, OwnableUpgradeable, IHedgeManager

**Author:** Logarithm Labs

OffChainPositionManager is a smart contract component designed to interact with off-chain perpetual protocols to manage hedge positions. By coordinating with off-chain systems, such as through an oracle or relayer network, the contract adjusts perpetual positions to maintain a target exposure aligned with the strategy’s requirements. This component is ideal for delta-neutral strategies seeking yield from funding payments on off-chain perpetual markets.

*OffChainPositionManager is an upgradeable smart contract, deployed through the beacon proxy pattern.*

### State Variables

#### OffChainPositionManagerStorageLocation

```solidity
bytes32 private constant OffChainPositionManagerStorageLocation =
    0xc79dcf1ab1ed210e1b815a3e944622845af0e197fa2b370829d3b756c740ef00;
```

### Functions

#### \_getOffChainPositionManagerStorage

```solidity
function _getOffChainPositionManagerStorage() private pure returns (OffChainPositionManagerStorage storage $);
```

#### onlyAgent

*Authorize caller if it is a configured agent.*

```solidity
modifier onlyAgent();
```

#### initialize

```solidity
function initialize(address config_, address strategy_, address agent_, address oracle_, bool isLong_)
    external
    initializer;
```

#### \_setAgent

```solidity
function _setAgent(address newAgent) internal;
```

#### setAgent

```solidity
function setAgent(address newAgent) external onlyOwner;
```

#### adjustPosition

Called to adjust the hedge position based on specified parameters.

```solidity
function adjustPosition(AdjustPositionPayload memory params) external;
```

**Parameters**

| Name     | Type                    | Description |
| -------- | ----------------------- | ----------- |
| `params` | `AdjustPositionPayload` |             |

#### reportState

*Reports the state of the hedge position.*

```solidity
function reportState(uint256 sizeInTokens, uint256 netBalance, uint256 markPrice) external onlyAgent;
```

#### reportStateAndExecuteRequest

*Reports the state of the hedge position while calling the strategy’s callback functions if there is a position adjustment request from the strategy.*

```solidity
function reportStateAndExecuteRequest(
    uint256 sizeInTokens,
    uint256 netBalance,
    uint256 markPrice,
    AdjustPositionPayload memory params
) external onlyAgent;
```

#### getLastRequest

*Returns the last request that was requested from strategy.*

```solidity
function getLastRequest() external view returns (RequestInfo memory);
```

#### clearIdleCollateral

Transfers idle assets to the vault to process withdraw requests.

```solidity
function clearIdleCollateral() public;
```

#### forcedTransferToAgent

```solidity
function forcedTransferToAgent(uint256 amount) external onlyAgent;
```

#### \_transferToAgent

```solidity
function _transferToAgent(uint256 amount) internal;
```

#### forcedTransferFromAgent

```solidity
function forcedTransferFromAgent(uint256 amount) external onlyAgent;
```

#### \_transferFromAgent

```solidity
function _transferFromAgent(uint256 amount) internal;
```

#### positionNetBalance

Gets the net collateral balance of the position, including pending adjustments.

```solidity
function positionNetBalance() public view virtual override returns (uint256);
```

**Returns**

| Name     | Type      | Description                                        |
| -------- | --------- | -------------------------------------------------- |
| `<none>` | `uint256` | The total collateral asset amount in the position. |

#### currentPositionState

*Returns the current state of position.*

```solidity
function currentPositionState() public view returns (PositionState memory);
```

#### currentLeverage

Retrieves the current leverage of the position.

```solidity
function currentLeverage() public view returns (uint256 leverage);
```

**Returns**

| Name       | Type      | Description                      |
| ---------- | --------- | -------------------------------- |
| `leverage` | `uint256` | The leverage ratio as a uint256. |

#### config

The address of OffChainConfig smart contract.

```solidity
function config() public view returns (IOffChainConfig);
```

#### agent

The address of agent.

```solidity
function agent() public view returns (address);
```

#### oracle

The address of oracle smart contract.

```solidity
function oracle() public view returns (address);
```

#### lastRequestRound

The last request round.

```solidity
function lastRequestRound() public view returns (uint256);
```

#### currentRound

The current round which is increased by reporting state.

```solidity
function currentRound() public view returns (uint256);
```

#### positionState

The position state at a specific round.

```solidity
function positionState(uint256 round) public view returns (PositionState memory);
```

#### pendingCollateralIncrease

The pending collateral amount that is transferred to agent to increase collateral, but not reported by agent.

```solidity
function pendingCollateralIncrease() public view returns (uint256);
```

#### requests

The request info at a specific round.

```solidity
function requests(uint256 round) public view returns (RequestInfo memory);
```

#### positionSizeInTokens

Returns the current size of the position in terms of index tokens.

```solidity
function positionSizeInTokens() public view returns (uint256);
```

**Returns**

| Name     | Type      | Description                               |
| -------- | --------- | ----------------------------------------- |
| `<none>` | `uint256` | The size of the position in index tokens. |

#### needKeep

Checks whether the `keep` function needs to be called to maintain the position.

```solidity
function needKeep() public pure virtual returns (bool);
```

**Returns**

| Name     | Type   | Description                                        |
| -------- | ------ | -------------------------------------------------- |
| `<none>` | `bool` | A boolean indicating if `keep` should be executed. |

#### keep

Called to maintain or adjust the hedge position as required by strategy logic.

*Executes actions needed to align the position with target hedge requirements.*

```solidity
function keep() public pure;
```

#### increaseCollateralMinMax

Returns the minimum and maximum collateral limits for increasing the position.

```solidity
function increaseCollateralMinMax() public view returns (uint256 min, uint256 max);
```

**Returns**

| Name  | Type      | Description                                       |
| ----- | --------- | ------------------------------------------------- |
| `min` | `uint256` | The minimum allowable collateral increase amount. |
| `max` | `uint256` | The maximum allowable collateral increase amount. |

#### increaseSizeMinMax

Returns the minimum and maximum limits for increasing the position size.

```solidity
function increaseSizeMinMax() public view returns (uint256 min, uint256 max);
```

**Returns**

| Name  | Type      | Description                                      |
| ----- | --------- | ------------------------------------------------ |
| `min` | `uint256` | The minimum allowable increase in position size. |
| `max` | `uint256` | The maximum allowable increase in position size. |

#### decreaseCollateralMinMax

Returns the minimum and maximum collateral limits for decreasing the position.

```solidity
function decreaseCollateralMinMax() public view returns (uint256 min, uint256 max);
```

**Returns**

| Name  | Type      | Description                                       |
| ----- | --------- | ------------------------------------------------- |
| `min` | `uint256` | The minimum allowable collateral decrease amount. |
| `max` | `uint256` | The maximum allowable collateral decrease amount. |

#### decreaseSizeMinMax

Returns the minimum and maximum limits for decreasing the position size.

```solidity
function decreaseSizeMinMax() public view returns (uint256 min, uint256 max);
```

**Returns**

| Name  | Type      | Description                                      |
| ----- | --------- | ------------------------------------------------ |
| `min` | `uint256` | The minimum allowable decrease in position size. |
| `max` | `uint256` | The maximum allowable decrease in position size. |

#### limitDecreaseCollateral

Retrieves the minimum decrease in collateral required for cost-efficient execution.

*Helps in optimizing gas usage and cost efficiency.*

```solidity
function limitDecreaseCollateral() public view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                                         |
| -------- | --------- | ----------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The minimum decrease collateral amount that qualifies for cost-effective execution. |

#### collateralToken

Returns the address of the collateral token used in the position.

```solidity
function collateralToken() public view returns (address);
```

**Returns**

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `<none>` | `address` | The address of the collateral token. |

#### indexToken

Returns the address of the index token used in the position.

```solidity
function indexToken() public view returns (address);
```

**Returns**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `<none>` | `address` | The address of the index token. |

#### idleCollateralAmount

The balance of collateral asset of this position manager.

```solidity
function idleCollateralAmount() public view returns (uint256);
```

### Events

#### AgentUpdated

*Emitted when agent gets updated.*

```solidity
event AgentUpdated(address indexed account, address indexed newAgent);
```

#### CreateRequest

*Emitted when a new request from strategy is created.*

```solidity
event CreateRequest(uint256 indexed round, uint256 sizeDeltaInTokens, uint256 collateralDeltaAmount, bool isIncrease);
```

#### ReportRequest

*Emitted when a report is executed after requesting.*

```solidity
event ReportRequest(
    uint256 indexed requestRound,
    uint256 indexed reportRound,
    uint256 sizeDeltaInTokens,
    uint256 collateralDeltaAmount,
    bool isIncrease
);
```

#### RequestIncreasePosition

*Emitted when a increase request is created.*

```solidity
event RequestIncreasePosition(uint256 collateralDeltaAmount, uint256 sizeDeltaInTokens, uint256 round);
```

#### RequestDecreasePosition

*Emitted when a decrease request is created.*

```solidity
event RequestDecreasePosition(uint256 collateralDeltaAmount, uint256 sizeDeltaInTokens, uint256 round);
```

#### AgentTransfer

*Emitted when asset is transferred to agent to increase collateral.*

```solidity
event AgentTransfer(address indexed caller, uint256 amount, bool toAgent);
```

#### ReportState

*Emitted when position’s state is reported.*

```solidity
event ReportState(uint256 positionSizeInTokens, uint256 positionNetBalance, uint256 markPrice, uint256 timestamp);
```

### Structs

#### PositionState

*Used to store the state of offchain position.*

```solidity
struct PositionState {
    uint256 sizeInTokens;
    uint256 netBalance;
    uint256 markPrice;
    uint256 timestamp;
}
```

#### RequestInfo

*Used for the request and response infos.*

```solidity
struct RequestInfo {
    AdjustPositionPayload request;
    AdjustPositionPayload response;
    uint256 requestTimestamp;
    uint256 responseRound;
    uint256 responseTimestamp;
    bool isReported;
}
```

#### OffChainPositionManagerStorage

```solidity
struct OffChainPositionManagerStorage {
    address config;
    address strategy;
    address agent;
    address oracle;
    address indexToken;
    address collateralToken;
    bool isLong;
    uint256 currentRound;
    uint256 lastRequestRound;
    uint256 pendingCollateralIncrease;
    mapping(uint256 round => PositionState) positionStates;
    mapping(uint256 round => RequestInfo) requests;
    uint256[] requestRounds;
}
```
