Skip to content

Commit fb8871b

Browse files
author
Sachin
authored
feat(MNYe): Add MNYe basis trading system deploy scripts (#36)
* Udpate package to 0.0.9-basis.0 * Add minReinvestUnits to existing deploy scripts * Add MNYe basis trading system deploy scripts * Add uni tests * Fix bugs * Update fee recipient on modules and add allowed caller * Fix missing import * Remove redundant if statement * Update set-v2-strategies to 0.0.10 * comment out updateFeeRecipient * Updated minReinvestUnits * Fix underflow bug * Deploy latest basis trading strategy to staging mainnet (#37) * update dependencies * Deploy to staging mainnet * Remove updateFeeRecipient util function; And fix failing test
1 parent 4a9babd commit fb8871b

File tree

11 files changed

+599
-20
lines changed

11 files changed

+599
-20
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import "module-alias/register";
2+
3+
import { HardhatRuntimeEnvironment as HRE } from "hardhat/types";
4+
import { DeployFunction } from "hardhat-deploy/types";
5+
import { ZERO } from "@utils/constants";
6+
import { BigNumber } from "ethers";
7+
import { solidityPack } from "ethers/lib/utils";
8+
9+
import {
10+
findDependency,
11+
getContractAddress,
12+
getCurrentStage,
13+
saveContractDeployment,
14+
getNetworkId
15+
} from "@utils/outputHelper";
16+
17+
import {
18+
PerpV2BasisContractSettings
19+
} from "../deployments/utils/types";
20+
21+
import {
22+
addExtension,
23+
deployBaseManager,
24+
prepareDeployment,
25+
stageAlreadyFinished,
26+
trackFinishedStage,
27+
updateSetManager,
28+
deployFeeExtension,
29+
setOperator,
30+
addApprovedCaller
31+
} from "@utils/deploys/deployUtils";
32+
33+
import {
34+
DEPENDENCY
35+
} from "../deployments/utils/dependencies";
36+
37+
import {
38+
CONTRACT_NAMES,
39+
EXCHANGE_SETTINGS,
40+
EXECUTION_SETTINGS,
41+
INCENTIVE_SETTINGS,
42+
METHODOLOGY_SETTINGS,
43+
ETH_DECIMALS,
44+
ETH_USDC_PRICE_FEED_DECIMALS,
45+
KOVAN_TESTNET_ID,
46+
PERP_TEST_USDC,
47+
IC_OPERATOR_MULTISIG,
48+
ALLOWED_CALLER,
49+
OPERATOR_FEE_SPLIT
50+
} from "../deployments/constants/005_mny_eth_system";
51+
52+
const {
53+
MNY_ETH_TOKEN,
54+
ETHUSD_PERP_CHAINLINK_ORACLE,
55+
PERPV2_ACCOUNT_BALANCE,
56+
PERPV2_BASIS_TRADING_MODULE,
57+
SLIPPAGE_ISSUANCE_MODULE,
58+
STREAMING_FEE_MODULE,
59+
TRADE_MODULE,
60+
UNISWAP_V3_QUOTER,
61+
USDC,
62+
WETH,
63+
V_ETH,
64+
V_USD,
65+
} = DEPENDENCY;
66+
const CURRENT_STAGE = getCurrentStage(__filename);
67+
68+
const func: DeployFunction = trackFinishedStage(CURRENT_STAGE, async function (hre: HRE) {
69+
const {
70+
deploy,
71+
deployer,
72+
networkConstant
73+
} = await prepareDeployment(hre);
74+
75+
// Deploy BaseManager
76+
await deployBaseManager(
77+
hre,
78+
CONTRACT_NAMES.BASE_MANAGER,
79+
MNY_ETH_TOKEN,
80+
deployer, // operator
81+
IC_OPERATOR_MULTISIG // methodologist
82+
);
83+
const networkId = getNetworkId();
84+
85+
// Perpetual Protocol has a fully deployed system on Optimistic Kovan. You can get the
86+
// kovan test USDC it uses from faucet at: https://kovan.optifaucet.com/
87+
const usdcTokenAddress = (networkId === KOVAN_TESTNET_ID)
88+
? await findDependency(PERP_TEST_USDC)
89+
: await findDependency(USDC);
90+
91+
// Deploy strategy extension
92+
await deployBasisTradingStrategyExtension();
93+
94+
const streamingFeeModuleAddress = await findDependency(STREAMING_FEE_MODULE);
95+
const issuanceModuleAddress = await findDependency(SLIPPAGE_ISSUANCE_MODULE);
96+
97+
// Deploy fee split extension
98+
await deployFeeExtension(
99+
hre,
100+
CONTRACT_NAMES.FEE_SPLIT_EXTENSION,
101+
CONTRACT_NAMES.BASE_MANAGER,
102+
OPERATOR_FEE_SPLIT,
103+
IC_OPERATOR_MULTISIG,
104+
streamingFeeModuleAddress,
105+
issuanceModuleAddress
106+
);
107+
108+
// Add extensions to manager
109+
await addExtension(hre, CONTRACT_NAMES.BASE_MANAGER, CONTRACT_NAMES.STRATEGY_EXTENSION);
110+
await addExtension(hre, CONTRACT_NAMES.BASE_MANAGER, CONTRACT_NAMES.FEE_SPLIT_EXTENSION);
111+
112+
// Add approved caller to strategy extension
113+
await addApprovedCaller(hre, CONTRACT_NAMES.STRATEGY_EXTENSION, [ALLOWED_CALLER], [true]);
114+
115+
// Set manager to BaseManager
116+
if (networkConstant !== "development") {
117+
await updateSetManager(hre, MNY_ETH_TOKEN, CONTRACT_NAMES.BASE_MANAGER);
118+
}
119+
120+
// Finally set operator to IC Operator multisig
121+
await setOperator(hre, CONTRACT_NAMES.BASE_MANAGER, IC_OPERATOR_MULTISIG);
122+
123+
async function deployBasisTradingStrategyExtension(): Promise<void> {
124+
const checkStrategyExtensionAddress = await getContractAddress(CONTRACT_NAMES.STRATEGY_EXTENSION);
125+
if (checkStrategyExtensionAddress == "") {
126+
const manager = await getContractAddress(CONTRACT_NAMES.BASE_MANAGER);
127+
128+
const contractSettings: PerpV2BasisContractSettings = {
129+
setToken: await findDependency(MNY_ETH_TOKEN),
130+
basisTradingModule: await findDependency(PERPV2_BASIS_TRADING_MODULE),
131+
tradeModule: await findDependency(TRADE_MODULE),
132+
quoter: await findDependency(UNISWAP_V3_QUOTER),
133+
perpV2AccountBalance: await findDependency(PERPV2_ACCOUNT_BALANCE),
134+
baseUSDPriceOracle: await findDependency(ETHUSD_PERP_CHAINLINK_ORACLE),
135+
twapInterval: ZERO,
136+
basePriceDecimalAdjustment: BigNumber.from(ETH_DECIMALS).sub(ETH_USDC_PRICE_FEED_DECIMALS),
137+
virtualBaseAddress: await findDependency(V_ETH),
138+
virtualQuoteAddress: await findDependency(V_USD),
139+
spotAssetAddress: await findDependency(WETH)
140+
};
141+
142+
const methodlogySettings = METHODOLOGY_SETTINGS;
143+
const executionSettings = EXECUTION_SETTINGS;
144+
const exchangeSettings = EXCHANGE_SETTINGS;
145+
const incentiveSettings = INCENTIVE_SETTINGS;
146+
147+
exchangeSettings.buyExactSpotTradeData = solidityPack(
148+
["address", "uint24", "address", "bool"],
149+
[await findDependency(WETH), BigNumber.from(3000), usdcTokenAddress, false]
150+
);
151+
exchangeSettings.sellExactSpotTradeData = solidityPack(
152+
["address", "uint24", "address", "bool"],
153+
[await findDependency(WETH), BigNumber.from(3000), usdcTokenAddress, true],
154+
);
155+
exchangeSettings.buySpotQuoteExactInputPath = solidityPack(
156+
["address", "uint24", "address"],
157+
[usdcTokenAddress, BigNumber.from(3000), await findDependency(WETH)]
158+
);
159+
160+
const constructorArgs = [
161+
manager,
162+
contractSettings,
163+
methodlogySettings,
164+
executionSettings,
165+
incentiveSettings,
166+
exchangeSettings
167+
];
168+
169+
const extensionDeploy = await deploy("DeltaNeutralBasisTradingStrategyExtension", {
170+
from: deployer,
171+
args: constructorArgs,
172+
log: true
173+
});
174+
175+
extensionDeploy.receipt && await saveContractDeployment({
176+
name: CONTRACT_NAMES.STRATEGY_EXTENSION,
177+
contractAddress: extensionDeploy.address,
178+
id: extensionDeploy.receipt.transactionHash,
179+
description: "Deployed MNYeBasisTradingStrategyExtension",
180+
constructorArgs
181+
});
182+
}
183+
}
184+
});
185+
186+
func.skip = stageAlreadyFinished(CURRENT_STAGE);
187+
188+
export default func;

optimism/deployments/constants/004_perp_basis_trading_system.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BigNumber } from "@ethersproject/bignumber";
22
import { ether } from "@utils/index";
33

4-
import { ONE_HOUR_IN_SECONDS } from "@utils/constants";
4+
import { ONE_HOUR_IN_SECONDS, TWO } from "@utils/constants";
55

66
export const CONTRACT_NAMES = {
77
BASE_MANAGER: "PerpV2BaseManager",
@@ -11,11 +11,12 @@ export const CONTRACT_NAMES = {
1111

1212
export const METHODOLOGY_SETTINGS = {
1313
targetLeverageRatio: ether(-1),
14-
minLeverageRatio: ether(-0.9),
14+
minLeverageRatio: ether(-0.95),
1515
maxLeverageRatio: ether(-1.1),
1616
recenteringSpeed: ether(0.1),
1717
rebalanceInterval: ONE_HOUR_IN_SECONDS.mul(2),
18-
reinvestInterval: ONE_HOUR_IN_SECONDS
18+
reinvestInterval: ONE_HOUR_IN_SECONDS,
19+
minReinvestUnits: TWO
1920
};
2021

2122
export const EXECUTION_SETTINGS = {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { BigNumber } from "@ethersproject/bignumber";
2+
import { ether } from "@utils/index";
3+
4+
import { ONE_DAY_IN_SECONDS ,MAX_UINT_256 } from "@utils/constants";
5+
6+
export const CONTRACT_NAMES = {
7+
BASE_MANAGER: "MNYeBaseManager",
8+
STANDARD_TOKEN_MOCK: "StandardTokenMock",
9+
STRATEGY_EXTENSION: "MNYeBasisTradingStrategyExtension",
10+
FEE_SPLIT_EXTENSION: "MNYeFeeSplitExtension"
11+
};
12+
13+
export const IC_OPERATOR_MULTISIG = "0xA047F6900FeE0b6195088a49009eA65365f7DD68";
14+
15+
export const ALLOWED_CALLER = "0x17d3FdB23128F8e376ffA444B8A84A30573864a6";
16+
17+
export const OPERATOR_FEE_SPLIT = ether(1); // 100%
18+
19+
export const METHODOLOGY_SETTINGS = {
20+
targetLeverageRatio: ether(-1), // -1x
21+
minLeverageRatio: ether(-0.95), // -0.95x
22+
maxLeverageRatio: ether(-2), // -2x
23+
recenteringSpeed: ether(1), // N/A; Unused value; Can't be set to 0; So set to 1
24+
rebalanceInterval: MAX_UINT_256, // Rebalance only when out of bounds
25+
reinvestInterval: ONE_DAY_IN_SECONDS.mul(7), // 7 days
26+
minReinvestUnits: BigNumber.from(10000) // 1 cent per Set; 1 bps at 100$ per Set
27+
};
28+
29+
export const EXECUTION_SETTINGS = {
30+
twapCooldownPeriod: BigNumber.from(30), // 30 sec cooldown
31+
slippageTolerance: ether(0.02), // 2% max slippage on regular rebalances
32+
};
33+
34+
export const INCENTIVE_SETTINGS = {
35+
incentivizedTwapCooldownPeriod: BigNumber.from(1), // 1 sec cooldown on ripcord
36+
incentivizedSlippageTolerance: ether(0.05), // 5% max slippage on ripcord
37+
etherReward: ether(1), // 1 ETH
38+
incentivizedLeverageRatio: ether(-3), // 3x
39+
};
40+
41+
export const EXCHANGE_SETTINGS = {
42+
exchangeName: "UniswapV3ExchangeAdapterV2",
43+
buyExactSpotTradeData: "", // will be overriden in the deploy script
44+
sellExactSpotTradeData: "", // will be overriden in the deploy script
45+
buySpotQuoteExactInputPath: "", // will be overriden in the deploy script
46+
twapMaxTradeSize: ether(30), // 30 ETH
47+
incentivizedTwapMaxTradeSize: ether(60) // 60 ETH
48+
};
49+
50+
export const ETH_DECIMALS = 18; // vETH decimals
51+
export const ETH_USDC_PRICE_FEED_DECIMALS = 8; // ETHUSD chainlink price feed decimals
52+
53+
export const PERP_TEST_USDC = "PERP_TEST_USDC";
54+
export const KOVAN_TESTNET_ID = 69;

0 commit comments

Comments
 (0)