@@ -33,7 +33,7 @@ import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/Prec
3333import { BaseExtension } from "../lib/BaseExtension.sol " ;
3434import { IAccountBalance } from "../interfaces/IAccountBalance.sol " ;
3535import { IBaseManager } from "../interfaces/IBaseManager.sol " ;
36- import { IChainlinkAggregatorV3 } from "../interfaces/IChainlinkAggregatorV3 .sol " ;
36+ import { IPriceFeed } from "../interfaces/IPriceFeed .sol " ;
3737import { IVault } from "../interfaces/IVault.sol " ;
3838
3939import { StringArrayUtils } from "../lib/StringArrayUtils.sol " ;
@@ -70,12 +70,12 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
7070
7171 struct ActionInfo {
7272 int256 baseBalance; // Balance of virtual base asset from Perp in precise units (10e18). E.g. vWBTC = 10e18
73- int256 quoteBalance; // Balance of virtual quote asset from Perp in precise units (10e18). E.g. vUSDC = 10e18
73+ int256 quoteBalance; // Balance of virtual quote asset from Perp in precise units (10e18). E.g. vUSD = 10e18
7474 IPerpV2LeverageModule.AccountInfo accountInfo; // Info on perpetual account including, collateral balance, owedRealizedPnl and pendingFunding
7575 int256 basePositionValue; // Valuation in USD adjusted for decimals in precise units (10e18)
7676 int256 quoteValue; // Valuation in USD adjusted for decimals in precise units (10e18)
77- int256 basePrice; // Price of base asset in precise units (10e18) from Chainlink
78- int256 quotePrice; // Price of quote asset in precise units (10e18) from Chainlink
77+ int256 basePrice; // Price of base asset in precise units (10e18) from PerpV2 Oracle
78+ int256 quotePrice; // Price of quote asset in precise units (10e18) from PerpV2 Oracle
7979 uint256 setTotalSupply; // Total supply of SetToken
8080 }
8181
@@ -90,8 +90,13 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
9090 ISetToken setToken; // Instance of leverage token
9191 IPerpV2LeverageModule perpV2LeverageModule; // Instance of Perp V2 leverage module
9292 IAccountBalance perpV2AccountBalance; // Instance of Perp V2 AccountBalance contract used to fetch position balances
93- IChainlinkAggregatorV3 basePriceOracle; // Chainlink oracle feed that returns prices in 8 decimals for base asset
94- IChainlinkAggregatorV3 quotePriceOracle; // Chainlink oracle feed that returns prices in 8 decimals for quote asset
93+ IPriceFeed baseUSDPriceOracle; // PerpV2 oracle that returns TWAP price for base asset in USD. IPriceFeed is a PerpV2 specific interface
94+ // to interact with differnt oracle providers, e.g. Band Protocol and Chainlink, for different assets
95+ // listed on PerpV2
96+ uint256 twapInterval; // TWAP interval to be used to fetch base asset price in seconds
97+ // PerpV2 uses a 15 min TWAP interval, i.e. twapInterval = 900
98+ uint256 basePriceDecimalAdjustment; // Decimal adjustment for the price returned by the PerpV2 oracle for the base asset.
99+ // Equal to vBaseAsset.decimals() - baseUSDPriceOracle.decimals()
95100 address virtualBaseAddress; // Address of virtual base asset (e.g. vETH, vWBTC etc)
96101 address virtualQuoteAddress; // Address of virtual USDC quote asset. The Perp V2 system uses USDC for all markets
97102 }
@@ -747,23 +752,25 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
747752 function _createActionInfo () internal view returns (ActionInfo memory ) {
748753 ActionInfo memory rebalanceInfo;
749754
750- // Calculate prices from chainlink. Chainlink returns prices with 8 decimal places, so we need to adjust by 10 ** 10 .
751- // In Perp v2, virtual tokens all have 18 decimals, therefore we do not need to make further adjustments to determine
752- // base and quote valuation
753- int256 rawBasePrice = strategy.basePriceOracle. latestAnswer ( );
754- int256 rawQuotePrice = strategy.quotePriceOracle. latestAnswer ();
755- rebalanceInfo.basePrice = rawBasePrice. mul ( 10 ** 10 );
756- rebalanceInfo.quotePrice = rawQuotePrice. mul ( 10 ** 10 );
755+ // Fetch base token prices from PerpV2 oracles and adjust them to 18 decimal places .
756+ int256 rawBasePrice = strategy.baseUSDPriceOracle. getPrice (strategy.twapInterval). toInt256 ();
757+ uint256 decimals = strategy.baseUSDPriceOracle. decimals ();
758+ rebalanceInfo.basePrice = rawBasePrice. mul (( 10 ** strategy.basePriceDecimalAdjustment). toInt256 () );
759+
760+ // vUSD price is fixed to 1$
761+ rebalanceInfo.quotePrice = PreciseUnitMath. preciseUnit (). toInt256 ( );
757762
758763 // Note: getTakerPositionSize returns zero if base balance is less than 10 wei
759764 rebalanceInfo.baseBalance = strategy.perpV2AccountBalance.getTakerPositionSize (address (strategy.setToken), strategy.virtualBaseAddress);
760765
761766 // Note: Fetching quote balance associated with a single position and not the net quote balance
762767 rebalanceInfo.quoteBalance = strategy.perpV2AccountBalance.getTakerOpenNotional (address (strategy.setToken), strategy.virtualBaseAddress);
768+
763769 rebalanceInfo.accountInfo = strategy.perpV2LeverageModule.getAccountInfo (strategy.setToken);
764770
771+ // In Perp v2, all virtual tokens have 18 decimals, therefore we do not need to make further adjustments to determine base valuation.
765772 rebalanceInfo.basePositionValue = rebalanceInfo.basePrice.preciseMul (rebalanceInfo.baseBalance);
766- rebalanceInfo.quoteValue = rebalanceInfo.quotePrice. preciseMul (rebalanceInfo. quoteBalance) ;
773+ rebalanceInfo.quoteValue = rebalanceInfo.quoteBalance;
767774
768775 rebalanceInfo.setTotalSupply = strategy.setToken.totalSupply ();
769776
0 commit comments