@@ -47,6 +47,7 @@ import { PreciseUnitMath } from "../../../lib/PreciseUnitMath.sol";
47
47
import { AddressArrayUtils } from "../../../lib/AddressArrayUtils.sol " ;
48
48
import { UnitConversionUtils } from "../../../lib/UnitConversionUtils.sol " ;
49
49
50
+
50
51
/**
51
52
* @title PerpV2LeverageModuleV2
52
53
* @author Set Protocol
@@ -60,8 +61,8 @@ import { UnitConversionUtils } from "../../../lib/UnitConversionUtils.sol";
60
61
* Any pending funding costs or PnL is carried by the current token holders. To be used safely this module MUST issue using the
61
62
* SlippageIssuanceModule or else issue and redeem transaction could be sandwich attacked.
62
63
*
63
- * NOTE: The external position unit is only updated on an as-needed basis during issuance/ redemption. It does not reflect the current
64
- * value of the Set's perpetual position. The current value can be calculated from getPositionNotionalInfo.
64
+ * NOTE: The external position unit is only updated on an as-needed basis during issuance, redemption, deposit and withdraw . It does not
65
+ * reflect the current value of the Set's perpetual position. The current value can be calculated from getPositionNotionalInfo.
65
66
*
66
67
* CHANGELOG:
67
68
* - This contract has the same functionality as `PerpV2LeverageModule` but smaller bytecode size. It extends ModuleBaseV2 (which uses
@@ -352,6 +353,10 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
352
353
onlyManagerAndValidSet (_setToken)
353
354
{
354
355
require (_collateralQuantityUnits > 0 , "Deposit amount is 0 " );
356
+ require (
357
+ _collateralQuantityUnits <= _setToken.getDefaultPositionRealUnit (address (collateralToken)).toUint256 (),
358
+ "Amount too high "
359
+ );
355
360
356
361
uint256 notionalDepositedQuantity = _depositAndUpdatePositions (_setToken, _collateralQuantityUnits);
357
362
@@ -374,6 +379,7 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
374
379
uint256 _collateralQuantityUnits
375
380
)
376
381
public
382
+ virtual
377
383
nonReentrant
378
384
onlyManagerAndValidSet (_setToken)
379
385
{
@@ -385,7 +391,7 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
385
391
}
386
392
387
393
/**
388
- * @dev MANAGER ONLY: Removes this module from the SetToken, via call by the SetToken. Deletes
394
+ * @dev SETTOKEN ONLY: Removes this module from the SetToken, via call by the SetToken. Deletes
389
395
* position mappings associated with SetToken.
390
396
*
391
397
* NOTE: Function will revert if there is greater than a position unit amount of USDC of account value.
@@ -555,7 +561,7 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
555
561
/**
556
562
* @dev GOVERNANCE ONLY: Update max perpetual positions per SetToken. Only callable by governance.
557
563
*
558
- * @param _maxPerpPositionsPerSet New max perpetual positons per set
564
+ * @param _maxPerpPositionsPerSet New max perpetual positions per set
559
565
*/
560
566
function updateMaxPerpPositionsPerSet (uint256 _maxPerpPositionsPerSet ) external onlyOwner {
561
567
maxPerpPositionsPerSet = _maxPerpPositionsPerSet;
@@ -830,12 +836,7 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
830
836
initialCollateralPositionBalance
831
837
);
832
838
833
- _setToken.editExternalPosition (
834
- address (collateralToken),
835
- address (this ),
836
- _calculateExternalPositionUnit (_setToken),
837
- ""
838
- );
839
+ _updateExternalPositionUnit (_setToken);
839
840
840
841
return collateralNotionalQuantity;
841
842
}
@@ -885,12 +886,7 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
885
886
initialCollateralPositionBalance
886
887
);
887
888
888
- _setToken.editExternalPosition (
889
- address (collateralToken),
890
- address (this ),
891
- _calculateExternalPositionUnit (_setToken),
892
- ""
893
- );
889
+ _updateExternalPositionUnit (_setToken);
894
890
895
891
return collateralNotionalQuantity;
896
892
}
@@ -1058,44 +1054,32 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
1058
1054
}
1059
1055
1060
1056
/**
1061
- * @dev Gets the mid-point price of a virtual asset from UniswapV3 markets maintained by Perp Protocol
1057
+ * @dev Sets the external position unit based on PerpV2 Vault collateral balance. If there is >= 1
1058
+ * position unit of USDC of collateral value, add the component and/or the external position to the
1059
+ * SetToken. Else, untracks the component and/or removes external position from the SetToken. Refer
1060
+ * to PositionV2#editExternalPosition for detailed flow.
1062
1061
*
1063
- * @param _baseToken Address of virtual token to price
1064
- * @return price Mid-point price of virtual token in UniswapV3 AMM market
1065
- */
1066
- function _calculateAMMSpotPrice (address _baseToken ) internal view returns (uint256 price ) {
1067
- address pool = perpMarketRegistry.getPool (_baseToken);
1068
- (uint160 sqrtPriceX96 , , , , , , ) = IUniswapV3Pool (pool).slot0 ();
1069
- uint256 priceX96 = sqrtPriceX96.formatSqrtPriceX96ToPriceX96 ();
1070
- return priceX96.formatX96ToX10_18 ();
1071
- }
1072
-
1073
- /**
1074
- * @dev Calculates the sum of collateralToken denominated market-prices of assets and debt for the Perp account per
1075
- * SetToken
1062
+ * NOTE: Setting external position unit to the collateral balance is acceptable because, as noted above, the
1063
+ * external position unit is only updated on an as-needed basis during issuance, redemption, deposit and
1064
+ * withdraw. It does not reflect the current value of the Set's perpetual position. The true current value can
1065
+ * be calculated from getPositionNotionalInfo.
1076
1066
*
1077
1067
* @param _setToken Instance of SetToken
1078
- * @return int256 External position unit
1079
1068
*/
1080
- function _calculateExternalPositionUnit (ISetToken _setToken ) internal view returns (int256 ) {
1081
- PerpV2Positions.PositionNotionalInfo[] memory positionInfo = getPositionNotionalInfo (_setToken);
1082
- uint256 positionLength = positionInfo.length ;
1083
- int256 totalPositionValue = 0 ;
1084
-
1085
- for (uint i = 0 ; i < positionLength; i++ ) {
1086
- int256 spotPrice = _calculateAMMSpotPrice (positionInfo[i].baseToken).toInt256 ();
1087
- totalPositionValue = totalPositionValue.add (
1088
- positionInfo[i].baseBalance.preciseMul (spotPrice)
1089
- );
1090
- }
1069
+ function _updateExternalPositionUnit (ISetToken _setToken ) internal {
1070
+ int256 collateralValueUnit = perpVault.getBalance (address (_setToken))
1071
+ .toPreciseUnitsFromDecimals (collateralDecimals)
1072
+ .preciseDiv (_setToken.totalSupply ().toInt256 ())
1073
+ .fromPreciseUnitToDecimals (collateralDecimals);
1091
1074
1092
- int256 externalPositionUnitInPreciseUnits = _calculatePartialAccountValuePositionUnit (_setToken)
1093
- .add (totalPositionValue.preciseDiv (_setToken.totalSupply ().toInt256 ()));
1094
-
1095
- return externalPositionUnitInPreciseUnits.fromPreciseUnitToDecimals (collateralDecimals);
1075
+ _setToken.editExternalPosition (
1076
+ address (collateralToken),
1077
+ address (this ),
1078
+ collateralValueUnit,
1079
+ ""
1080
+ );
1096
1081
}
1097
1082
1098
-
1099
1083
/**
1100
1084
* @dev Returns issuance or redemption adjustments in the format expected by `SlippageIssuanceModule`.
1101
1085
* The last recorded externalPositionUnit (current) is subtracted from a dynamically generated
@@ -1107,7 +1091,7 @@ contract PerpV2LeverageModuleV2 is ModuleBaseV2, ReentrancyGuard, Ownable, SetTo
1107
1091
* @param _setToken Instance of the SetToken
1108
1092
* @param _newExternalPositionUnit Dynamically calculated externalPositionUnit
1109
1093
* @return int256[] Components-length array with equity adjustment value at appropriate index
1110
- * @return int256[] Components-length array of zeroes (debt adjustements )
1094
+ * @return int256[] Components-length array of zeroes (debt adjustments )
1111
1095
*/
1112
1096
function _formatAdjustments (
1113
1097
ISetToken _setToken ,
0 commit comments