@harvest-finance/harvest-strategy-arbitrum 0.0.1-security → 1.0.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.

Potentially problematic release.


This version of @harvest-finance/harvest-strategy-arbitrum might be problematic. Click here for more details.

Files changed (199) hide show
  1. package/README.md +127 -5
  2. package/contracts/base/Controller.sol +358 -0
  3. package/contracts/base/Drip.sol +86 -0
  4. package/contracts/base/PotPool.sol +367 -0
  5. package/contracts/base/ProfitSharingReceiver.sol +38 -0
  6. package/contracts/base/Reader.sol +54 -0
  7. package/contracts/base/RewardForwarder.sol +109 -0
  8. package/contracts/base/VaultProxy.sol +34 -0
  9. package/contracts/base/VaultStorage.sol +205 -0
  10. package/contracts/base/VaultV1.sol +371 -0
  11. package/contracts/base/VaultV1GMX.sol +465 -0
  12. package/contracts/base/VaultV2.sol +111 -0
  13. package/contracts/base/VaultV2GMX.sol +111 -0
  14. package/contracts/base/factory/MegaFactory.sol +120 -0
  15. package/contracts/base/factory/interface/IPoolFactory.sol +6 -0
  16. package/contracts/base/factory/interface/IStrategyFactory.sol +6 -0
  17. package/contracts/base/factory/interface/IVaultFactory.sol +7 -0
  18. package/contracts/base/factory/pool/PotPoolFactory.sol +41 -0
  19. package/contracts/base/factory/strategy/UpgradableStrategyFactory.sol +19 -0
  20. package/contracts/base/factory/vault/RegularVaultFactory.sol +34 -0
  21. package/contracts/base/incentives/GlobalIncentivesExecutor.sol +85 -0
  22. package/contracts/base/incentives/GlobalIncentivesHelper.sol +174 -0
  23. package/contracts/base/incentives/NotifyHelperGeneric.sol +61 -0
  24. package/contracts/base/incentives/NotifyHelperStateful.sol +290 -0
  25. package/contracts/base/incentives/ViewerNotifyHelperStateful.sol +25 -0
  26. package/contracts/base/inheritance/Controllable.sol +25 -0
  27. package/contracts/base/inheritance/ControllableInit.sol +30 -0
  28. package/contracts/base/inheritance/Governable.sol +28 -0
  29. package/contracts/base/inheritance/GovernableInit.sol +50 -0
  30. package/contracts/base/inheritance/IUpgradeSource.sol +7 -0
  31. package/contracts/base/inheritance/OwnableWhitelist.sol +17 -0
  32. package/contracts/base/inheritance/Storage.sol +35 -0
  33. package/contracts/base/interface/IBalDex.sol +7 -0
  34. package/contracts/base/interface/IController.sol +132 -0
  35. package/contracts/base/interface/IDex.sol +9 -0
  36. package/contracts/base/interface/IERC4626.sol +261 -0
  37. package/contracts/base/interface/IGMXStrategy.sol +37 -0
  38. package/contracts/base/interface/IGlobalIncentivesHelper.sol +6 -0
  39. package/contracts/base/interface/IPotPool.sol +70 -0
  40. package/contracts/base/interface/IProfitSharingReceiver.sol +9 -0
  41. package/contracts/base/interface/IRewardForwarder.sol +57 -0
  42. package/contracts/base/interface/IStrategy.sol +37 -0
  43. package/contracts/base/interface/IUniversalLiquidator.sol +21 -0
  44. package/contracts/base/interface/IUniversalLiquidatorRegistry.sol +20 -0
  45. package/contracts/base/interface/IUpgradeSource.sol +9 -0
  46. package/contracts/base/interface/IVault.sol +58 -0
  47. package/contracts/base/interface/IVaultGMX.sol +71 -0
  48. package/contracts/base/interface/aura/IAuraBaseRewardPool.sol +25 -0
  49. package/contracts/base/interface/aura/IAuraBooster.sol +17 -0
  50. package/contracts/base/interface/aura/IAuraDepositor.sol +7 -0
  51. package/contracts/base/interface/balancer/Gauge.sol +22 -0
  52. package/contracts/base/interface/balancer/IBVault.sol +580 -0
  53. package/contracts/base/interface/balancer/IBalancerMinter.sol +114 -0
  54. package/contracts/base/interface/balancer/IGyroPool.sol +7 -0
  55. package/contracts/base/interface/balancer/linearPool/ILinearPool.sol +184 -0
  56. package/contracts/base/interface/balancer/linearPool/ILinearPoolFactory.sol +16 -0
  57. package/contracts/base/interface/balancer/linearPool/ILinearPoolRebalancer.sol +8 -0
  58. package/contracts/base/interface/balancer/linearPool/IPoolSwapStructs.sol +56 -0
  59. package/contracts/base/interface/compound/CTokenInterface.sol +29 -0
  60. package/contracts/base/interface/compound/IComptroller.sol +9 -0
  61. package/contracts/base/interface/dolomite/IDepositWithdraw.sol +13 -0
  62. package/contracts/base/interface/dolomite/IDolomiteMargin.sol +15 -0
  63. package/contracts/base/interface/dolomite/IRewardsDistributor.sol +11 -0
  64. package/contracts/base/interface/gamma/IClearing.sol +7 -0
  65. package/contracts/base/interface/gamma/IHypervisor.sol +9 -0
  66. package/contracts/base/interface/gamma/IUniProxy.sol +14 -0
  67. package/contracts/base/interface/gmx/EventUtils.sol +253 -0
  68. package/contracts/base/interface/gmx/ICallbackReceiver.sol +119 -0
  69. package/contracts/base/interface/gmx/IDataStore.sol +7 -0
  70. package/contracts/base/interface/gmx/IExchangeRouter.sol +38 -0
  71. package/contracts/base/interface/gmx/IGMXViewer.sol +7 -0
  72. package/contracts/base/interface/gmx/IHandler.sol +12 -0
  73. package/contracts/base/interface/gmx/IMarket.sol +7 -0
  74. package/contracts/base/interface/gmx/IOracle.sol +6 -0
  75. package/contracts/base/interface/gmx/IPriceFeed.sol +12 -0
  76. package/contracts/base/interface/gmx/IReader.sol +49 -0
  77. package/contracts/base/interface/gmx/IRoleStore.sol +6 -0
  78. package/contracts/base/interface/ipor/Errors.sol +20 -0
  79. package/contracts/base/interface/ipor/FuseStorageLib.sol +71 -0
  80. package/contracts/base/interface/ipor/FusesLib.sol +149 -0
  81. package/contracts/base/interface/ipor/IFuseCommon.sol +9 -0
  82. package/contracts/base/interface/ipor/IFuseInstantWithdraw.sol +14 -0
  83. package/contracts/base/interface/ipor/IMarketBalanceFuse.sol +10 -0
  84. package/contracts/base/interface/ipor/IPriceOracleMiddleware.sol +42 -0
  85. package/contracts/base/interface/ipor/IporMath.sol +110 -0
  86. package/contracts/base/interface/ipor/PlasmaVaultConfigLib.sol +106 -0
  87. package/contracts/base/interface/ipor/PlasmaVaultLib.sol +293 -0
  88. package/contracts/base/interface/ipor/PlasmaVaultStorageLib.sol +352 -0
  89. package/contracts/base/interface/merkl/IDistributor.sol +6 -0
  90. package/contracts/base/interface/notional/INProxy.sol +44 -0
  91. package/contracts/base/interface/notional/IPrimeToken.sol +6 -0
  92. package/contracts/base/interface/venus/IRewardsDistributor.sol +6 -0
  93. package/contracts/base/interface/weth/IWETH.sol +39 -0
  94. package/contracts/base/ipor/Erc4626BalanceFuse.sol +54 -0
  95. package/contracts/base/ipor/Erc4626SupplyFuse.sol +134 -0
  96. package/contracts/base/noop/NoopStrategyUpgradeable.sol +90 -0
  97. package/contracts/base/upgradability/BaseUpgradeabilityProxy.sol +60 -0
  98. package/contracts/base/upgradability/BaseUpgradeableStrategy.sol +144 -0
  99. package/contracts/base/upgradability/BaseUpgradeableStrategyStorage.sol +284 -0
  100. package/contracts/base/upgradability/IUpgradable.sol +7 -0
  101. package/contracts/base/upgradability/ReentrancyGuardUpgradeable.sol +51 -0
  102. package/contracts/base/upgradability/StrategyProxy.sol +34 -0
  103. package/contracts/strategies/aura/AuraStrategy.sol +403 -0
  104. package/contracts/strategies/aura/AuraStrategyMainnet_MORE_GYD.sol +32 -0
  105. package/contracts/strategies/aura/AuraStrategyMainnet_sUSDe_GYD.sol +31 -0
  106. package/contracts/strategies/aura/AuraStrategyMainnet_waFRAX_sFRAX.sol +31 -0
  107. package/contracts/strategies/aura/AuraStrategyMainnet_waGHO_GYD.sol +31 -0
  108. package/contracts/strategies/aura/AuraStrategyMainnet_waUSDC_GHO.sol +32 -0
  109. package/contracts/strategies/aura/AuraStrategyMainnet_waUSDC_GYD.sol +31 -0
  110. package/contracts/strategies/aura/AuraStrategyMainnet_waUSDT_GYD.sol +31 -0
  111. package/contracts/strategies/aura/AuraStrategyMainnet_wstETH_GYD.sol +31 -0
  112. package/contracts/strategies/camelot/CamelotV3Strategy.sol +304 -0
  113. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_ARB_USDC.sol +28 -0
  114. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_ETH_USDC.sol +28 -0
  115. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_ETH_USDT.sol +28 -0
  116. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_GMX_ETH.sol +28 -0
  117. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_GRAIL_ETH.sol +28 -0
  118. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_USDC_USDT.sol +28 -0
  119. package/contracts/strategies/camelot/CamelotV3StrategyMainnet_WBTC_ETH.sol +28 -0
  120. package/contracts/strategies/dolomite/DolomiteLendStrategy.sol +273 -0
  121. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_DAI.sol +26 -0
  122. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_GMX.sol +26 -0
  123. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_USDC.sol +26 -0
  124. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_USDCe.sol +26 -0
  125. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_USDT.sol +26 -0
  126. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_WBTC.sol +26 -0
  127. package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_WETH.sol +26 -0
  128. package/contracts/strategies/fluid/FluidLendStrategy.sol +241 -0
  129. package/contracts/strategies/fluid/FluidLendStrategyMainnet_ETH.sol +25 -0
  130. package/contracts/strategies/fluid/FluidLendStrategyMainnet_USDC.sol +25 -0
  131. package/contracts/strategies/fluid/FluidLendStrategyMainnet_USDT.sol +25 -0
  132. package/contracts/strategies/gmx/GMXStrategy.sol +472 -0
  133. package/contracts/strategies/gmx/GMXStrategyMainnet_WBTC.sol +25 -0
  134. package/contracts/strategies/gmx/GMXViewer.sol +110 -0
  135. package/contracts/strategies/notional/NotionalStrategy.sol +223 -0
  136. package/contracts/strategies/notional/NotionalStrategyMainnet_nETH.sol +27 -0
  137. package/contracts/strategies/notional/NotionalStrategyMainnet_nUSDC.sol +27 -0
  138. package/contracts/strategies/notional/NotionalStrategyMainnet_nUSDT.sol +27 -0
  139. package/contracts/strategies/notional/NotionalStrategyMainnet_nwstETH.sol +27 -0
  140. package/contracts/strategies/venus/VenusFoldStrategy.sol +591 -0
  141. package/contracts/strategies/venus/VenusFoldStrategyMainnet_ARB.sol +32 -0
  142. package/contracts/strategies/venus/VenusFoldStrategyMainnet_ETH_core.sol +32 -0
  143. package/contracts/strategies/venus/VenusFoldStrategyMainnet_ETH_lsd.sol +32 -0
  144. package/contracts/strategies/venus/VenusFoldStrategyMainnet_USDC.sol +32 -0
  145. package/contracts/strategies/venus/VenusFoldStrategyMainnet_USDT.sol +32 -0
  146. package/contracts/strategies/venus/VenusFoldStrategyMainnet_WBTC.sol +32 -0
  147. package/hardhat.config.js +60 -0
  148. package/index.js +42 -0
  149. package/package.json +38 -6
  150. package/scripts/01-deploy-vault-regular-with-upgradable-strategy.js +41 -0
  151. package/scripts/02-deploy-vault-regular.js +35 -0
  152. package/scripts/03-deploy-upgradable-strategy.js +40 -0
  153. package/scripts/04-deploy-new-implementation.js +24 -0
  154. package/scripts/05-deploy-GMXViewer.js +17 -0
  155. package/scripts/06-deploy-GMXVault.js +49 -0
  156. package/scripts/07-deploy-ipor-fuses.js +29 -0
  157. package/scripts/08-deploy-drip.js +20 -0
  158. package/scripts/README.md +55 -0
  159. package/scripts/utils.js +22 -0
  160. package/test/aura/more-gyd.js +140 -0
  161. package/test/aura/susde-gyd.js +140 -0
  162. package/test/aura/wafrax-sfrax.js +140 -0
  163. package/test/aura/wagho-gyd.js +140 -0
  164. package/test/aura/wausdc-gho.js +141 -0
  165. package/test/aura/wausdc-gyd.js +140 -0
  166. package/test/aura/wausdt-gyd.js +140 -0
  167. package/test/aura/wsteth-gyd.js +138 -0
  168. package/test/camelot/arb-usdc.js +125 -0
  169. package/test/camelot/eth-usdc.js +125 -0
  170. package/test/camelot/eth-usdt.js +125 -0
  171. package/test/camelot/gmx-eth.js +125 -0
  172. package/test/camelot/grail-eth.js +125 -0
  173. package/test/camelot/usdc-usdt.js +125 -0
  174. package/test/camelot/wbtc-eth.js +125 -0
  175. package/test/dolomite/dai.js +127 -0
  176. package/test/dolomite/gmx.js +134 -0
  177. package/test/dolomite/usdc.js +127 -0
  178. package/test/dolomite/usdce.js +127 -0
  179. package/test/dolomite/usdt.js +127 -0
  180. package/test/dolomite/wbtc.js +127 -0
  181. package/test/dolomite/weth.js +127 -0
  182. package/test/fluid/eth.js +127 -0
  183. package/test/fluid/usdc.js +134 -0
  184. package/test/fluid/usdt.js +134 -0
  185. package/test/gmx/wbtc.js +184 -0
  186. package/test/notional/neth.js +133 -0
  187. package/test/notional/nusdc.js +133 -0
  188. package/test/notional/nusdt.js +133 -0
  189. package/test/notional/nwsteth.js +133 -0
  190. package/test/test-config.js +28 -0
  191. package/test/utilities/Utils.js +96 -0
  192. package/test/utilities/hh-utils.js +248 -0
  193. package/test/utilities/make-vault.js +16 -0
  194. package/test/venus/arb.js +135 -0
  195. package/test/venus/eth-core.js +133 -0
  196. package/test/venus/eth-lsd.js +133 -0
  197. package/test/venus/usdc.js +133 -0
  198. package/test/venus/usdt.js +133 -0
  199. package/test/venus/wbtc.js +133 -0
@@ -0,0 +1,290 @@
1
+ // SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";
5
+ import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
6
+ import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
7
+ import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
8
+ import "../inheritance/Controllable.sol";
9
+ import "../PotPool.sol";
10
+
11
+ interface INotifyHelperGeneric {
12
+ function feeRewardForwarder() external view returns (address);
13
+
14
+ function notifyPools(uint256[] calldata amounts,
15
+ address[] calldata pools,
16
+ uint256 sum, address token
17
+ ) external;
18
+ }
19
+
20
+ interface INotifyHelperAmpliFARM {
21
+ function notifyPools(uint256[] calldata amounts,
22
+ address[] calldata pools,
23
+ uint256 sum
24
+ ) external;
25
+ }
26
+
27
+ contract NotifyHelperStateful is Controllable {
28
+
29
+ using SafeMathUpgradeable for uint256;
30
+ using SafeERC20Upgradeable for IERC20Upgradeable;
31
+
32
+ event ChangerSet(address indexed account, bool value);
33
+ event NotifierSet(address indexed account, bool value);
34
+ event Vesting(address pool, uint256 amount);
35
+ event PoolChanged(address indexed pool, uint256 percentage, uint256 notificationType, bool vests);
36
+
37
+ enum NotificationType {
38
+ VOID, AMPLIFARM, FARM, TRANSFER, PROFIT_SHARE, TOKEN
39
+ }
40
+
41
+ struct Notification {
42
+ address poolAddress;
43
+ NotificationType notificationType;
44
+ uint256 percentage;
45
+ bool vests;
46
+ }
47
+
48
+ struct WorkingNotification {
49
+ address[] pools;
50
+ uint256[] amounts;
51
+ uint256 checksum;
52
+ uint256 counter;
53
+ }
54
+
55
+ uint256 public VESTING_DENOMINATOR = 3;
56
+ uint256 public VESTING_NUMERATOR = 2;
57
+
58
+ mapping (address => bool) changer;
59
+ mapping (address => bool) notifier;
60
+
61
+ address public notifyHelperRegular;
62
+ address public notifyHelperAmpliFARM;
63
+ address public rewardToken;
64
+
65
+ Notification[] public notifications;
66
+ mapping (address => uint256) public poolToIndex;
67
+ mapping (uint256 => uint256) public numbers; // NotificationType to the number of pools
68
+
69
+ address public reserve;
70
+ address public vestingEscrow;
71
+ uint256 public totalPercentage; // maintain state to not have to calculate during emissions
72
+
73
+ modifier onlyChanger {
74
+ require(changer[msg.sender] || msg.sender == governance(), "Only changer");
75
+ _;
76
+ }
77
+
78
+ modifier onlyNotifier {
79
+ require(notifier[msg.sender], "Only notifier");
80
+ _;
81
+ }
82
+
83
+ constructor(address _storage,
84
+ address _notifyHelperRegular,
85
+ address _rewardToken,
86
+ address _notifyHelperAmpliFARM,
87
+ address _escrow,
88
+ address _reserve)
89
+ Controllable(_storage) {
90
+ // used for getting a reference to FeeRewardForwarder
91
+ notifyHelperRegular = _notifyHelperRegular;
92
+ rewardToken = _rewardToken;
93
+ notifyHelperAmpliFARM = _notifyHelperAmpliFARM;
94
+ vestingEscrow = _escrow;
95
+ reserve = _reserve;
96
+ require(_reserve != address(0), "invalid reserve");
97
+ require(_escrow != address(0), "invalid escrow");
98
+ }
99
+
100
+ /// Whitelisted entities can notify pools based on the state, both for FARM and iFARM
101
+ /// The only whitelisted entity here would be the minter helper
102
+ function notifyPools(uint256 total, uint256 /*timestamp*/) public onlyNotifier {
103
+ // transfer the tokens from the msg.sender to here
104
+ IERC20Upgradeable(rewardToken).safeTransferFrom(msg.sender, address(this), total);
105
+
106
+ // prepare the notification data
107
+ WorkingNotification memory ampliFARM = WorkingNotification(
108
+ new address[](numbers[uint256(NotificationType.AMPLIFARM)]),
109
+ new uint256[](numbers[uint256(NotificationType.AMPLIFARM)]),
110
+ 0,
111
+ 0
112
+ );
113
+ WorkingNotification memory regular = WorkingNotification(
114
+ new address[](numbers[uint256(NotificationType.FARM)]),
115
+ new uint256[](numbers[uint256(NotificationType.FARM)]),
116
+ 0,
117
+ 0
118
+ );
119
+ uint256 vestingAmount = 0;
120
+ for (uint256 i = 0; i < notifications.length; i++) {
121
+ Notification storage notification = notifications[i];
122
+ if (notification.notificationType == NotificationType.TRANSFER) {
123
+ // simple transfer
124
+ IERC20Upgradeable(rewardToken).safeTransfer(
125
+ notification.poolAddress,
126
+ total.mul(notification.percentage).div(totalPercentage)
127
+ );
128
+ } else {
129
+ // FARM or ampliFARM notification
130
+ WorkingNotification memory toUse = notification.notificationType == NotificationType.FARM ? regular : ampliFARM;
131
+ toUse.amounts[toUse.counter] = total.mul(notification.percentage).div(totalPercentage);
132
+ if (notification.vests) {
133
+ uint256 toVest = toUse.amounts[toUse.counter].mul(VESTING_NUMERATOR).div(VESTING_DENOMINATOR);
134
+ toUse.amounts[toUse.counter] = toUse.amounts[toUse.counter].sub(toVest);
135
+ vestingAmount = vestingAmount.add(toVest);
136
+ emit Vesting(notification.poolAddress, toVest);
137
+ }
138
+ toUse.pools[toUse.counter] = notification.poolAddress;
139
+ toUse.checksum = toUse.checksum.add(toUse.amounts[toUse.counter]);
140
+ toUse.counter = toUse.counter.add(1);
141
+ }
142
+ }
143
+
144
+ // handle vesting
145
+ if (vestingAmount > 0) {
146
+ IERC20Upgradeable(rewardToken).safeTransfer(vestingEscrow, vestingAmount);
147
+ }
148
+
149
+ // ampliFARM notifications
150
+ if (ampliFARM.checksum > 0) {
151
+ IERC20Upgradeable(rewardToken).approve(notifyHelperAmpliFARM, ampliFARM.checksum);
152
+ INotifyHelperAmpliFARM(notifyHelperAmpliFARM).notifyPools(ampliFARM.amounts, ampliFARM.pools, ampliFARM.checksum);
153
+ }
154
+
155
+ // regular notifications
156
+ if (regular.checksum > 0) {
157
+ IERC20Upgradeable(rewardToken).approve(notifyHelperRegular, regular.checksum);
158
+ INotifyHelperGeneric(notifyHelperRegular).notifyPools(
159
+ regular.amounts, regular.pools, regular.checksum, rewardToken
160
+ );
161
+ }
162
+
163
+ // send rest to the reserve
164
+ uint256 remainingBalance = IERC20Upgradeable(rewardToken).balanceOf(address(this));
165
+ if (remainingBalance > 0) {
166
+ IERC20Upgradeable(rewardToken).safeTransfer(reserve, remainingBalance);
167
+ }
168
+ }
169
+
170
+ /// Returning the governance
171
+ function transferGovernance(address target, address newStorage) external onlyGovernance {
172
+ Governable(target).setStorage(newStorage);
173
+ }
174
+
175
+ /// The governance configures whitelists
176
+ function setChanger(address who, bool value) external onlyGovernance {
177
+ changer[who] = value;
178
+ emit ChangerSet(who, value);
179
+ }
180
+
181
+ /// The governance configures whitelists
182
+ function setNotifier(address who, bool value) external onlyGovernance {
183
+ notifier[who] = value;
184
+ emit NotifierSet(who, value);
185
+ }
186
+
187
+ /// Whitelisted entity makes changes to the notifications
188
+ function setPoolBatch(address[] calldata poolAddress, uint256[] calldata poolPercentage, NotificationType[] calldata notificationType, bool[] calldata vests) external onlyChanger {
189
+ for (uint256 i = 0; i < poolAddress.length; i++) {
190
+ setPool(poolAddress[i], poolPercentage[i], notificationType[i], vests[i]);
191
+ }
192
+ }
193
+
194
+ /// Pool management, adds, updates or removes a transfer/notification
195
+ function setPool(address poolAddress, uint256 poolPercentage, NotificationType notificationType, bool vests) public onlyChanger {
196
+ require(notificationType != NotificationType.VOID, "Use valid indication");
197
+ require(notificationType != NotificationType.TOKEN, "We do not use TOKEN here");
198
+ if (notificationExists(poolAddress) && poolPercentage == 0) {
199
+ // remove
200
+ removeNotification(poolAddress);
201
+ } else if (notificationExists(poolAddress)) {
202
+ // update
203
+ updateNotification(poolAddress, notificationType, poolPercentage, vests);
204
+ } else if (poolPercentage > 0) {
205
+ // add because it does not exist
206
+ addNotification(poolAddress, poolPercentage, notificationType, vests);
207
+ }
208
+ emit PoolChanged(poolAddress, poolPercentage, uint256(notificationType), vests);
209
+ }
210
+
211
+ /// Configuration method for vesting for governance
212
+ function setVestingEscrow(address _escrow) external onlyGovernance {
213
+ vestingEscrow = _escrow;
214
+ }
215
+
216
+ /// Configuration method for vesting for governance
217
+ function setVesting(uint256 _numerator, uint256 _denominator) external onlyGovernance {
218
+ VESTING_DENOMINATOR = _numerator;
219
+ VESTING_NUMERATOR = _denominator;
220
+ }
221
+
222
+ function notificationExists(address poolAddress) public view returns(bool) {
223
+ if (notifications.length == 0) return false;
224
+ if (poolToIndex[poolAddress] != 0) return true;
225
+ return (notifications[0].poolAddress == poolAddress);
226
+ }
227
+
228
+ function removeNotification(address poolAddress) internal {
229
+ require(notificationExists(poolAddress), "notification does not exist");
230
+ uint256 index = poolToIndex[poolAddress];
231
+ Notification storage notification = notifications[index];
232
+
233
+ totalPercentage = totalPercentage.sub(notification.percentage);
234
+ numbers[uint256(notification.notificationType)] = numbers[uint256(notification.notificationType)].sub(1);
235
+
236
+ // move the last element here and pop from the array
237
+ notifications[index] = notifications[notifications.length.sub(1)];
238
+ poolToIndex[notifications[index].poolAddress] = index;
239
+ poolToIndex[poolAddress] = 0;
240
+ notifications.pop();
241
+ }
242
+
243
+ function updateNotification(address poolAddress, NotificationType notificationType, uint256 percentage, bool vesting) internal {
244
+ require(notificationExists(poolAddress), "notification does not exist");
245
+ require(percentage > 0, "notification is 0");
246
+ uint256 index = poolToIndex[poolAddress];
247
+ totalPercentage = totalPercentage.sub(notifications[index].percentage).add(percentage);
248
+ notifications[index].percentage = percentage;
249
+ notifications[index].vests = vesting;
250
+ if (notifications[index].notificationType != notificationType) {
251
+ numbers[uint256(notifications[index].notificationType)] = numbers[uint256(notifications[index].notificationType)].sub(1);
252
+ notifications[index].notificationType = notificationType;
253
+ numbers[uint256(notifications[index].notificationType)] = numbers[uint256(notifications[index].notificationType)].add(1);
254
+ }
255
+ }
256
+
257
+ function addNotification(address poolAddress, uint256 percentage, NotificationType notificationType, bool vesting) internal {
258
+ require(!notificationExists(poolAddress), "notification exists");
259
+ require(percentage > 0, "notification is 0");
260
+ require(PotPool(poolAddress).getRewardTokenIndex(rewardToken) != uint256(type(uint256).max), "Token not configured on pot pool");
261
+ Notification memory notification = Notification(poolAddress, notificationType, percentage, vesting);
262
+ notifications.push(notification);
263
+ totalPercentage = totalPercentage.add(notification.percentage);
264
+ numbers[uint256(notification.notificationType)] = numbers[uint256(notification.notificationType)].add(1);
265
+ poolToIndex[notification.poolAddress] = notifications.length.sub(1);
266
+ require(notificationExists(poolAddress), "notification was not added");
267
+ }
268
+
269
+ /// emergency draining of tokens and ETH as there should be none staying here
270
+ function emergencyDrain(address token, uint256 amount) public onlyGovernance {
271
+ if (token == address(0)) {
272
+ payable(msg.sender).transfer(amount);
273
+ } else {
274
+ IERC20Upgradeable(token).safeTransfer(msg.sender, amount);
275
+ }
276
+ }
277
+
278
+ function getConfig(uint256 totalAmount) external view returns(address[] memory, uint256[] memory, uint256[] memory) {
279
+ address[] memory pools = new address[](notifications.length);
280
+ uint256[] memory percentages = new uint256[](notifications.length);
281
+ uint256[] memory amounts = new uint256[](notifications.length);
282
+ for (uint256 i = 0; i < notifications.length; i++) {
283
+ Notification storage notification = notifications[i];
284
+ pools[i] = notification.poolAddress;
285
+ percentages[i] = notification.percentage.mul(1000000).div(totalPercentage);
286
+ amounts[i] = notification.percentage.mul(totalAmount).div(totalPercentage);
287
+ }
288
+ return (pools, percentages, amounts);
289
+ }
290
+ }
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "./NotifyHelperStateful.sol";
5
+
6
+ contract ViewerNotifyHelperStateful {
7
+
8
+ /// configuration check method
9
+ function getConfig(address helper, uint256 totalAmount)
10
+ external view returns(address[] memory, uint256[] memory, uint256[] memory, uint256[] memory) {
11
+ (
12
+ address[] memory pools,
13
+ uint256[] memory percentages,
14
+ uint256[] memory amounts
15
+ ) = NotifyHelperStateful(helper).getConfig(totalAmount);
16
+
17
+ uint256[] memory types = new uint256[](pools.length);
18
+ for (uint256 i = 0; i < pools.length; i++) {
19
+ (, NotifyHelperStateful.NotificationType notificationType, , ) = NotifyHelperStateful(helper).notifications(i);
20
+ types[i] = uint256(notificationType);
21
+ }
22
+
23
+ return (pools, percentages, amounts, types);
24
+ }
25
+ }
@@ -0,0 +1,25 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "./Governable.sol";
5
+
6
+ contract Controllable is Governable {
7
+
8
+ constructor(address _storage) Governable(_storage) {
9
+ }
10
+
11
+ modifier onlyController() {
12
+ require(store.isController(msg.sender), "Not a controller");
13
+ _;
14
+ }
15
+
16
+ modifier onlyControllerOrGovernance(){
17
+ require((store.isController(msg.sender) || store.isGovernance(msg.sender)),
18
+ "The caller must be controller or governance");
19
+ _;
20
+ }
21
+
22
+ function controller() public view returns (address) {
23
+ return store.controller();
24
+ }
25
+ }
@@ -0,0 +1,30 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "./GovernableInit.sol";
5
+
6
+ // A clone of Governable supporting the Initializable interface and pattern
7
+ contract ControllableInit is GovernableInit {
8
+
9
+ constructor() {
10
+ }
11
+
12
+ function initialize(address _storage) public override initializer {
13
+ GovernableInit.initialize(_storage);
14
+ }
15
+
16
+ modifier onlyController() {
17
+ require(Storage(_storage()).isController(msg.sender), "Not a controller");
18
+ _;
19
+ }
20
+
21
+ modifier onlyControllerOrGovernance(){
22
+ require((Storage(_storage()).isController(msg.sender) || Storage(_storage()).isGovernance(msg.sender)),
23
+ "The caller must be controller or governance");
24
+ _;
25
+ }
26
+
27
+ function controller() public view returns (address) {
28
+ return Storage(_storage()).controller();
29
+ }
30
+ }
@@ -0,0 +1,28 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "./Storage.sol";
5
+
6
+ contract Governable {
7
+
8
+ Storage public store;
9
+
10
+ constructor(address _store) {
11
+ require(_store != address(0), "new storage shouldn't be empty");
12
+ store = Storage(_store);
13
+ }
14
+
15
+ modifier onlyGovernance() {
16
+ require(store.isGovernance(msg.sender), "Not governance");
17
+ _;
18
+ }
19
+
20
+ function setStorage(address _store) public onlyGovernance {
21
+ require(_store != address(0), "new storage shouldn't be empty");
22
+ store = Storage(_store);
23
+ }
24
+
25
+ function governance() public view returns (address) {
26
+ return store.governance();
27
+ }
28
+ }
@@ -0,0 +1,50 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "../upgradability/ReentrancyGuardUpgradeable.sol";
5
+ import "./Storage.sol";
6
+
7
+ // A clone of Governable supporting the Initializable interface and pattern
8
+ contract GovernableInit is ReentrancyGuardUpgradeable {
9
+
10
+ bytes32 internal constant _STORAGE_SLOT = 0xa7ec62784904ff31cbcc32d09932a58e7f1e4476e1d041995b37c917990b16dc;
11
+
12
+ modifier onlyGovernance() {
13
+ require(Storage(_storage()).isGovernance(msg.sender), "Not governance");
14
+ _;
15
+ }
16
+
17
+ constructor() {
18
+ assert(_STORAGE_SLOT == bytes32(uint256(keccak256("eip1967.governableInit.storage")) - 1));
19
+ }
20
+
21
+ function initialize(address _store) public virtual initializer {
22
+ _setStorage(_store);
23
+ ReentrancyGuardUpgradeable.initialize();
24
+ }
25
+
26
+ function _setStorage(address newStorage) private {
27
+ bytes32 slot = _STORAGE_SLOT;
28
+ // solhint-disable-next-line no-inline-assembly
29
+ assembly {
30
+ sstore(slot, newStorage)
31
+ }
32
+ }
33
+
34
+ function setStorage(address _store) public onlyGovernance {
35
+ require(_store != address(0), "new storage shouldn't be empty");
36
+ _setStorage(_store);
37
+ }
38
+
39
+ function _storage() internal view returns (address str) {
40
+ bytes32 slot = _STORAGE_SLOT;
41
+ // solhint-disable-next-line no-inline-assembly
42
+ assembly {
43
+ str := sload(slot)
44
+ }
45
+ }
46
+
47
+ function governance() public view returns (address) {
48
+ return Storage(_storage()).governance();
49
+ }
50
+ }
@@ -0,0 +1,7 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ interface IUpgradeSource {
5
+ function shouldUpgrade() external view returns (bool, address);
6
+ function finalizeUpgrade() external;
7
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ import "@openzeppelin/contracts/access/Ownable.sol";
5
+
6
+ contract OwnableWhitelist is Ownable {
7
+ mapping (address => bool) public whitelist;
8
+
9
+ modifier onlyWhitelisted() {
10
+ require(whitelist[msg.sender] || msg.sender == owner(), "not allowed");
11
+ _;
12
+ }
13
+
14
+ function setWhitelist(address target, bool isWhitelisted) public onlyOwner {
15
+ whitelist[target] = isWhitelisted;
16
+ }
17
+ }
@@ -0,0 +1,35 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ contract Storage {
5
+
6
+ address public governance;
7
+ address public controller;
8
+
9
+ constructor() {
10
+ governance = msg.sender;
11
+ }
12
+
13
+ modifier onlyGovernance() {
14
+ require(isGovernance(msg.sender), "Not governance");
15
+ _;
16
+ }
17
+
18
+ function setGovernance(address _governance) public onlyGovernance {
19
+ require(_governance != address(0), "new governance shouldn't be empty");
20
+ governance = _governance;
21
+ }
22
+
23
+ function setController(address _controller) public onlyGovernance {
24
+ require(_controller != address(0), "new controller shouldn't be empty");
25
+ controller = _controller;
26
+ }
27
+
28
+ function isGovernance(address account) public view returns (bool) {
29
+ return account == governance;
30
+ }
31
+
32
+ function isController(address account) public view returns (bool) {
33
+ return account == controller;
34
+ }
35
+ }
@@ -0,0 +1,7 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ interface IBalDex {
5
+ function setFee(address token0, address token1, uint24 fee) external;
6
+ function setPool(address token0, address token1, bytes32 pool) external;
7
+ }
@@ -0,0 +1,132 @@
1
+ // SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ interface IController {
5
+
6
+ // ========================= Events =========================
7
+
8
+ event QueueProfitSharingChange(uint profitSharingNumerator, uint validAtTimestamp);
9
+ event ConfirmProfitSharingChange(uint profitSharingNumerator);
10
+
11
+ event QueueStrategistFeeChange(uint strategistFeeNumerator, uint validAtTimestamp);
12
+ event ConfirmStrategistFeeChange(uint strategistFeeNumerator);
13
+
14
+ event QueuePlatformFeeChange(uint platformFeeNumerator, uint validAtTimestamp);
15
+ event ConfirmPlatformFeeChange(uint platformFeeNumerator);
16
+
17
+ event QueueNextImplementationDelay(uint implementationDelay, uint validAtTimestamp);
18
+ event ConfirmNextImplementationDelay(uint implementationDelay);
19
+
20
+ event AddedStakingContract(address indexed stakingContract);
21
+ event RemovedStakingContract(address indexed stakingContract);
22
+
23
+ event SharePriceChangeLog(
24
+ address indexed vault,
25
+ address indexed strategy,
26
+ uint256 oldSharePrice,
27
+ uint256 newSharePrice,
28
+ uint256 timestamp
29
+ );
30
+
31
+ // ==================== Functions ====================
32
+
33
+ /**
34
+ * An EOA can safely interact with the system no matter what. If you're using Metamask, you're using an EOA. Only
35
+ * smart contracts may be affected by this grey list. This contract will not be able to ban any EOA from the system
36
+ * even if an EOA is being added to the greyList, he/she will still be able to interact with the whole system as if
37
+ * nothing happened. Only smart contracts will be affected by being added to the greyList. This grey list is only
38
+ * used in VaultV3.sol, see the code there for reference
39
+ */
40
+ function greyList(address _target) external view returns (bool);
41
+
42
+ function addressWhiteList(address _target) external view returns (bool);
43
+
44
+ function codeWhiteList(address _target) external view returns (bool);
45
+
46
+ function addToWhitelist(address _target) external;
47
+
48
+ function addCodeToWhitelist(address _target) external;
49
+
50
+ function store() external view returns (address);
51
+
52
+ function governance() external view returns (address);
53
+
54
+ function doHardWork(address _vault) external;
55
+
56
+ function addHardWorker(address _worker) external;
57
+
58
+ function removeHardWorker(address _worker) external;
59
+
60
+ function salvage(address _token, uint256 amount) external;
61
+
62
+ function salvageStrategy(address _strategy, address _token, uint256 amount) external;
63
+
64
+ /**
65
+ * @return The targeted profit token to convert all-non-compounding rewards to. Defaults to WETH.
66
+ */
67
+ function targetToken() external view returns (address);
68
+
69
+ function setTargetToken(address _targetToken) external;
70
+
71
+ function profitSharingReceiver() external view returns (address);
72
+
73
+ function setProfitSharingReceiver(address _profitSharingReceiver) external;
74
+
75
+ function protocolFeeReceiver() external view returns (address);
76
+
77
+ function setProtocolFeeReceiver(address _protocolFeeReceiver) external;
78
+
79
+ function rewardForwarder() external view returns (address);
80
+
81
+ function setRewardForwarder(address _rewardForwarder) external;
82
+
83
+ function universalLiquidator() external view returns (address);
84
+
85
+ function setUniversalLiquidator(address _universalLiquidator) external;
86
+
87
+ function dolomiteYieldFarmingRouter() external view returns (address);
88
+
89
+ function setDolomiteYieldFarmingRouter(address _value) external;
90
+
91
+ function nextImplementationDelay() external view returns (uint256);
92
+
93
+ function profitSharingNumerator() external view returns (uint256);
94
+
95
+ function strategistFeeNumerator() external view returns (uint256);
96
+
97
+ function platformFeeNumerator() external view returns (uint256);
98
+
99
+ function feeDenominator() external view returns (uint256);
100
+
101
+ function setProfitSharingNumerator(uint _profitSharingNumerator) external;
102
+
103
+ function confirmSetProfitSharingNumerator() external;
104
+
105
+ function setStrategistFeeNumerator(uint _strategistFeeNumerator) external;
106
+
107
+ function confirmSetStrategistFeeNumerator() external;
108
+
109
+ function setPlatformFeeNumerator(uint _platformFeeNumerator) external;
110
+
111
+ function confirmSetPlatformFeeNumerator() external;
112
+
113
+ function setNextImplementationDelay(uint256 _nextImplementationDelay) external;
114
+
115
+ function confirmNextImplementationDelay() external;
116
+
117
+ function nextProfitSharingNumerator() external view returns (uint256);
118
+
119
+ function nextProfitSharingNumeratorTimestamp() external view returns (uint256);
120
+
121
+ function nextStrategistFeeNumerator() external view returns (uint256);
122
+
123
+ function nextStrategistFeeNumeratorTimestamp() external view returns (uint256);
124
+
125
+ function nextPlatformFeeNumerator() external view returns (uint256);
126
+
127
+ function nextPlatformFeeNumeratorTimestamp() external view returns (uint256);
128
+
129
+ function tempNextImplementationDelay() external view returns (uint256);
130
+
131
+ function tempNextImplementationDelayTimestamp() external view returns (uint256);
132
+ }
@@ -0,0 +1,9 @@
1
+ //SPDX-License-Identifier: Unlicense
2
+ pragma solidity 0.8.26;
3
+
4
+ interface IDex {
5
+ function setFee(address token0, address token1, uint24 fee) external;
6
+ function setPool(address token0, address token1, address pool) external;
7
+ function setPool(address token0, address token1, bytes32 pool) external;
8
+ function pairSetup(address token0, address token1, address pool, uint256[5] calldata params) external;
9
+ }