polkamarkets-js 3.4.2 → 3.4.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polkamarkets-js",
3
- "version": "3.4.2",
3
+ "version": "3.4.3",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -0,0 +1,29 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ // Import your contracts here
7
+ import {PredictionMarketV3Manager} from "../contracts/PredictionMarketV3Manager.sol";
8
+ import {PredictionMarketV3_4} from "../contracts/PredictionMarketV3_4.sol";
9
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
10
+
11
+ contract AddAdminToLand is Script {
12
+ function run() public {
13
+ vm.startBroadcast();
14
+
15
+ address PREDICTION_MARKET_V3_MANAGER = address(0xBC39fa757886E8A56422Abc460b1FFfc70bbaeC6);
16
+ address PREDICTION_MARKET_V3 = address(0x39E66eE6b2ddaf4DEfDEd3038E0162180dbeF340);
17
+ address LAND_TOKEN = address(0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d);
18
+ address admin = address(0xAE7Bfff784EeEe7812D6527B72c77A7Ed773Ed9D);
19
+
20
+ // PredictionMarketV3_4(payable(PREDICTION_MARKET_V3)).setAllowedManager(PREDICTION_MARKET_V3_MANAGER, true);
21
+
22
+ PredictionMarketV3Manager(PREDICTION_MARKET_V3_MANAGER).addAdminToLand(
23
+ IERC20(LAND_TOKEN),
24
+ admin
25
+ );
26
+
27
+ vm.stopBroadcast();
28
+ }
29
+ }
@@ -0,0 +1,34 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {MerkleRewardsDistributor} from "../contracts/MerkleRewardsDistributor.sol";
7
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
+
9
+ contract ClaimMerkleRoot is Script {
10
+ function run() public {
11
+ vm.startBroadcast();
12
+
13
+ MerkleRewardsDistributor distributor = MerkleRewardsDistributor(address(0x846BBEF1e62c211a16fD3F4Cd15C54B010D85036));
14
+ IERC20 token = IERC20(address(0xf74B14ecbAdC9fBb283Fb3c8ae11E186856eae6f));
15
+ string memory contestId = "7663c7a6-5c93-40e2-9de7-21a821d363e3";
16
+ uint256 index = 4;
17
+ address account = address(0x68FcB3Db1BA4Abb85D9f9420A110948e6459d613);
18
+ uint256 amount = 200000;
19
+ bytes32[] memory merkleProof = new bytes32[](2);
20
+ merkleProof[0] = bytes32(0x7c0e1af482e345503812141a5583c24adcfb9304cd8674e2d55b875e1ec27fdc);
21
+ merkleProof[1] = bytes32(0x995dc3a28d8b8bcf31a29435a588bfcea38841d36509f285b0ea606c0ee574bf);
22
+
23
+ distributor.claim(
24
+ contestId,
25
+ IERC20(address(token)),
26
+ index,
27
+ account,
28
+ amount,
29
+ merkleProof
30
+ );
31
+
32
+ vm.stopBroadcast();
33
+ }
34
+ }
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ // Import your contracts here
7
+ import {PredictionMarketV3Manager} from "../contracts/PredictionMarketV3Manager.sol";
8
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9
+
10
+ contract CreateLand is Script {
11
+ function run() public {
12
+
13
+ vm.startBroadcast();
14
+
15
+ address PREDICTION_MARKET_V3_MANAGER = address(0xBC39fa757886E8A56422Abc460b1FFfc70bbaeC6);
16
+ address ADMIN_TOKEN = address(0x307893b1d9F2F6AF097310Ef6E49b90bc5a2Ee3d);
17
+ address LAND_TOKEN = address(0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d);
18
+
19
+ // IERC20(ADMIN_TOKEN).approve(PREDICTION_MARKET_V3_MANAGER, 1000 ether);
20
+
21
+ PredictionMarketV3Manager(PREDICTION_MARKET_V3_MANAGER).createLand(
22
+ IERC20(LAND_TOKEN),
23
+ IERC20(ADMIN_TOKEN)
24
+ );
25
+
26
+ vm.stopBroadcast();
27
+ }
28
+ }
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {PredictionMarketV3_4} from "../contracts/PredictionMarketV3_4.sol";
7
+ import {IPredictionMarketV3Manager} from "../contracts/IPredictionMarketV3Manager.sol";
8
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9
+
10
+ contract CreateMarkets is Script {
11
+ function run() public {
12
+
13
+ vm.startBroadcast();
14
+
15
+ address predictionMarket = address(0xb5625db4777262460589724693e6E032999FCCd5);
16
+ address manager = address(0x47b5E2Ef0B3e79b6f5432d983731c04855121796);
17
+ address arbitrator = address(0x68FcB3Db1BA4Abb85D9f9420A110948e6459d613);
18
+ address treasury = address(0x68FcB3Db1BA4Abb85D9f9420A110948e6459d613);
19
+ address distributor = address(0x68FcB3Db1BA4Abb85D9f9420A110948e6459d613);
20
+ uint256[] memory distribution = new uint256[](2);
21
+ distribution[0] = 100e6;
22
+ distribution[1] = 100e6;
23
+
24
+ // uint256 value = 1000000000000000000000;
25
+ // address token = address(0xAe86Ea629FB0454bEA8EC9Da19c1b4b3d0c9Ac41);
26
+ // uint256 fee = 0;
27
+
28
+ uint256 value = 1000 ether;
29
+ address token = address(0x49Ff827F0C8835ebd8109Cc3b51b80435ce44F09);
30
+ uint256 fee = 1e16;
31
+
32
+ // IERC20(token).approve(predictionMarket, 10000000 ether);
33
+ // PredictionMarketV3_4(payable(predictionMarket)).setAllowedManager(manager, true);
34
+
35
+ PredictionMarketV3_4(payable(predictionMarket)).createMarket(PredictionMarketV3_4.CreateMarketDescription({
36
+ value: value,
37
+ closesAt: 1765029602,
38
+ outcomes: 2,
39
+ token: IERC20(token),
40
+ distribution: distribution,
41
+ question: unicode"Will Oscar Piastri win the F1 Drivers Championship 2025?;The “Lando era” became the Oscar show—but can the rising star hold his nerve and beat Lando and Max to his first Drivers Championship?\\n\\n**Market dates:**\\n\\n- **Market Period**: From the publication date through December 6th, 2025, at 02:00 PM UTC\\n- **Market Closing:** December 6th, 2025, at 02:00 PM UTC ahead of the last race\\n- **Resolution Deadline:** This market will resolve based on the official race results published by Formula 1 after the publication of the results of the last race, or earlier if the outcome is reached. The resolution may be delayed if there are any announced investigations that could impact points-scoring positions\\n\\n**Resolution criteria:**\\n\\n- This market resolves to “Yes” if Oscar Piastri wins the Drivers Championship of Formula 1 in 2025.\\n- This market resolves to “No” if Oscar Piastri doesn’t win the Drivers Championship of Formula 1 in 2025\\n\\n**Cancellation/Invalidity details:**\\n\\nThis market will be cancelled if:\\n\\n- The 2025 Formula 1 season is cancelled or postponed indefinitely\\n- The racing format of the 2025 Formula 1 season changes significantly from the standard format\\n- No official result is declared\\n- The resolution source becomes unavailable for large period of the market period\\n\\nIn the event of cancellation, participants may claim their stakes at the market value of their open positions at the time of cancellation. This could result in a profit or a loss, depending on the price of their outstanding shares.␟\"Yes\",\"No\"␟Sports,F1;;https://www.formula1.com/en/results/2025/drivers;Formula 1␟",
42
+ image: unicode"␟QmWvnfTtJNLCiJTPDZwVVXq2QAt9RN5gCWCWwpxDg8GsVL,",
43
+ arbitrator: arbitrator,
44
+ buyFees: PredictionMarketV3_4.Fees({fee: fee, treasuryFee: fee, distributorFee: fee}),
45
+ sellFees: PredictionMarketV3_4.Fees({fee: 0, treasuryFee: 0, distributorFee: 0}),
46
+ treasury: treasury,
47
+ distributor: distributor,
48
+ realitioTimeout: 3600,
49
+ manager: IPredictionMarketV3Manager(manager)
50
+ }));
51
+
52
+ PredictionMarketV3_4(payable(predictionMarket)).createMarket(PredictionMarketV3_4.CreateMarketDescription({
53
+ value: value,
54
+ closesAt: 1767225542,
55
+ outcomes: 2,
56
+ token: IERC20(token),
57
+ distribution: distribution,
58
+ question: unicode"Bitcoin’s next hit: moon to $150K or dip to $50K?;**Market dates:**\\n\\n- **Market Period**: From the publication date through December 31st, 2025, at 11:59 PM UTC\\n- **Market Closing:** December 31st, 2025, at 11:59 PM UTC\\n- **Resolution Deadline:** The resolution will be determined after market closing, or earlier if the outcome is reached\\n\\n**Resolution criteria:**\\n\\n- The market resolves based on which condition is met first:\\n - **“≥ $150K”** if the BTC/USDT price on Binance reaches or exceeds $150,000.00\\n - **“≤ $50K”** if the BTC/USDT price on Binance drops to or below $50,000.00\\n\\n**Resolution details:**\\n\\n- The market resolves based on the Binance BTC/USDT spot price, using the 1-minute chart with the following specifications:\\n - 1-minute timeframe (\\\"1m\\\")\\n - \\\"Original\\\" view\\n - \\\"Close\\\" price of each candle\\n- Only the price of BTC/USDT as quoted by Binance (spot market) will be considered\\n\\n**Cancellation (Invalidity) Conditions**\\n\\nThis market will be **canceled/invalid** if:\\n\\n- The BTC/USDT spot price on Binance doesn’t reach either one of the two options until market close.\\n- The BTC/USDT spot market on Binance is suspended or becomes unreliable\\n- The Binance platform is unavailable or experiences significant disruptions during the Market Period\\n- Any circumstance prevents reliable price tracking during the Market Period\\n\\nIn the event of cancellation, participants may claim their stakes at the market value of their open positions at the time of cancellation. This could result in a profit or a loss, depending on the price of their outstanding shares.␟\"≥ $150K\",\"≤ $50K\"␟Crypto;;https://www.binance.com/en/trade/BTC_USDT?type=spot;Binance␟",
59
+ image: unicode"␟QmdWFkhqiUX3XxwFBMGP749Wpx1Y44KAqqCuhpnCzap7cg,",
60
+ arbitrator: arbitrator,
61
+ buyFees: PredictionMarketV3_4.Fees({fee: fee, treasuryFee: fee, distributorFee: fee}),
62
+ sellFees: PredictionMarketV3_4.Fees({fee: 0, treasuryFee: 0, distributorFee: 0}),
63
+ treasury: treasury,
64
+ distributor: distributor,
65
+ realitioTimeout: 3600,
66
+ manager: IPredictionMarketV3Manager(manager)
67
+ }));
68
+
69
+ vm.stopBroadcast();
70
+ }
71
+ }
@@ -0,0 +1,94 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ // Import your contracts here
7
+ import {PredictionMarketV3_4, IWETH} from "../contracts/PredictionMarketV3_4.sol";
8
+ import {PredictionMarketV3Manager} from "../contracts/PredictionMarketV3Manager.sol";
9
+ import {PredictionMarketV3Querier} from "../contracts/PredictionMarketV3Querier.sol";
10
+ import {IPredictionMarketV3Manager} from "../contracts/IPredictionMarketV3Manager.sol";
11
+ import {IPredictionMarketV3_4} from "../contracts/IPredictionMarketV3_4.sol";
12
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
13
+ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
14
+ import {RealityETH_ERC20_v3_0} from "@reality.eth/contracts/development/contracts/RealityETH_ERC20-3.0.sol";
15
+ import {ERC20MinterPauser} from "../contracts/ERC20MinterPauser.sol";
16
+ import {IRealityETH_ERC20} from "../contracts/IRealityETH_ERC20.sol";
17
+
18
+ contract DeployContracts is Script {
19
+ function run() public {
20
+ vm.startBroadcast();
21
+
22
+ address TOKEN = address(0x0);
23
+ address admin = address(0x0a70f6F09caa802D8d62dE9C7EdacE1d3b5Ca160);
24
+ address self = address(0x7C0F97fb24E8712E97285C7Ba7527ed6d0eb6995);
25
+ address WETH = address(0x0);
26
+ address REALITIO = address(0x0);
27
+ address PREDICTION_MARKET_V3_MANAGER = address(0x0);
28
+ address PREDICTION_MARKET_V3_QUERIER = address(0x0);
29
+ address payable PREDICTION_MARKET_V3_4 = payable(address(0x0));
30
+
31
+ // self transfer 0 ETH to trigger dummy transaction
32
+ // payable(self).transfer(0 ether);
33
+ // payable(self).transfer(0 ether);
34
+ // payable(self).transfer(0 ether);
35
+ // payable(self).transfer(0 ether);
36
+ // payable(self).transfer(0 ether);
37
+ // payable(self).transfer(0 ether);
38
+ // payable(self).transfer(0 ether);
39
+ // payable(self).transfer(0 ether);
40
+
41
+ // deploy PredictionMarketV3_4
42
+ PredictionMarketV3_4 impl = new PredictionMarketV3_4();
43
+ console.log("Implementation deployed at:", address(impl));
44
+
45
+ // Show initialization data for manual proxy deployment
46
+ bytes memory initData = abi.encodeCall(PredictionMarketV3_4.initialize, (IWETH(WETH), admin));
47
+ console.log("Initialization data for proxy:");
48
+ console.logBytes(initData);
49
+
50
+ console.log("\nFor proxy deployment, use OpenZeppelin's ERC1967Proxy:");
51
+ console.log("new ERC1967Proxy(", vm.toString(address(impl)), ", initData)");
52
+
53
+ ERC1967Proxy proxy = new ERC1967Proxy(
54
+ address(impl),
55
+ initData
56
+ );
57
+
58
+ console.log("PredictionMarketV3_4 deployed at:", address(proxy));
59
+ PREDICTION_MARKET_V3_4 = payable(address(proxy));
60
+
61
+ // deploy PredictionMarketV3Querier
62
+ PredictionMarketV3Querier querier = new PredictionMarketV3Querier(IPredictionMarketV3_4(PREDICTION_MARKET_V3_4));
63
+ console.log("PredictionMarketV3Querier deployed at:", address(querier));
64
+ PREDICTION_MARKET_V3_QUERIER = address(querier);
65
+
66
+ // deploy TOKEN
67
+ ERC20MinterPauser token = new ERC20MinterPauser("Myriad Cure", "MYRCURE");
68
+ console.log("TOKEN deployed at:", address(token));
69
+ TOKEN = address(token);
70
+ token.mint(admin, 10000000000000000000);
71
+
72
+ // deploy RealityETH_ERC20
73
+ RealityETH_ERC20_v3_0 realitio = new RealityETH_ERC20_v3_0();
74
+ console.log("RealityETH_ERC20 deployed at:", address(realitio));
75
+ IRealityETH_ERC20(address(realitio)).setToken(address(TOKEN));
76
+ REALITIO = address(realitio);
77
+
78
+ // deploy PredictionMarketV3_4Manager
79
+ PredictionMarketV3Manager manager = new PredictionMarketV3Manager(
80
+ PREDICTION_MARKET_V3_4,
81
+ IERC20(TOKEN),
82
+ 1 ether,
83
+ address(REALITIO),
84
+ admin
85
+ );
86
+ console.log("PredictionMarketV3Manager deployed at:", address(manager));
87
+ PREDICTION_MARKET_V3_MANAGER = address(manager);
88
+
89
+ // IERC20(TOKEN).approve(PREDICTION_MARKET_V3_MANAGER, 1000 ether);
90
+ // PredictionMarketV3_4(PREDICTION_MARKET_V3_4).setAllowedManager(PREDICTION_MARKET_V3_MANAGER, true);
91
+
92
+ vm.stopBroadcast();
93
+ }
94
+ }
@@ -0,0 +1,27 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {MerkleRewardsDistributor} from "../contracts/MerkleRewardsDistributor.sol";
7
+ import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
8
+
9
+ contract DeployMerkleRewardsDistributor is Script {
10
+ function run() public {
11
+ vm.startBroadcast();
12
+
13
+ address admin = address(0xAE7Bfff784EeEe7812D6527B72c77A7Ed773Ed9D);
14
+
15
+ // it's a proxy
16
+ address implementation = address(new MerkleRewardsDistributor());
17
+ bytes memory initData = abi.encodeCall(MerkleRewardsDistributor.initialize, (admin));
18
+ console.log("Initialization data for proxy:");
19
+ console.logBytes(initData);
20
+
21
+ ERC1967Proxy proxy = new ERC1967Proxy(implementation, initData);
22
+ MerkleRewardsDistributor distributor = MerkleRewardsDistributor(address(proxy));
23
+ console.log("MerkleRewardsDistributor deployed at:", address(distributor));
24
+
25
+ vm.stopBroadcast();
26
+ }
27
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {ERC20MinterPauser} from "../contracts/ERC20MinterPauser.sol";
7
+
8
+ contract DeployToken is Script {
9
+ function run() public {
10
+ vm.startBroadcast();
11
+
12
+ ERC20MinterPauser token = new ERC20MinterPauser("Myriad Cure", "MYRCURE");
13
+ console.log("Token deployed at:", address(token));
14
+
15
+ vm.stopBroadcast();
16
+ }
17
+ }
@@ -0,0 +1,24 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {ERC20MinterPauser} from "../contracts/ERC20MinterPauser.sol";
6
+
7
+ contract USDT is ERC20MinterPauser {
8
+ constructor(string memory _name, string memory _symbol) ERC20MinterPauser(_name, _symbol) {}
9
+
10
+ function decimals() public pure override returns (uint8) {
11
+ return 18;
12
+ }
13
+ }
14
+
15
+
16
+ contract DeployUSDT is Script {
17
+ function run() public {
18
+ vm.startBroadcast();
19
+
20
+ new USDT("Tether USD", "USDT");
21
+
22
+ vm.stopBroadcast();
23
+ }
24
+ }
@@ -0,0 +1,21 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {ERC20MinterPauser} from "../contracts/ERC20MinterPauser.sol";
7
+
8
+ contract MintTokens is Script {
9
+ function run() public {
10
+ vm.startBroadcast();
11
+
12
+ address token = address(0x54eC4711c4a429D7b0466dd169079f276a868462);
13
+ address user = address(0x68FcB3Db1BA4Abb85D9f9420A110948e6459d613);
14
+ uint256 amount = 1000000000000000000000000;
15
+
16
+ ERC20MinterPauser(token).mint(user, amount);
17
+ console.log("Tokens minted to:", user);
18
+
19
+ vm.stopBroadcast();
20
+ }
21
+ }
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {MerkleRewardsDistributor} from "../contracts/MerkleRewardsDistributor.sol";
7
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
+
9
+ contract PublishMerkleRoot is Script {
10
+ function run() public {
11
+ vm.startBroadcast();
12
+
13
+ MerkleRewardsDistributor distributor = MerkleRewardsDistributor(address(0x846BBEF1e62c211a16fD3F4Cd15C54B010D85036));
14
+ IERC20 token = IERC20(address(0xf74B14ecbAdC9fBb283Fb3c8ae11E186856eae6f));
15
+ bytes32 root = bytes32(0x07b1c91af93eaf54d8cf1644d632ddee695267f4044167b88842e90be3e4878e);
16
+ string memory contestId = "55d2ca19-fee9-4320-a7c6-aea620ba7588";
17
+
18
+ string[5] memory contestIds = [
19
+ "8c8f733c-ecca-4a8b-8ce9-a1208f04de2a",
20
+ "4f29b3d5-097a-404c-9014-9e5ba7cb38a0",
21
+ "1577b57f-e763-4d07-8c58-56d36a49563e",
22
+ "9fbcd4d2-3fb3-4c0b-9fcd-82e7604d1673",
23
+ "b72746ec-8046-4ae5-9a34-92270ab6c3f7"
24
+ ];
25
+
26
+ bytes32[5] memory roots = [
27
+ bytes32(0x29512536af9410dc44a47a16eeff9e65ebb3e05fd5c8369c2dfa59a5bee9e2ac),
28
+ bytes32(0x66af758212a3c1ee876654b4e354908f57caf337178f3895dcc059e2b507ee83),
29
+ bytes32(0x8d022151e97cfb76f08c309f24d13bea76d1f2d7d81c38f46c49d1584912f988),
30
+ bytes32(0x1936d0d67853de21b9f4bd6f369c545e77b63c98596e95d61306f1ac1c0848f9),
31
+ bytes32(0xe84504014594f44045abdb598af6253ac00d41f3da59002dcaa7fd4d3acaaf40)
32
+ ];
33
+
34
+ for (uint256 i = 0; i < contestIds.length; i++) {
35
+ distributor.publishRoot(
36
+ contestIds[i],
37
+ IERC20(address(token)),
38
+ roots[i]
39
+ );
40
+ }
41
+
42
+ // distributor.publishRoot(
43
+ // contestId,
44
+ // IERC20(address(token)),
45
+ // root
46
+ // );
47
+
48
+ vm.stopBroadcast();
49
+ }
50
+ }
@@ -0,0 +1,23 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {PredictionMarketV3_4} from "../contracts/PredictionMarketV3_4.sol";
7
+ import {IPredictionMarketV3Manager} from "../contracts/IPredictionMarketV3Manager.sol";
8
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9
+
10
+ contract ResolveMarket is Script {
11
+ function run() public {
12
+ vm.startBroadcast();
13
+
14
+ address predictionMarket = address(0x289E3908ECDc3c8CcceC5b6801E758549846Ab19);
15
+ uint256 marketId = 5;
16
+ uint256 outcomeId = 0;
17
+
18
+ PredictionMarketV3_4(payable(predictionMarket)).adminResolveMarketOutcome(
19
+ marketId,
20
+ outcomeId
21
+ );
22
+ }
23
+ }
@@ -0,0 +1,28 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ import {PredictionMarketV3_4} from "../contracts/PredictionMarketV3_4.sol";
7
+ import {IPredictionMarketV3Manager} from "../contracts/IPredictionMarketV3Manager.sol";
8
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
9
+
10
+ contract TradeMarket is Script {
11
+ function run() public {
12
+ vm.startBroadcast();
13
+
14
+ address predictionMarket = address(0x289E3908ECDc3c8CcceC5b6801E758549846Ab19);
15
+ uint256 marketId = 4;
16
+ uint256 outcomeId = 0;
17
+ uint256 minOutcomeSharesToBuy = 1;
18
+ uint256 amount = 1000000;
19
+
20
+ // PredictionMarketV3_4(payable(predictionMarket)).buy(
21
+ // marketId,
22
+ // outcomeId,
23
+ // minOutcomeSharesToBuy,
24
+ // amount
25
+ // );
26
+ PredictionMarketV3_4(payable(predictionMarket)).addLiquidity(marketId, amount, 0);
27
+ }
28
+ }
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: GPL-2.0
2
+ pragma solidity ^0.8.26;
3
+
4
+ import {Script} from "forge-std/Script.sol";
5
+ import {console} from "forge-std/console.sol";
6
+ // Import your contracts here
7
+ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
8
+ import {PredictionMarketV3_3, IWETH} from "../contracts/PredictionMarketV3_3.sol";
9
+ import {IPredictionMarketV3Manager} from "../contracts/IPredictionMarketV3Manager.sol";
10
+ import {PredictionMarketV3Manager, FantasyERC20} from "../contracts/PredictionMarketV3Manager.sol";
11
+ import {IRealityETH_ERC20} from "../contracts/IRealityETH_ERC20.sol";
12
+
13
+ contract UpdateMarket is Script {
14
+ function run() public {
15
+
16
+ vm.startBroadcast();
17
+
18
+ address payable PREDICTION_MARKET_V3_3 = payable(address(0x3e0F5F8F5Fb043aBFA475C0308417Bf72c463289));
19
+ address PREDICTION_MARKET_V3_MANAGER = address(0x68dDc91CCC06e63d74905D901A30edEA7C77EebE);
20
+
21
+ PredictionMarketV3_3.MarketState state = PredictionMarketV3_3(PREDICTION_MARKET_V3_3).getMarketState(486);
22
+ console2.log("state: ", state);
23
+
24
+ PredictionMarketV3_3.MarketUpdateDescription memory description = PredictionMarketV3_3.MarketUpdateDescription({
25
+ closesAtTimestamp: 1762066800,
26
+ balance: 456538064447348172635074428,
27
+ liquidity: 120000000000000000000000000,
28
+ sharesAvailable: 1272835104225672313766121101,
29
+ state: PredictionMarketV3_3.MarketState.open,
30
+ resolution: PredictionMarketV3_3.MarketResolution({
31
+ resolved: false,
32
+ realitio: IRealityETH_ERC20(0x71D76Ff3C2729071B2c52A667197d9f715029F2c),
33
+ outcomeId: 115792089237316195423570985008687907853269984665640564039457584007913129639935,
34
+ questionId: 0x21d6c6c195572d82a7d0a7ba677251dfd3839b21e09df9b39ae36ec99fa6744d,
35
+ realitioTimeout: 3600
36
+ }),
37
+ feesPoolWeight: 0,
38
+ feesTreasury: address(0xBc30e9765Dc8c735206c76DE96d369754eBbcc1f),
39
+ feesDistributor: address(0xBc30e9765Dc8c735206c76DE96d369754eBbcc1f),
40
+ buyFees: PredictionMarketV3_3.Fees({fee: 0, treasuryFee: 0, distributorFee: 0}),
41
+ sellFees: PredictionMarketV3_3.Fees({fee: 0, treasuryFee: 0, distributorFee: 0}),
42
+ outcomeCount: 5,
43
+ token: IERC20(0x0b07cf011B6e2b7E0803b892d97f751659940F23),
44
+ manager: IPredictionMarketV3Manager(0x2EbD002d755bdFadb9e5549aA00a80bd7fa408AE),
45
+ creator: address(0xBc30e9765Dc8c735206c76DE96d369754eBbcc1f),
46
+ paused: false
47
+ });
48
+
49
+ PredictionMarketV3_3(PREDICTION_MARKET_V3_3).updateMarket(486, description);
50
+ PredictionMarketV3_3(PREDICTION_MARKET_V3_3).updateMarketResolution(486, description);
51
+
52
+ state = PredictionMarketV3_3(PREDICTION_MARKET_V3_3).getMarketState(486);
53
+ console2.log("new state: ", state);
54
+ }
55
+ }
@@ -0,0 +1,57 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const outDir = path.join(__dirname, '../out');
5
+ const abisDir = path.join(__dirname, '../abis');
6
+
7
+ // Ensure abis directory exists
8
+ if (!fs.existsSync(abisDir)) {
9
+ fs.mkdirSync(abisDir, { recursive: true });
10
+ }
11
+
12
+ // Copy ABIs from out/ to abis/
13
+ function copyAbis() {
14
+ if (!fs.existsSync(outDir)) {
15
+ console.log('❌ /out directory not found. Run "forge build" first.');
16
+ process.exit(1);
17
+ }
18
+
19
+ const contracts = fs.readdirSync(outDir);
20
+ let copiedCount = 0;
21
+
22
+ contracts.forEach(contract => {
23
+ if (contract.endsWith('.sol')) {
24
+ const contractDir = path.join(outDir, contract);
25
+
26
+ if (fs.statSync(contractDir).isDirectory()) {
27
+ const contractFiles = fs.readdirSync(contractDir);
28
+
29
+ contractFiles.forEach(file => {
30
+ if (file.endsWith('.json')) {
31
+ try {
32
+ const sourcePath = path.join(contractDir, file);
33
+ const destPath = path.join(abisDir, file);
34
+
35
+ const contractData = JSON.parse(fs.readFileSync(sourcePath, 'utf8'));
36
+
37
+ // Extract only ABI (minified)
38
+ const abiData = {
39
+ abi: contractData.abi || []
40
+ };
41
+
42
+ fs.writeFileSync(destPath, JSON.stringify(abiData));
43
+ copiedCount++;
44
+ console.log(`✅ Copied ${file}`);
45
+ } catch (error) {
46
+ console.log(`⚠️ Failed to copy ${file}:`, error.message);
47
+ }
48
+ }
49
+ });
50
+ }
51
+ }
52
+ });
53
+
54
+ console.log(`\n🎉 Successfully copied ${copiedCount} contract ABIs to /abis directory`);
55
+ }
56
+
57
+ copyAbis();
@@ -37,6 +37,7 @@ class Application {
37
37
  web3EventsProvider,
38
38
  gasPrice,
39
39
  isSocialLogin = false,
40
+ useGaslessTransactions,
40
41
  socialLoginParams,
41
42
  startBlock,
42
43
  defaultDecimals,
@@ -48,6 +49,8 @@ class Application {
48
49
  // fixed gas price for txs (optional)
49
50
  this.gasPrice = gasPrice;
50
51
  this.isSocialLogin = isSocialLogin;
52
+ // If useGaslessTransactions is not explicitly set, default to true when isSocialLogin is true, otherwise false (backwards compatibility)
53
+ this.useGaslessTransactions = useGaslessTransactions !== undefined ? useGaslessTransactions : isSocialLogin;
51
54
  this.startBlock = startBlock;
52
55
  this.defaultDecimals = defaultDecimals;
53
56
  // use DualProvider to separate read (HttpProvider) and write (window.ethereum) operations
@@ -91,6 +94,8 @@ class Application {
91
94
  /**
92
95
  * @name login
93
96
  * @description Login with Metamask or a web3 provider
97
+ * @param {Object} provider
98
+ * @param {Boolean} isConnectedWallet
94
99
  */
95
100
  async login(provider = null, isConnectedWallet = null) {
96
101
  if (this.isSocialLogin) {
@@ -98,9 +103,14 @@ class Application {
98
103
  this.smartAccount = PolkamarketsSmartAccount.singleton.getInstanceIfExists()
99
104
  }
100
105
 
101
- if ((!this.smartAccount || !this.smartAccount.provider) && provider) {
106
+ if (provider) {
102
107
  PolkamarketsSmartAccount.singleton.clearInstance();
103
108
  this.smartAccount = PolkamarketsSmartAccount.singleton.getInstance(provider, this.socialLoginParams.networkConfig, isConnectedWallet);
109
+
110
+ // Store thirdweb account reference if provider has sendTransaction method
111
+ if (typeof provider.sendTransaction === 'function') {
112
+ this.smartAccount.thirdwebAccount = provider;
113
+ }
104
114
  }
105
115
 
106
116
  return true;
@@ -157,6 +167,7 @@ class Application {
157
167
  web3EventsProvider: this.web3EventsProvider,
158
168
  gasPrice: this.gasPrice,
159
169
  isSocialLogin: this.isSocialLogin,
170
+ useGaslessTransactions: this.useGaslessTransactions,
160
171
  startBlock: this.startBlock,
161
172
  defaultDecimals: this.defaultDecimals
162
173
  };
@@ -34,6 +34,7 @@ class IContract {
34
34
  web3EventsProvider,
35
35
  gasPrice,
36
36
  isSocialLogin = false,
37
+ useGaslessTransactions,
37
38
  startBlock
38
39
  }) {
39
40
  try {
@@ -58,6 +59,8 @@ class IContract {
58
59
  gasPrice,
59
60
  contract: new Contract(web3, abi, contractAddress),
60
61
  isSocialLogin,
62
+ // (For backwards compatibility) If useGaslessTransactions is not explicitly set, default to true when isSocialLogin is true, otherwise false
63
+ useGaslessTransactions: useGaslessTransactions !== undefined ? useGaslessTransactions : isSocialLogin,
61
64
  startBlock,
62
65
  };
63
66
  } catch (err) {
@@ -590,6 +593,30 @@ class IContract {
590
593
  return receipt;
591
594
  }
592
595
 
596
+ async useThirdWebWithUserPaidGas(tx, networkConfig, smartAccount) {
597
+ const client = createThirdwebClient({ clientId: networkConfig.thirdWebClientId });
598
+ const chain = defineChain(networkConfig.chainId);
599
+
600
+ if (!smartAccount || typeof smartAccount.sendTransaction !== 'function') {
601
+ throw new Error('Invalid account provided - expected thirdweb Account object with sendTransaction method');
602
+ }
603
+
604
+ const res = await smartAccount.sendTransaction({
605
+ to: tx.to,
606
+ data: tx.data,
607
+ gas: BigInt(500000),
608
+ chain: chain,
609
+ });
610
+
611
+ const receipt = await waitForReceipt({
612
+ client,
613
+ chain,
614
+ transactionHash: res.transactionHash,
615
+ });
616
+
617
+ return receipt;
618
+ }
619
+
593
620
  async sendGaslessTransactions(f) {
594
621
  const smartAccount = PolkamarketsSmartAccount.singleton.getInstance();
595
622
  const networkConfig = smartAccount.networkConfig;
@@ -799,9 +826,68 @@ class IContract {
799
826
  return transformedEvents;
800
827
  }
801
828
 
829
+ async sendSocialLoginGasTransactions(f) {
830
+ const smartAccount = PolkamarketsSmartAccount.singleton.getInstance();
831
+ const networkConfig = smartAccount.networkConfig;
832
+
833
+ const { isConnectedWallet, signer } = await smartAccount.providerIsConnectedWallet();
834
+
835
+ const methodName = f._method.name;
836
+
837
+ const contractInterface = new ethers.utils.Interface(this.params.abi.abi);
838
+ const methodCallData = contractInterface.encodeFunctionData(methodName, f.arguments);
839
+
840
+ const tx = {
841
+ to: this.params.contractAddress,
842
+ data: methodCallData,
843
+ };
844
+
845
+ try {
846
+ let receipt;
847
+
848
+ if (isConnectedWallet) {
849
+ const txResponse = await signer.sendTransaction({ ...tx, gasLimit: 210000 });
850
+ receipt = await txResponse.wait();
851
+ } else {
852
+ if (networkConfig.useThirdWeb) {
853
+ const thirdwebAccount = smartAccount.getThirdwebAccount();
854
+ if (!thirdwebAccount) {
855
+ throw new Error('ThirdWeb account not found. Make sure you passed the thirdweb account when calling login()');
856
+ }
857
+ receipt = await this.useThirdWebWithUserPaidGas(tx, networkConfig, thirdwebAccount);
858
+ } else {
859
+ throw new Error('User-paid transactions are only supported with ThirdWeb configuration');
860
+ }
861
+ }
862
+
863
+ console.log('receipt:', receipt.status, receipt.transactionHash);
864
+
865
+ if (receipt.logs) {
866
+ const events = receipt.logs.map(log => {
867
+ try {
868
+ const event = contractInterface.parseLog(log);
869
+ return event;
870
+ } catch (error) {
871
+ return null;
872
+ }
873
+ });
874
+ receipt.events = this.convertEtherEventsToWeb3Events(events);
875
+ }
876
+
877
+ return receipt;
878
+ } catch (error) {
879
+ console.error(error);
880
+ throw error;
881
+ }
882
+ }
883
+
802
884
  async __sendTx(f, call = false, value, callback = () => { }) {
803
885
  if (this.params.isSocialLogin && !call) {
804
- return await this.sendGaslessTransactions(f);
886
+ if (this.params.useGaslessTransactions) {
887
+ return await this.sendGaslessTransactions(f);
888
+ } else {
889
+ return await this.sendSocialLoginGasTransactions(f);
890
+ }
805
891
  } else {
806
892
  var res;
807
893
  if (!this.acc && !call) {
@@ -6,6 +6,11 @@ const { createPublicClient, http } = require('viem');
6
6
  const { signerToSimpleSmartAccount } = require('permissionless/accounts');
7
7
 
8
8
  class PolkamarketsSmartAccount {
9
+ networkConfig = null;
10
+ provider = null;
11
+ isConnectedWallet = null;
12
+ thirdwebAccount = null;
13
+ smartAccount = null;
9
14
 
10
15
  static PIMLICO_FACTORY_ADDRESS = '0x9406Cc6185a346906296840746125a0E44976454';
11
16
  static THIRDWEB_FACTORY_ADDRESS = '0x85e23b94e7F5E9cC1fF78BCe78cfb15B81f0DF00';
@@ -65,12 +70,30 @@ class PolkamarketsSmartAccount {
65
70
  return { isConnectedWallet: false, address: null, signer: null };
66
71
  }
67
72
 
73
+ getThirdwebAccount() {
74
+ if (this.thirdwebAccount) {
75
+ return this.thirdwebAccount;
76
+ }
77
+
78
+ // For backward compatibility, check if provider is already a thirdweb account
79
+ if (this.provider && typeof this.provider.sendTransaction === "function") {
80
+ return this.provider;
81
+ }
82
+
83
+ return null;
84
+ }
85
+
68
86
  async getAddress() {
69
87
  const { isConnectedWallet, address } = await this.providerIsConnectedWallet();
70
88
  if (isConnectedWallet) {
71
89
  return address;
72
90
  }
73
91
 
92
+ // Check if we have a stored thirdweb account (for agw support)
93
+ if (this.thirdwebAccount && this.thirdwebAccount.address) {
94
+ return this.thirdwebAccount.address;
95
+ }
96
+
74
97
  if (this.networkConfig.useThirdWeb && this.networkConfig.isZkSync) {
75
98
  if (this.provider.address) {
76
99
  return this.provider.address;