@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,134 @@
1
+ // Utilities
2
+ const Utils = require("../utilities/Utils.js");
3
+ const {
4
+ impersonates,
5
+ setupCoreProtocol,
6
+ depositVault,
7
+ } = require("../utilities/hh-utils.js");
8
+
9
+ const addresses = require("../test-config.js");
10
+ const { send } = require("@openzeppelin/test-helpers");
11
+ const BigNumber = require("bignumber.js");
12
+ const IERC20 = artifacts.require("IERC20");
13
+
14
+ //const Strategy = artifacts.require("");
15
+ const Strategy = artifacts.require("FluidLendStrategyMainnet_USDT");
16
+
17
+ // Developed and tested at blockNumber 259151500
18
+
19
+ // Vanilla Mocha test. Increased compatibility with tools that integrate Mocha.
20
+ describe("Arbitrum Mainnet Fluid Lend USDT", function() {
21
+ let accounts;
22
+
23
+ // external contracts
24
+ let underlying;
25
+
26
+ // external setup
27
+ let underlyingWhale = "0x518cbD952d66bC80d16aADa1b8987fBe3A7dD37d";
28
+ let usdt = "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9";
29
+ let weth = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";
30
+
31
+ // parties in the protocol
32
+ let governance;
33
+ let farmer1;
34
+
35
+ // numbers used in tests
36
+ let farmerBalance;
37
+
38
+ // Core protocol contracts
39
+ let controller;
40
+ let vault;
41
+ let strategy;
42
+
43
+ async function setupExternalContracts() {
44
+ underlying = await IERC20.at("0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9");
45
+ console.log("Fetching Underlying at: ", underlying.address);
46
+ }
47
+
48
+ async function setupBalance(){
49
+ let etherGiver = accounts[9];
50
+ await web3.eth.sendTransaction({ from: etherGiver, to: underlyingWhale, value: 10e18});
51
+ await web3.eth.sendTransaction({ from: etherGiver, to: addresses.ULOwner, value: 10e18});
52
+
53
+ farmerBalance = await underlying.balanceOf(underlyingWhale);
54
+ await underlying.transfer(farmer1, farmerBalance, { from: underlyingWhale });
55
+ }
56
+
57
+ before(async function() {
58
+ governance = addresses.Governance;
59
+ accounts = await web3.eth.getAccounts();
60
+
61
+ farmer1 = accounts[1];
62
+
63
+ // impersonate accounts
64
+ await impersonates([governance, underlyingWhale, addresses.ULOwner]);
65
+
66
+ let etherGiver = accounts[9];
67
+ await web3.eth.sendTransaction({ from: etherGiver, to: governance, value: 10e18});
68
+ await web3.eth.sendTransaction({ from: etherGiver, to: addresses.ULOwner, value: 10e18});
69
+
70
+ await setupExternalContracts();
71
+ [controller, vault, strategy] = await setupCoreProtocol({
72
+ "existingVaultAddress": null,
73
+ "strategyArtifact": Strategy,
74
+ "strategyArtifactIsUpgradable": true,
75
+ "underlying": underlying,
76
+ "governance": governance,
77
+ "ULOwner": addresses.ULOwner,
78
+ "liquidation": [
79
+ {"uniV3": [usdt, weth]},
80
+ ],
81
+ "uniV3Fee": [
82
+ [usdt, weth, '500'],
83
+ ]
84
+ });
85
+
86
+ // whale send underlying to farmers
87
+ await setupBalance();
88
+ });
89
+
90
+ describe("Happy path", function() {
91
+ it("Farmer should earn money", async function() {
92
+ let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1));
93
+ await depositVault(farmer1, underlying, vault, farmerBalance);
94
+
95
+ let hours = 10;
96
+ let blocksPerHour = 3600;
97
+ let oldSharePrice;
98
+ let newSharePrice;
99
+
100
+ for (let i = 0; i < hours; i++) {
101
+ console.log("loop ", i);
102
+
103
+ oldSharePrice = new BigNumber(await vault.getPricePerFullShare());
104
+ await controller.doHardWork(vault.address, { from: governance });
105
+ newSharePrice = new BigNumber(await vault.getPricePerFullShare());
106
+
107
+ console.log("old shareprice: ", oldSharePrice.toFixed());
108
+ console.log("new shareprice: ", newSharePrice.toFixed());
109
+ console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed());
110
+
111
+ apr = (newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))*365;
112
+ apy = ((newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))+1)**365;
113
+
114
+ console.log("instant APR:", apr*100, "%");
115
+ console.log("instant APY:", (apy-1)*100, "%");
116
+
117
+ await Utils.advanceNBlock(blocksPerHour);
118
+ }
119
+ await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 });
120
+ let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1));
121
+ Utils.assertBNGt(farmerNewBalance, farmerOldBalance);
122
+
123
+ apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))*365;
124
+ apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))+1)**365;
125
+
126
+ console.log("earned!");
127
+ console.log("APR:", apr*100, "%");
128
+ console.log("APY:", (apy-1)*100, "%");
129
+
130
+ await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch
131
+
132
+ });
133
+ });
134
+ });
@@ -0,0 +1,184 @@
1
+ // Utilities
2
+ const Utils = require("../utilities/Utils.js");
3
+ const { time } = require("@openzeppelin/test-helpers");
4
+ const {
5
+ impersonates,
6
+ setupCoreProtocol,
7
+ depositVault,
8
+ } = require("../utilities/hh-utils.js");
9
+
10
+ const addresses = require("../test-config.js");
11
+ const BigNumber = require("bignumber.js");
12
+ const IERC20 = artifacts.require("IERC20");
13
+ const IHandler = artifacts.require("IHandler");
14
+ const GMXViewer = artifacts.require("GMXViewer");
15
+
16
+ //const Strategy = artifacts.require("");
17
+ const Strategy = artifacts.require("GMXStrategyMainnet_WBTC");
18
+
19
+ // Developed and tested at blockNumber 264419400
20
+
21
+ // Vanilla Mocha test. Increased compatibility with tools that integrate Mocha.
22
+ describe("Arbitrum Mainnet GMX WBTC", function() {
23
+ let accounts;
24
+
25
+ // external contracts
26
+ let underlying;
27
+ let market;
28
+ let depositHandler;
29
+ let withdrawHandler;
30
+
31
+ // external setup
32
+ let underlyingWhale = "0xF066789028fE31D4f53B69B81b328B8218Cc0641";
33
+ let marketWhale = "0x0925eDb94a1be30297EC686dFB6B2314D5deA1bA";
34
+ let underlyingWhale2 = "0x7BcEFd1bc97a1AF01c5EdE3A3199AA11a77b6b45";
35
+ let keeper = "0xf1e1B2F4796d984CCb8485d43db0c64B83C1FA6d";
36
+
37
+ // parties in the protocol
38
+ let governance;
39
+ let farmer1;
40
+
41
+ // numbers used in tests
42
+ let farmerBalance;
43
+
44
+ // Core protocol contracts
45
+ let controller;
46
+ let vault;
47
+ let strategy;
48
+
49
+ async function setupExternalContracts() {
50
+ underlying = await IERC20.at("0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f");
51
+ market = await IERC20.at("0x7C11F78Ce78768518D743E81Fdfa2F860C6b9A77");
52
+ console.log("Fetching Underlying at: ", underlying.address);
53
+
54
+ depositHandler = await IHandler.at("0x321f3739983CC3E911fd67a83d1ee76238894Bd0");
55
+ withdrawHandler = await IHandler.at("0xA19fA3F0D8E7b7A8963420De504b624167e709B2");
56
+ }
57
+
58
+ async function setupBalance(){
59
+ let etherGiver = accounts[9];
60
+ await web3.eth.sendTransaction({ from: etherGiver, to: underlyingWhale, value: 10e18});
61
+ await web3.eth.sendTransaction({ from: etherGiver, to: addresses.ULOwner, value: 10e18});
62
+
63
+ farmerBalance = await underlying.balanceOf(underlyingWhale);
64
+ await underlying.transfer(farmer1, farmerBalance, { from: underlyingWhale });
65
+ }
66
+
67
+ before(async function() {
68
+ governance = addresses.Governance;
69
+ accounts = await web3.eth.getAccounts();
70
+
71
+ farmer1 = accounts[1];
72
+
73
+ // impersonate accounts
74
+ await impersonates([governance, underlyingWhale, marketWhale, underlyingWhale2, addresses.ULOwner, keeper]);
75
+
76
+ let etherGiver = accounts[9];
77
+ await web3.eth.sendTransaction({ from: etherGiver, to: governance, value: 10e18});
78
+ await web3.eth.sendTransaction({ from: etherGiver, to: addresses.ULOwner, value: 10e18});
79
+
80
+ await setupExternalContracts();
81
+ [controller, vault, strategy] = await setupCoreProtocol({
82
+ "existingVaultAddress": null,
83
+ "useGMXVault": true,
84
+ "strategyArtifact": Strategy,
85
+ "strategyArtifactIsUpgradable": true,
86
+ "underlying": underlying,
87
+ "governance": governance,
88
+ "ULOwner": addresses.ULOwner,
89
+ });
90
+
91
+ await web3.eth.sendTransaction({ from: etherGiver, to: strategy.address, value: 1e18});
92
+
93
+ let viewer = await GMXViewer.new("0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8", "0xa11B501c2dd83Acd29F6727570f2502FAaa617F2", "0x23D4Da5C7C6902D4C86d551CaE60d5755820df9E", {from: governance});
94
+
95
+ await strategy._setViewer(viewer.address);
96
+
97
+ // whale send underlying to farmers
98
+ await setupBalance();
99
+ });
100
+
101
+ describe("Happy path", function() {
102
+ it("Farmer should earn money", async function() {
103
+ let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1));
104
+ await depositVault(farmer1, underlying, vault, farmerBalance);
105
+ await depositHandler.executeDeposit(
106
+ "0x338e0a63a4b488e1d07d062e1f74ff1725576bed80feaf6326b47f43644cca4c",
107
+ [
108
+ ["0x47904963fc8b2340414262125aF798B9655E58Cd", "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f"],
109
+ ["0x83cBb05AA78014305194450c4AADAc887fe5DF7F", "0x83cBb05AA78014305194450c4AADAc887fe5DF7F"],
110
+ [
111
+ "0x0006fede3c3758908c63ee79f1ca04f5bd4ede1ff05709c761882103eed558ec000000000000000000000000000000000000000000000000000000001a5bf408000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000039d9e45394f473ab1f050a1b963e6b05351e52d71e507509ada0c95ed75b800000000000000000000000000000000000000000000000000000000670fbaab00000000000000000000000000000000000000000000000000000000670fbaab00000000000000000000000000000000000000000000000000006e9c10f8f21c00000000000000000000000000000000000000000000000000638a4b6412d3cc0000000000000000000000000000000000000000000000000000000067110c2b000000000000000000000000000000000000000000000e5cbdf09f0144e01e80000000000000000000000000000000000000000000000e5cb98e500bbbfb6980000000000000000000000000000000000000000000000e5d1a1e5a4a6c5000000000000000000000000000000000000000000000000000000000000000000006c2ee05e451f04be49a7042b97f9458339b152f5cb05316b283607607699667483b6345b40986500fcb7dd78dcc88093a92d1804b47b338923819a914d455b584bb3b62c8aa77d23170aa08369925af6b75ea07a71f34b5a50c24e62bc69d8b1faa434f49ce58563da76f1a2e836ffb845ed2c561fdc6424925df4d7f752458af46f71a4072c39bbf832c3cfd56ab28d558e5f31e360f0c70891b5feac1072cf16b0a9cebc238fa40044bc25cd4b10b49e325aed516b72803ce0eb46869f3c9f400000000000000000000000000000000000000000000000000000000000000066af6e71ab704c33a2b9b942094396eca9b3e009df16fc51e334b8c993d0486dc459dbdb2c62f85ad4d157c36ac717a0d8736843f151fe8eb14e560e3da7d41047078bb6341f54c4a39b2c169cf67528f7395ff8c27093ebc1e9b4f46939e0ed44d1b7a164585b0c2887c9f2a3960213d3fa1ee3ae30b9d759af5828b3de460f849a3192aeb551a2858a62c1cf11b8e180e2d98233059812f48144d12f247acae6f0ddb782b94d06fad9b692622a5c631b074d9c2423248fa1dea996d7ab718c8",
112
+ "0x0006fede3c3758908c63ee79f1ca04f5bd4ede1ff05709c761882103eed558ec000000000000000000000000000000000000000000000000000000001a5bf408000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000039d9e45394f473ab1f050a1b963e6b05351e52d71e507509ada0c95ed75b800000000000000000000000000000000000000000000000000000000670fbaab00000000000000000000000000000000000000000000000000000000670fbaab00000000000000000000000000000000000000000000000000006e9c10f8f21c00000000000000000000000000000000000000000000000000638a4b6412d3cc0000000000000000000000000000000000000000000000000000000067110c2b000000000000000000000000000000000000000000000e5cbdf09f0144e01e80000000000000000000000000000000000000000000000e5cb98e500bbbfb6980000000000000000000000000000000000000000000000e5d1a1e5a4a6c5000000000000000000000000000000000000000000000000000000000000000000006c2ee05e451f04be49a7042b97f9458339b152f5cb05316b283607607699667483b6345b40986500fcb7dd78dcc88093a92d1804b47b338923819a914d455b584bb3b62c8aa77d23170aa08369925af6b75ea07a71f34b5a50c24e62bc69d8b1faa434f49ce58563da76f1a2e836ffb845ed2c561fdc6424925df4d7f752458af46f71a4072c39bbf832c3cfd56ab28d558e5f31e360f0c70891b5feac1072cf16b0a9cebc238fa40044bc25cd4b10b49e325aed516b72803ce0eb46869f3c9f400000000000000000000000000000000000000000000000000000000000000066af6e71ab704c33a2b9b942094396eca9b3e009df16fc51e334b8c993d0486dc459dbdb2c62f85ad4d157c36ac717a0d8736843f151fe8eb14e560e3da7d41047078bb6341f54c4a39b2c169cf67528f7395ff8c27093ebc1e9b4f46939e0ed44d1b7a164585b0c2887c9f2a3960213d3fa1ee3ae30b9d759af5828b3de460f849a3192aeb551a2858a62c1cf11b8e180e2d98233059812f48144d12f247acae6f0ddb782b94d06fad9b692622a5c631b074d9c2423248fa1dea996d7ab718c8",
113
+ ]
114
+ ],
115
+ {from: keeper}
116
+ )
117
+ let farmerFarmBalance = new BigNumber(await vault.balanceOf(farmer1));
118
+
119
+ console.log(farmerOldBalance.toFixed(), farmerFarmBalance.toFixed())
120
+
121
+ let hours = 3;
122
+ let blocksPerHour = 100;
123
+ let oldSharePrice;
124
+ let newSharePrice;
125
+
126
+ for (let i = 0; i < hours; i++) {
127
+ console.log("loop ", i);
128
+ oldSharePrice = new BigNumber(await vault.getPricePerFullShare());
129
+ await controller.doHardWork(vault.address, { from: governance });
130
+ if (i == 0) {
131
+ }
132
+ newSharePrice = new BigNumber(await vault.getPricePerFullShare());
133
+
134
+
135
+ console.log("old shareprice: ", oldSharePrice.toFixed());
136
+ console.log("new shareprice: ", newSharePrice.toFixed());
137
+ console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed());
138
+
139
+ apr = (newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))*365;
140
+ apy = ((newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))+1)**365;
141
+
142
+ console.log("instant APR:", apr*100, "%");
143
+ console.log("instant APY:", (apy-1)*100, "%");
144
+
145
+ await Utils.advanceNBlock(blocksPerHour);
146
+
147
+ await market.transfer(strategy.address, new BigNumber(1e18), { from: marketWhale });
148
+ }
149
+ await time.increaseTo(1729088210)
150
+ // await underlying.transfer(strategy.address, farmerOldBalance, { from: underlyingWhale2 });
151
+ await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 });
152
+ let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1));
153
+ farmerFarmBalance = new BigNumber(await vault.balanceOf(farmer1));
154
+ console.log(farmerNewBalance.toFixed())
155
+ console.log(farmerNewBalance.toFixed(), farmerFarmBalance.toFixed())
156
+
157
+ await withdrawHandler.executeWithdrawal(
158
+ "0x71462bf1cb316898246c6f02e38b5aa36951b2b4ba639d2c7a632a6513f4d9c6",
159
+ [
160
+ ["0x47904963fc8b2340414262125aF798B9655E58Cd", "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f"],
161
+ ["0x83cBb05AA78014305194450c4AADAc887fe5DF7F", "0x83cBb05AA78014305194450c4AADAc887fe5DF7F"],
162
+ [
163
+ "0x0006fede3c3758908c63ee79f1ca04f5bd4ede1ff05709c761882103eed558ec000000000000000000000000000000000000000000000000000000001a5dfb01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003000101000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000039d9e45394f473ab1f050a1b963e6b05351e52d71e507509ada0c95ed75b800000000000000000000000000000000000000000000000000000000670fcad300000000000000000000000000000000000000000000000000000000670fcad300000000000000000000000000000000000000000000000000006e8d934b863000000000000000000000000000000000000000000000000000647eab351185c80000000000000000000000000000000000000000000000000000000067111c53000000000000000000000000000000000000000000000e68c5a1738d9bcc0180000000000000000000000000000000000000000000000e68c3a9170d83396a80000000000000000000000000000000000000000000000e69085406c31f8180000000000000000000000000000000000000000000000000000000000000000006eac11f7dacca9c41fd3233880b04a1f84d23e61a209a519aadb3952395656b3f89808509acf69a5e7e1ea222e46899569061c84784ff4268dd15b860d57704a7745a7519370113868ef99de1db07e43b6d6c9a62e29f2a45c633af59ed0493ecacb11ffdadb1dcd971bda012ecdde2c05457058b22f8358a47e638f68318a4c4e76a4da9c5ad5c4defd17f46a40d2fd15bd061aeb8e4c02a760c1dcb4578ef3b426e68b87573d05dd6d8d72bbb7e9ba748ec83c599cc3fb0d2d42c3e4098ff87000000000000000000000000000000000000000000000000000000000000000602ee3b6db4e3073cb3ea55b7f4bc6167a2df5fdd00ff5f8995761a8d507e57cb030da18ef022257df746f578dd60a8780ccc2999128dbf3e894956f511990949238e6546db4382d0c53133d114d77d28b28d8cfca94569dd25a9fdfd4b79a3821b96791e6c6b6e7761482398c443975d92b689f4a75a9fe96d5abd6e453e78cd64f4afb65e8fc9b09dafe615b8ed21c9d2823c5f9bfe792cfa8f6bc9a5a33b201013e021259d4901760bd68047dc55ea152496c47655a932dc90c6502568866e",
164
+ "0x0006fede3c3758908c63ee79f1ca04f5bd4ede1ff05709c761882103eed558ec000000000000000000000000000000000000000000000000000000001a5dfb01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003000101000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000039d9e45394f473ab1f050a1b963e6b05351e52d71e507509ada0c95ed75b800000000000000000000000000000000000000000000000000000000670fcad300000000000000000000000000000000000000000000000000000000670fcad300000000000000000000000000000000000000000000000000006e8d934b863000000000000000000000000000000000000000000000000000647eab351185c80000000000000000000000000000000000000000000000000000000067111c53000000000000000000000000000000000000000000000e68c5a1738d9bcc0180000000000000000000000000000000000000000000000e68c3a9170d83396a80000000000000000000000000000000000000000000000e69085406c31f8180000000000000000000000000000000000000000000000000000000000000000006eac11f7dacca9c41fd3233880b04a1f84d23e61a209a519aadb3952395656b3f89808509acf69a5e7e1ea222e46899569061c84784ff4268dd15b860d57704a7745a7519370113868ef99de1db07e43b6d6c9a62e29f2a45c633af59ed0493ecacb11ffdadb1dcd971bda012ecdde2c05457058b22f8358a47e638f68318a4c4e76a4da9c5ad5c4defd17f46a40d2fd15bd061aeb8e4c02a760c1dcb4578ef3b426e68b87573d05dd6d8d72bbb7e9ba748ec83c599cc3fb0d2d42c3e4098ff87000000000000000000000000000000000000000000000000000000000000000602ee3b6db4e3073cb3ea55b7f4bc6167a2df5fdd00ff5f8995761a8d507e57cb030da18ef022257df746f578dd60a8780ccc2999128dbf3e894956f511990949238e6546db4382d0c53133d114d77d28b28d8cfca94569dd25a9fdfd4b79a3821b96791e6c6b6e7761482398c443975d92b689f4a75a9fe96d5abd6e453e78cd64f4afb65e8fc9b09dafe615b8ed21c9d2823c5f9bfe792cfa8f6bc9a5a33b201013e021259d4901760bd68047dc55ea152496c47655a932dc90c6502568866e",
165
+ ]
166
+ ],
167
+ {from: keeper}
168
+ )
169
+ farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1));
170
+ console.log(farmerNewBalance.toFixed())
171
+ // Utils.assertBNGt(farmerNewBalance, farmerOldBalance);
172
+
173
+ apr = (farmerNewBalance.plus(farmerFarmBalance).toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))*365;
174
+ apy = ((farmerNewBalance.plus(farmerFarmBalance).toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))+1)**365;
175
+
176
+ console.log("earned!");
177
+ console.log("APR:", apr*100, "%");
178
+ console.log("APY:", (apy-1)*100, "%");
179
+
180
+ // await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch
181
+
182
+ });
183
+ });
184
+ });
@@ -0,0 +1,133 @@
1
+ // Utilities
2
+ const Utils = require("../utilities/Utils.js");
3
+ const { impersonates, setupCoreProtocol, depositVault } = require("../utilities/hh-utils.js");
4
+ const addresses = require("../test-config.js");
5
+
6
+ const BigNumber = require("bignumber.js");
7
+ const IERC20 = artifacts.require("@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20");
8
+
9
+ const Strategy = artifacts.require("NotionalStrategyMainnet_nETH");
10
+
11
+ //This test was developed at blockNumber 252737900
12
+
13
+ // Vanilla Mocha test. Increased compatibility with tools that integrate Mocha.
14
+ describe("Mainnet Notional nETH", function() {
15
+ let accounts;
16
+
17
+ // external contracts
18
+ let underlying;
19
+
20
+ // external setup
21
+ let underlyingWhale = "0xBC4f22D7BCcC2c3b928C6B85F4021CAC3A47963f";
22
+ let note = "0x019bE259BC299F3F653688c7655C87F998Bc7bC1";
23
+ let weth = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";
24
+ let arb = "0x912CE59144191C1204E64559FE8253a0e49E6548";
25
+
26
+ // parties in the protocol
27
+ let governance;
28
+ let farmer1;
29
+
30
+ // numbers used in tests
31
+ let farmerBalance;
32
+
33
+ // Core protocol contracts
34
+ let controller;
35
+ let vault;
36
+ let strategy;
37
+
38
+ async function setupExternalContracts() {
39
+ underlying = await IERC20.at("0x18b0Fc5A233acF1586Da7C199Ca9E3f486305A29");
40
+ console.log("Fetching Underlying at: ", underlying.address);
41
+ }
42
+
43
+ async function setupBalance(){
44
+ let etherGiver = accounts[9];
45
+ // Give whale some ether to make sure the following actions are good
46
+ await web3.eth.sendTransaction({ from: etherGiver, to: underlyingWhale, value: 10e18});
47
+ await web3.eth.sendTransaction({ from: etherGiver, to: addresses.ULOwner, value: 10e18});
48
+
49
+ farmerBalance = await underlying.balanceOf(underlyingWhale);
50
+ await underlying.transfer(farmer1, farmerBalance, { from: underlyingWhale });
51
+ }
52
+
53
+ before(async function() {
54
+ governance = addresses.Governance;
55
+ accounts = await web3.eth.getAccounts();
56
+
57
+ await web3.eth.sendTransaction({ from: accounts[8], to: governance, value: 10e18});
58
+ await web3.eth.sendTransaction({ from: accounts[8], to: addresses.ULOwner, value: 10e18});
59
+
60
+ farmer1 = accounts[1];
61
+
62
+ // impersonate accounts
63
+ await impersonates([governance, underlyingWhale, addresses.ULOwner]);
64
+
65
+ await setupExternalContracts();
66
+ [controller, vault, strategy] = await setupCoreProtocol({
67
+ "existingVaultAddress": null,
68
+ "strategyArtifact": Strategy,
69
+ "strategyArtifactIsUpgradable": true,
70
+ "underlying": underlying,
71
+ "governance": governance,
72
+ "liquidation": [
73
+ {"uniV3": [note, weth]},
74
+ {"camelot": [arb, weth]},
75
+ {"uniV3": [weth, note]}
76
+ ],
77
+ "uniV3Fee": [
78
+ [note, weth, 10000]
79
+ ],
80
+ "ULOwner": addresses.ULOwner
81
+ });
82
+
83
+ // whale send underlying to farmers
84
+ await setupBalance();
85
+ });
86
+
87
+ describe("Happy path", function() {
88
+ it("Farmer should earn money", async function() {
89
+ let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1));
90
+ await depositVault(farmer1, underlying, vault, farmerBalance);
91
+ let fTokenBalance = new BigNumber(await vault.balanceOf(farmer1));
92
+
93
+ // Using half days is to simulate how we doHardwork in the real world
94
+ let hours = 10;
95
+ let blocksPerHour = 2400;
96
+ let oldSharePrice;
97
+ let newSharePrice;
98
+ for (let i = 0; i < hours; i++) {
99
+ console.log("loop ", i);
100
+
101
+ oldSharePrice = new BigNumber(await vault.getPricePerFullShare());
102
+ await controller.doHardWork(vault.address, { from: governance });
103
+ newSharePrice = new BigNumber(await vault.getPricePerFullShare());
104
+
105
+ console.log("old shareprice: ", oldSharePrice.toFixed());
106
+ console.log("new shareprice: ", newSharePrice.toFixed());
107
+ console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed());
108
+
109
+ apr = (newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))*365;
110
+ apy = ((newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))+1)**365;
111
+
112
+ console.log("instant APR:", apr*100, "%");
113
+ console.log("instant APY:", (apy-1)*100, "%");
114
+ await vault.withdraw(fTokenBalance.div(10), { from: farmer1 });
115
+ await depositVault(farmer1, underlying, vault, new BigNumber(await underlying.balanceOf(farmer1)))
116
+ await Utils.advanceNBlock(blocksPerHour);
117
+ }
118
+ fTokenBalance = new BigNumber(await vault.balanceOf(farmer1));
119
+ await vault.withdraw(fTokenBalance, { from: farmer1 });
120
+ let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1));
121
+ Utils.assertBNGt(farmerNewBalance, farmerOldBalance);
122
+
123
+ apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))*365;
124
+ apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))+1)**365;
125
+
126
+ console.log("earned!");
127
+ console.log("Overall APR:", apr*100, "%");
128
+ console.log("Overall APY:", (apy-1)*100, "%");
129
+
130
+ await strategy.withdrawAllToVault({ from: governance }); // making sure can withdraw all for a next switch
131
+ });
132
+ });
133
+ });
@@ -0,0 +1,133 @@
1
+ // Utilities
2
+ const Utils = require("../utilities/Utils.js");
3
+ const { impersonates, setupCoreProtocol, depositVault } = require("../utilities/hh-utils.js");
4
+ const addresses = require("../test-config.js");
5
+
6
+ const BigNumber = require("bignumber.js");
7
+ const IERC20 = artifacts.require("@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20");
8
+
9
+ const Strategy = artifacts.require("NotionalStrategyMainnet_nUSDC");
10
+
11
+ //This test was developed at blockNumber 252737900
12
+
13
+ // Vanilla Mocha test. Increased compatibility with tools that integrate Mocha.
14
+ describe("Mainnet Notional nUSDC", function() {
15
+ let accounts;
16
+
17
+ // external contracts
18
+ let underlying;
19
+
20
+ // external setup
21
+ let underlyingWhale = "0x505E5ea6b384ea9C18E2313F2cF13C28AF576E0a";
22
+ let note = "0x019bE259BC299F3F653688c7655C87F998Bc7bC1";
23
+ let weth = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";
24
+ let arb = "0x912CE59144191C1204E64559FE8253a0e49E6548";
25
+
26
+ // parties in the protocol
27
+ let governance;
28
+ let farmer1;
29
+
30
+ // numbers used in tests
31
+ let farmerBalance;
32
+
33
+ // Core protocol contracts
34
+ let controller;
35
+ let vault;
36
+ let strategy;
37
+
38
+ async function setupExternalContracts() {
39
+ underlying = await IERC20.at("0x0F13fb925eDC3E1FE947209010d9c0E072986ADc");
40
+ console.log("Fetching Underlying at: ", underlying.address);
41
+ }
42
+
43
+ async function setupBalance(){
44
+ let etherGiver = accounts[9];
45
+ // Give whale some ether to make sure the following actions are good
46
+ await web3.eth.sendTransaction({ from: etherGiver, to: underlyingWhale, value: 10e18});
47
+ await web3.eth.sendTransaction({ from: etherGiver, to: addresses.ULOwner, value: 10e18});
48
+
49
+ farmerBalance = await underlying.balanceOf(underlyingWhale);
50
+ await underlying.transfer(farmer1, farmerBalance, { from: underlyingWhale });
51
+ }
52
+
53
+ before(async function() {
54
+ governance = addresses.Governance;
55
+ accounts = await web3.eth.getAccounts();
56
+
57
+ await web3.eth.sendTransaction({ from: accounts[8], to: governance, value: 10e18});
58
+ await web3.eth.sendTransaction({ from: accounts[8], to: addresses.ULOwner, value: 10e18});
59
+
60
+ farmer1 = accounts[1];
61
+
62
+ // impersonate accounts
63
+ await impersonates([governance, underlyingWhale, addresses.ULOwner]);
64
+
65
+ await setupExternalContracts();
66
+ [controller, vault, strategy] = await setupCoreProtocol({
67
+ "existingVaultAddress": null,
68
+ "strategyArtifact": Strategy,
69
+ "strategyArtifactIsUpgradable": true,
70
+ "underlying": underlying,
71
+ "governance": governance,
72
+ "liquidation": [
73
+ {"uniV3": [note, weth]},
74
+ {"camelot": [arb, weth]},
75
+ {"uniV3": [weth, note]}
76
+ ],
77
+ "uniV3Fee": [
78
+ [note, weth, 10000]
79
+ ],
80
+ "ULOwner": addresses.ULOwner
81
+ });
82
+
83
+ // whale send underlying to farmers
84
+ await setupBalance();
85
+ });
86
+
87
+ describe("Happy path", function() {
88
+ it("Farmer should earn money", async function() {
89
+ let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1));
90
+ await depositVault(farmer1, underlying, vault, farmerBalance);
91
+ let fTokenBalance = new BigNumber(await vault.balanceOf(farmer1));
92
+
93
+ // Using half days is to simulate how we doHardwork in the real world
94
+ let hours = 10;
95
+ let blocksPerHour = 2400;
96
+ let oldSharePrice;
97
+ let newSharePrice;
98
+ for (let i = 0; i < hours; i++) {
99
+ console.log("loop ", i);
100
+
101
+ oldSharePrice = new BigNumber(await vault.getPricePerFullShare());
102
+ await controller.doHardWork(vault.address, { from: governance });
103
+ newSharePrice = new BigNumber(await vault.getPricePerFullShare());
104
+
105
+ console.log("old shareprice: ", oldSharePrice.toFixed());
106
+ console.log("new shareprice: ", newSharePrice.toFixed());
107
+ console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed());
108
+
109
+ apr = (newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))*365;
110
+ apy = ((newSharePrice.toFixed()/oldSharePrice.toFixed()-1)*(24/(blocksPerHour/300))+1)**365;
111
+
112
+ console.log("instant APR:", apr*100, "%");
113
+ console.log("instant APY:", (apy-1)*100, "%");
114
+ await vault.withdraw(fTokenBalance.div(10), { from: farmer1 });
115
+ await depositVault(farmer1, underlying, vault, new BigNumber(await underlying.balanceOf(farmer1)))
116
+ await Utils.advanceNBlock(blocksPerHour);
117
+ }
118
+ fTokenBalance = new BigNumber(await vault.balanceOf(farmer1));
119
+ await vault.withdraw(fTokenBalance, { from: farmer1 });
120
+ let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1));
121
+ Utils.assertBNGt(farmerNewBalance, farmerOldBalance);
122
+
123
+ apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))*365;
124
+ apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/300))+1)**365;
125
+
126
+ console.log("earned!");
127
+ console.log("Overall APR:", apr*100, "%");
128
+ console.log("Overall APY:", (apy-1)*100, "%");
129
+
130
+ await strategy.withdrawAllToVault({ from: governance }); // making sure can withdraw all for a next switch
131
+ });
132
+ });
133
+ });