Skip to content

Commit

Permalink
feat: update quant position lens
Browse files Browse the repository at this point in the history
  • Loading branch information
kjr217 committed Oct 30, 2023
1 parent 3f144e5 commit a2e9938
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 34 deletions.
137 changes: 107 additions & 30 deletions packages/contracts/contracts/lens/QuantPositionLensMK1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
pragma solidity 0.8.9;

import "../Protocol.sol";
import "../OptionCatalogue.sol";
import "../interfaces/GammaInterface.sol";
import "../AlphaPortfolioValuesFeed.sol";
import "hardhat/console.sol";

/**
* @title Lens contract to get dhv positions for the quants
*/
contract QuantPositionLensMK1 {

// protocol
Protocol public protocol;

Protocol public immutable protocol;
OptionCatalogue public immutable catalogue;
address public immutable usdc;
address public immutable weth;
///////////////
/// structs ///
///////////////
Expand All @@ -23,8 +26,6 @@ contract QuantPositionLensMK1 {

struct InstrumentDrill {
address seriesAddress;
string name;
string symbol;
uint64 expiration;
bool isPut;
uint128 strike; // e18
Expand All @@ -33,48 +34,124 @@ contract QuantPositionLensMK1 {
int256 shortExposure; // e18
int256 longExposure; // e18
bytes32 optionHash;
bool isBuyable;
bool isSellable;
}

constructor(address _protocol) {
constructor(address _protocol, address _catalogue, address _usdc, address _weth) {
protocol = Protocol(_protocol);
catalogue = OptionCatalogue(_catalogue);
usdc = _usdc;
weth = _weth;
}

function DHVPosDrill() external view returns (DHVPosStruct memory) {
AlphaPortfolioValuesFeed pv = AlphaPortfolioValuesFeed(protocol.portfolioValuesFeed());
// get the length of the address set here to save gas on the for loop
address[] memory seriesAddresses = pv.getAddressSet();
uint256 lengthAddy = seriesAddresses.length;
console.log(lengthAddy);
InstrumentDrill[] memory instrumentDrills = new InstrumentDrill[](lengthAddy);
for (uint256 i = 0; i < lengthAddy; i++) {
address seriesAddress = seriesAddresses[i];
// get series
(Types.OptionSeries memory optionSeries, int256 shortExposure, int256 longExposure) = pv.storesForAddress(seriesAddress);
// get the list of strikes and expiries from the catalogue
uint64[] memory expirations = getExpirations();
// multiply by 2 to account for both collateral types
uint256 count = getCount(expirations) * 2;
uint64 iter;
InstrumentDrill[] memory instrumentDrills = new InstrumentDrill[](count);
for (uint i=0; i < expirations.length; i++) {
uint128[] memory callStrikes = catalogue.getOptionDetails(expirations[i], false);
uint128[] memory putStrikes = catalogue.getOptionDetails(expirations[i], true);
for (uint j=0; j < callStrikes.length; j++) {
instrumentDrills[iter] = instrumentDrillConstructor(expirations[i], callStrikes[j], false, usdc);
iter++;
instrumentDrills[iter] = instrumentDrillConstructor(expirations[i], callStrikes[j], false, weth);
iter++;
}
for (uint j=0; j < putStrikes.length; j++) {
instrumentDrills[iter] = instrumentDrillConstructor(expirations[i], putStrikes[j], true, usdc);
iter++;
instrumentDrills[iter] = instrumentDrillConstructor(expirations[i], putStrikes[j], true, weth);
iter++;
}
}
return DHVPosStruct(instrumentDrills);
}

function instrumentDrillConstructor(uint64 expiration, uint128 strike, bool isPut, address collateral) public view returns (InstrumentDrill memory) {
// get series address
IOptionRegistry optionRegistry = getOptionRegistry();
AlphaPortfolioValuesFeed pv = getPortfolioValuesFeed();
address seriesAddress = optionRegistry.getOtoken(
weth,
usdc,
expiration,
isPut,
strike,
collateral
);
(, int256 shortExposure, int256 longExposure) = pv.storesForAddress(seriesAddress);
bytes32 oHash =
keccak256(
abi.encodePacked(
optionSeries.expiration,
optionSeries.strike,
optionSeries.isPut
expiration,
strike,
isPut
)
);
int256 virtualNetDhvExposure = AlphaPortfolioValuesFeed(protocol.portfolioValuesFeed()).netDhvExposure(oHash);
IOtoken otoken = IOtoken(seriesAddress);

instrumentDrills[i] = InstrumentDrill(
OptionCatalogue.OptionStores memory stores = catalogue.getOptionStores(oHash);
return InstrumentDrill(
seriesAddress,
otoken.name(),
otoken.symbol(),
optionSeries.expiration,
optionSeries.isPut,
optionSeries.strike,
optionSeries.collateral,
expiration,
isPut,
strike,
collateral,
virtualNetDhvExposure,
shortExposure,
longExposure,
oHash
oHash,
stores.isBuyable,
stores.isSellable
);
}

function getExpirations() public view returns (uint64[] memory) {
uint64[] memory allExpirations = catalogue.getExpirations();
bool[] memory expirationMask = new bool[](allExpirations.length);
uint8 validCount;
for (uint i; i < allExpirations.length; i++) {
if (allExpirations[i] < block.timestamp) {
continue;
}
expirationMask[i] = true;
validCount++;
}
uint64[] memory expirations = new uint64[](validCount);
uint8 c;
for (uint i; i < expirationMask.length; i++) {
if (expirationMask[i]) {
expirations[c] = allExpirations[i];
c++;
}
}
return expirations;
}
function getCount(uint64[] memory expirations) internal view returns (uint256 count) {
for (uint i=0; i < expirations.length; i++) {
uint128[] memory callStrikes = catalogue.getOptionDetails(expirations[i], false);
uint128[] memory putStrikes = catalogue.getOptionDetails(expirations[i], true);
count += callStrikes.length;
count += putStrikes.length;
}
return DHVPosStruct(instrumentDrills);
}

/**
* @notice get the option registry used by the liquidity pool
* @return the option registrt contract
*/
function getOptionRegistry() internal view returns (IOptionRegistry) {
return IOptionRegistry(protocol.optionRegistry());
}

/**
* @notice get the portfolio values feed used by the liquidity pool
* @return the portfolio values feed contract
*/
function getPortfolioValuesFeed() internal view returns (AlphaPortfolioValuesFeed) {
return AlphaPortfolioValuesFeed(protocol.portfolioValuesFeed());
}
}
14 changes: 12 additions & 2 deletions packages/contracts/deploy/arbitrum/deployQuantPositionLensMK1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ import { QuantPositionLensMK1 } from "../../types/QuantPositionLensMK1"
// update these addresses to connect to the appropriate set of contracts

const protocolAddress = "0x4e920e9A901069d9b211646B6E191d81BA40E5FB"
const catalogueAddress = "0x44227Dc2a1d71FC07DC254Dfd42B1C44aFF12168"
const usdc = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
const weth = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"

export async function deployLens() {
const lensFactory = await ethers.getContractFactory("QuantPositionLensMK1")
const lens = (await lensFactory.deploy(
protocolAddress
protocolAddress,
catalogueAddress,
usdc,
weth
)) as QuantPositionLensMK1

console.log("quant lens contract deployed")
Expand All @@ -16,7 +23,10 @@ export async function deployLens() {
await hre.run("verify:verify", {
address: lens.address,
constructorArguments: [
protocolAddress
protocolAddress,
catalogueAddress,
usdc,
weth
]
})
console.log("quant lens verified")
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/test/LensMk1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ describe("Lens", async () => {
})
it("SETUP: deploy quant exposure lens contract", async () => {
const lensFactory = await ethers.getContractFactory("QuantPositionLensMK1")
quantLens = (await lensFactory.deploy(optionProtocol.address)) as QuantPositionLensMK1
quantLens = (await lensFactory.deploy(optionProtocol.address, catalogue.address, usd.address, weth.address)) as QuantPositionLensMK1
})
})
describe("Purchase a bunch of random options", async () => {
Expand Down Expand Up @@ -759,7 +759,7 @@ describe("Lens", async () => {
describe("Hit the quant Lens", async () => {
it("ping the lens contract", async () => {
const lensVals = await quantLens.DHVPosDrill()
console.log({lensVals})
// console.log({lensVals})
// console.log(lensVals[0])
// console.log(lensVals[2])
})
Expand Down

0 comments on commit a2e9938

Please sign in to comment.