@gooddollar/goodcollective-contracts 1.0.3 → 1.0.5-beta.7a2c704
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/contracts/DirectPayments/DirectPaymentsFactory.sol +70 -13
- package/contracts/DirectPayments/DirectPaymentsPool.sol +102 -40
- package/contracts/DirectPayments/ProvableNFT.sol +17 -11
- package/contracts/GoodCollective/GoodCollectiveSuperApp.sol +155 -77
- package/contracts/GoodCollective/IGoodCollectiveSuperApp.sol +12 -0
- package/contracts/utils/HelperLibrary.sol +83 -0
- package/package.json +13 -7
- package/releases/deployment.json +12022 -1689
- package/typechain-types/@gooddollar/goodprotocol/contracts/token/IFeesFormula.ts +115 -0
- package/typechain-types/@gooddollar/goodprotocol/contracts/token/index.ts +1 -0
- package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +176 -0
- package/typechain-types/@openzeppelin/contracts/access/index.ts +4 -0
- package/typechain-types/@openzeppelin/contracts/index.ts +2 -0
- package/typechain-types/@openzeppelin/contracts/proxy/beacon/BeaconProxy.ts +115 -0
- package/typechain-types/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.ts +247 -0
- package/typechain-types/@openzeppelin/contracts/proxy/beacon/index.ts +2 -0
- package/typechain-types/contracts/DirectPayments/DirectPaymentsFactory.ts +168 -14
- package/typechain-types/contracts/DirectPayments/DirectPaymentsPool.sol/DirectPaymentsPool.ts +419 -186
- package/typechain-types/contracts/DirectPayments/ProvableNFT.ts +32 -3
- package/typechain-types/contracts/GoodCollective/GoodCollectiveSuperApp.ts +170 -13
- package/typechain-types/contracts/utils/HelperLibrary.ts +154 -0
- package/typechain-types/contracts/utils/index.ts +1 -0
- package/typechain-types/factories/@gooddollar/goodprotocol/contracts/token/IFeesFormula__factory.ts +60 -0
- package/typechain-types/factories/@gooddollar/goodprotocol/contracts/token/index.ts +1 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +78 -0
- package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/index.ts +1 -0
- package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/BeaconProxy__factory.ts +143 -0
- package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon__factory.ts +170 -0
- package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/index.ts +2 -0
- package/typechain-types/factories/contracts/DirectPayments/DirectPaymentsFactory__factory.ts +226 -3
- package/typechain-types/factories/contracts/DirectPayments/DirectPaymentsPool.sol/DirectPaymentsPool__factory.ts +473 -95
- package/typechain-types/factories/contracts/DirectPayments/ProvableNFT__factory.ts +56 -1
- package/typechain-types/factories/contracts/GoodCollective/GoodCollectiveSuperApp__factory.ts +148 -4
- package/typechain-types/factories/contracts/utils/HelperLibrary__factory.ts +129 -0
- package/typechain-types/factories/contracts/utils/index.ts +1 -0
- package/typechain-types/hardhat.d.ts +45 -0
- package/typechain-types/index.ts +8 -0
|
@@ -5,6 +5,9 @@ pragma solidity >=0.8.0;
|
|
|
5
5
|
import "./DirectPaymentsPool.sol";
|
|
6
6
|
import "./ProvableNFT.sol";
|
|
7
7
|
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
|
8
|
+
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
|
|
9
|
+
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
|
|
10
|
+
|
|
8
11
|
import { AccessControlUpgradeable } from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
|
|
9
12
|
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
10
13
|
|
|
@@ -13,7 +16,15 @@ import "hardhat/console.sol";
|
|
|
13
16
|
contract DirectPaymentsFactory is AccessControlUpgradeable, UUPSUpgradeable {
|
|
14
17
|
error NOT_PROJECT_OWNER();
|
|
15
18
|
|
|
16
|
-
event PoolCreated(
|
|
19
|
+
event PoolCreated(
|
|
20
|
+
address indexed pool,
|
|
21
|
+
string indexed projectId,
|
|
22
|
+
string ipfs,
|
|
23
|
+
uint32 indexed nftType,
|
|
24
|
+
DirectPaymentsPool.PoolSettings poolSettings,
|
|
25
|
+
DirectPaymentsPool.SafetyLimits poolLimits
|
|
26
|
+
);
|
|
27
|
+
|
|
17
28
|
event PoolDetailsChanged(address indexed pool, string ipfs);
|
|
18
29
|
event PoolVerifiedChanged(address indexed pool, bool isVerified);
|
|
19
30
|
event UpdatedImpl(address indexed impl);
|
|
@@ -24,16 +35,18 @@ contract DirectPaymentsFactory is AccessControlUpgradeable, UUPSUpgradeable {
|
|
|
24
35
|
string projectId;
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
UpgradeableBeacon public impl;
|
|
28
39
|
ProvableNFT public nft;
|
|
29
40
|
uint32 public nextNftType;
|
|
30
41
|
|
|
31
42
|
mapping(address => PoolRegistry) public registry;
|
|
32
43
|
mapping(bytes32 => DirectPaymentsPool) public projectIdToControlPool;
|
|
33
44
|
|
|
45
|
+
address public feeRecipient;
|
|
46
|
+
uint32 public feeBps;
|
|
47
|
+
|
|
34
48
|
modifier onlyProjectOwnerOrNon(string memory projectId) {
|
|
35
49
|
DirectPaymentsPool controlPool = projectIdToControlPool[keccak256(bytes(projectId))];
|
|
36
|
-
console.log("control:%s sender:%s %s", address(controlPool), msg.sender);
|
|
37
50
|
// console.log("result %s", controlPool.hasRole(controlPool.DEFAULT_ADMIN_ROLE(), msg.sender));
|
|
38
51
|
if (address(controlPool) != address(0)) {
|
|
39
52
|
if (controlPool.hasRole(controlPool.DEFAULT_ADMIN_ROLE(), msg.sender) == false) {
|
|
@@ -55,38 +68,77 @@ contract DirectPaymentsFactory is AccessControlUpgradeable, UUPSUpgradeable {
|
|
|
55
68
|
|
|
56
69
|
function _authorizeUpgrade(address _impl) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {}
|
|
57
70
|
|
|
58
|
-
function initialize(
|
|
71
|
+
function initialize(
|
|
72
|
+
address _owner,
|
|
73
|
+
address _dpimpl,
|
|
74
|
+
ProvableNFT _nft,
|
|
75
|
+
address _feeRecipient,
|
|
76
|
+
uint32 _feeBps
|
|
77
|
+
) external initializer {
|
|
59
78
|
nextNftType = 1;
|
|
60
|
-
impl = _dpimpl;
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
impl = new UpgradeableBeacon(_dpimpl);
|
|
80
|
+
nft = _nft;
|
|
81
|
+
feeRecipient = _feeRecipient;
|
|
82
|
+
feeBps = _feeBps;
|
|
63
83
|
|
|
64
|
-
nft.grantRole(DEFAULT_ADMIN_ROLE, _owner);
|
|
65
84
|
_setupRole(DEFAULT_ADMIN_ROLE, _owner);
|
|
66
85
|
}
|
|
67
86
|
|
|
87
|
+
//TODO: implement a pool that's auto upgradeable using beacon method
|
|
88
|
+
function createBeaconPool(
|
|
89
|
+
string memory _projectId,
|
|
90
|
+
string memory _ipfs,
|
|
91
|
+
DirectPaymentsPool.PoolSettings memory _settings,
|
|
92
|
+
DirectPaymentsPool.SafetyLimits memory _limits
|
|
93
|
+
) external onlyProjectOwnerOrNon(_projectId) returns (DirectPaymentsPool pool) {
|
|
94
|
+
return _createPool(_projectId, _ipfs, _settings, _limits, true);
|
|
95
|
+
}
|
|
96
|
+
|
|
68
97
|
function createPool(
|
|
69
98
|
string memory _projectId,
|
|
70
99
|
string memory _ipfs,
|
|
71
100
|
DirectPaymentsPool.PoolSettings memory _settings,
|
|
72
101
|
DirectPaymentsPool.SafetyLimits memory _limits
|
|
73
102
|
) external onlyProjectOwnerOrNon(_projectId) returns (DirectPaymentsPool pool) {
|
|
103
|
+
return _createPool(_projectId, _ipfs, _settings, _limits, false);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function _createPool(
|
|
107
|
+
string memory _projectId,
|
|
108
|
+
string memory _ipfs,
|
|
109
|
+
DirectPaymentsPool.PoolSettings memory _settings,
|
|
110
|
+
DirectPaymentsPool.SafetyLimits memory _limits,
|
|
111
|
+
bool useBeacon
|
|
112
|
+
) internal returns (DirectPaymentsPool pool) {
|
|
74
113
|
//TODO: add check if msg.sender is whitelisted
|
|
75
114
|
|
|
76
115
|
_settings.nftType = nextNftType;
|
|
77
|
-
bytes memory initCall = abi.encodeWithSelector(
|
|
78
|
-
|
|
116
|
+
bytes memory initCall = abi.encodeWithSelector(
|
|
117
|
+
DirectPaymentsPool.initialize.selector,
|
|
118
|
+
nft,
|
|
119
|
+
_settings,
|
|
120
|
+
_limits,
|
|
121
|
+
address(this)
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
if (useBeacon) {
|
|
125
|
+
pool = DirectPaymentsPool(address(new BeaconProxy(address(impl), initCall)));
|
|
126
|
+
} else {
|
|
127
|
+
pool = DirectPaymentsPool(address(new ERC1967Proxy(impl.implementation(), initCall)));
|
|
128
|
+
}
|
|
79
129
|
|
|
80
130
|
nft.grantRole(nft.getManagerRole(nextNftType), _settings.manager);
|
|
81
131
|
nft.grantRole(nft.getManagerRole(nextNftType), address(pool));
|
|
82
132
|
pool.grantRole(pool.MINTER_ROLE(), _settings.manager);
|
|
83
133
|
|
|
84
|
-
|
|
134
|
+
//access control to project is determinted by the first pool access control rules
|
|
135
|
+
if (address(projectIdToControlPool[keccak256(bytes(_projectId))]) == address(0))
|
|
136
|
+
projectIdToControlPool[keccak256(bytes(_projectId))] = pool;
|
|
85
137
|
registry[address(pool)].ipfs = _ipfs;
|
|
86
138
|
registry[address(pool)].projectId = _projectId;
|
|
87
139
|
|
|
88
140
|
pool.renounceRole(DEFAULT_ADMIN_ROLE, address(this));
|
|
89
|
-
emit PoolCreated(address(pool), _projectId, _ipfs, nextNftType);
|
|
141
|
+
emit PoolCreated(address(pool), _projectId, _ipfs, nextNftType, _settings, _limits);
|
|
90
142
|
|
|
91
143
|
nextNftType++;
|
|
92
144
|
}
|
|
@@ -102,7 +154,12 @@ contract DirectPaymentsFactory is AccessControlUpgradeable, UUPSUpgradeable {
|
|
|
102
154
|
}
|
|
103
155
|
|
|
104
156
|
function updateImpl(address _impl) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
105
|
-
impl
|
|
157
|
+
impl.upgradeTo(_impl);
|
|
106
158
|
emit UpdatedImpl(_impl);
|
|
107
159
|
}
|
|
160
|
+
|
|
161
|
+
function setFeeInfo(address _feeRecipient, uint32 _feeBps) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
162
|
+
feeBps = _feeBps;
|
|
163
|
+
feeRecipient = _feeRecipient;
|
|
164
|
+
}
|
|
108
165
|
}
|
|
@@ -41,21 +41,39 @@ contract DirectPaymentsPool is
|
|
|
41
41
|
error NOT_MANAGER();
|
|
42
42
|
error ALREADY_CLAIMED(uint256);
|
|
43
43
|
error NFT_MISSING(uint256);
|
|
44
|
-
error NOT_MEMBER(address);
|
|
45
|
-
error NOT_WHITELISTED(address);
|
|
46
44
|
error OVER_MEMBER_LIMITS(address);
|
|
47
45
|
error OVER_GLOBAL_LIMITS();
|
|
48
46
|
error UNSUPPORTED_NFT();
|
|
49
47
|
error NO_BALANCE();
|
|
48
|
+
error NFTTYPE_CHANGED();
|
|
49
|
+
error EMPTY_MANAGER();
|
|
50
50
|
|
|
51
51
|
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
|
|
52
|
+
bytes32 public constant MEMBER_ROLE = keccak256("MEMBER_ROLE");
|
|
52
53
|
bytes32 public constant MINTER_ROLE = keccak256("MINTER");
|
|
53
54
|
|
|
55
|
+
event PoolCreated(
|
|
56
|
+
address indexed pool,
|
|
57
|
+
string indexed projectId,
|
|
58
|
+
string ipfs,
|
|
59
|
+
uint32 indexed nftType,
|
|
60
|
+
DirectPaymentsPool.PoolSettings poolSettings,
|
|
61
|
+
DirectPaymentsPool.SafetyLimits poolLimits
|
|
62
|
+
);
|
|
63
|
+
|
|
54
64
|
event PoolSettingsChanged(PoolSettings settings);
|
|
55
65
|
event PoolLimitsChanged(SafetyLimits limits);
|
|
56
|
-
event
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
event EventRewardClaimed(
|
|
67
|
+
uint256 indexed tokenId,
|
|
68
|
+
uint16 eventType,
|
|
69
|
+
uint32 eventTimestamp,
|
|
70
|
+
uint256 eventQuantity,
|
|
71
|
+
string eventUri,
|
|
72
|
+
address[] contributers,
|
|
73
|
+
uint256 rewardPerContributer
|
|
74
|
+
);
|
|
75
|
+
event NFTClaimed(uint256 indexed tokenId, uint256 totalRewards);
|
|
76
|
+
event NOT_MEMBER_OR_WHITELISTED(address contributer);
|
|
59
77
|
|
|
60
78
|
// Define functions
|
|
61
79
|
struct PoolSettings {
|
|
@@ -66,6 +84,7 @@ contract DirectPaymentsPool is
|
|
|
66
84
|
IMembersValidator membersValidator;
|
|
67
85
|
IIdentityV2 uniquenessValidator;
|
|
68
86
|
IERC20Upgradeable rewardToken;
|
|
87
|
+
bool allowRewardOverride;
|
|
69
88
|
}
|
|
70
89
|
|
|
71
90
|
struct SafetyLimits {
|
|
@@ -87,10 +106,10 @@ contract DirectPaymentsPool is
|
|
|
87
106
|
ProvableNFT public nft;
|
|
88
107
|
|
|
89
108
|
mapping(uint256 => bool) public claimedNfts;
|
|
90
|
-
mapping(address => bool)
|
|
109
|
+
mapping(address => bool) private members_unused; // using access control instead
|
|
91
110
|
mapping(address => LimitsData) public memberLimits;
|
|
92
111
|
LimitsData public globalLimits;
|
|
93
|
-
|
|
112
|
+
DirectPaymentsFactory public registry;
|
|
94
113
|
|
|
95
114
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
96
115
|
constructor(ISuperfluid _host, ISwapRouter _swapRouter) GoodCollectiveSuperApp(_host, _swapRouter) {}
|
|
@@ -99,7 +118,11 @@ contract DirectPaymentsPool is
|
|
|
99
118
|
* @dev Authorizes an upgrade for the implementation contract.
|
|
100
119
|
* @param impl The address of the new implementation contract.
|
|
101
120
|
*/
|
|
102
|
-
function _authorizeUpgrade(address impl) internal virtual override {}
|
|
121
|
+
function _authorizeUpgrade(address impl) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {}
|
|
122
|
+
|
|
123
|
+
function getRegistry() public view override returns (DirectPaymentsFactory) {
|
|
124
|
+
return DirectPaymentsFactory(registry);
|
|
125
|
+
}
|
|
103
126
|
|
|
104
127
|
/**
|
|
105
128
|
* @dev Initializes the contract with the given settings and limits.
|
|
@@ -110,20 +133,20 @@ contract DirectPaymentsPool is
|
|
|
110
133
|
function initialize(
|
|
111
134
|
ProvableNFT _nft,
|
|
112
135
|
PoolSettings memory _settings,
|
|
113
|
-
SafetyLimits memory _limits
|
|
136
|
+
SafetyLimits memory _limits,
|
|
137
|
+
DirectPaymentsFactory _registry
|
|
114
138
|
) external initializer {
|
|
115
|
-
|
|
139
|
+
registry = _registry;
|
|
116
140
|
settings = _settings;
|
|
117
141
|
limits = _limits;
|
|
118
142
|
nft = _nft;
|
|
119
143
|
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
|
120
144
|
_setupRole(DEFAULT_ADMIN_ROLE, _settings.manager);
|
|
121
|
-
|
|
122
145
|
setSuperToken(ISuperToken(address(settings.rewardToken)));
|
|
123
146
|
}
|
|
124
147
|
|
|
125
|
-
function upgradeToLatest(bytes memory data) external payable virtual
|
|
126
|
-
address impl = DirectPaymentsFactory(
|
|
148
|
+
function upgradeToLatest(bytes memory data) external payable virtual {
|
|
149
|
+
address impl = address(DirectPaymentsFactory(registry).impl());
|
|
127
150
|
_authorizeUpgrade(impl);
|
|
128
151
|
_upgradeToAndCallUUPS(impl, data, false);
|
|
129
152
|
}
|
|
@@ -164,17 +187,31 @@ contract DirectPaymentsPool is
|
|
|
164
187
|
uint totalRewards;
|
|
165
188
|
uint rewardsBalance = settings.rewardToken.balanceOf(address(this));
|
|
166
189
|
|
|
190
|
+
bool allowRewardOverride = settings.allowRewardOverride;
|
|
167
191
|
for (uint256 i = 0; i < _data.events.length; i++) {
|
|
168
|
-
|
|
192
|
+
uint reward = (
|
|
193
|
+
allowRewardOverride && _data.events[i].rewardOverride > 0
|
|
194
|
+
? _data.events[i].rewardOverride
|
|
195
|
+
: _eventReward(_data.events[i].subtype)
|
|
196
|
+
) * _data.events[i].quantity;
|
|
169
197
|
if (reward > 0) {
|
|
170
|
-
totalRewards += reward
|
|
198
|
+
totalRewards += reward;
|
|
171
199
|
if (totalRewards > rewardsBalance) revert NO_BALANCE();
|
|
172
200
|
rewardsBalance -= totalRewards;
|
|
173
|
-
_sendReward(_data.events[i].contributers, uint128(reward
|
|
201
|
+
_sendReward(_data.events[i].contributers, uint128(reward));
|
|
202
|
+
emit EventRewardClaimed(
|
|
203
|
+
_nftId,
|
|
204
|
+
_data.events[i].subtype,
|
|
205
|
+
_data.events[i].timestamp,
|
|
206
|
+
_data.events[i].quantity,
|
|
207
|
+
_data.events[i].eventUri,
|
|
208
|
+
_data.events[i].contributers,
|
|
209
|
+
uint128(reward / _data.events[i].contributers.length)
|
|
210
|
+
);
|
|
174
211
|
}
|
|
175
212
|
}
|
|
176
213
|
|
|
177
|
-
emit
|
|
214
|
+
emit NFTClaimed(_nftId, totalRewards);
|
|
178
215
|
}
|
|
179
216
|
|
|
180
217
|
/**
|
|
@@ -196,11 +233,17 @@ contract DirectPaymentsPool is
|
|
|
196
233
|
*/
|
|
197
234
|
function _sendReward(address[] memory recipients, uint128 reward) internal {
|
|
198
235
|
uint128 perReward = uint128(reward / recipients.length);
|
|
236
|
+
uint128 totalSent;
|
|
199
237
|
for (uint i = 0; i < recipients.length; i++) {
|
|
200
|
-
_enforceAndUpdateMemberLimits(recipients[i], perReward);
|
|
201
|
-
|
|
238
|
+
bool valid = _enforceAndUpdateMemberLimits(recipients[i], perReward);
|
|
239
|
+
if (valid) {
|
|
240
|
+
settings.rewardToken.safeTransfer(recipients[i], perReward);
|
|
241
|
+
totalSent += perReward;
|
|
242
|
+
} else {
|
|
243
|
+
emit NOT_MEMBER_OR_WHITELISTED(recipients[i]);
|
|
244
|
+
}
|
|
202
245
|
}
|
|
203
|
-
_enforceAndUpdateGlobalLimits(
|
|
246
|
+
_enforceAndUpdateGlobalLimits(totalSent);
|
|
204
247
|
}
|
|
205
248
|
|
|
206
249
|
/**
|
|
@@ -208,8 +251,11 @@ contract DirectPaymentsPool is
|
|
|
208
251
|
* @param member The address of the member to enforce and update limits for.
|
|
209
252
|
* @param reward The amount of rewards to enforce and update limits for.
|
|
210
253
|
*/
|
|
211
|
-
function _enforceAndUpdateMemberLimits(address member, uint128 reward) internal {
|
|
212
|
-
|
|
254
|
+
function _enforceAndUpdateMemberLimits(address member, uint128 reward) internal returns (bool) {
|
|
255
|
+
//dont revert on non valid members, just dont reward them (their reward is lost)
|
|
256
|
+
if (_addMember(member, "") == false) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
213
259
|
|
|
214
260
|
uint64 curMonth = _month();
|
|
215
261
|
if (memberLimits[member].lastReward + 60 * 60 * 24 < block.timestamp) //more than a day passed since last reward
|
|
@@ -234,6 +280,8 @@ contract DirectPaymentsPool is
|
|
|
234
280
|
memberLimits[member].daily > limits.maxMemberPerDay ||
|
|
235
281
|
memberLimits[member].monthly > limits.maxMemberPerMonth
|
|
236
282
|
) revert OVER_MEMBER_LIMITS(member);
|
|
283
|
+
|
|
284
|
+
return true;
|
|
237
285
|
}
|
|
238
286
|
|
|
239
287
|
/**
|
|
@@ -278,32 +326,23 @@ contract DirectPaymentsPool is
|
|
|
278
326
|
* @param extraData Additional data to validate the member.
|
|
279
327
|
*/
|
|
280
328
|
|
|
281
|
-
function
|
|
329
|
+
function _addMember(address member, bytes memory extraData) internal returns (bool isMember) {
|
|
330
|
+
if (hasRole(MEMBER_ROLE, member)) return true;
|
|
331
|
+
|
|
282
332
|
if (address(settings.uniquenessValidator) != address(0)) {
|
|
283
333
|
address rootAddress = settings.uniquenessValidator.getWhitelistedRoot(member);
|
|
284
|
-
if (rootAddress == address(0))
|
|
334
|
+
if (rootAddress == address(0)) return false;
|
|
285
335
|
}
|
|
286
336
|
|
|
337
|
+
// if no members validator then anyone can join the pool
|
|
287
338
|
if (address(settings.membersValidator) != address(0)) {
|
|
288
339
|
if (settings.membersValidator.isMemberValid(address(this), msg.sender, member, extraData) == false) {
|
|
289
|
-
|
|
340
|
+
return false;
|
|
290
341
|
}
|
|
291
|
-
} else {
|
|
292
|
-
// if no members validator then only admin can add members
|
|
293
|
-
if (hasRole(DEFAULT_ADMIN_ROLE, msg.sender) == false) revert NOT_MANAGER();
|
|
294
342
|
}
|
|
295
343
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* @dev Removes a member from the contract.
|
|
302
|
-
* @param member The address of the member to remove.
|
|
303
|
-
*/
|
|
304
|
-
function removeMember(address member) external onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
305
|
-
members[member] = false;
|
|
306
|
-
emit MemberRemoved(member);
|
|
344
|
+
_setupRole(MEMBER_ROLE, member);
|
|
345
|
+
return true;
|
|
307
346
|
}
|
|
308
347
|
|
|
309
348
|
function mintNFT(address _to, ProvableNFT.NFTData memory _nftData, bool withClaim) external onlyRole(MINTER_ROLE) {
|
|
@@ -314,7 +353,7 @@ contract DirectPaymentsPool is
|
|
|
314
353
|
}
|
|
315
354
|
|
|
316
355
|
/**
|
|
317
|
-
* @dev Receives an ERC721 token
|
|
356
|
+
* @dev Receives an ERC721 token
|
|
318
357
|
* @param operator The address of the operator that sent the token.
|
|
319
358
|
* @param from The address of the sender that sent the token.
|
|
320
359
|
* @param tokenId The ID of the token received.
|
|
@@ -340,4 +379,27 @@ contract DirectPaymentsPool is
|
|
|
340
379
|
if (nftData.nftType != settings.nftType) revert UNSUPPORTED_NFT();
|
|
341
380
|
return DirectPaymentsPool.onERC721Received.selector;
|
|
342
381
|
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* @dev Sets the safety limits for the pool.
|
|
385
|
+
* @param _limits The new safety limits.
|
|
386
|
+
*/
|
|
387
|
+
function setPoolLimits(SafetyLimits memory _limits) public onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
388
|
+
limits = _limits;
|
|
389
|
+
emit PoolLimitsChanged(_limits);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* @dev Sets the settings for the pool.
|
|
394
|
+
* @param _settings The new pool settings.
|
|
395
|
+
*/
|
|
396
|
+
function setPoolSettings(PoolSettings memory _settings) public onlyRole(DEFAULT_ADMIN_ROLE) {
|
|
397
|
+
if (_settings.nftType != settings.nftType) revert NFTTYPE_CHANGED();
|
|
398
|
+
if (_settings.manager == address(0)) revert EMPTY_MANAGER();
|
|
399
|
+
|
|
400
|
+
_revokeRole(DEFAULT_ADMIN_ROLE, settings.manager);
|
|
401
|
+
settings = _settings;
|
|
402
|
+
_setupRole(DEFAULT_ADMIN_ROLE, _settings.manager);
|
|
403
|
+
emit PoolSettingsChanged(_settings);
|
|
404
|
+
}
|
|
343
405
|
}
|
|
@@ -19,12 +19,15 @@ contract ProvableNFT is ERC721Upgradeable, AccessControlUpgradeable, UUPSUpgrade
|
|
|
19
19
|
bytes32 public constant MINTER_ROLE = keccak256(abi.encodePacked("MINTER"));
|
|
20
20
|
bytes16 private constant _SYMBOLS = "0123456789abcdef";
|
|
21
21
|
|
|
22
|
+
event ProvableNftMinted(uint256 tokenId, address to, bytes32 nftDataHash);
|
|
23
|
+
|
|
22
24
|
struct EventData {
|
|
23
25
|
uint16 subtype;
|
|
24
26
|
uint32 timestamp;
|
|
25
27
|
uint256 quantity;
|
|
26
28
|
string eventUri; //extra data related to event
|
|
27
29
|
address[] contributers;
|
|
30
|
+
uint128 rewardOverride; //override reward defined per 1 quantity of event, pool will use this instead of its own reward if allowRewardOverride is true
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
struct NFTData {
|
|
@@ -41,7 +44,9 @@ contract ProvableNFT is ERC721Upgradeable, AccessControlUpgradeable, UUPSUpgrade
|
|
|
41
44
|
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
function _authorizeUpgrade(address newimpl) internal virtual override
|
|
47
|
+
function _authorizeUpgrade(address /*newimpl*/) internal virtual override {
|
|
48
|
+
_onlyManager(0);
|
|
49
|
+
}
|
|
45
50
|
|
|
46
51
|
function supportsInterface(
|
|
47
52
|
bytes4 interfaceId
|
|
@@ -49,14 +54,13 @@ contract ProvableNFT is ERC721Upgradeable, AccessControlUpgradeable, UUPSUpgrade
|
|
|
49
54
|
return super.supportsInterface(interfaceId);
|
|
50
55
|
}
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
function _onlyManager(uint32 nftType) internal view {
|
|
53
58
|
if (
|
|
54
59
|
((nftType > 0 && hasRole(getManagerRole(nftType), msg.sender)) ||
|
|
55
60
|
hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) == false
|
|
56
61
|
) {
|
|
57
62
|
revert NOT_MANAGER(nftType);
|
|
58
63
|
}
|
|
59
|
-
_;
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
/**
|
|
@@ -72,23 +76,24 @@ contract ProvableNFT is ERC721Upgradeable, AccessControlUpgradeable, UUPSUpgrade
|
|
|
72
76
|
* @param _nftDataHash The hash of the NFT's data.
|
|
73
77
|
* @return tokenId ID of the newly minted NFT.
|
|
74
78
|
*/
|
|
75
|
-
function mint(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return _mint(_to, _uri, _nftDataHash, ""); //send false in calldata, assuming default receiver is a directpaymentspool. without nft data on chain it will fail.
|
|
79
|
+
function mint(address _to, string memory _uri, bytes32 _nftDataHash) public returns (uint256 tokenId) {
|
|
80
|
+
_onlyManager(0);
|
|
81
|
+
NFTData memory nftData;
|
|
82
|
+
|
|
83
|
+
return _mint(_to, _uri, _nftDataHash, nftData, ""); //send false in calldata, assuming default receiver is a directpaymentspool. without nft data on chain it will fail.
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
function _mint(
|
|
84
87
|
address _to,
|
|
85
88
|
string memory _uri,
|
|
86
89
|
bytes32 _nftDataHash,
|
|
90
|
+
NFTData memory /*_nftData*/,
|
|
87
91
|
bytes memory _callData
|
|
88
92
|
) internal returns (uint256 tokenId) {
|
|
89
93
|
tokenId = uint256(_nftDataHash);
|
|
90
94
|
nftDatas[tokenId].nftUri = _uri;
|
|
91
95
|
_safeMint(_to, tokenId, _callData);
|
|
96
|
+
emit ProvableNftMinted(tokenId, _to, _nftDataHash);
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
/**
|
|
@@ -109,7 +114,8 @@ contract ProvableNFT is ERC721Upgradeable, AccessControlUpgradeable, UUPSUpgrade
|
|
|
109
114
|
NFTData memory _nftData,
|
|
110
115
|
bool _withStore,
|
|
111
116
|
bytes memory _callData
|
|
112
|
-
) external
|
|
117
|
+
) external returns (uint256 tokenId) {
|
|
118
|
+
_onlyManager(_nftData.nftType);
|
|
113
119
|
if (_nftData.nftType == 0) revert BAD_NFTTYPE();
|
|
114
120
|
|
|
115
121
|
bytes32 dataHash = keccak256(abi.encode(_nftData));
|
|
@@ -123,7 +129,7 @@ contract ProvableNFT is ERC721Upgradeable, AccessControlUpgradeable, UUPSUpgrade
|
|
|
123
129
|
store.events.push(_nftData.events[i]);
|
|
124
130
|
}
|
|
125
131
|
}
|
|
126
|
-
_mint(_to, _nftData.nftUri, dataHash, _callData);
|
|
132
|
+
_mint(_to, _nftData.nftUri, dataHash, _nftData, _callData);
|
|
127
133
|
}
|
|
128
134
|
|
|
129
135
|
function proveNFTData(uint256 _tokenId, NFTData memory _nftData) public view returns (NFTData memory data) {
|