@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.
- package/README.md +127 -5
- package/contracts/base/Controller.sol +358 -0
- package/contracts/base/Drip.sol +86 -0
- package/contracts/base/PotPool.sol +367 -0
- package/contracts/base/ProfitSharingReceiver.sol +38 -0
- package/contracts/base/Reader.sol +54 -0
- package/contracts/base/RewardForwarder.sol +109 -0
- package/contracts/base/VaultProxy.sol +34 -0
- package/contracts/base/VaultStorage.sol +205 -0
- package/contracts/base/VaultV1.sol +371 -0
- package/contracts/base/VaultV1GMX.sol +465 -0
- package/contracts/base/VaultV2.sol +111 -0
- package/contracts/base/VaultV2GMX.sol +111 -0
- package/contracts/base/factory/MegaFactory.sol +120 -0
- package/contracts/base/factory/interface/IPoolFactory.sol +6 -0
- package/contracts/base/factory/interface/IStrategyFactory.sol +6 -0
- package/contracts/base/factory/interface/IVaultFactory.sol +7 -0
- package/contracts/base/factory/pool/PotPoolFactory.sol +41 -0
- package/contracts/base/factory/strategy/UpgradableStrategyFactory.sol +19 -0
- package/contracts/base/factory/vault/RegularVaultFactory.sol +34 -0
- package/contracts/base/incentives/GlobalIncentivesExecutor.sol +85 -0
- package/contracts/base/incentives/GlobalIncentivesHelper.sol +174 -0
- package/contracts/base/incentives/NotifyHelperGeneric.sol +61 -0
- package/contracts/base/incentives/NotifyHelperStateful.sol +290 -0
- package/contracts/base/incentives/ViewerNotifyHelperStateful.sol +25 -0
- package/contracts/base/inheritance/Controllable.sol +25 -0
- package/contracts/base/inheritance/ControllableInit.sol +30 -0
- package/contracts/base/inheritance/Governable.sol +28 -0
- package/contracts/base/inheritance/GovernableInit.sol +50 -0
- package/contracts/base/inheritance/IUpgradeSource.sol +7 -0
- package/contracts/base/inheritance/OwnableWhitelist.sol +17 -0
- package/contracts/base/inheritance/Storage.sol +35 -0
- package/contracts/base/interface/IBalDex.sol +7 -0
- package/contracts/base/interface/IController.sol +132 -0
- package/contracts/base/interface/IDex.sol +9 -0
- package/contracts/base/interface/IERC4626.sol +261 -0
- package/contracts/base/interface/IGMXStrategy.sol +37 -0
- package/contracts/base/interface/IGlobalIncentivesHelper.sol +6 -0
- package/contracts/base/interface/IPotPool.sol +70 -0
- package/contracts/base/interface/IProfitSharingReceiver.sol +9 -0
- package/contracts/base/interface/IRewardForwarder.sol +57 -0
- package/contracts/base/interface/IStrategy.sol +37 -0
- package/contracts/base/interface/IUniversalLiquidator.sol +21 -0
- package/contracts/base/interface/IUniversalLiquidatorRegistry.sol +20 -0
- package/contracts/base/interface/IUpgradeSource.sol +9 -0
- package/contracts/base/interface/IVault.sol +58 -0
- package/contracts/base/interface/IVaultGMX.sol +71 -0
- package/contracts/base/interface/aura/IAuraBaseRewardPool.sol +25 -0
- package/contracts/base/interface/aura/IAuraBooster.sol +17 -0
- package/contracts/base/interface/aura/IAuraDepositor.sol +7 -0
- package/contracts/base/interface/balancer/Gauge.sol +22 -0
- package/contracts/base/interface/balancer/IBVault.sol +580 -0
- package/contracts/base/interface/balancer/IBalancerMinter.sol +114 -0
- package/contracts/base/interface/balancer/IGyroPool.sol +7 -0
- package/contracts/base/interface/balancer/linearPool/ILinearPool.sol +184 -0
- package/contracts/base/interface/balancer/linearPool/ILinearPoolFactory.sol +16 -0
- package/contracts/base/interface/balancer/linearPool/ILinearPoolRebalancer.sol +8 -0
- package/contracts/base/interface/balancer/linearPool/IPoolSwapStructs.sol +56 -0
- package/contracts/base/interface/compound/CTokenInterface.sol +29 -0
- package/contracts/base/interface/compound/IComptroller.sol +9 -0
- package/contracts/base/interface/dolomite/IDepositWithdraw.sol +13 -0
- package/contracts/base/interface/dolomite/IDolomiteMargin.sol +15 -0
- package/contracts/base/interface/dolomite/IRewardsDistributor.sol +11 -0
- package/contracts/base/interface/gamma/IClearing.sol +7 -0
- package/contracts/base/interface/gamma/IHypervisor.sol +9 -0
- package/contracts/base/interface/gamma/IUniProxy.sol +14 -0
- package/contracts/base/interface/gmx/EventUtils.sol +253 -0
- package/contracts/base/interface/gmx/ICallbackReceiver.sol +119 -0
- package/contracts/base/interface/gmx/IDataStore.sol +7 -0
- package/contracts/base/interface/gmx/IExchangeRouter.sol +38 -0
- package/contracts/base/interface/gmx/IGMXViewer.sol +7 -0
- package/contracts/base/interface/gmx/IHandler.sol +12 -0
- package/contracts/base/interface/gmx/IMarket.sol +7 -0
- package/contracts/base/interface/gmx/IOracle.sol +6 -0
- package/contracts/base/interface/gmx/IPriceFeed.sol +12 -0
- package/contracts/base/interface/gmx/IReader.sol +49 -0
- package/contracts/base/interface/gmx/IRoleStore.sol +6 -0
- package/contracts/base/interface/ipor/Errors.sol +20 -0
- package/contracts/base/interface/ipor/FuseStorageLib.sol +71 -0
- package/contracts/base/interface/ipor/FusesLib.sol +149 -0
- package/contracts/base/interface/ipor/IFuseCommon.sol +9 -0
- package/contracts/base/interface/ipor/IFuseInstantWithdraw.sol +14 -0
- package/contracts/base/interface/ipor/IMarketBalanceFuse.sol +10 -0
- package/contracts/base/interface/ipor/IPriceOracleMiddleware.sol +42 -0
- package/contracts/base/interface/ipor/IporMath.sol +110 -0
- package/contracts/base/interface/ipor/PlasmaVaultConfigLib.sol +106 -0
- package/contracts/base/interface/ipor/PlasmaVaultLib.sol +293 -0
- package/contracts/base/interface/ipor/PlasmaVaultStorageLib.sol +352 -0
- package/contracts/base/interface/merkl/IDistributor.sol +6 -0
- package/contracts/base/interface/notional/INProxy.sol +44 -0
- package/contracts/base/interface/notional/IPrimeToken.sol +6 -0
- package/contracts/base/interface/venus/IRewardsDistributor.sol +6 -0
- package/contracts/base/interface/weth/IWETH.sol +39 -0
- package/contracts/base/ipor/Erc4626BalanceFuse.sol +54 -0
- package/contracts/base/ipor/Erc4626SupplyFuse.sol +134 -0
- package/contracts/base/noop/NoopStrategyUpgradeable.sol +90 -0
- package/contracts/base/upgradability/BaseUpgradeabilityProxy.sol +60 -0
- package/contracts/base/upgradability/BaseUpgradeableStrategy.sol +144 -0
- package/contracts/base/upgradability/BaseUpgradeableStrategyStorage.sol +284 -0
- package/contracts/base/upgradability/IUpgradable.sol +7 -0
- package/contracts/base/upgradability/ReentrancyGuardUpgradeable.sol +51 -0
- package/contracts/base/upgradability/StrategyProxy.sol +34 -0
- package/contracts/strategies/aura/AuraStrategy.sol +403 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_MORE_GYD.sol +32 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_sUSDe_GYD.sol +31 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_waFRAX_sFRAX.sol +31 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_waGHO_GYD.sol +31 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_waUSDC_GHO.sol +32 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_waUSDC_GYD.sol +31 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_waUSDT_GYD.sol +31 -0
- package/contracts/strategies/aura/AuraStrategyMainnet_wstETH_GYD.sol +31 -0
- package/contracts/strategies/camelot/CamelotV3Strategy.sol +304 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_ARB_USDC.sol +28 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_ETH_USDC.sol +28 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_ETH_USDT.sol +28 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_GMX_ETH.sol +28 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_GRAIL_ETH.sol +28 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_USDC_USDT.sol +28 -0
- package/contracts/strategies/camelot/CamelotV3StrategyMainnet_WBTC_ETH.sol +28 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategy.sol +273 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_DAI.sol +26 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_GMX.sol +26 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_USDC.sol +26 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_USDCe.sol +26 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_USDT.sol +26 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_WBTC.sol +26 -0
- package/contracts/strategies/dolomite/DolomiteLendStrategyMainnet_WETH.sol +26 -0
- package/contracts/strategies/fluid/FluidLendStrategy.sol +241 -0
- package/contracts/strategies/fluid/FluidLendStrategyMainnet_ETH.sol +25 -0
- package/contracts/strategies/fluid/FluidLendStrategyMainnet_USDC.sol +25 -0
- package/contracts/strategies/fluid/FluidLendStrategyMainnet_USDT.sol +25 -0
- package/contracts/strategies/gmx/GMXStrategy.sol +472 -0
- package/contracts/strategies/gmx/GMXStrategyMainnet_WBTC.sol +25 -0
- package/contracts/strategies/gmx/GMXViewer.sol +110 -0
- package/contracts/strategies/notional/NotionalStrategy.sol +223 -0
- package/contracts/strategies/notional/NotionalStrategyMainnet_nETH.sol +27 -0
- package/contracts/strategies/notional/NotionalStrategyMainnet_nUSDC.sol +27 -0
- package/contracts/strategies/notional/NotionalStrategyMainnet_nUSDT.sol +27 -0
- package/contracts/strategies/notional/NotionalStrategyMainnet_nwstETH.sol +27 -0
- package/contracts/strategies/venus/VenusFoldStrategy.sol +591 -0
- package/contracts/strategies/venus/VenusFoldStrategyMainnet_ARB.sol +32 -0
- package/contracts/strategies/venus/VenusFoldStrategyMainnet_ETH_core.sol +32 -0
- package/contracts/strategies/venus/VenusFoldStrategyMainnet_ETH_lsd.sol +32 -0
- package/contracts/strategies/venus/VenusFoldStrategyMainnet_USDC.sol +32 -0
- package/contracts/strategies/venus/VenusFoldStrategyMainnet_USDT.sol +32 -0
- package/contracts/strategies/venus/VenusFoldStrategyMainnet_WBTC.sol +32 -0
- package/hardhat.config.js +60 -0
- package/index.js +42 -0
- package/package.json +38 -6
- package/scripts/01-deploy-vault-regular-with-upgradable-strategy.js +41 -0
- package/scripts/02-deploy-vault-regular.js +35 -0
- package/scripts/03-deploy-upgradable-strategy.js +40 -0
- package/scripts/04-deploy-new-implementation.js +24 -0
- package/scripts/05-deploy-GMXViewer.js +17 -0
- package/scripts/06-deploy-GMXVault.js +49 -0
- package/scripts/07-deploy-ipor-fuses.js +29 -0
- package/scripts/08-deploy-drip.js +20 -0
- package/scripts/README.md +55 -0
- package/scripts/utils.js +22 -0
- package/test/aura/more-gyd.js +140 -0
- package/test/aura/susde-gyd.js +140 -0
- package/test/aura/wafrax-sfrax.js +140 -0
- package/test/aura/wagho-gyd.js +140 -0
- package/test/aura/wausdc-gho.js +141 -0
- package/test/aura/wausdc-gyd.js +140 -0
- package/test/aura/wausdt-gyd.js +140 -0
- package/test/aura/wsteth-gyd.js +138 -0
- package/test/camelot/arb-usdc.js +125 -0
- package/test/camelot/eth-usdc.js +125 -0
- package/test/camelot/eth-usdt.js +125 -0
- package/test/camelot/gmx-eth.js +125 -0
- package/test/camelot/grail-eth.js +125 -0
- package/test/camelot/usdc-usdt.js +125 -0
- package/test/camelot/wbtc-eth.js +125 -0
- package/test/dolomite/dai.js +127 -0
- package/test/dolomite/gmx.js +134 -0
- package/test/dolomite/usdc.js +127 -0
- package/test/dolomite/usdce.js +127 -0
- package/test/dolomite/usdt.js +127 -0
- package/test/dolomite/wbtc.js +127 -0
- package/test/dolomite/weth.js +127 -0
- package/test/fluid/eth.js +127 -0
- package/test/fluid/usdc.js +134 -0
- package/test/fluid/usdt.js +134 -0
- package/test/gmx/wbtc.js +184 -0
- package/test/notional/neth.js +133 -0
- package/test/notional/nusdc.js +133 -0
- package/test/notional/nusdt.js +133 -0
- package/test/notional/nwsteth.js +133 -0
- package/test/test-config.js +28 -0
- package/test/utilities/Utils.js +96 -0
- package/test/utilities/hh-utils.js +248 -0
- package/test/utilities/make-vault.js +16 -0
- package/test/venus/arb.js +135 -0
- package/test/venus/eth-core.js +133 -0
- package/test/venus/eth-lsd.js +133 -0
- package/test/venus/usdc.js +133 -0
- package/test/venus/usdt.js +133 -0
- 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,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,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
|
+
}
|