Skip to content

Commit

Permalink
Merge pull request #113 from equilibria-xyz/dev
Browse files Browse the repository at this point in the history
0.0.3-beta.2
  • Loading branch information
arjun-io authored Oct 30, 2024
2 parents 45c18c7 + 047158e commit 7473c75
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 64 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ dist

src/abi/Lens.abi.ts
src/abi/VaultLens.abi.ts
src/abi/MarketMetadataLens.abi.ts
src/types/generated
src/types/gql

Expand Down
File renamed without changes.
56 changes: 56 additions & 0 deletions contracts/Lens.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import '@perennial/core/contracts/interfaces/IMarket.sol';
import '@perennial/core/contracts/types/OracleReceipt.sol';
import '@perennial/oracle/contracts/interfaces/IOracle.sol';
import '@perennial/oracle/contracts/interfaces/IKeeperFactory.sol';
import '@perennial/oracle/contracts/interfaces/IOracleFactory.sol';
import '@perennial/oracle/contracts/interfaces/IKeeperOracle.sol';
import * as Vault from '@perennial/vault/contracts/interfaces/IVault.sol';
import '@perennial/vault/contracts/interfaces/IVaultFactory.sol';
import '@equilibria/root/number/types/UFixed6.sol';
Expand Down Expand Up @@ -317,3 +319,57 @@ contract VaultLens {
}
}
}

interface ILensOracle is IOracle {
function oracles(uint256 id) external view returns (Epoch memory);
}

contract MarketMetadataLens {
struct MarketMetadata {
string name;
IMarket marketAddress;
RiskParameter riskParameter;
MarketParameter marketParameter;
ILensOracle oracle;
IOracleFactory oracleFactory;
IKeeperOracle subOracle;
IKeeperFactory subOracleFactory;
IKeeperFactory.PayoffDefinition oraclePayoffDefinition;
string subOracleFactoryType;
bytes32 oracleId;
bytes32 oracleUnderlyingId;
OracleParameter oracleFactoryParameter;
KeeperOracleParameter subOracleFactoryParameter;
IGasOracle commitmentGasOracle;
IGasOracle settlementGasOracle;
}

function metadata(IMarket[] memory markets) public view returns (MarketMetadata[] memory marketMetadata) {
marketMetadata = new MarketMetadata[](markets.length);
for (uint i = 0; i < markets.length; i++) {
marketMetadata[i] = metadata(markets[i]);
}
}

function metadata(IMarket market) public view returns (MarketMetadata memory marketMetadata) {
marketMetadata.marketAddress = market;
marketMetadata.riskParameter = market.riskParameter();
marketMetadata.marketParameter = market.parameter();
marketMetadata.oracle = ILensOracle(address(market.oracle()));
marketMetadata.oracleFactory = IOracleFactory(address(marketMetadata.oracle.factory()));
marketMetadata.oracleFactoryParameter = marketMetadata.oracleFactory.parameter();
marketMetadata.name = marketMetadata.oracle.name();
marketMetadata.oracleId = marketMetadata.oracleFactory.ids(marketMetadata.oracle);

IOracle.OracleGlobal memory global = marketMetadata.oracle.global();
marketMetadata.subOracle = IKeeperOracle(address(marketMetadata.oracle.oracles(global.current).provider));
marketMetadata.subOracleFactory = IKeeperFactory(address(marketMetadata.subOracle.factory()));
marketMetadata.oraclePayoffDefinition = marketMetadata.subOracleFactory.toUnderlyingPayoff(marketMetadata.oracleId);
marketMetadata.subOracleFactoryType = marketMetadata.subOracleFactory.factoryType();
marketMetadata.oracleUnderlyingId = marketMetadata.subOracleFactory.toUnderlyingId(marketMetadata.oracleId);

marketMetadata.subOracleFactoryParameter = marketMetadata.subOracleFactory.parameter();
marketMetadata.commitmentGasOracle = marketMetadata.subOracleFactory.commitmentGasOracle();
marketMetadata.settlementGasOracle = marketMetadata.subOracleFactory.settlementGasOracle();
}
}
2 changes: 1 addition & 1 deletion graph-codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dotenvConfig({ path: './.env.local' }) // point to root of project for now

const config: CodegenConfig = {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
schema: [process.env.GRAPH_URL_ARBITRUM!, process.env.GRAPH_URL_ARBITRUM_SEPOLIA!],
schema: [process.env.GRAPH_URL_ARBITRUM!],
documents: ['src/graphQueries/**/*.{ts,tsx}'],
generates: {
'./src/types/gql/': {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@perennial/sdk",
"version": "0.0.3-beta.1",
"version": "0.0.3-beta.2",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -34,7 +34,7 @@
"@graphql-typed-document-node/core": "^3.2.0",
"@openzeppelin/contracts": "4.8.0",
"@perennial/core": "1.3.0-rc1",
"@perennial/oracle": "1.3.0-rc2",
"@perennial/oracle": "1.3.0-rc3",
"@perennial/vault": "1.3.0-rc1",
"@perennial/verifier": "1.3.0-rc1",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/lensAbiCopy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
const fs = require('fs')
const path = require('path')

const lenses = ['Lens', 'VaultLens']
const lenses = ['Lens', 'VaultLens', 'MarketMetadataLens']

lenses.forEach((lens) => {
const lensJsonPath = path.join(__dirname, `../artifacts/contracts/Lens.sol/${lens}.json`)
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export {
type MarketSnapshots,
fetchMarketOracles,
fetchMarketSnapshots,
fetchMarketSettlementFees,
} from './lib/markets/chain'

// Market - Graph
Expand Down
95 changes: 43 additions & 52 deletions src/lib/markets/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,13 @@ import {
addressToMarket,
calculateFundingAndInterestForSides,
chainMarketsWithAddress,
notEmpty,
} from '../..'
import { GasOracleAbi } from '../../abi/GasOracle.abi'
import { LensAbi, LensDeployedBytecode } from '../../abi/Lens.abi'
import { MarketMetadataLensAbi, MarketMetadataLensDeployedBytecode } from '../../abi/MarketMetadataLens.abi'
import { SupportedMarketMapping } from '../../constants'
import { calcLeverage, calcNotional, getStatusForSnapshot, sideFromPosition } from '../../utils/positionUtils'
import {
getKeeperFactoryContract,
getKeeperOracleContract,
getMarketContract,
getOracleContract,
getOracleFactoryContract,
} from '../contracts'
import { OracleClients, marketOraclesToUpdateDataRequest, oracleCommitmentsLatest } from '../oracle'

export type MarketOracles = NonNullable<Awaited<ReturnType<typeof fetchMarketOracles>>>
Expand All @@ -39,63 +34,57 @@ export async function fetchMarketOracles(
publicClient: PublicClient,
markets?: SupportedMarket[],
) {
// TODO: Convert this to a Lens call?
const marketsWithAddress = chainMarketsWithAddress(chainId, markets)
const fetchMarketOracles = async (market: SupportedMarket, marketAddress: Address) => {
const marketContract = getMarketContract(marketAddress, publicClient)
const [riskParameter, oracleAddress] = await Promise.all([
marketContract.read.riskParameter(),
marketContract.read.oracle(),
])
// Fetch oracle data
const oracle = getOracleContract(oracleAddress, publicClient)
const [global, oracleName] = await Promise.all([oracle.read.global(), oracle.read.name()])
const [keeperOracle] = await oracle.read.oracles([global[0]])
const keeperOracleContract = getKeeperOracleContract(keeperOracle, publicClient)
const subOracleFactory = getKeeperFactoryContract(await keeperOracleContract.read.factory(), publicClient)
const marketMetadataLens = getContractAddress({ from: zeroAddress, nonce: MaxUint256 })
const lensResult = await publicClient.readContract({
address: marketMetadataLens,
abi: MarketMetadataLensAbi,
functionName: 'metadata',
args: [marketsWithAddress.map(({ marketAddress }) => marketAddress)],
stateOverride: [
{
address: marketMetadataLens,
code: MarketMetadataLensDeployedBytecode,
balance: maxUint256,
},
],
})

const oracleFactory = getOracleFactoryContract(chainId, publicClient)
const id = await oracleFactory.read.ids([oracleAddress])
const [parameter, underlyingId, subOracleFactoryType, commitmentGasOracle, settlementGasOracle] = await Promise.all(
[
subOracleFactory.read.parameter(),
subOracleFactory.read.toUnderlyingId([id]),
subOracleFactory.read.factoryType(),
subOracleFactory.read.commitmentGasOracle(),
subOracleFactory.read.settlementGasOracle(),
],
)
const parseLensResult = (market: SupportedMarket, marketAddress: Address) => {
const marketLensResult = lensResult.find((result) => result.marketAddress === marketAddress)
if (!marketLensResult) return

return {
market,
marketAddress,
oracleName,
oracleFactoryAddress: oracleFactory.address,
oracleAddress,
subOracleFactoryAddress: subOracleFactory.address,
subOracleAddress: keeperOracle,
subOracleFactoryType,
id,
underlyingId,
minValidTime: parameter.validFrom,
staleAfter: riskParameter.staleAfter,
commitmentGasOracle,
settlementGasOracle,
oracleName: marketLensResult.name,
oracleFactoryAddress: marketLensResult.oracleFactory,
oracleAddress: marketLensResult.oracle,
subOracleFactoryAddress: marketLensResult.subOracleFactory,
subOracleAddress: marketLensResult.subOracle,
subOracleFactoryType: marketLensResult.subOracleFactoryType,
id: marketLensResult.oracleId,
underlyingId: marketLensResult.oracleUnderlyingId,
minValidTime: marketLensResult.subOracleFactoryParameter.validFrom,
staleAfter: marketLensResult.riskParameter.staleAfter,
maxSettlementFee: marketLensResult.oracleFactoryParameter.maxSettlementFee,
commitmentGasOracle: marketLensResult.commitmentGasOracle,
settlementGasOracle: marketLensResult.settlementGasOracle,
}
}

const marketData = await Promise.all(
marketsWithAddress.map(({ market, marketAddress }) => {
return fetchMarketOracles(market, marketAddress)
}),
)
const marketData = marketsWithAddress
.map(({ market, marketAddress }) => {
return parseLensResult(market, marketAddress)
})
.filter(notEmpty)

return marketData.reduce(
(acc, market) => {
acc[market.market] = market
return acc
},
{} as SupportedMarketMapping<Awaited<ReturnType<typeof fetchMarketOracles>>>,
{} as SupportedMarketMapping<NonNullable<Awaited<ReturnType<typeof parseLensResult>>>>,
)
}

Expand Down Expand Up @@ -438,10 +427,12 @@ export async function fetchMarketSettlementFees({
(acc, market) => {
const commitmentCost = commitmentCostCache.get(marketOracles[market].commitmentGasOracle) ?? 0n
const settlementCost = settlementCostCache.get(marketOracles[market].settlementGasOracle) ?? 0n
const maxCost = marketOracles[market].maxSettlementFee

acc[market] = {
commitmentCost,
settlementCost,
totalCost: commitmentCost + settlementCost,
commitmentCost: Big6Math.min(commitmentCost, maxCost),
settlementCost: Big6Math.min(settlementCost, maxCost),
totalCost: Big6Math.min(commitmentCost + settlementCost, maxCost),
}
return acc
},
Expand Down
2 changes: 1 addition & 1 deletion src/lib/markets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ export class MarketsModule {
* @param isMaker boolean - Filter for maker orders
* @returns User's open orders.
*/
openOrders: (args: OmitBound<Parameters<typeof fetchOpenOrders>[0]> & OptionalAddress & OptionalMarkets) => {
openOrders: (args: OmitBound<Parameters<typeof fetchOpenOrders>[0]> & OptionalAddress & OptionalMarkets = {}) => {
if (!this.config.graphClient) {
throw new Error('Graph client required to fetch open orders.')
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils/big6Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ export class Big6Math {

public static fromDecimals(amount: bigint, decimals: number): bigint {
const exponent = BigInt(Big6Math.FIXED_DECIMALS - decimals)
if (exponent >= 0n) return amount * (10n ** exponent)
return amount / (10n ** (exponent * -1n))
if (exponent >= 0n) return amount * 10n ** exponent
return amount / 10n ** (exponent * -1n)
}

public static to18Decimals(amount: bigint): bigint {
Expand Down

0 comments on commit 7473c75

Please sign in to comment.