@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.
Files changed (38) hide show
  1. package/contracts/DirectPayments/DirectPaymentsFactory.sol +70 -13
  2. package/contracts/DirectPayments/DirectPaymentsPool.sol +102 -40
  3. package/contracts/DirectPayments/ProvableNFT.sol +17 -11
  4. package/contracts/GoodCollective/GoodCollectiveSuperApp.sol +155 -77
  5. package/contracts/GoodCollective/IGoodCollectiveSuperApp.sol +12 -0
  6. package/contracts/utils/HelperLibrary.sol +83 -0
  7. package/package.json +13 -7
  8. package/releases/deployment.json +12022 -1689
  9. package/typechain-types/@gooddollar/goodprotocol/contracts/token/IFeesFormula.ts +115 -0
  10. package/typechain-types/@gooddollar/goodprotocol/contracts/token/index.ts +1 -0
  11. package/typechain-types/@openzeppelin/contracts/access/Ownable.ts +176 -0
  12. package/typechain-types/@openzeppelin/contracts/access/index.ts +4 -0
  13. package/typechain-types/@openzeppelin/contracts/index.ts +2 -0
  14. package/typechain-types/@openzeppelin/contracts/proxy/beacon/BeaconProxy.ts +115 -0
  15. package/typechain-types/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.ts +247 -0
  16. package/typechain-types/@openzeppelin/contracts/proxy/beacon/index.ts +2 -0
  17. package/typechain-types/contracts/DirectPayments/DirectPaymentsFactory.ts +168 -14
  18. package/typechain-types/contracts/DirectPayments/DirectPaymentsPool.sol/DirectPaymentsPool.ts +419 -186
  19. package/typechain-types/contracts/DirectPayments/ProvableNFT.ts +32 -3
  20. package/typechain-types/contracts/GoodCollective/GoodCollectiveSuperApp.ts +170 -13
  21. package/typechain-types/contracts/utils/HelperLibrary.ts +154 -0
  22. package/typechain-types/contracts/utils/index.ts +1 -0
  23. package/typechain-types/factories/@gooddollar/goodprotocol/contracts/token/IFeesFormula__factory.ts +60 -0
  24. package/typechain-types/factories/@gooddollar/goodprotocol/contracts/token/index.ts +1 -0
  25. package/typechain-types/factories/@openzeppelin/contracts/access/Ownable__factory.ts +78 -0
  26. package/typechain-types/factories/@openzeppelin/contracts/access/index.ts +4 -0
  27. package/typechain-types/factories/@openzeppelin/contracts/index.ts +1 -0
  28. package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/BeaconProxy__factory.ts +143 -0
  29. package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon__factory.ts +170 -0
  30. package/typechain-types/factories/@openzeppelin/contracts/proxy/beacon/index.ts +2 -0
  31. package/typechain-types/factories/contracts/DirectPayments/DirectPaymentsFactory__factory.ts +226 -3
  32. package/typechain-types/factories/contracts/DirectPayments/DirectPaymentsPool.sol/DirectPaymentsPool__factory.ts +473 -95
  33. package/typechain-types/factories/contracts/DirectPayments/ProvableNFT__factory.ts +56 -1
  34. package/typechain-types/factories/contracts/GoodCollective/GoodCollectiveSuperApp__factory.ts +148 -4
  35. package/typechain-types/factories/contracts/utils/HelperLibrary__factory.ts +129 -0
  36. package/typechain-types/factories/contracts/utils/index.ts +1 -0
  37. package/typechain-types/hardhat.d.ts +45 -0
  38. package/typechain-types/index.ts +8 -0
@@ -6,44 +6,53 @@ import { SuperAppBaseFlow } from "./SuperAppBaseFlow.sol";
6
6
  import { ISuperfluid, ISuperToken, SuperAppDefinitions } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
7
7
  import { ISuperGoodDollar } from "@gooddollar/goodprotocol/contracts/token/superfluid/ISuperGoodDollar.sol";
8
8
  import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
9
+ import { CFAv1Library, IConstantFlowAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/apps/CFAv1Library.sol";
9
10
 
10
11
  import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
11
12
  import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
12
13
 
14
+ import "../DirectPayments/DirectPaymentsFactory.sol";
15
+ import "../utils/HelperLibrary.sol";
16
+
13
17
  // import "hardhat/console.sol";
14
18
 
15
19
  abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
20
+ int96 public constant MIN_FLOW_RATE = 386e9;
21
+
16
22
  using SuperTokenV1Library for ISuperToken;
23
+ using CFAv1Library for CFAv1Library.InitData;
17
24
 
18
25
  error ZERO_ADDRESS();
19
26
  error ZERO_AMOUNT();
20
27
  error UNSUPPORTED_TOKEN();
21
28
  error ONLY_HOST_OR_SENDER(address);
29
+ error FEE_FLOW_FAILED(int96 curFeeRate, int96 newFeeRate);
30
+ error MIN_FLOWRATE(int96 flowRate);
22
31
 
23
- event SupporterUpdated(address indexed supporter, uint256 contribution, int96 flowRate, uint256 lastUpdated);
24
-
25
- //TODO: ask about "view" for beforeagreement functions
32
+ /**
33
+ * @dev Emitted when a supporter's contribution or flow rate is updated
34
+ * @param supporter The address of the supporter
35
+ * @param previousContribution The previous total contribution amount
36
+ * @param contribution The new total contribution amount
37
+ * @param previousFlowRate The previous flow rate if isFlowUpdate otherwise 0
38
+ * @param flowRate The new flow rate
39
+ * @param isFlowUpdate True if the update was a flow rate update, false if it was a single contribution update
40
+ */
41
+ event SupporterUpdated(
42
+ address indexed supporter,
43
+ uint256 previousContribution,
44
+ uint256 contribution,
45
+ int96 previousFlowRate,
46
+ int96 flowRate,
47
+ bool isFlowUpdate
48
+ );
49
+
50
+ //TODO:
26
51
  // ask about "receiver" can it be different then app?
27
52
 
28
53
  /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
29
54
  ISwapRouter public immutable swapRouter;
30
55
 
31
- /**
32
- * @dev A struct containing information about a token swap
33
- * @param swapFrom The address of the token being swapped
34
- * @param amount The amount of tokens being swapped
35
- * @param minReturn The minimum amount of tokens to be received in the swap
36
- * @param timestamp The deadline for the swap to occur
37
- * @param path The path of tokens to take in a uniswap v3 multi-hop swap, encoded as bytes
38
- */
39
- struct SwapData {
40
- address swapFrom;
41
- uint256 amount;
42
- uint256 minReturn;
43
- uint256 deadline;
44
- bytes path;
45
- }
46
-
47
56
  struct SupporterData {
48
57
  uint256 contribution;
49
58
  int96 flowRate;
@@ -54,7 +63,12 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
54
63
 
55
64
  mapping(address => SupporterData) public supporters;
56
65
 
57
- uint256[50] private _reserved;
66
+ //initialize cfaV1 variable
67
+ CFAv1Library.InitData public cfaV1;
68
+
69
+ IGoodCollectiveSuperApp.Stats public stats;
70
+
71
+ uint256[48] private _reserved;
58
72
 
59
73
  /// @custom:oz-upgrades-unsafe-allow constructor
60
74
  constructor(ISuperfluid _host, ISwapRouter _swapRouter) SuperAppBaseFlow(_host) {
@@ -62,6 +76,8 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
62
76
  swapRouter = _swapRouter;
63
77
  }
64
78
 
79
+ function getRegistry() public view virtual returns (DirectPaymentsFactory);
80
+
65
81
  /**
66
82
  * @dev Sets the address of the super token and registers the app with the host
67
83
  * @param _superToken The address of the super token contract
@@ -77,6 +93,14 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
77
93
 
78
94
  // Register the app with the host
79
95
  host.registerApp(callBackDefinitions);
96
+
97
+ //initialize InitData struct, and set equal to cfaV1
98
+ cfaV1 = CFAv1Library.InitData(
99
+ host,
100
+ IConstantFlowAgreementV1(
101
+ address(host.getAgreementClass(keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1")))
102
+ )
103
+ );
80
104
  }
81
105
 
82
106
  function isAcceptedSuperToken(ISuperToken _superToken) public view override returns (bool) {
@@ -89,6 +113,14 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
89
113
  return supporter.contribution + uint96(supporter.flowRate) * (block.timestamp - supporter.lastUpdated);
90
114
  }
91
115
 
116
+ function getRealtimeStats()
117
+ public
118
+ view
119
+ returns (uint256 netIncome, uint256 totalFees, int96 incomeFlowRate, int96 feeRate)
120
+ {
121
+ return HelperLibrary.getRealtimeStats(stats, superToken);
122
+ }
123
+
92
124
  /**
93
125
  * @dev This function is called when a token transfer occurs
94
126
  * @param _sender The address of the sender
@@ -100,16 +132,16 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
100
132
  if (_amount == 0) revert ZERO_AMOUNT();
101
133
 
102
134
  // Update the contribution amount for the sender in the supporters mapping
103
- _updateSupporter(_sender, int96(int256(_amount / 1000)), block.timestamp - 1000);
135
+ _updateSupporter(_sender, int256(_amount), 0, "");
104
136
 
105
137
  return true;
106
138
  }
107
139
 
108
140
  /**
109
- * @dev This function supports the Superfluid protocol by allowing a sender to contribute tokens to the network.
141
+ * @dev allow single contribution. user needs to approve tokens first. can be used in superfluid batch actions.
110
142
  * @param _sender The address of the sender who is contributing tokens.
111
143
  * @param _amount The amount of tokens being contributed.
112
- * @param _ctx The context of the transaction for superfluid
144
+ * @param _ctx The context of the transaction for superfluid in case this was used in superfluid batch. otherwise can be empty.
113
145
  * @return Returns the context of the transaction.
114
146
  */
115
147
  function support(
@@ -123,7 +155,7 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
123
155
  TransferHelper.safeTransferFrom(address(superToken), _sender, address(this), _amount);
124
156
 
125
157
  // Update the contribution amount for the sender in the supporters mapping
126
- _updateSupporter(_sender, int96(int256(_amount / 1000)), block.timestamp - 1000);
158
+ _updateSupporter(_sender, int256(_amount), 0, ""); //we pass empty ctx since this is not a flow but a single donation
127
159
 
128
160
  return _ctx;
129
161
  }
@@ -136,42 +168,11 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
136
168
  * @return Returns the context of the transaction
137
169
  */
138
170
  function handleSwap(
139
- SwapData memory _customData,
171
+ HelperLibrary.SwapData memory _customData,
140
172
  address _sender,
141
173
  bytes memory _ctx
142
174
  ) external onlyHostOrSender(_sender) returns (bytes memory) {
143
- // Transfer the tokens from the sender to this contract
144
- TransferHelper.safeTransferFrom(_customData.swapFrom, _sender, address(this), _customData.amount);
145
-
146
- // Approve the router to spend the tokens
147
- TransferHelper.safeApprove(_customData.swapFrom, address(swapRouter), _customData.amount);
148
-
149
- if (_customData.path.length > 0) {
150
- // If a path is provided, execute a multi-hop swap
151
- ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
152
- path: _customData.path,
153
- recipient: _sender,
154
- deadline: _customData.deadline,
155
- amountIn: _customData.amount,
156
- amountOutMinimum: _customData.minReturn
157
- });
158
- swapRouter.exactInput(params);
159
- } else {
160
- // If no path is provided, execute a single-hop swap
161
- ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
162
- tokenIn: _customData.swapFrom,
163
- tokenOut: address(superToken),
164
- fee: 10000,
165
- recipient: _sender,
166
- deadline: _customData.deadline,
167
- amountIn: _customData.amount,
168
- amountOutMinimum: _customData.minReturn,
169
- sqrtPriceLimitX96: 0
170
- });
171
-
172
- // Execute the swap using `exactInputSingle`
173
- swapRouter.exactInputSingle(params);
174
- }
175
+ HelperLibrary.handleSwap(swapRouter, _customData, address(superToken), _sender);
175
176
 
176
177
  // Return the context of the transaction
177
178
  return _ctx;
@@ -189,10 +190,7 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
189
190
  bytes calldata _ctx
190
191
  ) internal virtual override returns (bytes memory /*newCtx*/) {
191
192
  // Update the supporter's information
192
- _updateSupporter(_sender, 0, 0);
193
-
194
- // Return the context of the transaction
195
- return _ctx;
193
+ return _updateSupporter(_sender, 0, 0, _ctx);
196
194
  }
197
195
 
198
196
  /**
@@ -211,10 +209,7 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
211
209
  bytes calldata _ctx
212
210
  ) internal virtual override returns (bytes memory /*newCtx*/) {
213
211
  // Update the supporter's information
214
- _updateSupporter(_sender, _previousFlowRate, _lastUpdated);
215
-
216
- // Return the context of the transaction
217
- return _ctx;
212
+ return _updateSupporter(_sender, _previousFlowRate, _lastUpdated, _ctx);
218
213
  }
219
214
 
220
215
  /**
@@ -234,29 +229,112 @@ abstract contract GoodCollectiveSuperApp is SuperAppBaseFlow {
234
229
  bytes calldata _ctx
235
230
  ) internal virtual override returns (bytes memory /*newCtx*/) {
236
231
  // Update the supporter's information
237
- _updateSupporter(_sender, _previousFlowRate, _lastUpdated);
238
-
239
- // Return the context of the transaction
240
- return _ctx;
232
+ return _updateSupporter(_sender, _previousFlowRate, _lastUpdated, _ctx);
241
233
  }
242
234
 
243
235
  /**
244
236
  * @dev Updates the information for a supporter
245
237
  * @param _supporter The address of the supporter
246
- * @param _previousFlowRate The previous flow rate of the stream
238
+ * @param _previousFlowRateOrAmount The previous flow rate of the stream or single donation amount
247
239
  * @param _lastUpdated The timestamp of the last update to the stream
240
+ * @param _ctx flow context
248
241
  */
249
- function _updateSupporter(address _supporter, int96 _previousFlowRate, uint256 _lastUpdated) internal {
242
+ function _updateSupporter(
243
+ address _supporter,
244
+ int256 _previousFlowRateOrAmount,
245
+ uint256 _lastUpdated,
246
+ bytes memory _ctx
247
+ ) internal returns (bytes memory newCtx) {
248
+ newCtx = _ctx;
249
+ bool _isFlow = _ctx.length > 0;
250
+ _updateStats(_isFlow ? 0 : uint256(_previousFlowRateOrAmount));
250
251
  // Get the current flow rate for the supporter
251
- (, int96 flowRate, , ) = superToken.getFlowInfo(_supporter, address(this));
252
+ int96 flowRate = superToken.getFlowRate(_supporter, address(this));
253
+ uint256 prevContribution = supporters[_supporter].contribution;
254
+ if (_isFlow) {
255
+ //enforce minimal flow rate
256
+ if (flowRate > 0 && flowRate < MIN_FLOW_RATE) revert MIN_FLOWRATE(flowRate);
257
+ // Update the supporter's information
258
+ supporters[_supporter].lastUpdated = uint128(block.timestamp);
259
+ supporters[_supporter].flowRate = flowRate;
260
+ supporters[_supporter].contribution +=
261
+ uint96(int96(_previousFlowRateOrAmount)) *
262
+ (block.timestamp - _lastUpdated);
263
+ newCtx = _takeFeeFlow(flowRate - int96(_previousFlowRateOrAmount), _ctx);
264
+ // we update the last rate after we do all changes to our own flows
265
+ stats.lastIncomeRate = superToken.getNetFlowRate(address(this));
266
+ } else {
267
+ supporters[_supporter].contribution += uint256(_previousFlowRateOrAmount);
268
+ _takeFeeSingle(uint256(_previousFlowRateOrAmount));
269
+ }
252
270
 
253
- // Update the supporter's information
254
- supporters[_supporter].lastUpdated = uint128(block.timestamp);
255
- supporters[_supporter].flowRate = flowRate;
256
- supporters[_supporter].contribution += uint96(_previousFlowRate) * (block.timestamp - _lastUpdated);
257
- emit SupporterUpdated(_supporter, supporters[_supporter].contribution, flowRate, block.timestamp);
271
+ emit SupporterUpdated(
272
+ _supporter,
273
+ prevContribution,
274
+ supporters[_supporter].contribution,
275
+ _isFlow ? int96(int256(_previousFlowRateOrAmount)) : int96(0),
276
+ flowRate,
277
+ _isFlow
278
+ );
258
279
  }
259
280
 
281
+ // this should be called before any flow rate changes
282
+ function _updateStats(uint256 _amount) internal {
283
+ //use last rate before the current possible rate update
284
+ stats.netIncome += uint96(stats.lastIncomeRate) * (block.timestamp - stats.lastUpdate);
285
+ uint feeBps;
286
+ if (address(getRegistry()) != address(0)) {
287
+ feeBps = getRegistry().feeBps();
288
+ //fees sent to last recipient, the flowRate to recipient still wasnt updated.
289
+ stats.totalFees +=
290
+ uint96(superToken.getFlowRate(address(this), stats.lastFeeRecipient)) *
291
+ (block.timestamp - stats.lastUpdate);
292
+ }
293
+ if (_amount > 0) {
294
+ stats.netIncome += (_amount * (10000 - feeBps)) / 10000;
295
+ stats.totalFees += (_amount * feeBps) / 10000;
296
+ }
297
+ stats.lastUpdate = block.timestamp;
298
+ }
299
+
300
+ function _takeFeeFlow(int96 _diffRate, bytes memory _ctx) internal returns (bytes memory newCtx) {
301
+ newCtx = _ctx;
302
+ if (address(getRegistry()) == address(0)) return newCtx;
303
+ address recipient = getRegistry().feeRecipient();
304
+ int96 curFeeRate = superToken.getFlowRate(address(this), stats.lastFeeRecipient);
305
+ bool newRecipient;
306
+ if (recipient != stats.lastFeeRecipient) {
307
+ newRecipient = true;
308
+ if (stats.lastFeeRecipient != address(0)) {
309
+ //delete old recipient flow
310
+ if (curFeeRate > 0)
311
+ newCtx = cfaV1.deleteFlowWithCtx(newCtx, address(this), stats.lastFeeRecipient, superToken); //passing in the ctx which is sent to the callback here
312
+ }
313
+ stats.lastFeeRecipient = recipient;
314
+ }
315
+ if (recipient == address(0)) return newCtx;
316
+
317
+ int96 feeRateChange = (_diffRate * int32(getRegistry().feeBps())) / 10000;
318
+ int96 newFeeRate = curFeeRate + feeRateChange;
319
+ if (newFeeRate <= 0 && newRecipient == false) {
320
+ newCtx = cfaV1.deleteFlowWithCtx(newCtx, address(this), recipient, superToken); //passing in the ctx which is sent to the callback here
321
+ } else if (curFeeRate > 0 && newRecipient == false) {
322
+ newCtx = cfaV1.updateFlowWithCtx(newCtx, recipient, superToken, newFeeRate); //passing in the ctx which is sent to the callback here
323
+ } else if (newFeeRate > 0) newCtx = cfaV1.createFlowWithCtx(newCtx, recipient, superToken, newFeeRate); //passing in the ctx which is sent to the callback here
324
+ }
325
+
326
+ function _takeFeeSingle(uint256 _amount) internal {
327
+ if (address(getRegistry()) == address(0)) return;
328
+ address recipient = getRegistry().feeRecipient();
329
+ if (recipient == address(0)) return;
330
+
331
+ uint256 fee = (_amount * getRegistry().feeBps()) / 10000;
332
+ TransferHelper.safeTransfer(address(superToken), recipient, fee);
333
+ }
334
+
335
+ /**
336
+ * for methods that can be called via superfluid batch or directly
337
+ */
260
338
  modifier onlyHostOrSender(address _sender) {
261
339
  if (msg.sender != _sender && msg.sender != address(host)) revert ONLY_HOST_OR_SENDER(msg.sender);
262
340
  _;
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity >=0.8.0;
3
+
4
+ interface IGoodCollectiveSuperApp {
5
+ struct Stats {
6
+ uint256 netIncome; //without fees
7
+ uint256 totalFees;
8
+ uint256 lastUpdate;
9
+ address lastFeeRecipient;
10
+ int96 lastIncomeRate;
11
+ }
12
+ }
@@ -0,0 +1,83 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity >=0.8.0;
4
+
5
+ import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
6
+ import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
7
+ import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
8
+ import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
9
+
10
+ import "../GoodCollective/IGoodCollectiveSuperApp.sol";
11
+
12
+ library HelperLibrary {
13
+ using SuperTokenV1Library for ISuperToken;
14
+
15
+ /**
16
+ * @dev A struct containing information about a token swap
17
+ * @param swapFrom The address of the token being swapped
18
+ * @param amount The amount of tokens being swapped
19
+ * @param minReturn The minimum amount of tokens to be received in the swap
20
+ * @param timestamp The deadline for the swap to occur
21
+ * @param path The path of tokens to take in a uniswap v3 multi-hop swap, encoded as bytes
22
+ */
23
+ struct SwapData {
24
+ address swapFrom;
25
+ uint256 amount;
26
+ uint256 minReturn;
27
+ uint256 deadline;
28
+ bytes path;
29
+ }
30
+
31
+ function handleSwap(
32
+ ISwapRouter swapRouter,
33
+ SwapData memory _customData,
34
+ address outTokenIfNoPath,
35
+ address _sender
36
+ ) external {
37
+ // Transfer the tokens from the sender to this contract
38
+ TransferHelper.safeTransferFrom(_customData.swapFrom, _sender, address(this), _customData.amount);
39
+
40
+ // Approve the router to spend the tokens
41
+ TransferHelper.safeApprove(_customData.swapFrom, address(swapRouter), _customData.amount);
42
+
43
+ if (_customData.path.length > 0) {
44
+ // If a path is provided, execute a multi-hop swap
45
+ ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
46
+ path: _customData.path,
47
+ recipient: _sender,
48
+ deadline: _customData.deadline,
49
+ amountIn: _customData.amount,
50
+ amountOutMinimum: _customData.minReturn
51
+ });
52
+ swapRouter.exactInput(params);
53
+ } else {
54
+ // If no path is provided, execute a single-hop swap
55
+ ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
56
+ tokenIn: _customData.swapFrom,
57
+ tokenOut: outTokenIfNoPath,
58
+ fee: 10000,
59
+ recipient: _sender,
60
+ deadline: _customData.deadline,
61
+ amountIn: _customData.amount,
62
+ amountOutMinimum: _customData.minReturn,
63
+ sqrtPriceLimitX96: 0
64
+ });
65
+
66
+ // Execute the swap using `exactInputSingle`
67
+ swapRouter.exactInputSingle(params);
68
+ }
69
+ }
70
+
71
+ function getRealtimeStats(
72
+ IGoodCollectiveSuperApp.Stats memory stats,
73
+ ISuperToken superToken
74
+ ) external view returns (uint256 netIncome, uint256 totalFees, int96 incomeFlowRate, int96 feeRate) {
75
+ incomeFlowRate = stats.lastIncomeRate;
76
+ netIncome = stats.netIncome + uint96(stats.lastIncomeRate) * (block.timestamp - stats.lastUpdate);
77
+ feeRate = superToken.getFlowRate(address(this), stats.lastFeeRecipient);
78
+ totalFees =
79
+ stats.totalFees +
80
+ uint96(superToken.getFlowRate(address(this), stats.lastFeeRecipient)) *
81
+ (block.timestamp - stats.lastUpdate);
82
+ }
83
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gooddollar/goodcollective-contracts",
3
3
  "packageManager": "yarn@3.2.1",
4
- "version": "1.0.3",
4
+ "version": "1.0.5-beta.7a2c704",
5
5
  "license": "MIT",
6
6
  "types": "./typechain-types/index.ts",
7
7
  "files": [
@@ -10,11 +10,11 @@
10
10
  "releases"
11
11
  ],
12
12
  "devDependencies": {
13
- "@gooddollar/goodprotocol": "file:.yalc/@gooddollar/goodprotocol",
13
+ "@gooddollar/goodprotocol": "^2.0.15",
14
14
  "@nomicfoundation/hardhat-chai-matchers": "^1.0.0",
15
15
  "@nomicfoundation/hardhat-network-helpers": "^1.0.0",
16
16
  "@nomicfoundation/hardhat-toolbox": "2.*",
17
- "@nomicfoundation/hardhat-verify": "^1.0.1",
17
+ "@nomicfoundation/hardhat-verify": "^1.1.1",
18
18
  "@nomiclabs/hardhat-ethers": "^2.0.0",
19
19
  "@nomiclabs/hardhat-etherscan": "^3.0.0",
20
20
  "@openzeppelin/contracts": "^4.9.2",
@@ -26,13 +26,16 @@
26
26
  "@types/chai": "^4.2.0",
27
27
  "@types/mocha": ">=9.1.0",
28
28
  "@types/prettier": "^2",
29
+ "@types/sinon-chai": "^3.2.3",
29
30
  "@typescript-eslint/eslint-plugin": "^5.60.0",
30
31
  "@uniswap/v3-periphery": "^1.4.3",
31
32
  "chai": "^4.2.0",
32
33
  "dotenv": "^16.3.1",
34
+ "ethereum-waffle": "^3.0.0",
33
35
  "graphql": "^16.7.1",
34
- "hardhat": "2.14.*",
36
+ "hardhat": "^2.17.1",
35
37
  "hardhat-abi-exporter": "^2.10.1",
38
+ "hardhat-celo": "^0.0.4",
36
39
  "hardhat-contract-sizer": "^2.10.0",
37
40
  "hardhat-deploy": "^0.11.31",
38
41
  "hardhat-gas-reporter": "^1.0.8",
@@ -44,6 +47,7 @@
44
47
  "typescript": "^5.1.3"
45
48
  },
46
49
  "scripts": {
50
+ "build": "yarn compile",
47
51
  "compile": "npx hardhat compile",
48
52
  "clean": "npx hardhat clean",
49
53
  "solhint": "solhint ./contracts/**/*.sol",
@@ -58,7 +62,9 @@
58
62
  "test": "npx hardhat test",
59
63
  "test:coverage": "npx hardhat coverage",
60
64
  "deploy": "hardhat deploy --export-all ./releases/deployment.json",
61
- "prepublish": "yarn version patch && yarn compile",
62
- "publish": "yarn npm publish --access public"
65
+ "prepublish": "yarn version patch && yarn compile && git add package.json && git commit -m \"version bump\"",
66
+ "publish": "yarn npm publish --access public",
67
+ "test:setup": "yarn exec ./scripts/deployContracts.sh",
68
+ "verify": "npx hardhat run scripts/verify.ts --network ${0}"
63
69
  }
64
- }
70
+ }