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-multi-token.ts --network localhost
12+ //
13+ // The following deployment state is executed:
14+ //
15+ // - Deploy system
16+ // - Deploy SetToken with 1 WBTC
17+ // - Basic Issue 10
18+ // - Basic Redeem 5
19+ // - Trade 0.5 WBTC for WETH on kyber
20+ // - Accrue fee
21+ // - Change fee recipient
22+ // - Update streaming fee
23+ // - Update SetToken manager
24+
25+ import "module-alias/register" ;
26+ import { BigNumber } from "@ethersproject/bignumber" ;
27+ import { ethers } from "hardhat" ;
28+ import { EMPTY_BYTES , ONE_YEAR_IN_SECONDS , ZERO } from "@utils/constants" ;
29+ import DeployHelper from "@utils/deploys" ;
30+ import { ether } from "@utils/index" ;
31+ import { getAccounts , getSystemFixture , increaseTimeAsync } from "@utils/test/index" ;
32+ import { StreamingFeeState } from "@utils/types" ;
33+
34+ async function main ( ) {
35+
36+ console . log ( "Starting deployment" ) ;
37+
38+ const [ owner , manager1 , manager2 , manager3 ] = await getAccounts ( ) ;
39+
40+ const wbtcRate = ether ( 33 ) ; // 1 WBTC = 33 ETH
41+ const wbtcUnits = BigNumber . from ( 100000000 ) ; // 1 WBTC in base units 1 * 10 ** 8
42+
43+ // Deploy system
44+ const deployer = new DeployHelper ( owner . wallet ) ;
45+ const setup = getSystemFixture ( owner . address ) ;
46+ await setup . initialize ( ) ;
47+
48+ // StreamingFeeModule Deployment
49+ let streamingFeeModule = await deployer . modules . deployStreamingFeeModule ( setup . controller . address ) ;
50+ await setup . controller . addModule ( streamingFeeModule . address ) ;
51+
52+ // TradeModule Deployment
53+ let tradeModule = await deployer . modules . deployTradeModule ( setup . controller . address ) ;
54+ await setup . controller . addModule ( tradeModule . address ) ;
55+
56+ // Deploy Mock Kyber reserve. Only allows trading from/to WETH
57+ const kyberNetworkProxy = await deployer . mocks . deployKyberNetworkProxyMock ( setup . weth . address ) ;
58+ await kyberNetworkProxy . addToken ( setup . wbtc . address , wbtcRate , 8 ) ;
59+ const kyberExchangeAdapter = await deployer . adapters . deployKyberExchangeAdapter (
60+ kyberNetworkProxy . address ,
61+ ) ;
62+ const kyberAdapterName = "KYBER" ;
63+
64+ await setup . integrationRegistry . batchAddIntegration (
65+ [ tradeModule . address ] ,
66+ [ kyberAdapterName ] ,
67+ [ kyberExchangeAdapter . address ] ,
68+ ) ;
69+
70+ // DEPLOY A SETTOKEN (with issuanceModule, TradeModule, and StreamingFeeModule)
71+
72+ let setToken = await setup . createSetToken (
73+ [ setup . wbtc . address ] ,
74+ [ wbtcUnits ] ,
75+ [
76+ setup . issuanceModule . address ,
77+ tradeModule . address ,
78+ streamingFeeModule . address
79+ ] ,
80+ manager1 . address ,
81+ "SetToken" ,
82+ "SET"
83+ ) ;
84+
85+ // Initialize StreamingFeeModule
86+ let streamingFeePercentage = ether ( .02 ) ;
87+ let subjectSettings = {
88+ feeRecipient : manager1 . address ,
89+ maxStreamingFeePercentage : ether ( .1 ) ,
90+ streamingFeePercentage : streamingFeePercentage ,
91+ lastStreamingFeeTimestamp : ZERO ,
92+ } as StreamingFeeState ;
93+ streamingFeeModule = streamingFeeModule . connect ( manager1 . wallet ) ;
94+ await streamingFeeModule . initialize ( setToken . address , subjectSettings ) ;
95+ await setToken . isInitializedModule ( streamingFeeModule . address ) ;
96+
97+ // Initialize TradeModule
98+ tradeModule = tradeModule . connect ( manager1 . wallet ) ;
99+ await tradeModule . initialize ( setToken . address ) ;
100+ await setToken . isInitializedModule ( tradeModule . address ) ;
101+
102+ // Deploy mock issuance hook and initialize issuance module
103+ setup . issuanceModule = setup . issuanceModule . connect ( manager1 . wallet ) ;
104+ const mockPreIssuanceHook = await deployer . mocks . deployManagerIssuanceHookMock ( ) ;
105+ await setup . issuanceModule . initialize ( setToken . address , mockPreIssuanceHook . address ) ;
106+
107+ // Transfer WBTC from owner to manager for issuance
108+ setup . wbtc = setup . wbtc . connect ( owner . wallet ) ;
109+ await setup . wbtc . transfer ( manager1 . address , wbtcUnits . mul ( 100 ) ) ;
110+
111+ // Approve WBTC to IssuanceModule
112+ setup . wbtc = setup . wbtc . connect ( manager1 . wallet ) ;
113+ await setup . wbtc . approve ( setup . issuanceModule . address , ethers . constants . MaxUint256 ) ;
114+
115+ // Issue 10 SetTokens
116+ setup . issuanceModule = setup . issuanceModule . connect ( owner . wallet ) ;
117+ const issueQuantity = ether ( 10 ) ;
118+ await setup . issuanceModule . issue ( setToken . address , issueQuantity , owner . address ) ;
119+
120+ // Redeem 5 SetTokens
121+ const redeemQuantity = ether ( 5 ) ;
122+ setToken = setToken . connect ( owner . wallet ) ;
123+ await setToken . approve ( setup . issuanceModule . address , ethers . constants . MaxUint256 ) ;
124+ await setup . issuanceModule . redeem ( setToken . address , redeemQuantity , owner . address ) ;
125+
126+ // Trade on Kyber
127+
128+ // Fund Kyber reserve with WETH
129+ setup . weth = setup . weth . connect ( owner . wallet ) ;
130+ await setup . weth . transfer ( kyberNetworkProxy . address , ether ( 1000 ) ) ;
131+
132+ const sourceTokenQuantity = wbtcUnits . div ( 2 ) ; // Trade 0.5 WBTC
133+ const sourceTokenDecimals = await setup . wbtc . decimals ( ) ;
134+ const destinationTokenQuantity = wbtcRate . mul ( sourceTokenQuantity ) . div ( 10 ** sourceTokenDecimals ) ;
135+ const subjectData = EMPTY_BYTES ;
136+ const subjectMinDestinationQuantity = destinationTokenQuantity . sub ( ether ( 0.5 ) ) ; // Receive a min of 16 WETH for 0.5 WBTC
137+
138+ await tradeModule . trade (
139+ setToken . address ,
140+ kyberAdapterName ,
141+ setup . wbtc . address ,
142+ sourceTokenQuantity ,
143+ setup . weth . address ,
144+ subjectMinDestinationQuantity ,
145+ subjectData
146+ ) ;
147+
148+ // Accrue streaming fee (fast-forward one year)
149+ const subjectTimeFastForward = ONE_YEAR_IN_SECONDS ;
150+ await increaseTimeAsync ( subjectTimeFastForward ) ;
151+ await streamingFeeModule . accrueFee ( setToken . address ) ;
152+
153+ // Change fee recipient
154+ let newFeeRecipient = manager2 . address ;
155+ await streamingFeeModule . updateFeeRecipient ( setToken . address , newFeeRecipient ) ;
156+
157+ // Update streaming fee
158+ streamingFeePercentage = ether ( .03 ) ;
159+ await streamingFeeModule . updateStreamingFee ( setToken . address , streamingFeePercentage ) ;
160+
161+ // Update Manager
162+ setToken = setToken . connect ( manager1 . wallet ) ;
163+ await setToken . setManager ( manager2 . address ) ;
164+
165+
166+ // DEPLOY A SECOND SETTOKEN
167+
168+ let setToken2 = await setup . createSetToken (
169+ [ setup . wbtc . address ] ,
170+ [ wbtcUnits ] ,
171+ [
172+ setup . issuanceModule . address ,
173+ tradeModule . address ,
174+ streamingFeeModule . address
175+ ] ,
176+ manager3 . address ,
177+ "SetToken2" ,
178+ "SET2"
179+ ) ;
180+
181+ // Update Manager
182+ setToken2 = setToken2 . connect ( manager3 . wallet ) ;
183+ await setToken2 . setManager ( manager1 . address ) ;
184+
185+ // Initialize StreamingFeeModule
186+ streamingFeePercentage = ether ( .015 ) ;
187+ subjectSettings = {
188+ feeRecipient : manager1 . address ,
189+ maxStreamingFeePercentage : ether ( .05 ) ,
190+ streamingFeePercentage : streamingFeePercentage ,
191+ lastStreamingFeeTimestamp : ZERO ,
192+ } as StreamingFeeState ;
193+ streamingFeeModule = streamingFeeModule . connect ( manager1 . wallet ) ;
194+ await streamingFeeModule . initialize ( setToken2 . address , subjectSettings ) ;
195+ await setToken2 . isInitializedModule ( streamingFeeModule . address ) ;
196+
197+ // Initialize TradeModule
198+ tradeModule = tradeModule . connect ( manager1 . wallet ) ;
199+ await tradeModule . initialize ( setToken2 . address ) ;
200+ await setToken2 . isInitializedModule ( tradeModule . address ) ;
201+
202+ // Deploy mock issuance hook and initialize issuance module
203+ setup . issuanceModule = setup . issuanceModule . connect ( manager1 . wallet ) ;
204+ // mockPreIssuanceHook = await deployer.mocks.deployManagerIssuanceHookMock();
205+ await setup . issuanceModule . initialize ( setToken2 . address , mockPreIssuanceHook . address ) ;
206+
207+ // Transfer WBTC from owner to manager for issuance
208+ setup . wbtc = setup . wbtc . connect ( owner . wallet ) ;
209+ await setup . wbtc . transfer ( manager1 . address , wbtcUnits . mul ( 100 ) ) ;
210+
211+ // Approve WBTC to IssuanceModule
212+ setup . wbtc = setup . wbtc . connect ( manager1 . wallet ) ;
213+ await setup . wbtc . approve ( setup . issuanceModule . address , ethers . constants . MaxUint256 ) ;
214+
215+ // Issue SetTokens
216+ setup . issuanceModule = setup . issuanceModule . connect ( owner . wallet ) ;
217+ await setup . issuanceModule . issue ( setToken2 . address , ether ( 8 ) , owner . address ) ;
218+
219+ // Redeem SetTokens
220+ setToken2 = setToken2 . connect ( owner . wallet ) ;
221+ await setToken2 . approve ( setup . issuanceModule . address , ethers . constants . MaxUint256 ) ;
222+ await setup . issuanceModule . redeem ( setToken2 . address , ether ( 2 ) , owner . address ) ;
223+
224+ // Trade on Kyber
225+ await tradeModule . trade (
226+ setToken2 . address ,
227+ kyberAdapterName ,
228+ setup . wbtc . address ,
229+ sourceTokenQuantity ,
230+ setup . weth . address ,
231+ subjectMinDestinationQuantity ,
232+ subjectData
233+ ) ;
234+
235+ // Accrue streaming fee (fast-forward one year)
236+ await increaseTimeAsync ( subjectTimeFastForward ) ;
237+ await streamingFeeModule . accrueFee ( setToken2 . address ) ;
238+
239+ // Change fee recipient
240+ newFeeRecipient = manager3 . address ;
241+ await streamingFeeModule . updateFeeRecipient ( setToken2 . address , newFeeRecipient ) ;
242+
243+ // Update streaming fee
244+ streamingFeePercentage = ether ( .025 ) ;
245+ await streamingFeeModule . updateStreamingFee ( setToken2 . address , streamingFeePercentage ) ;
246+
247+ }
248+
249+ main ( ) . catch ( e => {
250+ console . error ( e ) ;
251+ process . exit ( 1 ) ;
252+ } ) ;
0 commit comments