From 09c51591881f470e857359fe72090a3041918acc Mon Sep 17 00:00:00 2001 From: Silly Date: Sun, 25 Apr 2021 04:53:22 -0700 Subject: [PATCH] Neonic Strategy --- .../neonic/NeonicStrategyMainnet_NEON_BNB.sol | 31 +++++ .../NeonicStrategyMainnet_NEON_BTCB.sol | 33 +++++ .../NeonicStrategyMainnet_NEON_BUSD.sol | 31 +++++ .../NeonicStrategyMainnet_NEON_CAKE.sol | 31 +++++ .../neonic/NeonicStrategyMainnet_NEON_ETH.sol | 31 +++++ test/neonic/neon-bnb.js | 122 +++++++++++++++++ test/neonic/neon-btcb.js | 127 ++++++++++++++++++ test/neonic/neon-busd.js | 126 +++++++++++++++++ test/neonic/neon-cake.js | 126 +++++++++++++++++ test/neonic/neon-eth.js | 126 +++++++++++++++++ 10 files changed, 784 insertions(+) create mode 100644 contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BNB.sol create mode 100644 contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BTCB.sol create mode 100644 contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BUSD.sol create mode 100644 contracts/strategies/neonic/NeonicStrategyMainnet_NEON_CAKE.sol create mode 100644 contracts/strategies/neonic/NeonicStrategyMainnet_NEON_ETH.sol create mode 100644 test/neonic/neon-bnb.js create mode 100644 test/neonic/neon-btcb.js create mode 100644 test/neonic/neon-busd.js create mode 100644 test/neonic/neon-cake.js create mode 100644 test/neonic/neon-eth.js diff --git a/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BNB.sol b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BNB.sol new file mode 100644 index 0000000..33f18d4 --- /dev/null +++ b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BNB.sol @@ -0,0 +1,31 @@ +//SPDX-License-Identifier: Unlicense + +pragma solidity 0.6.12; + +import "../../base/masterchef/GeneralMasterChefStrategyDepositFee.sol"; + +contract NeonicStrategyMainnet_NEON_BNB is GeneralMasterChefStrategyDepositFee { + + address public neon_bnb_unused; // just a differentiator for the bytecode + + constructor() public {} + + function initializeStrategy( + address _storage, + address _vault + ) public initializer { + address underlying = address(0x1C0641d2677703DEcfA8E49E6C90E7E462007CA4); + address neon = address(0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87); + address wbnb = address(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c); + GeneralMasterChefStrategyDepositFee.initializeStrategy( + _storage, + underlying, + _vault, + address(0x045502eE488806BDF22928B6228BDD162B5056f6), // master chef contract + neon, + 0, // Pool id + true // is LP asset + ); + pancakeswapRoutes[wbnb] = [neon, wbnb]; + } +} diff --git a/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BTCB.sol b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BTCB.sol new file mode 100644 index 0000000..6abf33d --- /dev/null +++ b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BTCB.sol @@ -0,0 +1,33 @@ +//SPDX-License-Identifier: Unlicense + +pragma solidity 0.6.12; + +import "../../base/masterchef/GeneralMasterChefStrategyDepositFee.sol"; + +contract NeonicStrategyMainnet_NEON_BTCB is GeneralMasterChefStrategyDepositFee { + + address public neon_btcb_unused; // just a differentiator for the bytecode + + constructor() public {} + + function initializeStrategy( + address _storage, + address _vault + ) public initializer { + address underlying = address(0x17baE1a9FaCaA596a10C3BB90F6Dbb970847BB05); + address neon = address(0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87); + address busd = address(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56); + address wbnb = address(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c); + address btcb = address(0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c); + GeneralMasterChefStrategyDepositFee.initializeStrategy( + _storage, + underlying, + _vault, + address(0x045502eE488806BDF22928B6228BDD162B5056f6), // master chef contract + neon, + 4, // Pool id + true // is LP asset + ); + pancakeswapRoutes[btcb] = [neon, busd, wbnb, btcb]; + } +} diff --git a/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BUSD.sol b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BUSD.sol new file mode 100644 index 0000000..7e20edb --- /dev/null +++ b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_BUSD.sol @@ -0,0 +1,31 @@ +//SPDX-License-Identifier: Unlicense + +pragma solidity 0.6.12; + +import "../../base/masterchef/GeneralMasterChefStrategyDepositFee.sol"; + +contract NeonicStrategyMainnet_NEON_BUSD is GeneralMasterChefStrategyDepositFee { + + address public neon_busd_unused; // just a differentiator for the bytecode + + constructor() public {} + + function initializeStrategy( + address _storage, + address _vault + ) public initializer { + address underlying = address(0xaB953EFFA07e7FB7E694b25169ef515Aa8Ae9Daf); + address neon = address(0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87); + address busd = address(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56); + GeneralMasterChefStrategyDepositFee.initializeStrategy( + _storage, + underlying, + _vault, + address(0x045502eE488806BDF22928B6228BDD162B5056f6), // master chef contract + neon, + 1, // Pool id + true // is LP asset + ); + pancakeswapRoutes[busd] = [neon, busd]; + } +} diff --git a/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_CAKE.sol b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_CAKE.sol new file mode 100644 index 0000000..c94112d --- /dev/null +++ b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_CAKE.sol @@ -0,0 +1,31 @@ +//SPDX-License-Identifier: Unlicense + +pragma solidity 0.6.12; + +import "../../base/masterchef/GeneralMasterChefStrategyDepositFee.sol"; + +contract NeonicStrategyMainnet_NEON_CAKE is GeneralMasterChefStrategyDepositFee { + + address public neon_cake_unused; // just a differentiator for the bytecode + + constructor() public {} + + function initializeStrategy( + address _storage, + address _vault + ) public initializer { + address underlying = address(0xEAbBe7646B1D3ba1f3D32c8439ec828fD653cB64); + address neon = address(0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87); + address cake = address(0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82); + GeneralMasterChefStrategyDepositFee.initializeStrategy( + _storage, + underlying, + _vault, + address(0x045502eE488806BDF22928B6228BDD162B5056f6), // master chef contract + neon, + 2, // Pool id + true // is LP asset + ); + pancakeswapRoutes[cake] = [neon, cake]; + } +} diff --git a/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_ETH.sol b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_ETH.sol new file mode 100644 index 0000000..25f5ff5 --- /dev/null +++ b/contracts/strategies/neonic/NeonicStrategyMainnet_NEON_ETH.sol @@ -0,0 +1,31 @@ +//SPDX-License-Identifier: Unlicense + +pragma solidity 0.6.12; + +import "../../base/masterchef/GeneralMasterChefStrategyDepositFee.sol"; + +contract NeonicStrategyMainnet_NEON_ETH is GeneralMasterChefStrategyDepositFee { + + address public neon_eth_unused; // just a differentiator for the bytecode + + constructor() public {} + + function initializeStrategy( + address _storage, + address _vault + ) public initializer { + address underlying = address(0xFa7D22ec8F803F4A3eF0efc6e053d3017d77CC66); + address neon = address(0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87); + address eth = address(0x2170Ed0880ac9A755fd29B2688956BD959F933F8); + GeneralMasterChefStrategyDepositFee.initializeStrategy( + _storage, + underlying, + _vault, + address(0x045502eE488806BDF22928B6228BDD162B5056f6), // master chef contract + neon, + 3, // Pool id + true // is LP asset + ); + pancakeswapRoutes[eth] = [neon, eth]; + } +} diff --git a/test/neonic/neon-bnb.js b/test/neonic/neon-bnb.js new file mode 100644 index 0000000..fe7dc67 --- /dev/null +++ b/test/neonic/neon-bnb.js @@ -0,0 +1,122 @@ +// Utilities +const Utils = require("../utilities/Utils.js"); +const { + impersonates, + setupCoreProtocol, + depositVault, + swapBNBToToken, + addLiquidity +} = require("../utilities/hh-utils.js"); + +const { send } = require("@openzeppelin/test-helpers"); +const BigNumber = require("bignumber.js"); +const IBEP20 = artifacts.require("IBEP20"); + +//const Strategy = artifacts.require(""); +const Strategy = artifacts.require("NeonicStrategyMainnet_NEON_BNB"); + + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("BSC Mainnet Neonic NEON/BNB", function() { + let accounts; + + // external contracts + let underlying; + + // external setup + let wbnb = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; + let neonAddr = "0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87"; + let eth = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"; + + // parties in the protocol + let governance; + let farmer1; + + // numbers used in tests + let farmerBalance; + + // Core protocol contracts + let controller; + let vault; + let strategy; + + async function setupExternalContracts() { + underlying = await IBEP20.at("0x1C0641d2677703DEcfA8E49E6C90E7E462007CA4"); + console.log("Fetching Underlying at: ", underlying.address); + } + + async function setupBalance(){ + neon = await IBEP20.at(neonAddr); + await swapBNBToToken(farmer1, [wbnb, neon.address], "100" + "000000000000000000"); + farmerNeonBalance = await neon.balanceOf(farmer1); + await addLiquidity(farmer1, "BNB", neon, "100" + "000000000000000000", farmerNeonBalance); + farmerBalance = await underlying.balanceOf(farmer1); + } + + before(async function() { + governance = "0xf00dD244228F51547f0563e60bCa65a30FBF5f7f"; + accounts = await web3.eth.getAccounts(); + + farmer1 = accounts[1]; + + // impersonate accounts + await impersonates([governance]); + + let etherGiver = accounts[9]; + await send.ether(etherGiver, governance, "100" + "000000000000000000") + + await setupExternalContracts(); + [controller, vault, strategy] = await setupCoreProtocol({ + "existingVaultAddress": null, + "strategyArtifact": Strategy, + "strategyArtifactIsUpgradable": true, + "underlying": underlying, + "governance": governance, + "liquidationPath": [neonAddr, wbnb, eth], + }); + + await strategy.setSellFloor(0, {from:governance}); + + // whale send underlying to farmers + await setupBalance(); + }); + + describe("Happy path", function() { + it("Farmer should earn money", async function() { + let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1)); + await depositVault(farmer1, underlying, vault, farmerBalance); + + // Using half days is to simulate how we doHardwork in the real world + let hours = 10; + let blocksPerHour = 2400; + let oldSharePrice; + let newSharePrice; + for (let i = 0; i < hours; i++) { + console.log("loop ", i); + + oldSharePrice = new BigNumber(await vault.getPricePerFullShare()); + await controller.doHardWork(vault.address, { from: governance }); + newSharePrice = new BigNumber(await vault.getPricePerFullShare()); + + console.log("old shareprice: ", oldSharePrice.toFixed()); + console.log("new shareprice: ", newSharePrice.toFixed()); + console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed()); + + await Utils.advanceNBlock(blocksPerHour); + } + await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 }); + let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1)); + Utils.assertBNGt(farmerNewBalance, farmerOldBalance); + + apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))*365; + apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))+1)**365; + + console.log("earned!"); + console.log("APR:", apr*100, "%"); + console.log("APY:", (apy-1)*100, "%"); + + await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch + + }); + }); +}); diff --git a/test/neonic/neon-btcb.js b/test/neonic/neon-btcb.js new file mode 100644 index 0000000..5c03cbf --- /dev/null +++ b/test/neonic/neon-btcb.js @@ -0,0 +1,127 @@ +// Utilities +const Utils = require("../utilities/Utils.js"); +const { + impersonates, + setupCoreProtocol, + depositVault, + swapBNBToToken, + addLiquidity +} = require("../utilities/hh-utils.js"); + +const { send } = require("@openzeppelin/test-helpers"); +const BigNumber = require("bignumber.js"); +const IBEP20 = artifacts.require("IBEP20"); + +//const Strategy = artifacts.require(""); +const Strategy = artifacts.require("NeonicStrategyMainnet_NEON_BTCB"); + + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("BSC Mainnet Neonic NEON/BTCB", function() { + let accounts; + + // external contracts + let underlying; + + // external setup + let wbnb = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; + let neonAddr = "0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87"; + let btcbAddr = "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c"; + let busd = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56"; + let eth = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"; + + // parties in the protocol + let governance; + let farmer1; + + // numbers used in tests + let farmerBalance; + + // Core protocol contracts + let controller; + let vault; + let strategy; + + async function setupExternalContracts() { + underlying = await IBEP20.at("0x17baE1a9FaCaA596a10C3BB90F6Dbb970847BB05"); + console.log("Fetching Underlying at: ", underlying.address); + } + + async function setupBalance(){ + neon = await IBEP20.at(neonAddr); + btcb = await IBEP20.at(btcbAddr); + await swapBNBToToken(farmer1, [wbnb, neon.address], "100" + "000000000000000000"); + await swapBNBToToken(farmer1, [wbnb, btcb.address], "100" + "000000000000000000"); + farmerNeonBalance = await neon.balanceOf(farmer1); + farmerBtcbBalance = await btcb.balanceOf(farmer1); + await addLiquidity(farmer1, btcb, neon, farmerBtcbBalance, farmerNeonBalance); + farmerBalance = await underlying.balanceOf(farmer1); + } + + before(async function() { + governance = "0xf00dD244228F51547f0563e60bCa65a30FBF5f7f"; + accounts = await web3.eth.getAccounts(); + + farmer1 = accounts[1]; + + // impersonate accounts + await impersonates([governance]); + + let etherGiver = accounts[9]; + await send.ether(etherGiver, governance, "100" + "000000000000000000") + + await setupExternalContracts(); + [controller, vault, strategy] = await setupCoreProtocol({ + "existingVaultAddress": null, + "strategyArtifact": Strategy, + "strategyArtifactIsUpgradable": true, + "underlying": underlying, + "governance": governance, + "liquidationPath": [neonAddr, busd, wbnb, eth], + }); + + await strategy.setSellFloor(0, {from:governance}); + + // whale send underlying to farmers + await setupBalance(); + }); + + describe("Happy path", function() { + it("Farmer should earn money", async function() { + let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1)); + await depositVault(farmer1, underlying, vault, farmerBalance); + + // Using half days is to simulate how we doHardwork in the real world + let hours = 10; + let blocksPerHour = 2400; + let oldSharePrice; + let newSharePrice; + for (let i = 0; i < hours; i++) { + console.log("loop ", i); + + oldSharePrice = new BigNumber(await vault.getPricePerFullShare()); + await controller.doHardWork(vault.address, { from: governance }); + newSharePrice = new BigNumber(await vault.getPricePerFullShare()); + + console.log("old shareprice: ", oldSharePrice.toFixed()); + console.log("new shareprice: ", newSharePrice.toFixed()); + console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed()); + + await Utils.advanceNBlock(blocksPerHour); + } + await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 }); + let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1)); + Utils.assertBNGt(farmerNewBalance, farmerOldBalance); + + apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))*365; + apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))+1)**365; + + console.log("earned!"); + console.log("APR:", apr*100, "%"); + console.log("APY:", (apy-1)*100, "%"); + + await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch + + }); + }); +}); diff --git a/test/neonic/neon-busd.js b/test/neonic/neon-busd.js new file mode 100644 index 0000000..8dbc4f2 --- /dev/null +++ b/test/neonic/neon-busd.js @@ -0,0 +1,126 @@ +// Utilities +const Utils = require("../utilities/Utils.js"); +const { + impersonates, + setupCoreProtocol, + depositVault, + swapBNBToToken, + addLiquidity +} = require("../utilities/hh-utils.js"); + +const { send } = require("@openzeppelin/test-helpers"); +const BigNumber = require("bignumber.js"); +const IBEP20 = artifacts.require("IBEP20"); + +//const Strategy = artifacts.require(""); +const Strategy = artifacts.require("NeonicStrategyMainnet_NEON_BUSD"); + + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("BSC Mainnet Neonic NEON/BUSD", function() { + let accounts; + + // external contracts + let underlying; + + // external setup + let wbnb = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; + let neonAddr = "0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87"; + let busdAddr = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56"; + let eth = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"; + + // parties in the protocol + let governance; + let farmer1; + + // numbers used in tests + let farmerBalance; + + // Core protocol contracts + let controller; + let vault; + let strategy; + + async function setupExternalContracts() { + underlying = await IBEP20.at("0xaB953EFFA07e7FB7E694b25169ef515Aa8Ae9Daf"); + console.log("Fetching Underlying at: ", underlying.address); + } + + async function setupBalance(){ + neon = await IBEP20.at(neonAddr); + busd = await IBEP20.at(busdAddr); + await swapBNBToToken(farmer1, [wbnb, neon.address], "100" + "000000000000000000"); + await swapBNBToToken(farmer1, [wbnb, busd.address], "100" + "000000000000000000"); + farmerNeonBalance = await neon.balanceOf(farmer1); + farmerBusdBalance = await busd.balanceOf(farmer1); + await addLiquidity(farmer1, busd, neon, farmerBusdBalance, farmerNeonBalance); + farmerBalance = await underlying.balanceOf(farmer1); + } + + before(async function() { + governance = "0xf00dD244228F51547f0563e60bCa65a30FBF5f7f"; + accounts = await web3.eth.getAccounts(); + + farmer1 = accounts[1]; + + // impersonate accounts + await impersonates([governance]); + + let etherGiver = accounts[9]; + await send.ether(etherGiver, governance, "100" + "000000000000000000") + + await setupExternalContracts(); + [controller, vault, strategy] = await setupCoreProtocol({ + "existingVaultAddress": null, + "strategyArtifact": Strategy, + "strategyArtifactIsUpgradable": true, + "underlying": underlying, + "governance": governance, + "liquidationPath": [neonAddr, wbnb, eth], + }); + + await strategy.setSellFloor(0, {from:governance}); + + // whale send underlying to farmers + await setupBalance(); + }); + + describe("Happy path", function() { + it("Farmer should earn money", async function() { + let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1)); + await depositVault(farmer1, underlying, vault, farmerBalance); + + // Using half days is to simulate how we doHardwork in the real world + let hours = 10; + let blocksPerHour = 2400; + let oldSharePrice; + let newSharePrice; + for (let i = 0; i < hours; i++) { + console.log("loop ", i); + + oldSharePrice = new BigNumber(await vault.getPricePerFullShare()); + await controller.doHardWork(vault.address, { from: governance }); + newSharePrice = new BigNumber(await vault.getPricePerFullShare()); + + console.log("old shareprice: ", oldSharePrice.toFixed()); + console.log("new shareprice: ", newSharePrice.toFixed()); + console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed()); + + await Utils.advanceNBlock(blocksPerHour); + } + await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 }); + let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1)); + Utils.assertBNGt(farmerNewBalance, farmerOldBalance); + + apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))*365; + apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))+1)**365; + + console.log("earned!"); + console.log("APR:", apr*100, "%"); + console.log("APY:", (apy-1)*100, "%"); + + await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch + + }); + }); +}); diff --git a/test/neonic/neon-cake.js b/test/neonic/neon-cake.js new file mode 100644 index 0000000..be7fbd1 --- /dev/null +++ b/test/neonic/neon-cake.js @@ -0,0 +1,126 @@ +// Utilities +const Utils = require("../utilities/Utils.js"); +const { + impersonates, + setupCoreProtocol, + depositVault, + swapBNBToToken, + addLiquidity +} = require("../utilities/hh-utils.js"); + +const { send } = require("@openzeppelin/test-helpers"); +const BigNumber = require("bignumber.js"); +const IBEP20 = artifacts.require("IBEP20"); + +//const Strategy = artifacts.require(""); +const Strategy = artifacts.require("NeonicStrategyMainnet_NEON_CAKE"); + + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("BSC Mainnet Neonic NEON/CAKE", function() { + let accounts; + + // external contracts + let underlying; + + // external setup + let wbnb = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; + let neonAddr = "0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87"; + let cakeAddr = "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82"; + let eth = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"; + + // parties in the protocol + let governance; + let farmer1; + + // numbers used in tests + let farmerBalance; + + // Core protocol contracts + let controller; + let vault; + let strategy; + + async function setupExternalContracts() { + underlying = await IBEP20.at("0xEAbBe7646B1D3ba1f3D32c8439ec828fD653cB64"); + console.log("Fetching Underlying at: ", underlying.address); + } + + async function setupBalance(){ + neon = await IBEP20.at(neonAddr); + cake = await IBEP20.at(cakeAddr); + await swapBNBToToken(farmer1, [wbnb, neon.address], "100" + "000000000000000000"); + await swapBNBToToken(farmer1, [wbnb, cake.address], "100" + "000000000000000000"); + farmerNeonBalance = await neon.balanceOf(farmer1); + farmerCakeBalance = await cake.balanceOf(farmer1); + await addLiquidity(farmer1, cake, neon, farmerCakeBalance, farmerNeonBalance); + farmerBalance = await underlying.balanceOf(farmer1); + } + + before(async function() { + governance = "0xf00dD244228F51547f0563e60bCa65a30FBF5f7f"; + accounts = await web3.eth.getAccounts(); + + farmer1 = accounts[1]; + + // impersonate accounts + await impersonates([governance]); + + let etherGiver = accounts[9]; + await send.ether(etherGiver, governance, "100" + "000000000000000000") + + await setupExternalContracts(); + [controller, vault, strategy] = await setupCoreProtocol({ + "existingVaultAddress": null, + "strategyArtifact": Strategy, + "strategyArtifactIsUpgradable": true, + "underlying": underlying, + "governance": governance, + "liquidationPath": [neonAddr, wbnb, eth], + }); + + await strategy.setSellFloor(0, {from:governance}); + + // whale send underlying to farmers + await setupBalance(); + }); + + describe("Happy path", function() { + it("Farmer should earn money", async function() { + let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1)); + await depositVault(farmer1, underlying, vault, farmerBalance); + + // Using half days is to simulate how we doHardwork in the real world + let hours = 10; + let blocksPerHour = 2400; + let oldSharePrice; + let newSharePrice; + for (let i = 0; i < hours; i++) { + console.log("loop ", i); + + oldSharePrice = new BigNumber(await vault.getPricePerFullShare()); + await controller.doHardWork(vault.address, { from: governance }); + newSharePrice = new BigNumber(await vault.getPricePerFullShare()); + + console.log("old shareprice: ", oldSharePrice.toFixed()); + console.log("new shareprice: ", newSharePrice.toFixed()); + console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed()); + + await Utils.advanceNBlock(blocksPerHour); + } + await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 }); + let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1)); + Utils.assertBNGt(farmerNewBalance, farmerOldBalance); + + apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))*365; + apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))+1)**365; + + console.log("earned!"); + console.log("APR:", apr*100, "%"); + console.log("APY:", (apy-1)*100, "%"); + + await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch + + }); + }); +}); diff --git a/test/neonic/neon-eth.js b/test/neonic/neon-eth.js new file mode 100644 index 0000000..7570366 --- /dev/null +++ b/test/neonic/neon-eth.js @@ -0,0 +1,126 @@ +// Utilities +const Utils = require("../utilities/Utils.js"); +const { + impersonates, + setupCoreProtocol, + depositVault, + swapBNBToToken, + addLiquidity +} = require("../utilities/hh-utils.js"); + +const { send } = require("@openzeppelin/test-helpers"); +const BigNumber = require("bignumber.js"); +const IBEP20 = artifacts.require("IBEP20"); + +//const Strategy = artifacts.require(""); +const Strategy = artifacts.require("NeonicStrategyMainnet_NEON_ETH"); + + +// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. +describe("BSC Mainnet Neonic NEON/ETH", function() { + let accounts; + + // external contracts + let underlying; + + // external setup + let wbnb = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; + let neonAddr = "0x94026f0227cE0c9611e8a228f114F9F19CC3Fa87"; + let ethAddr = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"; + let eth = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"; + + // parties in the protocol + let governance; + let farmer1; + + // numbers used in tests + let farmerBalance; + + // Core protocol contracts + let controller; + let vault; + let strategy; + + async function setupExternalContracts() { + underlying = await IBEP20.at("0xFa7D22ec8F803F4A3eF0efc6e053d3017d77CC66"); + console.log("Fetching Underlying at: ", underlying.address); + } + + async function setupBalance(){ + neon = await IBEP20.at(neonAddr); + eth = await IBEP20.at(ethAddr); + await swapBNBToToken(farmer1, [wbnb, neon.address], "100" + "000000000000000000"); + await swapBNBToToken(farmer1, [wbnb, eth.address], "100" + "000000000000000000"); + farmerNeonBalance = await neon.balanceOf(farmer1); + farmerEthBalance = await eth.balanceOf(farmer1); + await addLiquidity(farmer1, eth, neon, farmerEthBalance, farmerNeonBalance); + farmerBalance = await underlying.balanceOf(farmer1); + } + + before(async function() { + governance = "0xf00dD244228F51547f0563e60bCa65a30FBF5f7f"; + accounts = await web3.eth.getAccounts(); + + farmer1 = accounts[1]; + + // impersonate accounts + await impersonates([governance]); + + let etherGiver = accounts[9]; + await send.ether(etherGiver, governance, "100" + "000000000000000000") + + await setupExternalContracts(); + [controller, vault, strategy] = await setupCoreProtocol({ + "existingVaultAddress": null, + "strategyArtifact": Strategy, + "strategyArtifactIsUpgradable": true, + "underlying": underlying, + "governance": governance, + "liquidationPath": [neonAddr, wbnb, eth], + }); + + await strategy.setSellFloor(0, {from:governance}); + + // whale send underlying to farmers + await setupBalance(); + }); + + describe("Happy path", function() { + it("Farmer should earn money", async function() { + let farmerOldBalance = new BigNumber(await underlying.balanceOf(farmer1)); + await depositVault(farmer1, underlying, vault, farmerBalance); + + // Using half days is to simulate how we doHardwork in the real world + let hours = 10; + let blocksPerHour = 2400; + let oldSharePrice; + let newSharePrice; + for (let i = 0; i < hours; i++) { + console.log("loop ", i); + + oldSharePrice = new BigNumber(await vault.getPricePerFullShare()); + await controller.doHardWork(vault.address, { from: governance }); + newSharePrice = new BigNumber(await vault.getPricePerFullShare()); + + console.log("old shareprice: ", oldSharePrice.toFixed()); + console.log("new shareprice: ", newSharePrice.toFixed()); + console.log("growth: ", newSharePrice.toFixed() / oldSharePrice.toFixed()); + + await Utils.advanceNBlock(blocksPerHour); + } + await vault.withdraw(new BigNumber(await vault.balanceOf(farmer1)).toFixed(), { from: farmer1 }); + let farmerNewBalance = new BigNumber(await underlying.balanceOf(farmer1)); + Utils.assertBNGt(farmerNewBalance, farmerOldBalance); + + apr = (farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))*365; + apy = ((farmerNewBalance.toFixed()/farmerOldBalance.toFixed()-1)*(24/(blocksPerHour*hours/1200))+1)**365; + + console.log("earned!"); + console.log("APR:", apr*100, "%"); + console.log("APY:", (apy-1)*100, "%"); + + await strategy.withdrawAllToVault({from:governance}); // making sure can withdraw all for a next switch + + }); + }); +});