diff --git a/contracts/interfaces/wonderland.sol b/contracts/interfaces/wonderland.sol new file mode 100644 index 000000000..26e03c748 --- /dev/null +++ b/contracts/interfaces/wonderland.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + + +interface IDistributor { + function distribute() external returns ( bool ); +} + +interface IMemo { + function rebase( uint256 ohmProfit_, uint epoch_) external returns (uint256); + + function circulatingSupply() external view returns (uint256); + + function balanceOf(address who) external view returns (uint256); + + function gonsForBalance( uint amount ) external view returns ( uint ); + + function balanceForGons( uint gons ) external view returns ( uint ); + + function index() external view returns ( uint ); +} + + +interface IWarmup { + function retrieve( address staker_, uint amount_ ) external; +} + + +interface ITreasury { + function deposit( uint _amount, address _token, uint _profit ) external returns ( bool ); + function valueOf( address _token, uint _amount ) external view returns ( uint value_ ); + function mintRewards( address _recipient, uint _amount ) external; +} + + +enum PARAMETER { VESTING, PAYOUT, DEBT, MINPRICE } + +interface ITimeBondDepository { + function initializeBondTerms(uint _controlVariable, uint _minimumPrice, uint _maxPayout, uint _maxDebt, uint _initialDebt, uint32 _vestingTerm) external; + + function setBondTerms ( PARAMETER _parameter, uint _input ) external; + + function setAdjustment ( bool _addition, uint _increment, uint _target, uint32 _buffer ) external; + + function setStaking( address _staking, bool _helper ) external; + + function deposit( uint _amount, uint _maxPrice, address _depositor) external payable returns ( uint ); + + function redeem( address _recipient, bool _stake ) external returns ( uint ); + + function stakeOrSend( address _recipient, bool _stake, uint _amount ) external returns ( uint ); +} + +interface ITimeStaking { + function rebase() external; + function unstake( uint _amount, bool _trigger) external; +} + +interface IStaking { + function stake( uint _amount, address _recipient ) external returns ( bool ); + function claim( address _recipient ) external; +} + +interface IStakingHelper { + function stake( uint _amount, address _recipient ) external; +} \ No newline at end of file diff --git a/contracts/lib/safe-math.sol b/contracts/lib/safe-math.sol index 31baf623f..c4b6b913b 100644 --- a/contracts/lib/safe-math.sol +++ b/contracts/lib/safe-math.sol @@ -33,6 +33,13 @@ library SafeMath { return c; } + function add32(uint32 a, uint32 b) internal pure returns (uint32) { + uint32 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). diff --git a/contracts/snowglobes/traderJoe/snowglobe-joe-avax-craft.sol b/contracts/snowglobes/traderJoe/snowglobe-joe-avax-craft.sol new file mode 100644 index 000000000..93b6e82b8 --- /dev/null +++ b/contracts/snowglobes/traderJoe/snowglobe-joe-avax-craft.sol @@ -0,0 +1,131 @@ +// https://github.com/iearn-finance/vaults/blob/master/contracts/vaults/yVault.sol + +pragma solidity ^0.6.7; + +import "../../interfaces/controller.sol"; + +import "../../lib/erc20.sol"; +import "../../lib/safe-math.sol"; + +contract SnowGlobeJoeAvaxCraft is ERC20 { + using SafeERC20 for IERC20; + using Address for address; + using SafeMath for uint256; + + IERC20 public token; + + uint256 public min = 9500; + uint256 public constant max = 10000; + + address public governance; + address public timelock; + address public controller; + + constructor(address _token, address _governance, address _timelock, address _controller) + public + ERC20( + string(abi.encodePacked("freezing ", ERC20(_token).name())), + string(abi.encodePacked("s", ERC20(_token).symbol())) + ) + { + _setupDecimals(ERC20(_token).decimals()); + token = IERC20(_token); + governance = _governance; + timelock = _timelock; + controller = _controller; + } + + function balance() public view returns (uint256) { + return + token.balanceOf(address(this)).add( + IController(controller).balanceOf(address(token)) + ); + } + + function setMin(uint256 _min) external { + require(msg.sender == governance, "!governance"); + require(_min <= max, "numerator cannot be greater than denominator"); + min = _min; + } + + function setGovernance(address _governance) public { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) public { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) public { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // Custom logic in here for how much the globes allows to be borrowed + // Sets minimum required on-hand to keep small withdrawals cheap + function available() public view returns (uint256) { + return token.balanceOf(address(this)).mul(min).div(max); + } + + function earn() public { + uint256 _bal = available(); + token.safeTransfer(controller, _bal); + IController(controller).earn(address(token), _bal); + } + + function depositAll() external { + deposit(token.balanceOf(msg.sender)); + } + + function deposit(uint256 _amount) public { + uint256 _pool = balance(); + uint256 _before = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 _after = token.balanceOf(address(this)); + _amount = _after.sub(_before); // Additional check for deflationary tokens + uint256 shares = 0; + if (totalSupply() == 0) { + shares = _amount; + } else { + shares = (_amount.mul(totalSupply())).div(_pool); + } + _mint(msg.sender, shares); + } + + function withdrawAll() external { + withdraw(balanceOf(msg.sender)); + } + + // Used to swap any borrowed reserve over the debt limit to liquidate to 'token' + function harvest(address reserve, uint256 amount) external { + require(msg.sender == controller, "!controller"); + require(reserve != address(token), "token"); + IERC20(reserve).safeTransfer(controller, amount); + } + + // No rebalance implementation for lower fees and faster swaps + function withdraw(uint256 _shares) public { + uint256 r = (balance().mul(_shares)).div(totalSupply()); + _burn(msg.sender, _shares); + + // Check balance + uint256 b = token.balanceOf(address(this)); + if (b < r) { + uint256 _withdraw = r.sub(b); + IController(controller).withdraw(address(token), _withdraw); + uint256 _after = token.balanceOf(address(this)); + uint256 _diff = _after.sub(b); + if (_diff < _withdraw) { + r = b.add(_diff); + } + } + + token.safeTransfer(msg.sender, r); + } + + function getRatio() public view returns (uint256) { + return balance().mul(1e18).div(totalSupply()); + } +} diff --git a/contracts/snowglobes/wonderland/snowglobe-time-avax-time.sol b/contracts/snowglobes/wonderland/snowglobe-time-avax-time.sol new file mode 100644 index 000000000..1f3fcde9f --- /dev/null +++ b/contracts/snowglobes/wonderland/snowglobe-time-avax-time.sol @@ -0,0 +1,136 @@ +// https://github.com/iearn-finance/vaults/blob/master/contracts/vaults/yVault.sol + +pragma solidity ^0.6.7; + +import "../../interfaces/controller.sol"; + +import "../../lib/erc20.sol"; +import "../../lib/safe-math.sol"; + +contract SnowGlobeTimeAvaxTime is ERC20 { + using SafeERC20 for IERC20; + using Address for address; + using SafeMath for uint256; + + IERC20 public token; + + uint256 public min = 9500; + uint256 public constant max = 10000; + + address public governance; + address public timelock; + address public controller; + + constructor( + address _token, + address _governance, + address _timelock, + address _controller + ) + public + ERC20( + string(abi.encodePacked("freezing ", ERC20(_token).name())), + string(abi.encodePacked("s", ERC20(_token).symbol())) + ) + { + _setupDecimals(ERC20(_token).decimals()); + token = IERC20(_token); + governance = _governance; + timelock = _timelock; + controller = _controller; + } + + function balance() public view returns (uint256) { + return + token.balanceOf(address(this)).add( + IController(controller).balanceOf(address(token)) + ); + } + + function setMin(uint256 _min) external { + require(msg.sender == governance, "!governance"); + require(_min <= max, "numerator cannot be greater than denominator"); + min = _min; + } + + function setGovernance(address _governance) public { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) public { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) public { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // Custom logic in here for how much the globes allows to be borrowed + // Sets minimum required on-hand to keep small withdrawals cheap + function available() public view returns (uint256) { + return token.balanceOf(address(this)).mul(min).div(max); + } + + function earn() public { + uint256 _bal = available(); + token.safeTransfer(controller, _bal); + IController(controller).earn(address(token), _bal); + } + + function depositAll() external { + deposit(token.balanceOf(msg.sender)); + } + + function deposit(uint256 _amount) public { + uint256 _pool = balance(); + uint256 _before = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 _after = token.balanceOf(address(this)); + _amount = _after.sub(_before); // Additional check for deflationary tokens + uint256 shares = 0; + if (totalSupply() == 0) { + shares = _amount; + } else { + shares = (_amount.mul(totalSupply())).div(_pool); + } + _mint(msg.sender, shares); + } + + function withdrawAll() external { + withdraw(balanceOf(msg.sender)); + } + + // Used to swap any borrowed reserve over the debt limit to liquidate to 'token' + function harvest(address reserve, uint256 amount) external { + require(msg.sender == controller, "!controller"); + require(reserve != address(token), "token"); + IERC20(reserve).safeTransfer(controller, amount); + } + + // No rebalance implementation for lower fees and faster swaps + function withdraw(uint256 _shares) public { + uint256 r = (balance().mul(_shares)).div(totalSupply()); + _burn(msg.sender, _shares); + + // Check balance + uint256 b = token.balanceOf(address(this)); + if (b < r) { + uint256 _withdraw = r.sub(b); + IController(controller).withdraw(address(token), _withdraw); + uint256 _after = token.balanceOf(address(this)); + uint256 _diff = _after.sub(b); + if (_diff < _withdraw) { + r = b.add(_diff); + } + } + + token.safeTransfer(msg.sender, r); + } + + function getRatio() public view returns (uint256) { + return balance().mul(1e18).div(totalSupply()); + } +} diff --git a/contracts/snowglobes/wonderland/snowglobe-time-avax.sol b/contracts/snowglobes/wonderland/snowglobe-time-avax.sol new file mode 100644 index 000000000..601cecb43 --- /dev/null +++ b/contracts/snowglobes/wonderland/snowglobe-time-avax.sol @@ -0,0 +1,136 @@ +// https://github.com/iearn-finance/vaults/blob/master/contracts/vaults/yVault.sol + +pragma solidity ^0.6.7; + +import "../../interfaces/controller.sol"; + +import "../../lib/erc20.sol"; +import "../../lib/safe-math.sol"; + +contract SnowGlobeTimeAvax is ERC20 { + using SafeERC20 for IERC20; + using Address for address; + using SafeMath for uint256; + + IERC20 public token; + + uint256 public min = 9500; + uint256 public constant max = 10000; + + address public governance; + address public timelock; + address public controller; + + constructor( + address _token, + address _governance, + address _timelock, + address _controller + ) + public + ERC20( + string(abi.encodePacked("freezing ", ERC20(_token).name())), + string(abi.encodePacked("s", ERC20(_token).symbol())) + ) + { + _setupDecimals(ERC20(_token).decimals()); + token = IERC20(_token); + governance = _governance; + timelock = _timelock; + controller = _controller; + } + + function balance() public view returns (uint256) { + return + token.balanceOf(address(this)).add( + IController(controller).balanceOf(address(token)) + ); + } + + function setMin(uint256 _min) external { + require(msg.sender == governance, "!governance"); + require(_min <= max, "numerator cannot be greater than denominator"); + min = _min; + } + + function setGovernance(address _governance) public { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) public { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) public { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // Custom logic in here for how much the globes allows to be borrowed + // Sets minimum required on-hand to keep small withdrawals cheap + function available() public view returns (uint256) { + return token.balanceOf(address(this)).mul(min).div(max); + } + + function earn() public { + uint256 _bal = available(); + token.safeTransfer(controller, _bal); + IController(controller).earn(address(token), _bal); + } + + function depositAll() external { + deposit(token.balanceOf(msg.sender)); + } + + function deposit(uint256 _amount) public { + uint256 _pool = balance(); + uint256 _before = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 _after = token.balanceOf(address(this)); + _amount = _after.sub(_before); // Additional check for deflationary tokens + uint256 shares = 0; + if (totalSupply() == 0) { + shares = _amount; + } else { + shares = (_amount.mul(totalSupply())).div(_pool); + } + _mint(msg.sender, shares); + } + + function withdrawAll() external { + withdraw(balanceOf(msg.sender)); + } + + // Used to swap any borrowed reserve over the debt limit to liquidate to 'token' + function harvest(address reserve, uint256 amount) external { + require(msg.sender == controller, "!controller"); + require(reserve != address(token), "token"); + IERC20(reserve).safeTransfer(controller, amount); + } + + // No rebalance implementation for lower fees and faster swaps + function withdraw(uint256 _shares) public { + uint256 r = (balance().mul(_shares)).div(totalSupply()); + _burn(msg.sender, _shares); + + // Check balance + uint256 b = token.balanceOf(address(this)); + if (b < r) { + uint256 _withdraw = r.sub(b); + IController(controller).withdraw(address(token), _withdraw); + uint256 _after = token.balanceOf(address(this)); + uint256 _diff = _after.sub(b); + if (_diff < _withdraw) { + r = b.add(_diff); + } + } + + token.safeTransfer(msg.sender, r); + } + + function getRatio() public view returns (uint256) { + return balance().mul(1e18).div(totalSupply()); + } +} diff --git a/contracts/snowglobes/wonderland/snowglobe-time-mim-time.sol b/contracts/snowglobes/wonderland/snowglobe-time-mim-time.sol new file mode 100644 index 000000000..efc13d0f4 --- /dev/null +++ b/contracts/snowglobes/wonderland/snowglobe-time-mim-time.sol @@ -0,0 +1,136 @@ +// https://github.com/iearn-finance/vaults/blob/master/contracts/vaults/yVault.sol + +pragma solidity ^0.6.7; + +import "../../interfaces/controller.sol"; + +import "../../lib/erc20.sol"; +import "../../lib/safe-math.sol"; + +contract SnowGlobeTimeMimTime is ERC20 { + using SafeERC20 for IERC20; + using Address for address; + using SafeMath for uint256; + + IERC20 public token; + + uint256 public min = 9500; + uint256 public constant max = 10000; + + address public governance; + address public timelock; + address public controller; + + constructor( + address _token, + address _governance, + address _timelock, + address _controller + ) + public + ERC20( + string(abi.encodePacked("freezing ", ERC20(_token).name())), + string(abi.encodePacked("s", ERC20(_token).symbol())) + ) + { + _setupDecimals(ERC20(_token).decimals()); + token = IERC20(_token); + governance = _governance; + timelock = _timelock; + controller = _controller; + } + + function balance() public view returns (uint256) { + return + token.balanceOf(address(this)).add( + IController(controller).balanceOf(address(token)) + ); + } + + function setMin(uint256 _min) external { + require(msg.sender == governance, "!governance"); + require(_min <= max, "numerator cannot be greater than denominator"); + min = _min; + } + + function setGovernance(address _governance) public { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) public { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) public { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // Custom logic in here for how much the globes allows to be borrowed + // Sets minimum required on-hand to keep small withdrawals cheap + function available() public view returns (uint256) { + return token.balanceOf(address(this)).mul(min).div(max); + } + + function earn() public { + uint256 _bal = available(); + token.safeTransfer(controller, _bal); + IController(controller).earn(address(token), _bal); + } + + function depositAll() external { + deposit(token.balanceOf(msg.sender)); + } + + function deposit(uint256 _amount) public { + uint256 _pool = balance(); + uint256 _before = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 _after = token.balanceOf(address(this)); + _amount = _after.sub(_before); // Additional check for deflationary tokens + uint256 shares = 0; + if (totalSupply() == 0) { + shares = _amount; + } else { + shares = (_amount.mul(totalSupply())).div(_pool); + } + _mint(msg.sender, shares); + } + + function withdrawAll() external { + withdraw(balanceOf(msg.sender)); + } + + // Used to swap any borrowed reserve over the debt limit to liquidate to 'token' + function harvest(address reserve, uint256 amount) external { + require(msg.sender == controller, "!controller"); + require(reserve != address(token), "token"); + IERC20(reserve).safeTransfer(controller, amount); + } + + // No rebalance implementation for lower fees and faster swaps + function withdraw(uint256 _shares) public { + uint256 r = (balance().mul(_shares)).div(totalSupply()); + _burn(msg.sender, _shares); + + // Check balance + uint256 b = token.balanceOf(address(this)); + if (b < r) { + uint256 _withdraw = r.sub(b); + IController(controller).withdraw(address(token), _withdraw); + uint256 _after = token.balanceOf(address(this)); + uint256 _diff = _after.sub(b); + if (_diff < _withdraw) { + r = b.add(_diff); + } + } + + token.safeTransfer(msg.sender, r); + } + + function getRatio() public view returns (uint256) { + return balance().mul(1e18).div(totalSupply()); + } +} diff --git a/contracts/snowglobes/wonderland/snowglobe-time-mim.sol b/contracts/snowglobes/wonderland/snowglobe-time-mim.sol new file mode 100644 index 000000000..26acafea5 --- /dev/null +++ b/contracts/snowglobes/wonderland/snowglobe-time-mim.sol @@ -0,0 +1,136 @@ +// https://github.com/iearn-finance/vaults/blob/master/contracts/vaults/yVault.sol + +pragma solidity ^0.6.7; + +import "../../interfaces/controller.sol"; + +import "../../lib/erc20.sol"; +import "../../lib/safe-math.sol"; + +contract SnowGlobeTimeMim is ERC20 { + using SafeERC20 for IERC20; + using Address for address; + using SafeMath for uint256; + + IERC20 public token; + + uint256 public min = 9500; + uint256 public constant max = 10000; + + address public governance; + address public timelock; + address public controller; + + constructor( + address _token, + address _governance, + address _timelock, + address _controller + ) + public + ERC20( + string(abi.encodePacked("freezing ", ERC20(_token).name())), + string(abi.encodePacked("s", ERC20(_token).symbol())) + ) + { + _setupDecimals(ERC20(_token).decimals()); + token = IERC20(_token); + governance = _governance; + timelock = _timelock; + controller = _controller; + } + + function balance() public view returns (uint256) { + return + token.balanceOf(address(this)).add( + IController(controller).balanceOf(address(token)) + ); + } + + function setMin(uint256 _min) external { + require(msg.sender == governance, "!governance"); + require(_min <= max, "numerator cannot be greater than denominator"); + min = _min; + } + + function setGovernance(address _governance) public { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) public { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) public { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // Custom logic in here for how much the globes allows to be borrowed + // Sets minimum required on-hand to keep small withdrawals cheap + function available() public view returns (uint256) { + return token.balanceOf(address(this)).mul(min).div(max); + } + + function earn() public { + uint256 _bal = available(); + token.safeTransfer(controller, _bal); + IController(controller).earn(address(token), _bal); + } + + function depositAll() external { + deposit(token.balanceOf(msg.sender)); + } + + function deposit(uint256 _amount) public { + uint256 _pool = balance(); + uint256 _before = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 _after = token.balanceOf(address(this)); + _amount = _after.sub(_before); // Additional check for deflationary tokens + uint256 shares = 0; + if (totalSupply() == 0) { + shares = _amount; + } else { + shares = (_amount.mul(totalSupply())).div(_pool); + } + _mint(msg.sender, shares); + } + + function withdrawAll() external { + withdraw(balanceOf(msg.sender)); + } + + // Used to swap any borrowed reserve over the debt limit to liquidate to 'token' + function harvest(address reserve, uint256 amount) external { + require(msg.sender == controller, "!controller"); + require(reserve != address(token), "token"); + IERC20(reserve).safeTransfer(controller, amount); + } + + // No rebalance implementation for lower fees and faster swaps + function withdraw(uint256 _shares) public { + uint256 r = (balance().mul(_shares)).div(totalSupply()); + _burn(msg.sender, _shares); + + // Check balance + uint256 b = token.balanceOf(address(this)); + if (b < r) { + uint256 _withdraw = r.sub(b); + IController(controller).withdraw(address(token), _withdraw); + uint256 _after = token.balanceOf(address(this)); + uint256 _diff = _after.sub(b); + if (_diff < _withdraw) { + r = b.add(_diff); + } + } + + token.safeTransfer(msg.sender, r); + } + + function getRatio() public view returns (uint256) { + return balance().mul(1e18).div(totalSupply()); + } +} diff --git a/contracts/snowglobes/wonderland/snowglobe-time-x-time.sol b/contracts/snowglobes/wonderland/snowglobe-time-x-time.sol new file mode 100644 index 000000000..a9c727590 --- /dev/null +++ b/contracts/snowglobes/wonderland/snowglobe-time-x-time.sol @@ -0,0 +1,136 @@ +// https://github.com/iearn-finance/vaults/blob/master/contracts/vaults/yVault.sol + +pragma solidity ^0.6.7; + +import "../../interfaces/controller.sol"; + +import "../../lib/erc20.sol"; +import "../../lib/safe-math.sol"; + +contract SnowGlobeTimeXTime is ERC20 { + using SafeERC20 for IERC20; + using Address for address; + using SafeMath for uint256; + + IERC20 public token; + + uint256 public min = 9500; + uint256 public constant max = 10000; + + address public governance; + address public timelock; + address public controller; + + constructor( + address _token, + address _governance, + address _timelock, + address _controller + ) + public + ERC20( + string(abi.encodePacked("freezing ", ERC20(_token).name())), + string(abi.encodePacked("s", ERC20(_token).symbol())) + ) + { + _setupDecimals(ERC20(_token).decimals()); + token = IERC20(_token); + governance = _governance; + timelock = _timelock; + controller = _controller; + } + + function balance() public view returns (uint256) { + return + token.balanceOf(address(this)).add( + IController(controller).balanceOf(address(token)) + ); + } + + function setMin(uint256 _min) external { + require(msg.sender == governance, "!governance"); + require(_min <= max, "numerator cannot be greater than denominator"); + min = _min; + } + + function setGovernance(address _governance) public { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) public { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) public { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // Custom logic in here for how much the globes allows to be borrowed + // Sets minimum required on-hand to keep small withdrawals cheap + function available() public view returns (uint256) { + return token.balanceOf(address(this)).mul(min).div(max); + } + + function earn() public { + uint256 _bal = available(); + token.safeTransfer(controller, _bal); + IController(controller).earn(address(token), _bal); + } + + function depositAll() external { + deposit(token.balanceOf(msg.sender)); + } + + function deposit(uint256 _amount) public { + uint256 _pool = balance(); + uint256 _before = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 _after = token.balanceOf(address(this)); + _amount = _after.sub(_before); // Additional check for deflationary tokens + uint256 shares = 0; + if (totalSupply() == 0) { + shares = _amount; + } else { + shares = (_amount.mul(totalSupply())).div(_pool); + } + _mint(msg.sender, shares); + } + + function withdrawAll() external { + withdraw(balanceOf(msg.sender)); + } + + // Used to swap any borrowed reserve over the debt limit to liquidate to 'token' + function harvest(address reserve, uint256 amount) external { + require(msg.sender == controller, "!controller"); + require(reserve != address(token), "token"); + IERC20(reserve).safeTransfer(controller, amount); + } + + // No rebalance implementation for lower fees and faster swaps + function withdraw(uint256 _shares) public { + uint256 r = (balance().mul(_shares)).div(totalSupply()); + _burn(msg.sender, _shares); + + // Check balance + uint256 b = token.balanceOf(address(this)); + if (b < r) { + uint256 _withdraw = r.sub(b); + IController(controller).withdraw(address(token), _withdraw); + uint256 _after = token.balanceOf(address(this)); + uint256 _diff = _after.sub(b); + if (_diff < _withdraw) { + r = b.add(_diff); + } + } + + token.safeTransfer(msg.sender, r); + } + + function getRatio() public view returns (uint256) { + return balance().mul(1e18).div(totalSupply()); + } +} diff --git a/contracts/strategies/strategy-time-farm.sol b/contracts/strategies/strategy-time-farm.sol new file mode 100644 index 000000000..3bcb370bf --- /dev/null +++ b/contracts/strategies/strategy-time-farm.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "./strategy-wonderland-base.sol"; + +abstract contract TimeFarm is TimeBase{ + uint256 public _initialMemo; + address public bond; + + uint256 public _initial; // initial amount of memories/time for harvesting later + + constructor( + address _bond, + address _want, + address _governance, + address _strategist, + address _controller, + address _timelock + ) + public + TimeBase(_want, _governance, _strategist, _controller, _timelock) + { + bond = _bond; + } + + function balanceOfPool() public view override returns (uint256) { + uint256 amount = IMemo(memo).balanceOf(address(this)); + return amount; + } + + receive() external payable {} + + function getHarvestable() external view returns (uint256, uint256) { + uint256 pendingMemories = IERC20(memo).balanceOf(address(this)); + uint256 profit = _initialMemo.sub(pendingMemories); + return (pendingMemories, profit); + } + + function harvest() public override onlyBenevolent { + ITimeStaking(staking).rebase(); + + if (want != time) { + uint256 _rebaseMemo = IERC20(memo).balanceOf(address(this)); + uint _amount = _rebaseMemo.sub(_initialMemo); + + if (_amount > 0) { + // 10% locked up for future governance + uint256 _keep = _amount.mul(keep).div(keepMax); + if (_keep > 0) { + _takeFeeTimeToSnob(_keep); + } + } + } + } + + + function _withdrawSome(uint256 _amount) internal override returns (uint256) { + IERC20(memo).safeApprove(staking, 0); + IERC20(memo).safeApprove(staking, _amount); + ITimeStaking(staking).unstake(_amount, true); + + return _amount; + } + +} \ No newline at end of file diff --git a/contracts/strategies/strategy-wonderland-base.sol b/contracts/strategies/strategy-wonderland-base.sol new file mode 100644 index 000000000..7cdd6cabb --- /dev/null +++ b/contracts/strategies/strategy-wonderland-base.sol @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "../lib/ownable.sol"; +import "../lib/safe-math.sol"; +import "../lib/erc20.sol"; + +import "../interfaces/icequeen.sol"; +import "../interfaces/globe.sol"; +import "../interfaces/joe.sol"; +import "../interfaces/wonderland.sol"; +import "../interfaces/controller.sol"; +import "../interfaces/wavax.sol"; + +//Wonderland Strategy Contract Basics +abstract contract TimeBase { + + using SafeMath for uint256; + using SafeMath for uint32; + using SafeERC20 for IERC20; + + // staking contract for rewards + address public staking = 0x4456B87Af11e87E329AB7d7C7A246ed1aC2168B9; + + uint256 public maxPrice; + + // Tokens + address public want; + address public constant joe = 0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd; + address public constant wavax = 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7; + address public constant snob = 0xC38f41A296A4493Ff429F1238e030924A1542e50; + address public constant time = 0xb54f16fB19478766A268F172C9480f8da1a7c9C3; // token given as payment for bond + address public constant memo = 0x136Acd46C134E8269052c62A67042D6bDeDde3C9; + + address public stakingHelper = 0x096BBfB78311227b805c968b070a81D358c13379; // to stake and claim if no staking warmup + bool public useHelper; + bool _stake; + + // Dex + address public constant joeRouter = 0x60aE616a2155Ee3d9A68541Ba4544862310933d4; + + // xSnob Fee Distributor + address public feeDistributor = 0xAd86ef5fD2eBc25bb9Db41A1FE8d0f2a322c7839; + + // Perfomance fees - start with 0% + uint256 public performanceTreasuryFee = 0; + uint256 public constant performanceTreasuryMax = 10000; + + uint256 public performanceDevFee = 0; + uint256 public constant performanceDevMax = 10000; + + // How many rewards tokens to keep? start with 10% converted to Snowballss + uint256 public keep = 1000; + uint256 public constant keepMax = 10000; + + //portion to seend to fee distributor + uint256 public revenueShare = 3000; + uint256 public constant revenueShareMax = 10000; + + // Withdrawal fee 0% + // - 0% to treasury + // - 0% to dev fund + uint256 public withdrawalTreasuryFee = 0; + uint256 public constant withdrawalTreasuryMax = 100000; + + uint256 public withdrawalDevFundFee = 0; + uint256 public constant withdrawalDevFundMax = 100000; + + // User accounts + address public governance; + address public controller; + address public strategist; + address public timelock; + + mapping(address => bool) public harvesters; + + + constructor ( + address _want, + address _governance, + address _strategist, + address _controller, + address _timelock + ) public { + require(_want != address(0)); + require(_governance != address(0)); + require(_strategist != address(0)); + require(_controller != address(0)); + require(_timelock != address(0)); + + want = _want; + governance = _governance; + strategist = _strategist; + controller = _controller; + timelock = _timelock; + } + + // **** Modifiers **** // + + modifier onlyBenevolent { + require( + harvesters[msg.sender] || + msg.sender == governance || + msg.sender == strategist + ); + _; + } + + // **** Views **** // + + function balanceOfWant() public view returns (uint256) { + return IERC20(want).balanceOf(address(this)); + } + + function balanceOfPool() public virtual view returns (uint256); + + function balanceOf() public view returns (uint256) { + return balanceOfWant().add(balanceOfPool()); + } + + function getName() external virtual pure returns (string memory); + + // **** Setters **** // + + function setKeep(uint256 _keep) external { + require(msg.sender == timelock, "!timelock"); + keep = _keep; + } + + function setRevenueShare(uint256 _share) external { + require(msg.sender == timelock, "!timelock"); + revenueShare = _share; + } + + function whitelistHarvester(address _harvester) external { + require(msg.sender == governance || + msg.sender == strategist, "not authorized"); + harvesters[_harvester] = true; + } + + function revokeHarvester(address _harvester) external { + require(msg.sender == governance || + msg.sender == strategist, "not authorized"); + harvesters[_harvester] = false; + } + + function setFeeDistributor(address _feeDistributor) external { + require(msg.sender == governance, "not authorized"); + feeDistributor = _feeDistributor; + } + + function setWithdrawalDevFundFee(uint256 _withdrawalDevFundFee) external { + require(msg.sender == timelock, "!timelock"); + withdrawalDevFundFee = _withdrawalDevFundFee; + } + + function setWithdrawalTreasuryFee(uint256 _withdrawalTreasuryFee) external { + require(msg.sender == timelock, "!timelock"); + withdrawalTreasuryFee = _withdrawalTreasuryFee; + } + + function setPerformanceDevFee(uint256 _performanceDevFee) external { + require(msg.sender == timelock, "!timelock"); + performanceDevFee = _performanceDevFee; + } + + function setPerformanceTreasuryFee(uint256 _performanceTreasuryFee) + external + { + require(msg.sender == timelock, "!timelock"); + performanceTreasuryFee = _performanceTreasuryFee; + } + + function setStrategist(address _strategist) external { + require(msg.sender == governance, "!governance"); + strategist = _strategist; + } + + function setGovernance(address _governance) external { + require(msg.sender == governance, "!governance"); + governance = _governance; + } + + function setTimelock(address _timelock) external { + require(msg.sender == timelock, "!timelock"); + timelock = _timelock; + } + + function setController(address _controller) external { + require(msg.sender == timelock, "!timelock"); + controller = _controller; + } + + // **** State mutations **** // + function deposit() public virtual; + + // Controller only function for creating additional rewards from dust + function withdraw(IERC20 _asset) external returns (uint256 balance) { + require(msg.sender == controller, "!controller"); + require(want != address(_asset), "want"); + balance = _asset.balanceOf(address(this)); + _asset.safeTransfer(controller, balance); + } + + // Withdraw partial funds, normally used with a globe withdrawal + function withdraw(uint256 _amount) external { + require(msg.sender == controller, "!controller"); + uint256 _balance = IERC20(want).balanceOf(address(this)); + if (_balance < _amount) { + _amount = _withdrawSome(_amount.sub(_balance)); + _amount = _amount.add(_balance); + } + + uint256 _feeDev = _amount.mul(withdrawalDevFundFee).div( + withdrawalDevFundMax + ); + IERC20(want).safeTransfer(IController(controller).devfund(), _feeDev); + + uint256 _feeTreasury = _amount.mul(withdrawalTreasuryFee).div( + withdrawalTreasuryMax + ); + IERC20(want).safeTransfer( + IController(controller).treasury(), + _feeTreasury + ); + + address _globe = IController(controller).globes(address(want)); + require(_globe != address(0), "!globe"); // additional protection so we don't burn the funds + + IERC20(want).safeTransfer(_globe, _amount.sub(_feeDev).sub(_feeTreasury)); + } + + // Withdraw funds, used to swap between strategies + function withdrawForSwap(uint256 _amount) + external + returns (uint256 balance) + { + require(msg.sender == controller, "!controller"); + _withdrawSome(_amount); + + balance = IERC20(want).balanceOf(address(this)); + + address _globe = IController(controller).globes(address(want)); + require(_globe != address(0), "!globe"); + IERC20(want).safeTransfer(_globe, balance); + } + + // Withdraw all funds, normally used when migrating strategies + function withdrawAll() external returns (uint256 balance) { + require(msg.sender == controller, "!controller"); + _withdrawAll(); + + balance = IERC20(want).balanceOf(address(this)); + + address _globe = IController(controller).globes(address(want)); + require(_globe != address(0), "!globe"); // additional protection so we don't burn the funds + IERC20(want).safeTransfer(_globe, balance); + } + + function _withdrawAll() internal { + _withdrawSome(balanceOfPool()); + } + + function _withdrawSome(uint256 _amount) internal virtual returns (uint256); + + function harvest() public virtual; + + // **** Emergency functions **** // + + function execute(address _target, bytes memory _data) + public + payable + returns (bytes memory response) + { + require(msg.sender == timelock, "!timelock"); + require(_target != address(0), "!target"); + + // call contract in current context + assembly { + let succeeded := delegatecall( + sub(gas(), 5000), + _target, + add(_data, 0x20), + mload(_data), + 0, + 0 + ) + let size := returndatasize() + + response := mload(0x40) + mstore( + 0x40, + add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))) + ) + mstore(response, size) + returndatacopy(add(response, 0x20), 0, size) + + switch iszero(succeeded) + case 1 { + // throw if delegatecall failed + revert(add(response, 0x20), size) + } + } + } + + + // **** Internal functions **** + function _swapTraderJoe( + address _from, + address _to, + uint256 _amount + ) internal { + require(_to != address(0)); + // Swap with TraderJoe + IERC20(_from).safeApprove(joeRouter, 0); + IERC20(_from).safeApprove(joeRouter, _amount); + address[] memory path; + if (_from == joe || _to == joe) { + path = new address[](2); + path[0] = _from; + path[1] = _to; + } + else if (_from == wavax || _to == wavax) { + path = new address[](2); + path[0] = _from; + path[1] = _to; + } + else { + path = new address[](3); + path[0] = _from; + path[1] = wavax; + path[2] = _to; + } + IJoeRouter(joeRouter).swapExactTokensForTokens( + _amount, + 0, + path, + address(this), + now.add(60) + ); + } + + function _swapTraderJoeWithPath(address[] memory path, uint256 _amount) + internal + { + require(path[1] != address(0)); + + IJoeRouter(joeRouter).swapExactTokensForTokens( + _amount, + 0, + path, + address(this), + now.add(60) + ); + } + + function _takeFeeTimeToSnob(uint256 _keep) internal { + IERC20(memo).safeApprove(staking, 0); + IERC20(memo).safeApprove(staking, _keep); + ITimeStaking(staking).unstake(_keep, true); + + address[] memory path = new address[](3); + path[0] = time; + path[1] = wavax; + path[2] = snob; + IERC20(time).safeApprove(joeRouter, 0); + IERC20(time).safeApprove(joeRouter, _keep); + _swapTraderJoeWithPath(path, _keep); + uint256 _snob = IERC20(snob).balanceOf(address(this)); + uint256 _share = _snob.mul(revenueShare).div(revenueShareMax); + IERC20(snob).safeTransfer(feeDistributor, _share); + IERC20(snob).safeTransfer( + IController(controller).treasury(), + _snob.sub(_share) + ); + } + + function _distributePerformanceFeesAndDeposit() internal { + uint256 _want = IERC20(want).balanceOf(address(this)); + + if (_want > 0) { + // Redeposit into contract + IERC20(want).safeTransfer( + IController(controller).treasury(), + _want.mul(performanceTreasuryFee).div(performanceTreasuryMax) + ); + + // Performance fee + IERC20(want).safeTransfer( + IController(controller).devfund(), + _want.mul(performanceDevFee).div(performanceDevMax) + ); + + deposit(); + } + } + +} \ No newline at end of file diff --git a/contracts/strategies/wonderland/strategy-time-avax-time.sol b/contracts/strategies/wonderland/strategy-time-avax-time.sol new file mode 100644 index 000000000..a261b341a --- /dev/null +++ b/contracts/strategies/wonderland/strategy-time-avax-time.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "../strategy-time-farm.sol"; + +contract StrategyTimeAvaxTimeLp is TimeFarm { + + // want/lp token for depositing into depositLP for minting Time + address public avax_time_lp = 0xf64e1c5B6E17031f5504481Ac8145F4c3eab4917; + address public avaxTimeBond = 0xc26850686ce755FFb8690EA156E5A6cf03DcBDE1; + + + constructor( + address _governance, + address _strategist, + address _controller, + address _timelock + ) + public + TimeFarm( + avaxTimeBond, + avax_time_lp, + _governance, + _strategist, + _controller, + _timelock + ) + {} + + // Deposit bond (lp or other token) so that we can get mint Time at a discount and autostake + function deposit() public override { + // Wrap the avax + uint256 _avax = address(this).balance; + if (_avax > 0) { + WAVAX(wavax).deposit{value: _avax}(); + } + + uint256 _wavax = IERC20(wavax).balanceOf(address(this)); + uint256 _time = IERC20(time).balanceOf(address(this)); + + if (_wavax > 0 && _time > 0){ + IERC20(wavax).safeApprove(joeRouter, 0); + IERC20(wavax).safeApprove(joeRouter, _wavax); + + IERC20(time).safeApprove(joeRouter, 0); + IERC20(time).safeApprove(joeRouter, _time); + + // Adds in liquidity for TIME/AVAX + IJoeRouter(joeRouter).addLiquidity( + wavax, + time, + _wavax, + _time, + 0, + 0, + address(this), + now + 60 + ); + } + + uint256 _amount = IERC20(avax_time_lp).balanceOf(address(this)); + + IERC20(avax_time_lp).safeApprove(avaxTimeBond, 0); + IERC20(avax_time_lp).safeApprove(avaxTimeBond, _amount); + + ITimeBondDepository(avaxTimeBond).deposit(_amount, maxPrice, address(this)); + ITimeBondDepository(avaxTimeBond).redeem(address(this), _stake); + + _initialMemo = IERC20(memo).balanceOf(address(this)); + } + + // **** Views **** + + function getName() external pure override returns (string memory) { + return "StrategyTimeAvaxTimeLp"; + } +} diff --git a/contracts/strategies/wonderland/strategy-time-avax.sol b/contracts/strategies/wonderland/strategy-time-avax.sol new file mode 100644 index 000000000..ad08ea8da --- /dev/null +++ b/contracts/strategies/wonderland/strategy-time-avax.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "../strategy-time-farm.sol"; + +contract StrategyTimeAvaxLp is TimeFarm { + + // want token for depositing into depositLP for minting Time + address avaxBond = 0xE02B1AA2c4BE73093BE79d763fdFFC0E3cf67318; + + + constructor( + address _governance, + address _strategist, + address _controller, + address _timelock + ) + public + TimeFarm( + avaxBond, + wavax, + _governance, + _strategist, + _controller, + _timelock + ) + {} + + // Deposit bond (lp or other token) so that we can get mint Time at a discount and autostake + function deposit() public override { + // Wrap the avax + uint256 _avax = address(this).balance; + if (_avax > 0) { + WAVAX(wavax).deposit{value: _avax}(); + } + + uint256 _amount = IERC20(want).balanceOf(address(this)); + + IERC20(want).safeApprove(avaxBond, 0); + IERC20(want).safeApprove(avaxBond, _amount); + + ITimeBondDepository(avaxBond).deposit(_amount, maxPrice, address(this)); + ITimeBondDepository(avaxBond).redeem(address(this), _stake); + + _initialMemo = IERC20(memo).balanceOf(address(this)); + } + + // **** Views **** + + function getName() external pure override returns (string memory) { + return "StrategyTimeAvaxLp"; + } +} diff --git a/contracts/strategies/wonderland/strategy-time-mim-time.sol b/contracts/strategies/wonderland/strategy-time-mim-time.sol new file mode 100644 index 000000000..c4165af37 --- /dev/null +++ b/contracts/strategies/wonderland/strategy-time-mim-time.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "../strategy-time-farm.sol"; + +contract StrategyTimeMimTimeLp is TimeFarm { + + // want/lp token for depositing into depositLP for minting Time + address public mim_time_lp = 0x113f413371fC4CC4C9d6416cf1DE9dFd7BF747Df; + address public mimTimeBond = 0xA184AE1A71EcAD20E822cB965b99c287590c4FFe; + address public mim = 0x130966628846BFd36ff31a822705796e8cb8C18D; + + + constructor( + address _governance, + address _strategist, + address _controller, + address _timelock + ) + public + TimeFarm( + mimTimeBond, + mim_time_lp, + _governance, + _strategist, + _controller, + _timelock + ) + {} + + // Deposit bond (lp or other token) so that we can get mint Time at a discount and autostake + function deposit() public override { + uint256 _mim = IERC20(mim).balanceOf(address(this)); + uint256 _time = IERC20(time).balanceOf(address(this)); + + if (_mim > 0 && _time > 0){ + IERC20(mim).safeApprove(joeRouter, 0); + IERC20(mim).safeApprove(joeRouter, _mim); + + IERC20(time).safeApprove(joeRouter, 0); + IERC20(time).safeApprove(joeRouter, _time); + + // Adds in liquidity for TIME/MIM + IJoeRouter(joeRouter).addLiquidity( + mim, + time, + _mim, + _time, + 0, + 0, + address(this), + now + 60 + ); + } + + uint256 _amount = IERC20(want).balanceOf(address(this)); + + IERC20(mim_time_lp).safeApprove(mimTimeBond, 0); + IERC20(mim_time_lp).safeApprove(mimTimeBond, _amount); + + ITimeBondDepository(mimTimeBond).deposit(_amount, maxPrice, address(this)); + ITimeBondDepository(mimTimeBond).redeem(address(this), _stake); + + _initialMemo = IERC20(memo).balanceOf(address(this)); + } + + // **** Views **** + + function getName() external pure override returns (string memory) { + return "StrategyTimeMimTimeLp"; + } +} diff --git a/contracts/strategies/wonderland/strategy-time-mim.sol b/contracts/strategies/wonderland/strategy-time-mim.sol new file mode 100644 index 000000000..99457c01b --- /dev/null +++ b/contracts/strategies/wonderland/strategy-time-mim.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "../strategy-time-farm.sol"; + +contract StrategyTimeMimLp is TimeFarm { + + // want token for depositing into depositLP for minting Time + address public mim = 0x130966628846BFd36ff31a822705796e8cb8C18D; + address public mimBond = 0x694738E0A438d90487b4a549b201142c1a97B556; + + constructor( + address _governance, + address _strategist, + address _controller, + address _timelock + ) + public + TimeFarm( + mimBond, + mim, + _governance, + _strategist, + _controller, + _timelock + ) + {} + + // Deposit bond (lp or other token) so that we can get mint Time at a discount and autostake + function deposit() public override { + uint256 _amount = IERC20(want).balanceOf(address(this)); + + IERC20(want).safeApprove(mimBond, 0); + IERC20(want).safeApprove(mimBond, _amount); + + ITimeBondDepository(mimBond).deposit(_amount, maxPrice, address(this)); // deposit mim for time tokens + ITimeBondDepository(mimBond).redeem(address(this), _stake); // stake time tokens + + _initialMemo = IERC20(memo).balanceOf(address(this)); + } + + // **** Views **** + + function getName() external pure override returns (string memory) { + return "StrategyTimeMimLp"; + } +} diff --git a/contracts/strategies/wonderland/strategy-time-x-time.sol b/contracts/strategies/wonderland/strategy-time-x-time.sol new file mode 100644 index 000000000..f8499e5ce --- /dev/null +++ b/contracts/strategies/wonderland/strategy-time-x-time.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.7; + +import "../strategy-time-farm.sol"; + +abstract contract StrategyTimeXTimeLp is TimeFarm { + + constructor( + address _governance, + address _strategist, + address _controller, + address _timelock + ) + public + TimeFarm( + bond, + time, + _governance, + _strategist, + _controller, + _timelock + ) + {} + + // Deposits the Time token in the staking contract + function deposit () public override { + // the amount of Time tokens that you want to stake + uint256 _amount = IERC20(time).balanceOf(address(this)); + + if (_amount > 0){ + if ( useHelper ) { // use if staking warmup is 0 + IERC20(time).safeApprove( address(stakingHelper), 0 ); + IERC20(time).safeApprove( address(stakingHelper), _amount ); + IStakingHelper(stakingHelper).stake( _amount, address(this) ); + } else { + IERC20(time).safeApprove( address(staking), 0 ); + IERC20(time).safeApprove( address(staking), _amount ); + IStaking(staking).stake( _amount, address(this) ); + } + } + _initialMemo = IERC20(memo).balanceOf(address(this)); + } + + // **** Views **** + + function getName() external pure override returns (string memory) { + return "StrategyTimeXTimeLp"; + } +} diff --git a/test/LPStrats/all-strats.js b/test/LPStrats/all-strats.js index ccbbd91a9..0a278aa97 100644 --- a/test/LPStrats/all-strats.js +++ b/test/LPStrats/all-strats.js @@ -314,16 +314,16 @@ const tests = [ // controllerAddress: "", // snowglobeAddress: "0x07e7dF7F0612B7dc6789ba402b17c7108c932d05", // }, - { - name: "PngAvaxRoco", - controllerAddress: "", - snowglobeAddress: "", - }, - { - name: "PngAvaxFrax", - controllerAddress: "", - snowglobeAddress: "", - }, + // { + // name: "PngAvaxRoco", + // controllerAddress: "", + // snowglobeAddress: "", + // }, + // { + // name: "PngAvaxFrax", + // controllerAddress: "", + // snowglobeAddress: "", + // }, // { // name: "JoeAvaxPng", // controllerAddress: "", @@ -544,11 +544,16 @@ const tests = [ // controllerAddress: "", // snowglobeAddress: "0xAFB27fB1c5bd91A80d18A321D6dC09aDd6a94219", // }, -// { -// name: "JoeAvaxRoco", -// controllerAddress: "", -// snowglobeAddress: "", -// }, + // { + // name: "JoeAvaxRoco", + // controllerAddress: "", + // snowglobeAddress: "", + // }, + { + name: "TimeAvaxTime", + controllerAddress: "", + snowglobeAddress: "", + }, ]; for (const test of tests) { diff --git a/test/lp-strategy-test.js b/test/lp-strategy-test.js index 56c7e3399..a0e7bb7de 100644 --- a/test/lp-strategy-test.js +++ b/test/lp-strategy-test.js @@ -15,7 +15,7 @@ const doLPStrategyTest = (name, _snowglobeAddr, _controllerAddr, globeABI, strat let globeContract, strategyContract; let strategyBalance, assetAddr, strategyAddr; let snowglobeAddr = _snowglobeAddr ? _snowglobeAddr : ""; - let controllerAddr = _controllerAddr ? _controllerAddr : "0xf7B8D9f8a82a7a6dd448398aFC5c77744Bd6cb85"; + let controllerAddr = _controllerAddr ? _controllerAddr : "0xACc69DEeF119AB5bBf14e6Aaf0536eAFB3D6e046"; const txnAmt = "25000000000000000000000"; const slot = _slot ? _slot : 1;