polkamarkets-js 1.0.2 → 3.1.0
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.
- package/.openzeppelin/unknown-1337.json +2056 -0
- package/CONTRIBUTING.md +36 -0
- package/README.md +24 -25
- package/_book/README.md +590 -0
- package/_book/core.md +50 -0
- package/_book/gitbook/fonts/fontawesome/FontAwesome.otf +0 -0
- package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.eot +0 -0
- package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.svg +685 -0
- package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.ttf +0 -0
- package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff +0 -0
- package/_book/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 +0 -0
- package/_book/gitbook/gitbook-plugin-fontsettings/fontsettings.js +240 -0
- package/_book/gitbook/gitbook-plugin-fontsettings/website.css +291 -0
- package/_book/gitbook/gitbook-plugin-highlight/ebook.css +135 -0
- package/_book/gitbook/gitbook-plugin-highlight/website.css +434 -0
- package/_book/gitbook/gitbook-plugin-lunr/lunr.min.js +7 -0
- package/_book/gitbook/gitbook-plugin-lunr/search-lunr.js +59 -0
- package/_book/gitbook/gitbook-plugin-search/lunr.min.js +7 -0
- package/_book/gitbook/gitbook-plugin-search/search-engine.js +50 -0
- package/_book/gitbook/gitbook-plugin-search/search.css +35 -0
- package/_book/gitbook/gitbook-plugin-search/search.js +213 -0
- package/_book/gitbook/gitbook-plugin-sharing/buttons.js +90 -0
- package/_book/gitbook/gitbook.js +4 -0
- package/_book/gitbook/images/apple-touch-icon-precomposed-152.png +0 -0
- package/_book/gitbook/images/favicon.ico +0 -0
- package/_book/gitbook/style.css +9 -0
- package/_book/gitbook/theme.js +4 -0
- package/_book/index.html +705 -0
- package/_book/intro.md +32 -0
- package/_book/search_index.json +1 -0
- package/book.json +8 -0
- package/build/contracts/AccessControl.json +1 -0
- package/build/contracts/AccessControlEnumerable.json +1 -0
- package/build/contracts/Achievements.json +1 -0
- package/build/contracts/Address.json +1 -0
- package/build/contracts/BalanceHolder.json +1 -0
- package/build/contracts/BalanceHolder_ERC20.json +1 -0
- package/build/contracts/CeilDiv.json +1 -0
- package/build/contracts/Clones.json +1 -0
- package/build/contracts/Context.json +1 -0
- package/build/contracts/Counters.json +1 -0
- package/build/contracts/ERC165.json +1 -0
- package/build/contracts/ERC20.json +1 -0
- package/build/contracts/ERC20Burnable.json +1 -0
- package/build/contracts/ERC20Pausable.json +1 -0
- package/build/contracts/ERC20PresetMinterPauser.json +1 -0
- package/build/contracts/ERC721.json +1 -0
- package/build/contracts/EnumerableMap.json +1 -0
- package/build/contracts/EnumerableSet.json +1 -0
- package/build/contracts/FantasyERC20.json +1 -0
- package/build/contracts/IAccessControl.json +1 -0
- package/build/contracts/IAccessControlEnumerable.json +1 -0
- package/build/contracts/IBalanceHolder_ERC20.json +1 -0
- package/build/contracts/IERC165.json +1 -0
- package/build/contracts/IERC20.json +1 -0
- package/build/contracts/IERC20Metadata.json +1 -0
- package/build/contracts/IERC20Permit.json +1 -0
- package/build/contracts/IERC721.json +1 -0
- package/build/contracts/IERC721Enumerable.json +1 -0
- package/build/contracts/IERC721Metadata.json +1 -0
- package/build/contracts/IERC721Receiver.json +1 -0
- package/build/contracts/IFantasyERC20.json +1 -0
- package/build/contracts/IPredictionMarketV3.json +1 -0
- package/build/contracts/IPredictionMarketV3Factory.json +1 -0
- package/build/contracts/IPredictionMarketV3Manager.json +1 -0
- package/build/contracts/IRealityETH_ERC20.json +1 -0
- package/build/contracts/IRealityETH_IERC20.json +1 -0
- package/build/contracts/IWETH.json +1 -0
- package/build/contracts/LandFactory.json +1 -0
- package/build/contracts/Math.json +1 -0
- package/build/contracts/Migrations.json +1 -0
- package/build/contracts/Ownable.json +1 -0
- package/build/contracts/Pausable.json +1 -0
- package/build/contracts/PredictionMarket.json +1 -0
- package/build/contracts/PredictionMarketV2.json +1 -0
- package/build/contracts/PredictionMarketV3.json +1 -0
- package/build/contracts/PredictionMarketV3Controller.json +1 -0
- package/build/contracts/PredictionMarketV3Factory.json +1 -0
- package/build/contracts/PredictionMarketV3Manager.json +1 -0
- package/build/contracts/PredictionMarketV3Querier.json +1 -0
- package/build/contracts/RealitioERC20.json +1 -0
- package/build/contracts/RealitioForeignArbitrationProxyWithAppeals.json +1 -0
- package/build/contracts/RealitioHomeArbitrationProxy.json +1 -0
- package/build/contracts/RealitioSafeMath256.json +1 -0
- package/build/contracts/RealitioSafeMath32.json +1 -0
- package/build/contracts/RealityETH_ERC20_Factory.json +1 -0
- package/build/contracts/RealityETH_ERC20_v3_0.json +1 -0
- package/build/contracts/ReentrancyGuard.json +1 -0
- package/build/contracts/SafeERC20.json +1 -0
- package/build/contracts/SafeMath.json +1 -0
- package/build/contracts/Strings.json +1 -0
- package/build/contracts/Voting.json +1 -0
- package/build/contracts/WETH9.json +1 -0
- package/build/contracts/test.json +1 -0
- package/cleanContracts.js +22 -0
- package/contracts/FantasyERC20.sol +81 -0
- package/contracts/IFantasyERC20.sol +20 -0
- package/contracts/IPredictionMarketV3.sol +207 -0
- package/contracts/IPredictionMarketV3Factory.sol +10 -0
- package/contracts/IPredictionMarketV3Manager.sol +12 -0
- package/contracts/IRealityETH_ERC20.sol +64 -0
- package/contracts/LandFactory.sol +248 -0
- package/contracts/Migrations.sol +24 -0
- package/contracts/PredictionMarketV3.sol +1332 -0
- package/contracts/PredictionMarketV3Controller.sol +87 -0
- package/contracts/PredictionMarketV3Factory.sol +205 -0
- package/contracts/PredictionMarketV3Manager.sol +45 -0
- package/contracts/PredictionMarketV3Querier.sol +79 -0
- package/contracts/RealityETH_ERC20_Factory.sol +54 -0
- package/contracts/Voting.sol +153 -0
- package/contracts/WETH9.sol +62 -0
- package/help.txt +8 -0
- package/index.js +3 -0
- package/migrations/10_deploy_weth.js +5 -0
- package/migrations/11_deploy_full_flow.js +99 -0
- package/migrations/12_deploy_pm_v3_querier.js +7 -0
- package/migrations/13_deploy_pm_v3_factory.js +14 -0
- package/migrations/1_initial_migration.js +5 -0
- package/migrations/2_deploy_erc20.js +10 -0
- package/migrations/3_deploy_realitio.js +11 -0
- package/migrations/4_deploy_pm.js +20 -0
- package/migrations/5_seed_markets.js +51 -0
- package/migrations/6_deploy_achievements.js +5 -0
- package/migrations/7_deploy_voting.js +14 -0
- package/migrations/8_deploy_pm_v2.js +20 -0
- package/migrations/9_seed_markets_v2.js +68 -0
- package/package.json +106 -13
- package/src/Application.js +421 -0
- package/src/interfaces/index.js +19 -0
- package/src/models/AchievementsContract.js +217 -0
- package/src/models/ArbitrationContract.js +69 -0
- package/src/models/ArbitrationProxyContract.js +32 -0
- package/src/models/ERC20Contract.js +156 -0
- package/src/models/FantasyERC20Contract.js +92 -0
- package/src/models/IContract.js +1002 -0
- package/src/models/PolkamarketsSmartAccount.js +100 -0
- package/src/models/PredictionMarketContract.js +562 -0
- package/src/models/PredictionMarketV2Contract.js +830 -0
- package/src/models/PredictionMarketV3Contract.js +233 -0
- package/src/models/PredictionMarketV3ControllerContract.js +102 -0
- package/src/models/PredictionMarketV3FactoryContract.js +96 -0
- package/src/models/PredictionMarketV3ManagerContract.js +111 -0
- package/src/models/PredictionMarketV3QuerierContract.js +24 -0
- package/src/models/RealitioERC20Contract.js +286 -0
- package/src/models/VotingContract.js +182 -0
- package/src/models/WETH9Contract.js +92 -0
- package/src/models/index.js +33 -0
- package/src/utils/Account.js +40 -0
- package/src/utils/Contract.js +120 -0
- package/src/utils/Numbers.js +94 -0
- package/tests/fantasyERC20Contract.js +225 -0
- package/tests/index.js +10 -0
- package/tests/predictionMarketContract.js +466 -0
- package/tests/predictionMarketV2Contract.js +1042 -0
- package/tests/predictionMarketV3Contract.js +1079 -0
- package/tests/predictionMarketV3ControllerContract.js +613 -0
- package/tests/predictionMarketV3FactoryContract.js +469 -0
- package/tests/predictionMarketV3ManagerContract.js +610 -0
- package/tests/utils.js +16 -0
- package/tests/votingContract.js +490 -0
- package/tooling/docs/jsdoc.json +6 -0
- package/truffle-config.js +134 -0
- package/polkamarkets.js +0 -436
|
@@ -0,0 +1,610 @@
|
|
|
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 V3 Manager', async () => {
|
|
10
|
+
require('dotenv').config();
|
|
11
|
+
|
|
12
|
+
const TOKEN_AMOUNT_TO_CLAIM = 10;
|
|
13
|
+
const LOCK_AMOUNT = 5;
|
|
14
|
+
const NEW_LOCK_AMOUNT = 1;
|
|
15
|
+
|
|
16
|
+
const USER1_ADDRESS = process.env.TEST_USER1_ADDRESS;
|
|
17
|
+
const USER1_PRIVATE_KEY = process.env.TEST_USER1_PRIVATE_KEY;
|
|
18
|
+
const USER2_ADDRESS = process.env.TEST_USER2_ADDRESS;
|
|
19
|
+
const USER2_PRIVATE_KEY = process.env.TEST_USER2_PRIVATE_KEY;
|
|
20
|
+
|
|
21
|
+
let app;
|
|
22
|
+
let accountAddress;
|
|
23
|
+
let predictionMarketContract;
|
|
24
|
+
let predictionMarketManagerContract;
|
|
25
|
+
let realitioERC20Contract
|
|
26
|
+
let pmmTokenContract;
|
|
27
|
+
|
|
28
|
+
let landId = 0;
|
|
29
|
+
|
|
30
|
+
context('Contract Deployment', async () => {
|
|
31
|
+
it('should start the Application', mochaAsync(async () => {
|
|
32
|
+
app = new Application({
|
|
33
|
+
web3Provider: process.env.WEB3_PROVIDER,
|
|
34
|
+
web3PrivateKey: process.env.WEB3_PRIVATE_KEY
|
|
35
|
+
});
|
|
36
|
+
expect(app).to.not.equal(null);
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
it('should deploy Prediction Market Contract', mochaAsync(async () => {
|
|
40
|
+
accountAddress = await app.getAddress();
|
|
41
|
+
|
|
42
|
+
// Create Contract
|
|
43
|
+
predictionMarketContract = app.getPredictionMarketV3Contract({});
|
|
44
|
+
predictionMarketManagerContract = app.getPredictionMarketV3ManagerContract({});
|
|
45
|
+
realitioERC20Contract = app.getRealitioERC20Contract({});
|
|
46
|
+
pmmTokenContract = app.getERC20Contract({});
|
|
47
|
+
|
|
48
|
+
// Deploy
|
|
49
|
+
await pmmTokenContract.deploy({params: ['Polkamarkets', 'POLK']});
|
|
50
|
+
const pmmTokenContractAddress = pmmTokenContract.getAddress();
|
|
51
|
+
|
|
52
|
+
await realitioERC20Contract.deploy({});
|
|
53
|
+
let realitioContractAddress = realitioERC20Contract.getAddress();
|
|
54
|
+
|
|
55
|
+
await predictionMarketContract.deploy({
|
|
56
|
+
params: [
|
|
57
|
+
'0x0000000000000000000000000000000000000000'
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
const predictionMarketContractAddress = predictionMarketContract.getAddress();
|
|
61
|
+
|
|
62
|
+
await predictionMarketManagerContract.deploy({
|
|
63
|
+
params: [
|
|
64
|
+
predictionMarketContractAddress,
|
|
65
|
+
pmmTokenContractAddress,
|
|
66
|
+
(LOCK_AMOUNT * 10**18).toString(), // TODO: improve this
|
|
67
|
+
realitioContractAddress
|
|
68
|
+
]
|
|
69
|
+
});
|
|
70
|
+
const predictionMarketManagerContractAddress = predictionMarketManagerContract.getAddress();
|
|
71
|
+
// minting and approving pmmTokenContract to spend tokens
|
|
72
|
+
await pmmTokenContract.mint({
|
|
73
|
+
address: accountAddress,
|
|
74
|
+
amount: '1000'
|
|
75
|
+
});
|
|
76
|
+
await pmmTokenContract.approve({
|
|
77
|
+
address: predictionMarketManagerContractAddress,
|
|
78
|
+
amount: '1000000'
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
expect(predictionMarketContractAddress).to.not.equal(null);
|
|
82
|
+
expect(predictionMarketManagerContractAddress).to.not.equal(null);
|
|
83
|
+
expect(realitioContractAddress).to.not.equal(null);
|
|
84
|
+
expect(pmmTokenContractAddress).to.not.equal(null);
|
|
85
|
+
}));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
context('Land Management', async () => {
|
|
89
|
+
context('Land Creation', async () => {
|
|
90
|
+
it('should create a Land', mochaAsync(async () => {
|
|
91
|
+
const currentLandIndex = await predictionMarketManagerContract.getLandTokensLength();
|
|
92
|
+
landId = currentLandIndex;
|
|
93
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
94
|
+
|
|
95
|
+
await predictionMarketManagerContract.createLand({
|
|
96
|
+
name: 'Token',
|
|
97
|
+
symbol: 'TOKEN',
|
|
98
|
+
tokenAmountToClaim: TOKEN_AMOUNT_TO_CLAIM,
|
|
99
|
+
tokenToAnswer: pmmTokenContract.getAddress(),
|
|
100
|
+
});
|
|
101
|
+
const land = await predictionMarketManagerContract.getLandById({ id: currentLandIndex });
|
|
102
|
+
const newLandIndex = await predictionMarketManagerContract.getLandTokensLength();
|
|
103
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
104
|
+
|
|
105
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance - LOCK_AMOUNT);
|
|
106
|
+
expect(newLandIndex).to.equal(currentLandIndex + 1);
|
|
107
|
+
expect(land.token).to.not.equal('0x0000000000000000000000000000000000000000');
|
|
108
|
+
expect(land.active).to.equal(true);
|
|
109
|
+
expect(land.lockAmount).to.equal(LOCK_AMOUNT);
|
|
110
|
+
expect(land.lockUser).to.equal(accountAddress);
|
|
111
|
+
expect(land.realitio).to.not.equal('0x0000000000000000000000000000000000000000');
|
|
112
|
+
}));
|
|
113
|
+
|
|
114
|
+
it('should create another Land', mochaAsync(async () => {
|
|
115
|
+
const currentLandIndex = await predictionMarketManagerContract.getLandTokensLength();
|
|
116
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
117
|
+
|
|
118
|
+
await predictionMarketManagerContract.createLand({
|
|
119
|
+
name: 'Token 2',
|
|
120
|
+
symbol: 'TOKEN2',
|
|
121
|
+
tokenAmountToClaim: TOKEN_AMOUNT_TO_CLAIM,
|
|
122
|
+
tokenToAnswer: pmmTokenContract.getAddress(),
|
|
123
|
+
});
|
|
124
|
+
const land = await predictionMarketManagerContract.getLandById({ id: currentLandIndex });
|
|
125
|
+
const newLandIndex = await predictionMarketManagerContract.getLandTokensLength();
|
|
126
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
127
|
+
|
|
128
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance - LOCK_AMOUNT);
|
|
129
|
+
expect(newLandIndex).to.equal(currentLandIndex + 1);
|
|
130
|
+
expect(land.token).to.not.equal('0x0000000000000000000000000000000000000000');
|
|
131
|
+
expect(land.active).to.equal(true);
|
|
132
|
+
expect(land.lockAmount).to.equal(LOCK_AMOUNT);
|
|
133
|
+
expect(land.lockUser).to.equal(accountAddress);
|
|
134
|
+
expect(land.realitio).to.not.equal('0x0000000000000000000000000000000000000000');
|
|
135
|
+
}));
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
context('Land Admins', async () => {
|
|
139
|
+
let landId = 0;
|
|
140
|
+
let token;
|
|
141
|
+
|
|
142
|
+
const user1 = USER1_ADDRESS;
|
|
143
|
+
const user2 = USER2_ADDRESS;
|
|
144
|
+
|
|
145
|
+
let user1App;
|
|
146
|
+
let user1PredictionMarketManagerContract;
|
|
147
|
+
|
|
148
|
+
before(mochaAsync(async () => {
|
|
149
|
+
const land = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
150
|
+
token = land.token;
|
|
151
|
+
|
|
152
|
+
user1App = new Application({
|
|
153
|
+
web3Provider: process.env.WEB3_PROVIDER,
|
|
154
|
+
web3PrivateKey: USER1_PRIVATE_KEY
|
|
155
|
+
});
|
|
156
|
+
user1PredictionMarketManagerContract = user1App.getPredictionMarketV3ManagerContract({
|
|
157
|
+
contractAddress: predictionMarketManagerContract.getAddress()
|
|
158
|
+
});
|
|
159
|
+
}));
|
|
160
|
+
|
|
161
|
+
it('should add an admin to a Land', mochaAsync(async () => {
|
|
162
|
+
const currentIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
163
|
+
await predictionMarketManagerContract.addAdminToLand({
|
|
164
|
+
token,
|
|
165
|
+
user: user2
|
|
166
|
+
});
|
|
167
|
+
const newIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
168
|
+
|
|
169
|
+
expect(currentIsAdmin).to.equal(false);
|
|
170
|
+
expect(newIsAdmin).to.equal(true);
|
|
171
|
+
}));
|
|
172
|
+
|
|
173
|
+
it('should remove an admin from a Land', mochaAsync(async () => {
|
|
174
|
+
const currentIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
175
|
+
await predictionMarketManagerContract.removeAdminFromLand({
|
|
176
|
+
token,
|
|
177
|
+
user: user2
|
|
178
|
+
});
|
|
179
|
+
const newIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
180
|
+
|
|
181
|
+
expect(currentIsAdmin).to.equal(true);
|
|
182
|
+
expect(newIsAdmin).to.equal(false);
|
|
183
|
+
}));
|
|
184
|
+
|
|
185
|
+
it('should not be able to add an admin to a Land if not an admin making the call', mochaAsync(async () => {
|
|
186
|
+
const currentIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
187
|
+
try {
|
|
188
|
+
await user1PredictionMarketManagerContract.addAdminToLand({
|
|
189
|
+
token,
|
|
190
|
+
user: user2
|
|
191
|
+
});
|
|
192
|
+
} catch(e) {
|
|
193
|
+
// not logging error, as tx is expected to fail
|
|
194
|
+
}
|
|
195
|
+
const newIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
196
|
+
|
|
197
|
+
expect(currentIsAdmin).to.equal(false);
|
|
198
|
+
expect(newIsAdmin).to.equal(false);
|
|
199
|
+
}));
|
|
200
|
+
|
|
201
|
+
it('should be able to add/remove an admin to a Land after being made admin', mochaAsync(async () => {
|
|
202
|
+
await predictionMarketManagerContract.addAdminToLand({
|
|
203
|
+
token,
|
|
204
|
+
user: user1
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const currentIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
208
|
+
await user1PredictionMarketManagerContract.addAdminToLand({
|
|
209
|
+
token,
|
|
210
|
+
user: user2
|
|
211
|
+
});
|
|
212
|
+
const newIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
213
|
+
|
|
214
|
+
expect(currentIsAdmin).to.equal(false);
|
|
215
|
+
expect(newIsAdmin).to.equal(true);
|
|
216
|
+
|
|
217
|
+
await user1PredictionMarketManagerContract.removeAdminFromLand({
|
|
218
|
+
token,
|
|
219
|
+
user: user2
|
|
220
|
+
});
|
|
221
|
+
const lastNewIsAdmin = await predictionMarketManagerContract.isLandAdmin({ token, user: user2 });
|
|
222
|
+
|
|
223
|
+
expect(lastNewIsAdmin).to.equal(false);
|
|
224
|
+
|
|
225
|
+
// resetting user1 admin status
|
|
226
|
+
await predictionMarketManagerContract.removeAdminFromLand({
|
|
227
|
+
token,
|
|
228
|
+
user: user1
|
|
229
|
+
});
|
|
230
|
+
}));
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
context('Land Disabling + Enabling + Offset', async () => {
|
|
234
|
+
let landId = 0;
|
|
235
|
+
let land;
|
|
236
|
+
let token;
|
|
237
|
+
|
|
238
|
+
let user1App;
|
|
239
|
+
let user1PredictionMarketManagerContract;
|
|
240
|
+
|
|
241
|
+
let landTokenContract;
|
|
242
|
+
|
|
243
|
+
before(mochaAsync(async () => {
|
|
244
|
+
land = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
245
|
+
landTokenContract = app.getFantasyERC20Contract({contractAddress: land.token});
|
|
246
|
+
token = land.token;
|
|
247
|
+
|
|
248
|
+
user1App = new Application({
|
|
249
|
+
web3Provider: process.env.WEB3_PROVIDER,
|
|
250
|
+
web3PrivateKey: USER1_PRIVATE_KEY
|
|
251
|
+
});
|
|
252
|
+
user1PredictionMarketManagerContract = user1App.getPredictionMarketV3ManagerContract({
|
|
253
|
+
contractAddress: predictionMarketManagerContract.getAddress()
|
|
254
|
+
});
|
|
255
|
+
}));
|
|
256
|
+
|
|
257
|
+
it('should not be able to disable a Land if not an admin making the call', mochaAsync(async () => {
|
|
258
|
+
try {
|
|
259
|
+
await user1PredictionMarketManagerContract.disableLand({
|
|
260
|
+
token
|
|
261
|
+
});
|
|
262
|
+
} catch(e) {
|
|
263
|
+
// not logging error, as tx is expected to fail
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const refreshedLand = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
267
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
268
|
+
|
|
269
|
+
expect(land.active).to.equal(true);
|
|
270
|
+
expect(refreshedLand.active).to.equal(true);
|
|
271
|
+
}));
|
|
272
|
+
|
|
273
|
+
it('should disable a Land', mochaAsync(async () => {
|
|
274
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
275
|
+
const currentPaused = await landTokenContract.paused();
|
|
276
|
+
await predictionMarketManagerContract.disableLand({
|
|
277
|
+
token: land.token
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
const refreshedLand = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
281
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
282
|
+
const newPaused = await landTokenContract.paused();
|
|
283
|
+
|
|
284
|
+
expect(land.active).to.equal(true);
|
|
285
|
+
expect(currentPaused).to.equal(false);
|
|
286
|
+
expect(newPaused).to.equal(true);
|
|
287
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance + LOCK_AMOUNT);
|
|
288
|
+
expect(refreshedLand.token).to.equal(land.token);
|
|
289
|
+
expect(refreshedLand.active).to.equal(false);
|
|
290
|
+
expect(refreshedLand.lockAmount).to.equal(0);
|
|
291
|
+
expect(refreshedLand.lockUser).to.equal('0x0000000000000000000000000000000000000000');
|
|
292
|
+
expect(refreshedLand.realitio).to.equal(land.realitio);
|
|
293
|
+
}));
|
|
294
|
+
|
|
295
|
+
it('should not be able to disable a Land if already disabled', mochaAsync(async () => {
|
|
296
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
297
|
+
try {
|
|
298
|
+
await predictionMarketManagerContract.disableLand({
|
|
299
|
+
token
|
|
300
|
+
});
|
|
301
|
+
} catch(e) {
|
|
302
|
+
// not logging error, as tx is expected to fail
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const refreshedLand = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
306
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
307
|
+
|
|
308
|
+
expect(refreshedLand.active).to.equal(false);
|
|
309
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance);
|
|
310
|
+
}));
|
|
311
|
+
|
|
312
|
+
it('should enable a Land', mochaAsync(async () => {
|
|
313
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
314
|
+
const currentPaused = await landTokenContract.paused();
|
|
315
|
+
await predictionMarketManagerContract.enableLand({
|
|
316
|
+
token: land.token
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const refreshedLand = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
320
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
321
|
+
const newPaused = await landTokenContract.paused();
|
|
322
|
+
|
|
323
|
+
expect(currentPaused).to.equal(true);
|
|
324
|
+
expect(newPaused).to.equal(false);
|
|
325
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance - LOCK_AMOUNT);
|
|
326
|
+
expect(refreshedLand.token).to.equal(land.token);
|
|
327
|
+
expect(refreshedLand.active).to.equal(true);
|
|
328
|
+
expect(refreshedLand.lockAmount).to.equal(LOCK_AMOUNT);
|
|
329
|
+
expect(refreshedLand.lockUser).to.equal(accountAddress);
|
|
330
|
+
expect(refreshedLand.realitio).to.equal(land.realitio);
|
|
331
|
+
}));
|
|
332
|
+
|
|
333
|
+
it('should be able to update lock amount if not the contract owner', mochaAsync(async () => {
|
|
334
|
+
const currentLockAmount = await predictionMarketManagerContract.lockAmount();
|
|
335
|
+
expect(currentLockAmount).to.equal(LOCK_AMOUNT);
|
|
336
|
+
|
|
337
|
+
try {
|
|
338
|
+
await user1PredictionMarketManagerContract.updateLockAmount({
|
|
339
|
+
amount: NEW_LOCK_AMOUNT,
|
|
340
|
+
});
|
|
341
|
+
} catch(e) {
|
|
342
|
+
// not logging error, as tx is expected to fail
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const newLockAmount = await predictionMarketManagerContract.lockAmount();
|
|
346
|
+
expect(newLockAmount).to.equal(LOCK_AMOUNT);
|
|
347
|
+
}));
|
|
348
|
+
|
|
349
|
+
it('should be able to update lock amount', mochaAsync(async () => {
|
|
350
|
+
const currentLockAmount = await predictionMarketManagerContract.lockAmount();
|
|
351
|
+
expect(currentLockAmount).to.equal(LOCK_AMOUNT);
|
|
352
|
+
|
|
353
|
+
await predictionMarketManagerContract.updateLockAmount({
|
|
354
|
+
amount: NEW_LOCK_AMOUNT,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
const newLockAmount = await predictionMarketManagerContract.lockAmount();
|
|
358
|
+
expect(newLockAmount).to.equal(NEW_LOCK_AMOUNT);
|
|
359
|
+
}));
|
|
360
|
+
|
|
361
|
+
it('should not be able to unlock offset from land if not an admin', mochaAsync(async () => {
|
|
362
|
+
const currentLockAmount = await predictionMarketManagerContract.lockAmount();
|
|
363
|
+
expect(currentLockAmount).to.equal(NEW_LOCK_AMOUNT);
|
|
364
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
await user1PredictionMarketManagerContract.unlockOffsetFromLand({
|
|
368
|
+
token: land.token
|
|
369
|
+
});
|
|
370
|
+
} catch(e) {
|
|
371
|
+
// not logging error, as tx is expected to fail
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const refreshedLand = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
375
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
376
|
+
|
|
377
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance);
|
|
378
|
+
expect(refreshedLand.lockAmount).to.equal(LOCK_AMOUNT);
|
|
379
|
+
}));
|
|
380
|
+
|
|
381
|
+
it('should be able to unlock offset from land', mochaAsync(async () => {
|
|
382
|
+
const currentLockAmount = await predictionMarketManagerContract.lockAmount();
|
|
383
|
+
expect(currentLockAmount).to.equal(NEW_LOCK_AMOUNT);
|
|
384
|
+
const currentPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
385
|
+
|
|
386
|
+
await predictionMarketManagerContract.unlockOffsetFromLand({
|
|
387
|
+
token: land.token
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const refreshedLand = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
391
|
+
const newPmmTokenBalance = await pmmTokenContract.balanceOf({ address: accountAddress });
|
|
392
|
+
|
|
393
|
+
expect(newPmmTokenBalance).to.equal(currentPmmTokenBalance + LOCK_AMOUNT - NEW_LOCK_AMOUNT);
|
|
394
|
+
expect(refreshedLand.lockAmount).to.equal(NEW_LOCK_AMOUNT);
|
|
395
|
+
}));
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
context('Land Markets', async () => {
|
|
400
|
+
let landId = 0;
|
|
401
|
+
let marketId = 0;
|
|
402
|
+
let outcomeId = 0;
|
|
403
|
+
let value = 0.01;
|
|
404
|
+
let land;
|
|
405
|
+
|
|
406
|
+
let user1;
|
|
407
|
+
let user1App;
|
|
408
|
+
let user1PredictionMarketContract;
|
|
409
|
+
|
|
410
|
+
let landTokenContract;
|
|
411
|
+
let user1LandTokenContract;
|
|
412
|
+
|
|
413
|
+
before(mochaAsync(async () => {
|
|
414
|
+
land = await predictionMarketManagerContract.getLandById({ id: landId });
|
|
415
|
+
|
|
416
|
+
user1 = USER1_ADDRESS;
|
|
417
|
+
user1App = new Application({
|
|
418
|
+
web3Provider: process.env.WEB3_PROVIDER,
|
|
419
|
+
web3PrivateKey: USER1_PRIVATE_KEY
|
|
420
|
+
});
|
|
421
|
+
user1PredictionMarketContract = user1App.getPredictionMarketV3Contract({
|
|
422
|
+
contractAddress: predictionMarketContract.getAddress()
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
landTokenContract = app.getFantasyERC20Contract({contractAddress: land.token});
|
|
426
|
+
user1LandTokenContract = user1App.getFantasyERC20Contract({contractAddress: land.token});
|
|
427
|
+
// approving land token to spend tokens
|
|
428
|
+
await landTokenContract.claimAndApproveTokens();
|
|
429
|
+
await user1LandTokenContract.claimAndApproveTokens();
|
|
430
|
+
}));
|
|
431
|
+
|
|
432
|
+
context('Market Creation', async () => {
|
|
433
|
+
it('should not be able to create a Market if not an admin making the call', mochaAsync(async () => {
|
|
434
|
+
const currentMarketIds = await predictionMarketContract.getMarkets();
|
|
435
|
+
const currentLandTokenBalance = await landTokenContract.balanceOf({ address: user1 });
|
|
436
|
+
expect(currentLandTokenBalance).to.equal(TOKEN_AMOUNT_TO_CLAIM);
|
|
437
|
+
|
|
438
|
+
try {
|
|
439
|
+
await user1PredictionMarketContract.mintAndCreateMarket({
|
|
440
|
+
value,
|
|
441
|
+
name: 'Will BTC price close above 100k$ on May 1st 2025',
|
|
442
|
+
description: 'This is a description',
|
|
443
|
+
image: 'foo-bar',
|
|
444
|
+
category: 'Foo;Bar',
|
|
445
|
+
oracleAddress: '0x0000000000000000000000000000000000000001', // TODO
|
|
446
|
+
duration: moment('2025-05-01').unix(),
|
|
447
|
+
outcomes: ['Yes', 'No'],
|
|
448
|
+
token: landTokenContract.getAddress(),
|
|
449
|
+
realitioAddress: land.realitio,
|
|
450
|
+
realitioTimeout: 300,
|
|
451
|
+
PM3ManagerAddress: predictionMarketManagerContract.getAddress()
|
|
452
|
+
});
|
|
453
|
+
} catch(e) {
|
|
454
|
+
// not logging error, as tx is expected to fail
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
const newMarketIds = await predictionMarketContract.getMarkets();
|
|
458
|
+
expect(newMarketIds.length).to.equal(currentMarketIds.length);
|
|
459
|
+
}));
|
|
460
|
+
|
|
461
|
+
it('should create a Market', mochaAsync(async () => {
|
|
462
|
+
const currentMarketIds = await predictionMarketContract.getMarkets();
|
|
463
|
+
const currentLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
464
|
+
expect(currentLandTokenBalance).to.equal(TOKEN_AMOUNT_TO_CLAIM);
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
const res = await predictionMarketContract.mintAndCreateMarket({
|
|
468
|
+
value,
|
|
469
|
+
name: 'Will BTC price close above 100k$ on May 1st 2025',
|
|
470
|
+
description: 'This is a description',
|
|
471
|
+
image: 'foo-bar',
|
|
472
|
+
category: 'Foo;Bar',
|
|
473
|
+
oracleAddress: '0x0000000000000000000000000000000000000001', // TODO
|
|
474
|
+
duration: moment('2025-05-01').unix(),
|
|
475
|
+
outcomes: ['Yes', 'No'],
|
|
476
|
+
token: landTokenContract.getAddress(),
|
|
477
|
+
realitioAddress: land.realitio,
|
|
478
|
+
realitioTimeout: 300,
|
|
479
|
+
PM3ManagerAddress: predictionMarketManagerContract.getAddress()
|
|
480
|
+
});
|
|
481
|
+
expect(res.status).to.equal(true);
|
|
482
|
+
} catch(e) {
|
|
483
|
+
console.log(e);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const newLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
487
|
+
const newMarketIds = await predictionMarketContract.getMarkets();
|
|
488
|
+
expect(newMarketIds.length).to.equal(currentMarketIds.length + 1);
|
|
489
|
+
// balance remains the same since tokens were minted
|
|
490
|
+
expect(newLandTokenBalance).to.equal(currentLandTokenBalance);
|
|
491
|
+
}));
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
context('Market Interaction', async () => {
|
|
495
|
+
it('should be able to buy shares when land enabled', mochaAsync(async () => {
|
|
496
|
+
const minOutcomeSharesToBuy = 0.015;
|
|
497
|
+
const currentLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
498
|
+
|
|
499
|
+
try {
|
|
500
|
+
const res = await predictionMarketContract.buy({marketId, outcomeId, value, minOutcomeSharesToBuy});
|
|
501
|
+
expect(res.status).to.equal(true);
|
|
502
|
+
} catch(e) {
|
|
503
|
+
console.log(e);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const newLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
507
|
+
const amountTransferred = Number((currentLandTokenBalance - newLandTokenBalance).toFixed(5));
|
|
508
|
+
|
|
509
|
+
expect(amountTransferred).to.equal(value);
|
|
510
|
+
}));
|
|
511
|
+
|
|
512
|
+
it('should sell outcome shares', mochaAsync(async () => {
|
|
513
|
+
const outcomeId = 0;
|
|
514
|
+
const maxOutcomeSharesToSell = 0.015;
|
|
515
|
+
|
|
516
|
+
const currentLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
517
|
+
|
|
518
|
+
try {
|
|
519
|
+
const res = await predictionMarketContract.sell({marketId, outcomeId, value, maxOutcomeSharesToSell});
|
|
520
|
+
expect(res.status).to.equal(true);
|
|
521
|
+
} catch(e) {
|
|
522
|
+
console.log(e);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
const newLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
526
|
+
const amountTransferred = Number((newLandTokenBalance - currentLandTokenBalance).toFixed(5));
|
|
527
|
+
|
|
528
|
+
expect(amountTransferred).to.equal(value);
|
|
529
|
+
}));
|
|
530
|
+
|
|
531
|
+
it('should not be able to buy shares when land disabled', mochaAsync(async () => {
|
|
532
|
+
const minOutcomeSharesToBuy = 0.015;
|
|
533
|
+
const currentLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
534
|
+
|
|
535
|
+
await predictionMarketManagerContract.disableLand({
|
|
536
|
+
token: land.token
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
try {
|
|
540
|
+
const res = await predictionMarketContract.buy({marketId, outcomeId, value, minOutcomeSharesToBuy});
|
|
541
|
+
expect(res.status).to.equal(true);
|
|
542
|
+
} catch(e) {
|
|
543
|
+
// not logging error, as tx is expected to fail
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const newLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
547
|
+
const amountTransferred = currentLandTokenBalance - newLandTokenBalance;
|
|
548
|
+
|
|
549
|
+
expect(amountTransferred).to.equal(0);
|
|
550
|
+
}));
|
|
551
|
+
|
|
552
|
+
it('should be able to buy shares when land enabled again', mochaAsync(async () => {
|
|
553
|
+
const minOutcomeSharesToBuy = 0.015;
|
|
554
|
+
const currentLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
555
|
+
|
|
556
|
+
await predictionMarketManagerContract.enableLand({
|
|
557
|
+
token: land.token
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
try {
|
|
561
|
+
const res = await predictionMarketContract.buy({marketId, outcomeId, value, minOutcomeSharesToBuy});
|
|
562
|
+
expect(res.status).to.equal(true);
|
|
563
|
+
} catch(e) {
|
|
564
|
+
console.log(e);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const newLandTokenBalance = await landTokenContract.balanceOf({ address: accountAddress });
|
|
568
|
+
const amountTransferred = Number((currentLandTokenBalance - newLandTokenBalance).toFixed(5));
|
|
569
|
+
|
|
570
|
+
expect(amountTransferred).to.equal(value);
|
|
571
|
+
}));
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
context('Market Resolution', async () => {
|
|
575
|
+
let outcomeId = 1;
|
|
576
|
+
|
|
577
|
+
it('should not be able to resolve a Market if not an admin making the call', mochaAsync(async () => {
|
|
578
|
+
try {
|
|
579
|
+
await user1PredictionMarketContract.adminResolveMarketOutcome({
|
|
580
|
+
marketId,
|
|
581
|
+
outcomeId
|
|
582
|
+
});
|
|
583
|
+
} catch(e) {
|
|
584
|
+
// not logging error, as tx is expected to fail
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const market = await predictionMarketContract.getMarketData({ marketId });
|
|
588
|
+
expect(market.state).to.equal(0);
|
|
589
|
+
}));
|
|
590
|
+
|
|
591
|
+
it('should be able to resolve a Market', mochaAsync(async () => {
|
|
592
|
+
try {
|
|
593
|
+
const res = await predictionMarketContract.adminResolveMarketOutcome({
|
|
594
|
+
marketId,
|
|
595
|
+
outcomeId
|
|
596
|
+
});
|
|
597
|
+
expect(res.status).to.equal(true);
|
|
598
|
+
} catch(e) {
|
|
599
|
+
console.log(e);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// doing dummy transaction to get the latest block
|
|
603
|
+
await landTokenContract.approve({ address: '0x000000000000000000000000000000000000dead', amount: 0 });
|
|
604
|
+
|
|
605
|
+
const market = await predictionMarketContract.getMarketData({ marketId });
|
|
606
|
+
expect(market.state).to.equal(2);
|
|
607
|
+
}));
|
|
608
|
+
});
|
|
609
|
+
});
|
|
610
|
+
});
|
package/tests/utils.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const mochaAsync = (fn) => {
|
|
2
|
+
return done => {
|
|
3
|
+
fn.call().then(done, err => {
|
|
4
|
+
done(err);
|
|
5
|
+
});
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const detectValidationErrors = (res) => {
|
|
10
|
+
if (res.message == 'Validation errors') {
|
|
11
|
+
console.log(res.errors[0]);
|
|
12
|
+
return true;
|
|
13
|
+
} else {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|