@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,149 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
5
+ import {FuseStorageLib} from "./FuseStorageLib.sol";
6
+ import {PlasmaVaultStorageLib} from "./PlasmaVaultStorageLib.sol";
7
+
8
+ /// @title Fuses Library responsible for managing fuses in the Plasma Vault
9
+ library FusesLib {
10
+ using Address for address;
11
+
12
+ event FuseAdded(address fuse);
13
+ event FuseRemoved(address fuse);
14
+ event BalanceFuseAdded(uint256 marketId, address fuse);
15
+ event BalanceFuseRemoved(uint256 marketId, address fuse);
16
+
17
+ error FuseAlreadyExists();
18
+ error FuseDoesNotExist();
19
+ error FuseUnsupported(address fuse);
20
+ error BalanceFuseAlreadyExists(uint256 marketId, address fuse);
21
+ error BalanceFuseDoesNotExist(uint256 marketId, address fuse);
22
+ error BalanceFuseNotReadyToRemove(uint256 marketId, address fuse, uint256 currentBalance);
23
+
24
+ /// @notice Checks if the fuse is supported
25
+ /// @param fuse_ The address of the fuse
26
+ /// @return true if the fuse is supported
27
+ function isFuseSupported(address fuse_) internal view returns (bool) {
28
+ return FuseStorageLib.getFuses().value[fuse_] != 0;
29
+ }
30
+
31
+ /// @notice Checks if the balance fuse is supported
32
+ /// @param marketId_ The market id
33
+ /// @param fuse_ The address of the fuse
34
+ /// @return true if the balance fuse is supported
35
+ function isBalanceFuseSupported(uint256 marketId_, address fuse_) internal view returns (bool) {
36
+ return PlasmaVaultStorageLib.getBalanceFuses().value[marketId_] == fuse_;
37
+ }
38
+
39
+ /// @notice Gets the balance fuse for the market
40
+ /// @param marketId_ The market id
41
+ /// @return The address of the balance fuse
42
+ function getBalanceFuse(uint256 marketId_) internal view returns (address) {
43
+ return PlasmaVaultStorageLib.getBalanceFuses().value[marketId_];
44
+ }
45
+
46
+ /// @notice Gets the array of stored and supported Fuses
47
+ /// @return The array of Fuses
48
+ function getFusesArray() internal view returns (address[] memory) {
49
+ return FuseStorageLib.getFusesArray().value;
50
+ }
51
+
52
+ /// @notice Gets the index of the fuse in the fuses array
53
+ /// @param fuse_ The address of the fuse
54
+ /// @return The index of the fuse in the fuses array stored in Plasma Vault
55
+ function getFuseArrayIndex(address fuse_) internal view returns (uint256) {
56
+ return FuseStorageLib.getFuses().value[fuse_];
57
+ }
58
+
59
+ /// @notice Adds a fuse to supported fuses
60
+ /// @param fuse_ The address of the fuse
61
+ function addFuse(address fuse_) internal {
62
+ FuseStorageLib.Fuses storage fuses = FuseStorageLib.getFuses();
63
+
64
+ uint256 keyIndexValue = fuses.value[fuse_];
65
+
66
+ if (keyIndexValue != 0) {
67
+ revert FuseAlreadyExists();
68
+ }
69
+
70
+ uint256 newLastFuseId = FuseStorageLib.getFusesArray().value.length + 1;
71
+
72
+ /// @dev for balance fuses, value is a index + 1 in the fusesArray
73
+ fuses.value[fuse_] = newLastFuseId;
74
+
75
+ FuseStorageLib.getFusesArray().value.push(fuse_);
76
+
77
+ emit FuseAdded(fuse_);
78
+ }
79
+
80
+ /// @notice Removes a fuse from supported fuses
81
+ /// @param fuse_ The address of the fuse
82
+ function removeFuse(address fuse_) internal {
83
+ FuseStorageLib.Fuses storage fuses = FuseStorageLib.getFuses();
84
+
85
+ uint256 indexToRemove = fuses.value[fuse_];
86
+
87
+ if (indexToRemove == 0) {
88
+ revert FuseDoesNotExist();
89
+ }
90
+
91
+ address lastKeyInArray = FuseStorageLib.getFusesArray().value[FuseStorageLib.getFusesArray().value.length - 1];
92
+
93
+ fuses.value[lastKeyInArray] = indexToRemove;
94
+
95
+ fuses.value[fuse_] = 0;
96
+
97
+ /// @dev balanceFuses mapping contains values as index + 1
98
+ FuseStorageLib.getFusesArray().value[indexToRemove - 1] = lastKeyInArray;
99
+
100
+ FuseStorageLib.getFusesArray().value.pop();
101
+
102
+ emit FuseRemoved(fuse_);
103
+ }
104
+
105
+ /// @notice Adds a balance fuse to the market
106
+ /// @param marketId_ The market id
107
+ /// @param fuse_ The address of the fuse
108
+ /// @dev Every market can have one dedicated balance fuse
109
+ function addBalanceFuse(uint256 marketId_, address fuse_) internal {
110
+ address currentFuse = PlasmaVaultStorageLib.getBalanceFuses().value[marketId_];
111
+
112
+ if (currentFuse == fuse_) {
113
+ revert BalanceFuseAlreadyExists(marketId_, fuse_);
114
+ }
115
+
116
+ PlasmaVaultStorageLib.getBalanceFuses().value[marketId_] = fuse_;
117
+
118
+ emit BalanceFuseAdded(marketId_, fuse_);
119
+ }
120
+
121
+ /// @notice Removes a balance fuse from the market
122
+ /// @param marketId_ The market id
123
+ /// @param fuse_ The address of the fuse
124
+ /// @dev Every market can have one dedicated balance fuse
125
+ function removeBalanceFuse(uint256 marketId_, address fuse_) internal {
126
+ address currentBalanceFuse = PlasmaVaultStorageLib.getBalanceFuses().value[marketId_];
127
+
128
+ if (currentBalanceFuse != fuse_) {
129
+ revert BalanceFuseDoesNotExist(marketId_, fuse_);
130
+ }
131
+
132
+ uint256 wadBalanceAmountInUSD = abi.decode(
133
+ currentBalanceFuse.functionDelegateCall(abi.encodeWithSignature("balanceOf()")),
134
+ (uint256)
135
+ );
136
+
137
+ if (wadBalanceAmountInUSD > calculateAllowedDustInBalanceFuse()) {
138
+ revert BalanceFuseNotReadyToRemove(marketId_, fuse_, wadBalanceAmountInUSD);
139
+ }
140
+
141
+ PlasmaVaultStorageLib.getBalanceFuses().value[marketId_] = address(0);
142
+
143
+ emit BalanceFuseRemoved(marketId_, fuse_);
144
+ }
145
+
146
+ function calculateAllowedDustInBalanceFuse() private view returns (uint256) {
147
+ return 10 ** (PlasmaVaultStorageLib.getERC4626Storage().underlyingDecimals / 2);
148
+ }
149
+ }
@@ -0,0 +1,9 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ /// @title Interface for Fuses Common functions
5
+ interface IFuseCommon {
6
+ /// @notice Market ID associated with the Fuse
7
+ //solhint-disable-next-line
8
+ function MARKET_ID() external view returns (uint256);
9
+ }
@@ -0,0 +1,14 @@
1
+
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+ pragma solidity 0.8.26;
4
+
5
+ /// @title Interface for Fuses - instant withdraw from the market
6
+ interface IFuseInstantWithdraw {
7
+ /// @notice Instant withdraw assets from the external market
8
+ /// @param params - array of parameters
9
+ /// @dev - Notice! Always first param is the asset value in underlying
10
+ /// @dev params[0] is asset value in underlying, next params are specific for the Fuse,
11
+ /// @dev params[1] - could be address of the asset, address of the external vault or address of the market or any other specific param for the Fuse
12
+ /// @dev params[n] - any other specific param for a given the Fuse
13
+ function instantWithdraw(bytes32[] calldata params) external;
14
+ }
@@ -0,0 +1,10 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ /// @title Interface for Fuses responsible for providing the balance of the PlasmaVault address in the market in USD
5
+ interface IMarketBalanceFuse {
6
+ /// @notice Get the balance of the Plasma Vault in the market in USD
7
+ /// @dev Notice! Every Balance Fuse have to implement this exact function signature, because it is used by Plasma Vault engine
8
+ /// @return balanceValue The balance of the Plasma Vault in the market in USD, represented in 18 decimals
9
+ function balanceOf() external returns (uint256 balanceValue);
10
+ }
@@ -0,0 +1,42 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ /// @title Interface to an aggregator of price feeds for assets, responsible for providing the prices of assets in a given quote currency
5
+ interface IPriceOracleMiddleware {
6
+ error EmptyArrayNotSupported();
7
+ error ArrayLengthMismatch();
8
+ error UnexpectedPriceResult();
9
+ error UnsupportedAsset();
10
+ error ZeroAddress(string variableName);
11
+ error WrongDecimals();
12
+ error WrongDecimalsInPriceFeed();
13
+
14
+ /// @notice Returns the price of the given asset in given decimals
15
+ /// @return assetPrice price in QUOTE_CURRENCY of the asset
16
+ /// @return decimals number of decimals of the asset price
17
+ function getAssetPrice(address asset) external view returns (uint256 assetPrice, uint256 decimals);
18
+
19
+ /// @notice Returns the prices of the given assets in given decimals
20
+ /// @return assetPrices prices in QUOTE_CURRENCY of the assets represented in given decimals
21
+ /// @return decimalsList number of decimals of the asset prices
22
+ function getAssetsPrices(
23
+ address[] calldata assets
24
+ ) external view returns (uint256[] memory assetPrices, uint256[] memory decimalsList);
25
+
26
+ /// @notice Returns address of source of the asset price - it could be IPOR Price Feed or Chainlink Aggregator or any other source of price for a given asset
27
+ /// @param asset address of the asset
28
+ /// @return address of the source of the asset price
29
+ function getSourceOfAssetPrice(address asset) external view returns (address);
30
+
31
+ /// @notice Sets the sources of the asset prices
32
+ /// @param assets array of addresses of the assets
33
+ function setAssetsPricesSources(address[] calldata assets, address[] calldata sources) external;
34
+
35
+ /// @notice Returns the address of the quote currency to which all the prices are relative, in IPOR Fusion it is the USD
36
+ //solhint-disable-next-line
37
+ function QUOTE_CURRENCY() external view returns (address);
38
+
39
+ /// @notice Returns the number of decimals of the quote currency, by default it is 8 for USD, but can be different for other types of Price Oracles Middlewares
40
+ //solhint-disable-next-line
41
+ function QUOTE_CURRENCY_DECIMALS() external view returns (uint256);
42
+ }
@@ -0,0 +1,110 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ /// @title Ipor Math library with math functions
5
+ library IporMath {
6
+ uint256 private constant WAD_DECIMALS = 18;
7
+ uint256 public constant BASIS_OF_POWER = 10;
8
+
9
+ /// @dev The index of the most significant bit in a 256-bit signed integer
10
+ uint256 private constant MSB = 255;
11
+
12
+ function min(uint256 a, uint256 b) internal pure returns (uint256) {
13
+ return a < b ? a : b;
14
+ }
15
+
16
+ /// @notice Converts the value to WAD decimals, WAD decimals are 18
17
+ /// @param value The value to convert
18
+ /// @param assetDecimals The decimals of the asset
19
+ /// @return The value in WAD decimals
20
+ function convertToWad(uint256 value, uint256 assetDecimals) internal pure returns (uint256) {
21
+ if (value > 0) {
22
+ if (assetDecimals == WAD_DECIMALS) {
23
+ return value;
24
+ } else if (assetDecimals > WAD_DECIMALS) {
25
+ return division(value, BASIS_OF_POWER ** (assetDecimals - WAD_DECIMALS));
26
+ } else {
27
+ return value * BASIS_OF_POWER ** (WAD_DECIMALS - assetDecimals);
28
+ }
29
+ } else {
30
+ return value;
31
+ }
32
+ }
33
+
34
+ /// @notice Converts the value to WAD decimals, WAD decimals are 18
35
+ /// @param value The value to convert
36
+ /// @param assetDecimals The decimals of the asset
37
+ /// @return The value in WAD decimals
38
+ function convertWadToAssetDecimals(uint256 value, uint256 assetDecimals) internal pure returns (uint256) {
39
+ if (assetDecimals == WAD_DECIMALS) {
40
+ return value;
41
+ } else if (assetDecimals > WAD_DECIMALS) {
42
+ return value * WAD_DECIMALS ** (assetDecimals - WAD_DECIMALS);
43
+ } else {
44
+ return division(value, BASIS_OF_POWER ** (WAD_DECIMALS - assetDecimals));
45
+ }
46
+ }
47
+
48
+ /// @notice Converts the int value to WAD decimals, WAD decimals are 18
49
+ /// @param value The int value to convert
50
+ /// @param assetDecimals The decimals of the asset
51
+ /// @return The value in WAD decimals, int
52
+ function convertToWadInt(int256 value, uint256 assetDecimals) internal pure returns (int256) {
53
+ if (value == 0) {
54
+ return 0;
55
+ }
56
+ if (assetDecimals == WAD_DECIMALS) {
57
+ return value;
58
+ } else if (assetDecimals > WAD_DECIMALS) {
59
+ return divisionInt(value, int256(BASIS_OF_POWER ** (assetDecimals - WAD_DECIMALS)));
60
+ } else {
61
+ return value * int256(BASIS_OF_POWER ** (WAD_DECIMALS - assetDecimals));
62
+ }
63
+ }
64
+
65
+ /// @notice Divides two int256 numbers and rounds the result to the nearest integer
66
+ /// @param x The numerator
67
+ /// @param y The denominator
68
+ /// @return z The result of the division
69
+ function divisionInt(int256 x, int256 y) internal pure returns (int256 z) {
70
+ uint256 absX = uint256(x < 0 ? -x : x);
71
+ uint256 absY = uint256(y < 0 ? -y : y);
72
+
73
+ // Use bitwise XOR to get the sign on MBS bit then shift to LSB
74
+ // sign == 0x0000...0000 == 0 if the number is non-negative
75
+ // sign == 0xFFFF...FFFF == -1 if the number is negative
76
+ int256 sign = (x ^ y) >> MSB;
77
+
78
+ uint256 divAbs;
79
+ uint256 remainder;
80
+
81
+ unchecked {
82
+ divAbs = absX / absY;
83
+ remainder = absX % absY;
84
+ }
85
+ // Check if we need to round
86
+ if (sign < 0) {
87
+ // remainder << 1 left shift is equivalent to multiplying by 2
88
+ if (remainder << 1 > absY) {
89
+ ++divAbs;
90
+ }
91
+ } else {
92
+ if (remainder << 1 >= absY) {
93
+ ++divAbs;
94
+ }
95
+ }
96
+
97
+ // (sign | 1) is cheaper than (sign < 0) ? -1 : 1;
98
+ unchecked {
99
+ z = int256(divAbs) * (sign | 1);
100
+ }
101
+ }
102
+
103
+ /// @notice Divides two uint256 numbers and rounds the result to the nearest integer
104
+ /// @param x The numerator
105
+ /// @param y The denominator
106
+ /// @return z The result of the division
107
+ function division(uint256 x, uint256 y) internal pure returns (uint256 z) {
108
+ z = x / y;
109
+ }
110
+ }
@@ -0,0 +1,106 @@
1
+
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+ pragma solidity 0.8.26;
4
+
5
+ import {PlasmaVaultStorageLib} from "./PlasmaVaultStorageLib.sol";
6
+
7
+ /// @title Plasma Vault Configuration Library responsible for managing the configuration of the Plasma Vault
8
+ library PlasmaVaultConfigLib {
9
+ event MarketSubstratesGranted(uint256 marketId, bytes32[] substrates);
10
+
11
+ /// @notice Checks if the substrate treated as an asset is granted for the market
12
+ /// @param marketId_ The market id
13
+ /// @param substrateAsAsset The address of the substrate treated as an asset
14
+ /// @return true if the substrate is granted for the market
15
+ /// @dev Substrates are stored as bytes32
16
+ function isSubstrateAsAssetGranted(uint256 marketId_, address substrateAsAsset) internal view returns (bool) {
17
+ PlasmaVaultStorageLib.MarketSubstratesStruct storage marketSubstrates = _getMarketSubstrates(marketId_);
18
+ return marketSubstrates.substrateAllowances[addressToBytes32(substrateAsAsset)] == 1;
19
+ }
20
+
21
+ /// @notice Checks if the substrate is granted for the market
22
+ /// @param marketId_ The market id
23
+ /// @param substrate_ The bytes32 of the substrate
24
+ /// @return true if the substrate is granted for the market
25
+ /// @dev Substrates can be asset, vault, or any other params
26
+ function isMarketSubstrateGranted(uint256 marketId_, bytes32 substrate_) internal view returns (bool) {
27
+ PlasmaVaultStorageLib.MarketSubstratesStruct storage marketSubstrates = _getMarketSubstrates(marketId_);
28
+ return marketSubstrates.substrateAllowances[substrate_] == 1;
29
+ }
30
+
31
+ /// @notice Gets the market substrates for the market
32
+ /// @param marketId_ The market id
33
+ /// @return The array of substrates
34
+ function getMarketSubstrates(uint256 marketId_) internal view returns (bytes32[] memory) {
35
+ return _getMarketSubstrates(marketId_).substrates;
36
+ }
37
+
38
+ /// @notice Grants the substrates for the market
39
+ /// @param marketId_ The market id
40
+ /// @param substrates_ The array of substrates
41
+ /// @dev Substrates can be asset, vault, or any other params, only granted substrates can be used by Fuses in interaction with a given market and external protocols.
42
+ function grantMarketSubstrates(uint256 marketId_, bytes32[] memory substrates_) internal {
43
+ PlasmaVaultStorageLib.MarketSubstratesStruct storage marketSubstrates = _getMarketSubstrates(marketId_);
44
+
45
+ _revokeMarketSubstrates(marketSubstrates);
46
+
47
+ bytes32[] memory list = new bytes32[](substrates_.length);
48
+ for (uint256 i; i < substrates_.length; ++i) {
49
+ marketSubstrates.substrateAllowances[substrates_[i]] = 1;
50
+ list[i] = substrates_[i];
51
+ }
52
+
53
+ marketSubstrates.substrates = list;
54
+
55
+ emit MarketSubstratesGranted(marketId_, substrates_);
56
+ }
57
+
58
+ /// @notice Grants the substrates treated as assets for the market
59
+ /// @param marketId_ The market id
60
+ /// @param substratesAsAssets_ The array of substrates treated as assets
61
+ /// @dev Substrates are stored as bytes32, only granted substrates can be used by Fuses in interaction with a given market and external protocols.
62
+ function grantSubstratesAsAssetsToMarket(uint256 marketId_, address[] calldata substratesAsAssets_) internal {
63
+ PlasmaVaultStorageLib.MarketSubstratesStruct storage marketSubstrates = _getMarketSubstrates(marketId_);
64
+
65
+ _revokeMarketSubstrates(marketSubstrates);
66
+
67
+ bytes32[] memory list = new bytes32[](substratesAsAssets_.length);
68
+
69
+ for (uint256 i; i < substratesAsAssets_.length; ++i) {
70
+ marketSubstrates.substrateAllowances[addressToBytes32(substratesAsAssets_[i])] = 1;
71
+ list[i] = addressToBytes32(substratesAsAssets_[i]);
72
+ }
73
+
74
+ marketSubstrates.substrates = list;
75
+
76
+ emit MarketSubstratesGranted(marketId_, list);
77
+ }
78
+
79
+ function _revokeMarketSubstrates(PlasmaVaultStorageLib.MarketSubstratesStruct storage marketSubstrates) private {
80
+ uint256 length = marketSubstrates.substrates.length;
81
+ for (uint256 i; i < length; ++i) {
82
+ marketSubstrates.substrateAllowances[marketSubstrates.substrates[i]] = 0;
83
+ }
84
+ }
85
+
86
+ /// @notice Converts the substrate as bytes32 to value address
87
+ /// @param substrate_ The bytes32 of the substrate
88
+ /// @return The address of the substrate
89
+ function bytes32ToAddress(bytes32 substrate_) internal pure returns (address) {
90
+ return address(uint160(uint256(substrate_)));
91
+ }
92
+
93
+ /// @notice Converts the address to bytes32
94
+ /// @param address_ The address of the substrate
95
+ /// @return The bytes32 of the substrate
96
+ function addressToBytes32(address address_) internal pure returns (bytes32) {
97
+ return bytes32(uint256(uint160(address_)));
98
+ }
99
+
100
+ /// @notice Gets the market substrates configuration for a specific market
101
+ function _getMarketSubstrates(
102
+ uint256 marketId_
103
+ ) private view returns (PlasmaVaultStorageLib.MarketSubstratesStruct storage) {
104
+ return PlasmaVaultStorageLib.getMarketSubstrates().value[marketId_];
105
+ }
106
+ }