|
| 1 | +// Deploy Hardhat Network State for Subgraph Tests |
| 2 | +// ----------------------------------------------- |
| 3 | +// This script is intended for use with the set-protocol-v2-subgraph repository |
| 4 | +// for deploying a containerized local Hardhat node and test environment for |
| 5 | +// subgraph development. See command `task deploy-hardhat` in that repo for |
| 6 | +// more information. |
| 7 | +// |
| 8 | +// Standalone execution against a local Hardhat node deployed from this |
| 9 | +// repository is possible via the following command: |
| 10 | +// |
| 11 | +// npx hardhat run --no-compile $(pwd)/subgraph/test/deploy-state-delegated-manager.ts --network localhost |
| 12 | +// |
| 13 | +// The following deployment state and test cases are executed: |
| 14 | +// |
| 15 | +// Setup |
| 16 | +// - Deploy system |
| 17 | +// - Deploy ManagerCore |
| 18 | +// - Deploy DelegatedManagerFactory |
| 19 | +// - Deploy IssuanceExtension with IssuanceModule |
| 20 | +// - Deploy StreamingFeeSplitExtension |
| 21 | +// - Deploy TradeExtension and TradeModule |
| 22 | +// - Initialize ManagerCore |
| 23 | +// |
| 24 | +// Case 1: DelegatedManagerFactory deployed DelegatedManager and SetToken |
| 25 | +// - Deploy DelegatedManager and SetToken through DelegatedManagerFactory |
| 26 | +// - Initialize DelegatedManager through DelegatedManagerFactory |
| 27 | +// - Update owner |
| 28 | +// - Update methodologist |
| 29 | +// - Add operatorTwo |
| 30 | +// - Remove operatorOne |
| 31 | +// |
| 32 | +// Case 2: DelegatedManagerFactory deployed DelegatedManager with migrating SetToken |
| 33 | +// - Deploy SetToken through SetTokenCreator |
| 34 | +// - Deploy DelegatedManager through DelegatedManagerFactory |
| 35 | +// - Initialize DelegatedManager through DelegatedManagerFactory |
| 36 | +// |
| 37 | +// Case 3: DelegatedManagerFactory deployed DelegatedManager and SetToken, migrate to EOA manager |
| 38 | +// - Deploy DelegatedManager and SetToken through DelegatedManagerFactory |
| 39 | +// - Initialize DelegatedManager through DelegatedManagerFactory |
| 40 | +// - Remove extensions from DelegatedManager |
| 41 | +// - Change SetToken manager to EOA manager |
| 42 | +// |
| 43 | +// Case 4: EOA managed SetToken |
| 44 | +// - Deploy SetToken through SetTokenCreator |
| 45 | + |
| 46 | +import "module-alias/register"; |
| 47 | +import { getSystemFixture, getProtocolUtils } from "@setprotocol/set-protocol-v2/dist/utils/test/index"; |
| 48 | +import DeployHelper from "@utils/deploys"; |
| 49 | +import { |
| 50 | + ether, |
| 51 | + getAccounts, |
| 52 | +} from "@utils/index"; |
| 53 | +import { ADDRESS_ZERO, ZERO } from "@utils/constants"; |
| 54 | +import { StreamingFeeState } from "@utils/types"; |
| 55 | + |
| 56 | + |
| 57 | +async function main() { |
| 58 | + |
| 59 | + console.log("Starting deployment"); |
| 60 | + |
| 61 | + const [ |
| 62 | + ownerOne, |
| 63 | + ownerTwo, |
| 64 | + methodologistOne, |
| 65 | + methodologistTwo, |
| 66 | + operatorOne, |
| 67 | + operatorTwo, |
| 68 | + otherManager, |
| 69 | + ] = await getAccounts(); |
| 70 | + |
| 71 | + // Setup |
| 72 | + // ----------------------------------------------- |
| 73 | + |
| 74 | + // Deploy system |
| 75 | + const deployer = new DeployHelper(ownerOne.wallet); |
| 76 | + const protocolUtils = getProtocolUtils(); |
| 77 | + const setV2Setup = getSystemFixture(ownerOne.address); |
| 78 | + await setV2Setup.initialize(); |
| 79 | + |
| 80 | + // Deploy ManagerCore |
| 81 | + const managerCore = await deployer.managerCore.deployManagerCore(); |
| 82 | + |
| 83 | + // Deploy DelegatedManagerFactory |
| 84 | + const delegatedManagerFactory = await deployer.factories.deployDelegatedManagerFactory( |
| 85 | + managerCore.address, |
| 86 | + setV2Setup.controller.address, |
| 87 | + setV2Setup.factory.address |
| 88 | + ); |
| 89 | + |
| 90 | + // Deploy IssuanceExtension with IssuanceModule |
| 91 | + const issuanceModule = await deployer.setV2.deployIssuanceModule(setV2Setup.controller.address); |
| 92 | + await setV2Setup.controller.addModule(issuanceModule.address); |
| 93 | + const issuanceExtension = await deployer.globalExtensions.deployIssuanceExtension( |
| 94 | + managerCore.address, |
| 95 | + issuanceModule.address |
| 96 | + ); |
| 97 | + |
| 98 | + // Deploy StreamingFeeSplitExtension |
| 99 | + const streamingFeeSplitExtension = await deployer.globalExtensions.deployStreamingFeeSplitExtension( |
| 100 | + managerCore.address, |
| 101 | + setV2Setup.streamingFeeModule.address |
| 102 | + ); |
| 103 | + |
| 104 | + // Deploy TradeExtension and TradeModule |
| 105 | + const tradeModule = await deployer.setDeployer.modules.deployTradeModule(setV2Setup.controller.address); |
| 106 | + await setV2Setup.controller.addModule(tradeModule.address); |
| 107 | + const tradeExtension = await deployer.globalExtensions.deployTradeExtension( |
| 108 | + managerCore.address, |
| 109 | + tradeModule.address |
| 110 | + ); |
| 111 | + |
| 112 | + // Initialize ManagerCore |
| 113 | + await managerCore.initialize( |
| 114 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address], |
| 115 | + [delegatedManagerFactory.address] |
| 116 | + ); |
| 117 | + |
| 118 | + // Case 1: DelegatedManagerFactory deployed DelegatedManager and SetToken |
| 119 | + // ----------------------------------------------- |
| 120 | + |
| 121 | + // Deploy DelegatedManager and SetToken through DelegatedManagerFactory |
| 122 | + const txOne = await delegatedManagerFactory.connect(ownerOne.wallet).createSetAndManager( |
| 123 | + [setV2Setup.dai.address, setV2Setup.wbtc.address], |
| 124 | + [ether(1), ether(.1)], |
| 125 | + "TestTokenOne", |
| 126 | + "TT1", |
| 127 | + ownerOne.address, |
| 128 | + methodologistOne.address, |
| 129 | + [issuanceModule.address, setV2Setup.streamingFeeModule.address, tradeModule.address], |
| 130 | + [operatorOne.address], |
| 131 | + [setV2Setup.dai.address, setV2Setup.wbtc.address], |
| 132 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address] |
| 133 | + ); |
| 134 | + |
| 135 | + const setTokenOneAddress = await protocolUtils.getCreatedSetTokenAddress(txOne.hash); |
| 136 | + const initializeParamsOne = await delegatedManagerFactory.initializeState(setTokenOneAddress); |
| 137 | + const delegatedManagerOne = await deployer.manager.getDelegatedManager(initializeParamsOne.manager); |
| 138 | + |
| 139 | + // Initialize DelegatedManager through DelegatedManagerFactory |
| 140 | + const issuanceExtensionOneBytecode = issuanceExtension.interface.encodeFunctionData( |
| 141 | + "initializeModuleAndExtension", |
| 142 | + [ |
| 143 | + delegatedManagerOne.address, |
| 144 | + ether(0.1), |
| 145 | + ether(0.01), |
| 146 | + ether(0.01), |
| 147 | + delegatedManagerOne.address, |
| 148 | + ADDRESS_ZERO |
| 149 | + ] |
| 150 | + ); |
| 151 | + |
| 152 | + const feeSettingsOne = { |
| 153 | + feeRecipient: delegatedManagerOne.address, |
| 154 | + maxStreamingFeePercentage: ether(0.05), |
| 155 | + streamingFeePercentage: ether(0.01), |
| 156 | + lastStreamingFeeTimestamp: ZERO, |
| 157 | + } as StreamingFeeState; |
| 158 | + const streamingFeeSplitExtensionOneBytecode = streamingFeeSplitExtension.interface.encodeFunctionData( |
| 159 | + "initializeModuleAndExtension", |
| 160 | + [ |
| 161 | + delegatedManagerOne.address, |
| 162 | + feeSettingsOne |
| 163 | + ] |
| 164 | + ); |
| 165 | + |
| 166 | + const tradeExtensionOneBytecode = tradeExtension.interface.encodeFunctionData( |
| 167 | + "initializeModuleAndExtension", |
| 168 | + [delegatedManagerOne.address] |
| 169 | + ); |
| 170 | + |
| 171 | + await delegatedManagerFactory.connect(ownerOne.wallet).initialize( |
| 172 | + setTokenOneAddress, |
| 173 | + ether(0.5), |
| 174 | + ownerOne.address, |
| 175 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address], |
| 176 | + [issuanceExtensionOneBytecode, streamingFeeSplitExtensionOneBytecode, tradeExtensionOneBytecode] |
| 177 | + ); |
| 178 | + |
| 179 | + // Update owner |
| 180 | + await delegatedManagerOne.connect(ownerOne.wallet).transferOwnership(ownerTwo.address); |
| 181 | + |
| 182 | + // Update methodologist |
| 183 | + await delegatedManagerOne.connect(methodologistOne.wallet).setMethodologist(methodologistTwo.address); |
| 184 | + |
| 185 | + // Add operatorTwo |
| 186 | + await delegatedManagerOne.connect(ownerTwo.wallet).addOperators([operatorTwo.address]); |
| 187 | + |
| 188 | + // Remove operatorOne |
| 189 | + await delegatedManagerOne.connect(ownerTwo.wallet).removeOperators([operatorOne.address]); |
| 190 | + |
| 191 | + // Case 2: DelegatedManagerFactory deployed DelegatedManager with migrating SetToken |
| 192 | + // ----------------------------------------------- |
| 193 | + |
| 194 | + // Deploy SetToken through SetTokenCreator |
| 195 | + const setTokenTwo = await setV2Setup.createSetToken( |
| 196 | + [setV2Setup.dai.address], |
| 197 | + [ether(1)], |
| 198 | + [issuanceModule.address, setV2Setup.streamingFeeModule.address, tradeModule.address], |
| 199 | + ownerOne.address, |
| 200 | + "TestTokenTwo", |
| 201 | + "TT2" |
| 202 | + ); |
| 203 | + |
| 204 | + // Deploy DelegatedManager through DelegatedManagerFactory |
| 205 | + await delegatedManagerFactory.createManager( |
| 206 | + setTokenTwo.address, |
| 207 | + ownerOne.address, |
| 208 | + methodologistOne.address, |
| 209 | + [operatorOne.address], |
| 210 | + [setV2Setup.dai.address, setV2Setup.wbtc.address], |
| 211 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address] |
| 212 | + ); |
| 213 | + |
| 214 | + const initializeParamsTwo = await delegatedManagerFactory.initializeState(setTokenTwo.address); |
| 215 | + const delegatedManagerTwo = await deployer.manager.getDelegatedManager(initializeParamsTwo.manager); |
| 216 | + |
| 217 | + // Initialize DelegatedManager through DelegatedManagerFactory |
| 218 | + const issuanceExtensionTwoBytecode = issuanceExtension.interface.encodeFunctionData("initializeExtension", [delegatedManagerTwo.address]); |
| 219 | + const streamingFeeSplitExtensionTwoBytecode = streamingFeeSplitExtension.interface.encodeFunctionData("initializeExtension", [delegatedManagerTwo.address]); |
| 220 | + const tradeExtensionTwoBytecode = tradeExtension.interface.encodeFunctionData("initializeExtension", [delegatedManagerTwo.address]); |
| 221 | + |
| 222 | + await delegatedManagerFactory.connect(ownerOne.wallet).initialize( |
| 223 | + setTokenTwo.address, |
| 224 | + ether(0.5), |
| 225 | + ownerOne.address, |
| 226 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address], |
| 227 | + [issuanceExtensionTwoBytecode, streamingFeeSplitExtensionTwoBytecode, tradeExtensionTwoBytecode] |
| 228 | + ); |
| 229 | + |
| 230 | + // Case 3: DelegatedManagerFactory deployed DelegatedManager and SetToken, migrate to EOA manager |
| 231 | + // ----------------------------------------------- |
| 232 | + |
| 233 | + // Deploy DelegatedManager and SetToken through DelegatedManagerFactory |
| 234 | + const txThree = await delegatedManagerFactory.connect(ownerOne.wallet).createSetAndManager( |
| 235 | + [setV2Setup.dai.address, setV2Setup.wbtc.address], |
| 236 | + [ether(1), ether(.1)], |
| 237 | + "TestTokenThree", |
| 238 | + "TT3", |
| 239 | + ownerOne.address, |
| 240 | + methodologistOne.address, |
| 241 | + [issuanceModule.address, setV2Setup.streamingFeeModule.address, tradeModule.address], |
| 242 | + [operatorOne.address], |
| 243 | + [setV2Setup.dai.address, setV2Setup.wbtc.address], |
| 244 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address] |
| 245 | + ); |
| 246 | + |
| 247 | + const setTokenThreeAddress = await protocolUtils.getCreatedSetTokenAddress(txThree.hash); |
| 248 | + const initializeParamsThree = await delegatedManagerFactory.initializeState(setTokenThreeAddress); |
| 249 | + const delegatedManagerThree = await deployer.manager.getDelegatedManager(initializeParamsThree.manager); |
| 250 | + |
| 251 | + // Initialize DelegatedManager through DelegatedManagerFactory |
| 252 | + const issuanceExtensionThreeBytecode = issuanceExtension.interface.encodeFunctionData( |
| 253 | + "initializeModuleAndExtension", |
| 254 | + [ |
| 255 | + delegatedManagerThree.address, |
| 256 | + ether(0.1), |
| 257 | + ether(0.01), |
| 258 | + ether(0.01), |
| 259 | + delegatedManagerThree.address, |
| 260 | + ADDRESS_ZERO |
| 261 | + ] |
| 262 | + ); |
| 263 | + |
| 264 | + const feeSettingsThree = { |
| 265 | + feeRecipient: delegatedManagerThree.address, |
| 266 | + maxStreamingFeePercentage: ether(0.05), |
| 267 | + streamingFeePercentage: ether(0.01), |
| 268 | + lastStreamingFeeTimestamp: ZERO, |
| 269 | + } as StreamingFeeState; |
| 270 | + const streamingFeeSplitExtensionThreeBytecode = streamingFeeSplitExtension.interface.encodeFunctionData( |
| 271 | + "initializeModuleAndExtension", |
| 272 | + [ |
| 273 | + delegatedManagerThree.address, |
| 274 | + feeSettingsThree |
| 275 | + ] |
| 276 | + ); |
| 277 | + |
| 278 | + const tradeExtensionThreeBytecode = tradeExtension.interface.encodeFunctionData( |
| 279 | + "initializeModuleAndExtension", |
| 280 | + [delegatedManagerThree.address] |
| 281 | + ); |
| 282 | + |
| 283 | + await delegatedManagerFactory.connect(ownerOne.wallet).initialize( |
| 284 | + setTokenThreeAddress, |
| 285 | + ether(0.5), |
| 286 | + ownerOne.address, |
| 287 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address], |
| 288 | + [issuanceExtensionThreeBytecode, streamingFeeSplitExtensionThreeBytecode, tradeExtensionThreeBytecode] |
| 289 | + ); |
| 290 | + |
| 291 | + // Remove extensions from DelegatedManager |
| 292 | + await delegatedManagerThree.connect(ownerOne.wallet).removeExtensions( |
| 293 | + [issuanceExtension.address, streamingFeeSplitExtension.address, tradeExtension.address] |
| 294 | + ); |
| 295 | + |
| 296 | + // Change SetToken manager to EOA manager |
| 297 | + await delegatedManagerThree.connect(ownerOne.wallet).setManager(otherManager.address); |
| 298 | + |
| 299 | + // Case 4: EOA managed SetToken |
| 300 | + // ----------------------------------------------- |
| 301 | + |
| 302 | + // Deploy SetToken through SetTokenCreator |
| 303 | + await setV2Setup.createSetToken( |
| 304 | + [setV2Setup.dai.address], |
| 305 | + [ether(1)], |
| 306 | + [setV2Setup.issuanceModule.address], |
| 307 | + otherManager.address, |
| 308 | + "TestTokenFour", |
| 309 | + "TT4" |
| 310 | + ); |
| 311 | +} |
| 312 | + |
| 313 | +main().catch(e => { |
| 314 | + console.error(e); |
| 315 | + process.exit(1); |
| 316 | +}); |
0 commit comments