import { BigNumber } from "ethers" ; import { Address } from "../types" ; import { preciseMul , preciseMulCeil , preciseDiv , preciseDivCeil } from "./mathUtils" ; import { PRECISE_UNIT } from "../constants" ; import { SetToken , ISetValuer } from "../contracts" ; export const getExpectedIssuePositionMultiplier = ( previousPositionMultiplier , previousSupply , currentSupply ) : BigNumber => { const inflation = preciseDivCeil ( currentSupply . sub ( previousSupply ) , currentSupply ) ; return preciseMul ( previousPositionMultiplier , PRECISE_UNIT . sub ( inflation ) ) ; } ; export const getExpectedSetTokenIssueQuantity = async ( setToken , setValuer , reserveAsset , reserveAssetBaseUnits , reserveAssetQuantity , managerFeePercentage , protocolDirectFeePercentage , premiumPercentage ) : Promise < BigNumber > => { const setTokenValuation = await setValuer . calculateSetTokenValuation ( setToken . address , reserveAsset ) ; const setTokenSupply = await setToken . totalSupply ( ) ; const reserveQuantitySubFees = getExpectedPostFeeQuantity ( reserveAssetQuantity , managerFeePercentage , protocolDirectFeePercentage ) ; const reserveQuantitySubFeesAndPremium = reserveQuantitySubFees . sub ( preciseMul ( reserveQuantitySubFees , premiumPercentage ) ) ; const normalizedReserveQuantitySubFees = preciseDiv ( reserveQuantitySubFees , reserveAssetBaseUnits ) ; const normalizedReserveQuantitySubFeesAndPremium = preciseDiv ( reserveQuantitySubFeesAndPremium , reserveAssetBaseUnits ) ; const denominator = preciseMul ( setTokenSupply , setTokenValuation ) . add ( normalizedReserveQuantitySubFees ) . sub ( normalizedReserveQuantitySubFeesAndPremium ) ; return preciseDiv ( preciseMul ( normalizedReserveQuantitySubFeesAndPremium , setTokenSupply ) , denominator ) ; } ; export const getExpectedIssuePositionUnit = ( previousUnits , issueQuantity , previousSupply , currentSupply , newPositionMultiplier , managerFeePercentage , protocolDirectFeePercentage ) : BigNumber => { const issueQuantitySubFees = getExpectedPostFeeQuantity ( issueQuantity , managerFeePercentage , protocolDirectFeePercentage ) ; const numerator = preciseMul ( previousSupply , previousUnits ) . add ( issueQuantitySubFees ) ; const newPositionUnit = preciseDiv ( numerator , currentSupply ) ; const roundDownPositionUnit = preciseMul ( newPositionUnit , newPositionMultiplier ) ; return preciseDiv ( roundDownPositionUnit , newPositionMultiplier ) ; } ; export const getExpectedPostFeeQuantity = ( quantity , managerFeePercentage , protocolDirectFeePercentage ) : BigNumber => { const managerFees = preciseMul ( quantity , managerFeePercentage ) ; const protocolDirectFees = preciseMul ( quantity , protocolDirectFeePercentage ) ; return quantity . sub ( managerFees ) . sub ( protocolDirectFees ) ; } ; export const getExpectedReserveRedeemQuantity = ( setTokenQuantityToRedeem , setTokenValuation , reserveAssetBaseUnits , managerFeePercentage , protocolDirectFeePercentage , premiumPercentage ) : BigNumber => { const totalNotionalReserveQuantity = preciseMul ( setTokenValuation , setTokenQuantityToRedeem ) ; const totalPremium = preciseMulCeil ( totalNotionalReserveQuantity , premiumPercentage ) ; const totalNotionalReserveQuantitySubFees = getExpectedPostFeeQuantity ( totalNotionalReserveQuantity . sub ( totalPremium ) , managerFeePercentage , protocolDirectFeePercentage ) ; return preciseMul ( totalNotionalReserveQuantitySubFees , reserveAssetBaseUnits ) ; } ; export const getExpectedRedeemPositionMultiplier = ( previousPositionMultiplier , previousSupply , currentSupply ) : BigNumber => { const deflation = preciseDiv ( previousSupply . sub ( currentSupply ) , currentSupply ) ; return preciseMul ( previousPositionMultiplier , PRECISE_UNIT . add ( deflation ) ) ; } ; export const getExpectedRedeemPositionUnit = ( previousUnits , setTokenQuantityToRedeem , setTokenValuation , reserveAssetBaseUnits , previousSupply , currentSupply , newPositionMultiplier , managerFeePercentage , protocolDirectFeePercentage , premiumPercentage ) : BigNumber => { const totalNotionalReserveQuantity = preciseMul ( setTokenValuation , setTokenQuantityToRedeem ) ; const totalPremium = preciseMulCeil ( totalNotionalReserveQuantity , premiumPercentage ) ; const totalReserveBalance = preciseMul ( totalNotionalReserveQuantity . sub ( totalPremium ) , reserveAssetBaseUnits ) ; const numerator = preciseMul ( previousSupply , previousUnits ) . sub ( totalReserveBalance ) ; const newPositionUnit = preciseDiv ( numerator , currentSupply ) ; const roundDownPositionUnit = preciseMul ( newPositionUnit , newPositionMultiplier ) ; return preciseDiv ( roundDownPositionUnit , newPositionMultiplier ) ; } ;