polkamarkets-js 1.0.2 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/.openzeppelin/unknown-1337.json +2056 -0
  2. package/CONTRIBUTING.md +36 -0
  3. package/README.md +24 -25
  4. package/_book/README.md +590 -0
  5. package/_book/core.md +50 -0
  6. package/_book/gitbook/fonts/fontawesome/FontAwesome.otf +0 -0
  7. package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.eot +0 -0
  8. package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.svg +685 -0
  9. package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf +0 -0
  10. package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff +0 -0
  11. package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 +0 -0
  12. package/_book/gitbook/gitbook-plugin-fontsettings/fontsettings.js +240 -0
  13. package/_book/gitbook/gitbook-plugin-fontsettings/website.css +291 -0
  14. package/_book/gitbook/gitbook-plugin-highlight/ebook.css +135 -0
  15. package/_book/gitbook/gitbook-plugin-highlight/website.css +434 -0
  16. package/_book/gitbook/gitbook-plugin-lunr/lunr.min.js +7 -0
  17. package/_book/gitbook/gitbook-plugin-lunr/search-lunr.js +59 -0
  18. package/_book/gitbook/gitbook-plugin-search/lunr.min.js +7 -0
  19. package/_book/gitbook/gitbook-plugin-search/search-engine.js +50 -0
  20. package/_book/gitbook/gitbook-plugin-search/search.css +35 -0
  21. package/_book/gitbook/gitbook-plugin-search/search.js +213 -0
  22. package/_book/gitbook/gitbook-plugin-sharing/buttons.js +90 -0
  23. package/_book/gitbook/gitbook.js +4 -0
  24. package/_book/gitbook/images/apple-touch-icon-precomposed-152.png +0 -0
  25. package/_book/gitbook/images/favicon.ico +0 -0
  26. package/_book/gitbook/style.css +9 -0
  27. package/_book/gitbook/theme.js +4 -0
  28. package/_book/index.html +705 -0
  29. package/_book/intro.md +32 -0
  30. package/_book/search_index.json +1 -0
  31. package/book.json +8 -0
  32. package/build/contracts/AccessControl.json +1 -0
  33. package/build/contracts/AccessControlEnumerable.json +1 -0
  34. package/build/contracts/Achievements.json +1 -0
  35. package/build/contracts/Address.json +1 -0
  36. package/build/contracts/BalanceHolder.json +1 -0
  37. package/build/contracts/BalanceHolder_ERC20.json +1 -0
  38. package/build/contracts/CeilDiv.json +1 -0
  39. package/build/contracts/Clones.json +1 -0
  40. package/build/contracts/Context.json +1 -0
  41. package/build/contracts/Counters.json +1 -0
  42. package/build/contracts/ERC165.json +1 -0
  43. package/build/contracts/ERC20.json +1 -0
  44. package/build/contracts/ERC20Burnable.json +1 -0
  45. package/build/contracts/ERC20Pausable.json +1 -0
  46. package/build/contracts/ERC20PresetMinterPauser.json +1 -0
  47. package/build/contracts/ERC721.json +1 -0
  48. package/build/contracts/EnumerableMap.json +1 -0
  49. package/build/contracts/EnumerableSet.json +1 -0
  50. package/build/contracts/FantasyERC20.json +1 -0
  51. package/build/contracts/IAccessControl.json +1 -0
  52. package/build/contracts/IAccessControlEnumerable.json +1 -0
  53. package/build/contracts/IBalanceHolder_ERC20.json +1 -0
  54. package/build/contracts/IERC165.json +1 -0
  55. package/build/contracts/IERC20.json +1 -0
  56. package/build/contracts/IERC20Metadata.json +1 -0
  57. package/build/contracts/IERC20Permit.json +1 -0
  58. package/build/contracts/IERC721.json +1 -0
  59. package/build/contracts/IERC721Enumerable.json +1 -0
  60. package/build/contracts/IERC721Metadata.json +1 -0
  61. package/build/contracts/IERC721Receiver.json +1 -0
  62. package/build/contracts/IFantasyERC20.json +1 -0
  63. package/build/contracts/IPredictionMarketV3.json +1 -0
  64. package/build/contracts/IPredictionMarketV3Factory.json +1 -0
  65. package/build/contracts/IPredictionMarketV3Manager.json +1 -0
  66. package/build/contracts/IRealityETH_ERC20.json +1 -0
  67. package/build/contracts/IRealityETH_IERC20.json +1 -0
  68. package/build/contracts/IWETH.json +1 -0
  69. package/build/contracts/LandFactory.json +1 -0
  70. package/build/contracts/Math.json +1 -0
  71. package/build/contracts/Migrations.json +1 -0
  72. package/build/contracts/Ownable.json +1 -0
  73. package/build/contracts/Pausable.json +1 -0
  74. package/build/contracts/PredictionMarket.json +1 -0
  75. package/build/contracts/PredictionMarketV2.json +1 -0
  76. package/build/contracts/PredictionMarketV3.json +1 -0
  77. package/build/contracts/PredictionMarketV3Controller.json +1 -0
  78. package/build/contracts/PredictionMarketV3Factory.json +1 -0
  79. package/build/contracts/PredictionMarketV3Manager.json +1 -0
  80. package/build/contracts/PredictionMarketV3Querier.json +1 -0
  81. package/build/contracts/RealitioERC20.json +1 -0
  82. package/build/contracts/RealitioForeignArbitrationProxyWithAppeals.json +1 -0
  83. package/build/contracts/RealitioHomeArbitrationProxy.json +1 -0
  84. package/build/contracts/RealitioSafeMath256.json +1 -0
  85. package/build/contracts/RealitioSafeMath32.json +1 -0
  86. package/build/contracts/RealityETH_ERC20_Factory.json +1 -0
  87. package/build/contracts/RealityETH_ERC20_v3_0.json +1 -0
  88. package/build/contracts/ReentrancyGuard.json +1 -0
  89. package/build/contracts/SafeERC20.json +1 -0
  90. package/build/contracts/SafeMath.json +1 -0
  91. package/build/contracts/Strings.json +1 -0
  92. package/build/contracts/Voting.json +1 -0
  93. package/build/contracts/WETH9.json +1 -0
  94. package/build/contracts/test.json +1 -0
  95. package/cleanContracts.js +22 -0
  96. package/contracts/FantasyERC20.sol +81 -0
  97. package/contracts/IFantasyERC20.sol +20 -0
  98. package/contracts/IPredictionMarketV3.sol +207 -0
  99. package/contracts/IPredictionMarketV3Factory.sol +10 -0
  100. package/contracts/IPredictionMarketV3Manager.sol +12 -0
  101. package/contracts/IRealityETH_ERC20.sol +64 -0
  102. package/contracts/LandFactory.sol +248 -0
  103. package/contracts/Migrations.sol +24 -0
  104. package/contracts/PredictionMarketV3.sol +1332 -0
  105. package/contracts/PredictionMarketV3Controller.sol +87 -0
  106. package/contracts/PredictionMarketV3Factory.sol +205 -0
  107. package/contracts/PredictionMarketV3Manager.sol +45 -0
  108. package/contracts/PredictionMarketV3Querier.sol +79 -0
  109. package/contracts/RealityETH_ERC20_Factory.sol +54 -0
  110. package/contracts/Voting.sol +153 -0
  111. package/contracts/WETH9.sol +62 -0
  112. package/hardhat.config.js +4 -0
  113. package/help.txt +8 -0
  114. package/index.js +3 -0
  115. package/migrations/10_deploy_weth.js +5 -0
  116. package/migrations/11_deploy_full_flow.js +99 -0
  117. package/migrations/12_deploy_pm_v3_querier.js +7 -0
  118. package/migrations/13_deploy_pm_v3_factory.js +14 -0
  119. package/migrations/1_initial_migration.js +5 -0
  120. package/migrations/2_deploy_erc20.js +10 -0
  121. package/migrations/3_deploy_realitio.js +11 -0
  122. package/migrations/4_deploy_pm.js +20 -0
  123. package/migrations/5_seed_markets.js +51 -0
  124. package/migrations/6_deploy_achievements.js +5 -0
  125. package/migrations/7_deploy_voting.js +14 -0
  126. package/migrations/8_deploy_pm_v2.js +20 -0
  127. package/migrations/9_seed_markets_v2.js +68 -0
  128. package/package.json +106 -13
  129. package/src/Application.js +421 -0
  130. package/src/interfaces/index.js +19 -0
  131. package/src/models/AchievementsContract.js +217 -0
  132. package/src/models/ArbitrationContract.js +69 -0
  133. package/src/models/ArbitrationProxyContract.js +32 -0
  134. package/src/models/ERC20Contract.js +156 -0
  135. package/src/models/FantasyERC20Contract.js +92 -0
  136. package/src/models/IContract.js +1002 -0
  137. package/src/models/PolkamarketsSmartAccount.js +100 -0
  138. package/src/models/PredictionMarketContract.js +562 -0
  139. package/src/models/PredictionMarketV2Contract.js +830 -0
  140. package/src/models/PredictionMarketV3Contract.js +256 -0
  141. package/src/models/PredictionMarketV3ControllerContract.js +102 -0
  142. package/src/models/PredictionMarketV3FactoryContract.js +96 -0
  143. package/src/models/PredictionMarketV3ManagerContract.js +111 -0
  144. package/src/models/PredictionMarketV3QuerierContract.js +24 -0
  145. package/src/models/RealitioERC20Contract.js +286 -0
  146. package/src/models/VotingContract.js +182 -0
  147. package/src/models/WETH9Contract.js +92 -0
  148. package/src/models/index.js +33 -0
  149. package/src/utils/Account.js +40 -0
  150. package/src/utils/Contract.js +120 -0
  151. package/src/utils/Numbers.js +94 -0
  152. package/tests/fantasyERC20Contract.js +225 -0
  153. package/tests/index.js +10 -0
  154. package/tests/predictionMarketContract.js +466 -0
  155. package/tests/predictionMarketV2Contract.js +1042 -0
  156. package/tests/predictionMarketV3Contract.js +1079 -0
  157. package/tests/predictionMarketV3ControllerContract.js +613 -0
  158. package/tests/predictionMarketV3FactoryContract.js +469 -0
  159. package/tests/predictionMarketV3ManagerContract.js +610 -0
  160. package/tests/utils.js +16 -0
  161. package/tests/votingContract.js +490 -0
  162. package/tooling/docs/jsdoc.json +6 -0
  163. package/truffle-config.js +134 -0
  164. package/polkamarkets.js +0 -436
@@ -0,0 +1,466 @@
1
+
2
+
3
+ import { expect } from 'chai';
4
+ import moment from 'moment';
5
+
6
+ import { mochaAsync } from './utils';
7
+ import { Application } from '..';
8
+
9
+ context('Prediction Market Contract', async () => {
10
+ require('dotenv').config();
11
+
12
+ let app;
13
+ let predictionMarketContract;
14
+ let realitioERC20Contract
15
+ let ERC20Contract;
16
+
17
+ // market / outcome ids we'll make unit tests with
18
+ let marketId = 0;
19
+ let outcomeIds = [0, 1];
20
+ const ethAmount = 0.01;
21
+ let closeDateTime;
22
+
23
+ context('Contract Deployment', async () => {
24
+ it('should start the Application', mochaAsync(async () => {
25
+ app = new Application({
26
+ web3Provider: process.env.WEB3_PROVIDER,
27
+ web3PrivateKey: process.env.WEB3_PRIVATE_KEY,
28
+ });
29
+ expect(app).to.not.equal(null);
30
+ }));
31
+
32
+ it('should deploy Prediction Market Contract', mochaAsync(async () => {
33
+ // Create Contract
34
+ predictionMarketContract = app.getPredictionMarketContract({});
35
+ realitioERC20Contract = app.getRealitioERC20Contract({});
36
+ ERC20Contract = app.getERC20Contract({});
37
+ // // Deploy
38
+ await realitioERC20Contract.deploy({});
39
+ await ERC20Contract.deploy({ params: ['Polkamarkets', 'POLK'] });
40
+
41
+ const realitioContractAddress = realitioERC20Contract.getAddress();
42
+ const ERC20ContractAddress = ERC20Contract.getAddress();
43
+ const accountAddress = await predictionMarketContract.getMyAccount();
44
+
45
+ await predictionMarketContract.deploy({
46
+ params: [
47
+ 0,
48
+ ERC20ContractAddress,
49
+ 0,
50
+ realitioContractAddress,
51
+ 86400
52
+ ]
53
+ });
54
+ const predictionMarketContractAddress = predictionMarketContract.getAddress();
55
+
56
+ expect(predictionMarketContractAddress).to.not.equal(null);
57
+ expect(realitioContractAddress).to.not.equal(null);
58
+
59
+ // setting predictionMarket ownable vars
60
+ // await predictionMarketContract.getContract().methods.initialize().send({ from: accountAddress });
61
+ // // setting realitioERC20 governance vars
62
+ // await predictionMarketContract.getContract().methods.setRealitioERC20(realitioContractAddress).send({ from: accountAddress });
63
+ // await predictionMarketContract.getContract().methods.setRealitioTimeout(86400).send({ from: accountAddress });
64
+ // await predictionMarketContract.getContract().methods.setToken(ERC20ContractAddress).send({ from: accountAddress });
65
+ // await predictionMarketContract.getContract().methods.setRequiredBalance(0).send({ from: accountAddress });
66
+ }));
67
+ });
68
+
69
+ context('Market Creation', async () => {
70
+ it('should create a Market', mochaAsync(async () => {
71
+ closeDateTime = moment().add(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm');
72
+ try {
73
+ const res = await predictionMarketContract.createMarket({
74
+ name: 'Will BTC price close above 100k$ on May 1st 2022',
75
+ image: 'foo-bar',
76
+ category: 'Foo;Bar',
77
+ oracleAddress: '0x0000000000000000000000000000000000000001', // TODO
78
+ duration: moment(closeDateTime).unix(),
79
+ outcomes: ['Yes', 'No'],
80
+ ethAmount: ethAmount
81
+ });
82
+ expect(res.status).to.equal(true);
83
+ } catch (e) {
84
+ // TODO: review this
85
+ }
86
+
87
+ const marketIds = await predictionMarketContract.getMarkets();
88
+ marketId = marketIds[marketIds.length - 1];
89
+ expect(marketIds.length).to.equal(1);
90
+ expect(marketIds[marketIds.length - 1]).to.equal(marketId);
91
+ }));
92
+
93
+ it('should create another Market', mochaAsync(async () => {
94
+ const res = await predictionMarketContract.createMarket({
95
+ name: 'Will ETH price close above 10k$ on May 1st 2022',
96
+ image: 'foo-bar',
97
+ category: 'Foo;Bar',
98
+ oracleAddress: '0x0000000000000000000000000000000000000001', // TODO
99
+ duration: moment(closeDateTime).unix(),
100
+ outcomes: ['Yes', 'No'],
101
+ ethAmount: 0.001
102
+ });
103
+ expect(res.status).to.equal(true);
104
+
105
+ const marketIds = await predictionMarketContract.getMarkets();
106
+ expect(marketIds.length).to.equal(2);
107
+ }));
108
+ });
109
+
110
+ context('Market Data', async () => {
111
+ it('should get Market data', mochaAsync(async () => {
112
+ const res = await predictionMarketContract.getMarketData({ marketId: 0 });
113
+ expect(res).to.eql({
114
+ name: '',
115
+ closeDateTime,
116
+ state: 0,
117
+ oracleAddress: '0x0000000000000000000000000000000000000000',
118
+ liquidity: 0.01,
119
+ outcomeIds: [0, 1],
120
+ });
121
+ }));
122
+
123
+ it('should get Market details', mochaAsync(async () => {
124
+ const res = await predictionMarketContract.getMarketDetails({ marketId: 0 });
125
+ expect(res).to.eql({
126
+ name: 'Will BTC price close above 100k$ on May 1st 2022',
127
+ category: 'Foo',
128
+ subcategory: 'Bar',
129
+ outcomes: ['Yes', 'No'],
130
+ image: 'foo-bar'
131
+ });
132
+ }));
133
+
134
+ it('should get Market Outcomes data', mochaAsync(async () => {
135
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
136
+ expect(outcome1Data).to.include({
137
+ price: 0.5,
138
+ shares: 0.01
139
+ });
140
+
141
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
142
+ expect(outcome2Data).to.include({
143
+ price: 0.5,
144
+ shares: 0.01
145
+ });
146
+
147
+ // outcomes share prices should sum to 1
148
+ expect(outcome1Data.price + outcome2Data.price).to.equal(1);
149
+ // outcomes number of shares should dum to ethAmount * 2
150
+ expect(outcome1Data.shares + outcome2Data.shares).to.equal(ethAmount * 2);
151
+ }));
152
+ });
153
+
154
+ context('Market Interaction - Balanced Market (Same Outcome Odds)', async () => {
155
+ it('should add liquidity without changing shares balance', mochaAsync(async () => {
156
+ const myShares = await predictionMarketContract.getMyMarketShares({ marketId });
157
+ const marketData = await predictionMarketContract.getMarketData({ marketId });
158
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
159
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
160
+
161
+ // balanced market - same price in all outcomoes
162
+ expect(outcome1Data.price).to.equal(outcome2Data.price);
163
+
164
+ try {
165
+ const res = await predictionMarketContract.addLiquidity({ marketId, ethAmount })
166
+ expect(res.status).to.equal(true);
167
+ } catch (e) {
168
+ // TODO: review this
169
+ }
170
+
171
+ const myNewShares = await predictionMarketContract.getMyMarketShares({ marketId });
172
+ const newMarketData = await predictionMarketContract.getMarketData({ marketId });
173
+ const newOutcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
174
+ const newOutcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
175
+
176
+ expect(newMarketData.liquidity).to.above(marketData.liquidity);
177
+ expect(newMarketData.liquidity).to.equal(marketData.liquidity + ethAmount);
178
+
179
+ // Outcome prices shoud remain the same after providing liquidity
180
+ expect(newOutcome1Data.price).to.equal(outcome1Data.price);
181
+ expect(newOutcome2Data.price).to.equal(outcome2Data.price);
182
+
183
+ // Price balances are 0.5-0.5, liquidity will be added solely through liquidity shares
184
+ expect(myNewShares.liquidityShares).to.above(myShares.liquidityShares);
185
+ expect(myNewShares.liquidityShares).to.equal(myShares.liquidityShares + ethAmount);
186
+ // shares balance remains the same
187
+ expect(myNewShares.outcomeShares[0]).to.equal(myShares.outcomeShares[0]);
188
+ expect(myNewShares.outcomeShares[1]).to.equal(myShares.outcomeShares[1]);
189
+ }));
190
+
191
+ it('should remove liquidity without changing shares balance', mochaAsync(async () => {
192
+ const myShares = await predictionMarketContract.getMyMarketShares({ marketId });
193
+ const marketData = await predictionMarketContract.getMarketData({ marketId });
194
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
195
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
196
+ const contractBalance = Number(await predictionMarketContract.getBalance());
197
+
198
+ // balanced market - same price in all outcomoes
199
+ expect(outcome1Data.price).to.equal(outcome2Data.price);
200
+
201
+ try {
202
+ const res = await predictionMarketContract.removeLiquidity({ marketId, shares: ethAmount })
203
+ expect(res.status).to.equal(true);
204
+ } catch (e) {
205
+ // TODO: review this
206
+ }
207
+
208
+ const myNewShares = await predictionMarketContract.getMyMarketShares({ marketId });
209
+ const newMarketData = await predictionMarketContract.getMarketData({ marketId });
210
+ const newOutcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
211
+ const newOutcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
212
+ const newContractBalance = Number(await predictionMarketContract.getBalance());
213
+
214
+ expect(newMarketData.liquidity).to.below(marketData.liquidity);
215
+ expect(newMarketData.liquidity).to.equal(marketData.liquidity - ethAmount);
216
+
217
+ // Outcome prices shoud remain the same after providing liquidity
218
+ expect(newOutcome1Data.price).to.equal(outcome1Data.price);
219
+ expect(newOutcome2Data.price).to.equal(outcome2Data.price);
220
+
221
+ // Price balances are 0.5-0.5, liquidity will be added solely through liquidity shares
222
+ expect(myNewShares.liquidityShares).to.below(myShares.liquidityShares);
223
+ expect(myNewShares.liquidityShares).to.equal(myShares.liquidityShares - ethAmount);
224
+ // shares balance remains the same
225
+ expect(myNewShares.outcomeShares[0]).to.equal(myShares.outcomeShares[0]);
226
+ expect(myNewShares.outcomeShares[1]).to.equal(myShares.outcomeShares[1]);
227
+
228
+ // User gets liquidity tokens back in ETH
229
+ expect(newContractBalance).to.below(contractBalance);
230
+ // TODO: check amountTransferred from internal transactions
231
+ const amountTransferred = Number((contractBalance - newContractBalance).toFixed(5));
232
+ expect(amountTransferred).to.equal(ethAmount);
233
+ }));
234
+ });
235
+
236
+ context('Market Interaction - Unbalanced Market (Different Outcome Odds)', async () => {
237
+ it('should display my shares', mochaAsync(async () => {
238
+ const res = await predictionMarketContract.getMyMarketShares({ marketId });
239
+ // currently holding liquidity tokens from market creation
240
+ expect(res).to.eql({
241
+ liquidityShares: 0.01,
242
+ outcomeShares: {
243
+ 0: 0.00,
244
+ 1: 0.00,
245
+ }
246
+ });
247
+ }));
248
+
249
+ it('should buy outcome shares', mochaAsync(async () => {
250
+ const outcomeId = 0;
251
+ const minOutcomeSharesToBuy = 0.015;
252
+
253
+ const marketData = await predictionMarketContract.getMarketData({ marketId });
254
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
255
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
256
+ const contractBalance = Number(await predictionMarketContract.getBalance());
257
+
258
+ try {
259
+ const res = await predictionMarketContract.buy({ marketId, outcomeId, ethAmount, minOutcomeSharesToBuy });
260
+ expect(res.status).to.equal(true);
261
+ } catch (e) {
262
+ // TODO: review this
263
+ }
264
+
265
+ const newMarketData = await predictionMarketContract.getMarketData({ marketId });
266
+ const newOutcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
267
+ const newOutcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
268
+ const newContractBalance = Number(await predictionMarketContract.getBalance());
269
+
270
+ // outcome price should increase
271
+ expect(newOutcome1Data.price).to.above(outcome1Data.price);
272
+ expect(newOutcome1Data.price).to.equal(0.8);
273
+ // opposite outcome price should decrease
274
+ expect(newOutcome2Data.price).to.below(outcome2Data.price);
275
+ expect(newOutcome2Data.price).to.equal(0.2);
276
+ // Prices sum = 1
277
+ // 0.05 + 0.05 = 1
278
+ expect(newOutcome1Data.price + newOutcome2Data.price).to.equal(1);
279
+
280
+ // Liquidity value remains the same
281
+ expect(newMarketData.liquidity).to.equal(marketData.liquidity);
282
+
283
+ // outcome shares should decrease
284
+ expect(newOutcome1Data.shares).to.below(outcome1Data.shares);
285
+ expect(newOutcome1Data.shares).to.equal(0.005);
286
+ // opposite outcome shares should increase
287
+ expect(newOutcome2Data.shares).to.above(outcome2Data.shares);
288
+ expect(newOutcome2Data.shares).to.equal(0.02);
289
+ // # Shares Product = Liquidity^2
290
+ // 0.005 * 0.02 = 0.01^2
291
+ expect(outcome1Data.shares * outcome2Data.shares).to.equal(newMarketData.liquidity ** 2);
292
+ expect(newOutcome1Data.shares * newOutcome2Data.shares).to.equal(newMarketData.liquidity ** 2);
293
+
294
+ const myShares = await predictionMarketContract.getMyMarketShares({ marketId });
295
+ expect(myShares).to.eql({
296
+ liquidityShares: 0.01,
297
+ outcomeShares: {
298
+ 0: 0.015,
299
+ 1: 0.00,
300
+ }
301
+ });
302
+
303
+ // Contract adds ethAmount to balance
304
+ expect(newContractBalance).to.above(contractBalance);
305
+ // TODO: check amountReceived from internal transactions
306
+ const amountReceived = Number((newContractBalance - contractBalance).toFixed(5));
307
+ expect(amountReceived).to.equal(ethAmount);
308
+ }));
309
+
310
+ it('should add liquidity', mochaAsync(async () => {
311
+ const myShares = await predictionMarketContract.getMyMarketShares({ marketId });
312
+ const marketData = await predictionMarketContract.getMarketData({ marketId });
313
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
314
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
315
+
316
+ try {
317
+ const res = await predictionMarketContract.addLiquidity({ marketId, ethAmount })
318
+ expect(res.status).to.equal(true);
319
+ } catch (e) {
320
+ // TODO: review this
321
+ }
322
+
323
+ const myNewShares = await predictionMarketContract.getMyMarketShares({ marketId });
324
+ const newMarketData = await predictionMarketContract.getMarketData({ marketId });
325
+ const newOutcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
326
+ const newOutcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
327
+
328
+ // Outcome prices shoud remain the same after providing liquidity
329
+ expect(newOutcome1Data.price).to.equal(outcome1Data.price);
330
+ expect(newOutcome2Data.price).to.equal(outcome2Data.price);
331
+
332
+ // # Shares Product = Liquidity^2
333
+ // 0.0075 * 0.03 = 0.015^2
334
+ expect(newMarketData.liquidity).to.above(marketData.liquidity);
335
+ expect(newMarketData.liquidity).to.equal(0.015);
336
+ expect(newOutcome1Data.shares).to.above(outcome1Data.shares);
337
+ expect(newOutcome1Data.shares).to.equal(0.0075);
338
+ expect(newOutcome2Data.shares).to.above(outcome2Data.shares);
339
+ expect(newOutcome2Data.shares).to.equal(0.03);
340
+ expect(newOutcome1Data.shares * newOutcome2Data.shares).to.equal(newMarketData.liquidity ** 2);
341
+
342
+ // Price balances are not 0.5-0.5, liquidity will be added through shares + liquidity
343
+ expect(myNewShares.liquidityShares).to.above(myShares.liquidityShares);
344
+ expect(myNewShares.liquidityShares).to.equal(0.015);
345
+ // shares balance of higher odd outcome increases
346
+ expect(myNewShares.outcomeShares[0]).to.above(myShares.outcomeShares[0]);
347
+ expect(myNewShares.outcomeShares[0]).to.equal(0.0225);
348
+ // shares balance of lower odd outcome remains
349
+ expect(myNewShares.outcomeShares[1]).to.equal(myShares.outcomeShares[1]);
350
+ expect(myNewShares.outcomeShares[1]).to.equal(0);
351
+ }));
352
+
353
+ it('should remove liquidity', mochaAsync(async () => {
354
+ const myShares = await predictionMarketContract.getMyMarketShares({ marketId });
355
+ const marketData = await predictionMarketContract.getMarketData({ marketId });
356
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
357
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
358
+ const contractBalance = Number(await predictionMarketContract.getBalance());
359
+ const liquiditySharesToRemove = 0.005;
360
+
361
+ try {
362
+ const res = await predictionMarketContract.removeLiquidity({ marketId, shares: liquiditySharesToRemove });
363
+ expect(res.status).to.equal(true);
364
+ } catch (e) {
365
+ // TODO: review this
366
+ }
367
+
368
+ const myNewShares = await predictionMarketContract.getMyMarketShares({ marketId });
369
+ const newMarketData = await predictionMarketContract.getMarketData({ marketId });
370
+ const newOutcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
371
+ const newOutcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
372
+ const newContractBalance = Number(await predictionMarketContract.getBalance());
373
+
374
+ // Outcome prices shoud remain the same after removing liquidity
375
+ expect(newOutcome1Data.price).to.equal(outcome1Data.price);
376
+ expect(newOutcome2Data.price).to.equal(outcome2Data.price);
377
+
378
+ // # Shares Product = Liquidity^2
379
+ // 0.005 * 0.02 = 0.01^2
380
+ expect(newMarketData.liquidity).to.below(marketData.liquidity);
381
+ expect(newMarketData.liquidity).to.equal(0.01);
382
+ expect(newOutcome1Data.shares).to.below(outcome1Data.shares);
383
+ expect(newOutcome1Data.shares).to.equal(0.005);
384
+ expect(newOutcome2Data.shares).to.below(outcome2Data.shares);
385
+ expect(newOutcome2Data.shares).to.equal(0.02);
386
+ expect(newOutcome1Data.shares * newOutcome2Data.shares).to.equal(newMarketData.liquidity ** 2);
387
+
388
+ // Price balances are not 0.5-0.5, liquidity will be added through shares + liquidity
389
+ expect(myNewShares.liquidityShares).to.below(myShares.liquidityShares);
390
+ expect(myNewShares.liquidityShares).to.equal(0.01);
391
+ // shares balance of higher odd outcome remains
392
+ expect(myNewShares.outcomeShares[0]).to.equal(myShares.outcomeShares[0]);
393
+ expect(myNewShares.outcomeShares[0]).to.equal(0.0225);
394
+ // shares balance of lower odd outcome increases
395
+ expect(myNewShares.outcomeShares[1]).to.above(myShares.outcomeShares[1]);
396
+ expect(myNewShares.outcomeShares[1]).to.equal(0.0075);
397
+
398
+ // User gets part of the liquidity tokens back in ETH
399
+ expect(newContractBalance).to.below(contractBalance);
400
+ // TODO: check amountTransferred from internal transactions
401
+ const amountTransferred = Number((contractBalance - newContractBalance).toFixed(5));
402
+ expect(amountTransferred).to.equal(0.0025);
403
+ }));
404
+
405
+ it('should sell outcome shares', mochaAsync(async () => {
406
+ const outcomeId = 0;
407
+ const maxOutcomeSharesToSell = 0.015;
408
+
409
+ const marketData = await predictionMarketContract.getMarketData({ marketId });
410
+ const outcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
411
+ const outcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
412
+ const contractBalance = Number(await predictionMarketContract.getBalance());
413
+
414
+ try {
415
+ const res = await predictionMarketContract.sell({ marketId, outcomeId, ethAmount, maxOutcomeSharesToSell });
416
+ expect(res.status).to.equal(true);
417
+ } catch (e) {
418
+ // TODO: review this
419
+ }
420
+
421
+ const newMarketData = await predictionMarketContract.getMarketData({ marketId });
422
+ const newOutcome1Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[0] });
423
+ const newOutcome2Data = await predictionMarketContract.getOutcomeData({ marketId, outcomeId: outcomeIds[1] });
424
+ const newContractBalance = Number(await predictionMarketContract.getBalance());
425
+
426
+ // outcome price should decrease
427
+ expect(newOutcome1Data.price).to.below(outcome1Data.price);
428
+ expect(newOutcome1Data.price).to.equal(0.5);
429
+ // opposite outcome price should increase
430
+ expect(newOutcome2Data.price).to.above(outcome2Data.price);
431
+ expect(newOutcome2Data.price).to.equal(0.5);
432
+ // Prices sum = 1
433
+ // 0.05 + 0.05 = 1
434
+ expect(newOutcome1Data.price + newOutcome2Data.price).to.equal(1);
435
+
436
+ // Liquidity value remains the same
437
+ expect(newMarketData.liquidity).to.equal(marketData.liquidity);
438
+
439
+ // outcome shares should increase
440
+ expect(newOutcome1Data.shares).to.above(outcome1Data.shares);
441
+ expect(newOutcome1Data.shares).to.equal(0.01);
442
+ // opposite outcome shares should increase
443
+ expect(newOutcome2Data.shares).to.below(outcome2Data.shares);
444
+ expect(newOutcome2Data.shares).to.equal(0.01);
445
+ // # Shares Product = Liquidity^2
446
+ // 0.01 * 0.01 = 0.01^2
447
+ expect(outcome1Data.shares * outcome2Data.shares).to.equal(newMarketData.liquidity ** 2);
448
+ expect(newOutcome1Data.shares * newOutcome2Data.shares).to.equal(newMarketData.liquidity ** 2);
449
+
450
+ const myShares = await predictionMarketContract.getMyMarketShares({ marketId });
451
+ expect(myShares).to.eql({
452
+ liquidityShares: 0.01,
453
+ outcomeShares: {
454
+ 0: 0.0075,
455
+ 1: 0.0075,
456
+ }
457
+ });
458
+
459
+ // User gets shares value back in ETH
460
+ expect(newContractBalance).to.below(contractBalance);
461
+ // TODO: check amountTransferred from internal transactions
462
+ const amountTransferred = Number((contractBalance - newContractBalance).toFixed(5));
463
+ expect(amountTransferred).to.equal(0.01);
464
+ }));
465
+ });
466
+ });