Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
build/
## Typechain Types
types/
typechain-types/
## Hardhat artifacts
artifacts/

# VSCode
.vscode/settings.json
Expand Down
101 changes: 101 additions & 0 deletions contracts/libs/IMasterApeV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

/*
______ ______
/ \ / \
| ▓▓▓▓▓▓\ ______ ______ | ▓▓▓▓▓▓\__ __ __ ______ ______
| ▓▓__| ▓▓/ \ / \| ▓▓___\▓▓ \ | \ | \| \ / \
| ▓▓ ▓▓ ▓▓▓▓▓▓\ ▓▓▓▓▓▓\\▓▓ \| ▓▓ | ▓▓ | ▓▓ \▓▓▓▓▓▓\ ▓▓▓▓▓▓\
| ▓▓▓▓▓▓▓▓ ▓▓ | ▓▓ ▓▓ ▓▓_\▓▓▓▓▓▓\ ▓▓ | ▓▓ | ▓▓/ ▓▓ ▓▓ | ▓▓
| ▓▓ | ▓▓ ▓▓__/ ▓▓ ▓▓▓▓▓▓▓▓ \__| ▓▓ ▓▓_/ ▓▓_/ ▓▓ ▓▓▓▓▓▓▓ ▓▓__/ ▓▓
| ▓▓ | ▓▓ ▓▓ ▓▓\▓▓ \\▓▓ ▓▓\▓▓ ▓▓ ▓▓\▓▓ ▓▓ ▓▓ ▓▓
\▓▓ \▓▓ ▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓ \▓▓▓▓▓\▓▓▓▓ \▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓
| ▓▓ | ▓▓
| ▓▓ | ▓▓
\▓▓ \▓▓
* App: https://ApeSwap.finance
* Medium: https://ape-swap.medium.com
* Twitter: https://twitter.com/ape_swap
* Telegram: https://t.me/ape_swap
* Announcements: https://t.me/ape_swap_news
* Reddit: https://reddit.com/r/ApeSwap
* Instagram: https://instagram.com/ApeSwap.finance
* GitHub: https://github.com/ApeSwapFinance
*/

interface IMasterApeV2 {
function updateEmissionRate(uint256 _bananaPerSecond, bool _withUpdate) external; // onlyOwner

function updateHardCap(uint256 _hardCap) external; // onlyOwner

function setFeeAddress(address _feeAddress) external; // onlyOwner

function add(
uint256 _allocPoint,
address _stakeToken,
bool _withUpdate,
uint16 _depositFeeBP,
address _rewarder
) external; // onlyOwner

function set(
uint256 _pid,
uint256 _allocPoint,
bool _withUpdate,
uint16 _depositFeeBP,
address _rewarder
) external; // onlyOwner

function massUpdatePools() external;

function updatePool(uint256 _pid) external; // validatePool(_pid);

function depositTo(
uint256 _pid,
uint256 _amount,
address _to
) external; // validatePool(_pid);

function deposit(uint256 _pid, uint256 _amount) external; // validatePool(_pid);

function withdraw(uint256 _pid, uint256 _amount) external; // validatePool(_pid);

function withdrawTo(
uint256 _pid,
uint256 _amount,
address _to
) external; // validatePool(_pid);

function emergencyWithdraw(uint256 _pid) external;

function setPendingMasterApeOwner(address _pendingMasterApeOwner) external;

function bananaPerSecond() external view returns (uint256);

function poolLength() external view returns (uint256);

function totalAllocPoint() external view returns (uint256);

function getMultiplier(uint256 _from, uint256 _to) external view returns (uint256);

function pendingBanana(uint256 _pid, address _user) external view returns (uint256);

function userInfo(uint256, address)
external
view
returns (uint256 amount, uint256 rewardDebt);

function getPoolInfo(uint256 _pid)
external
view
returns (
address lpToken,
uint256 allocPoint,
address rewarder,
uint256 lastRewardBlock,
uint256 accBananaPerShare,
uint256 totalStaked,
uint16 depositFeeBP
);
}
56 changes: 20 additions & 36 deletions contracts/maximizer/BananaVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pragma solidity 0.8.6;
* App: https://apeswap.finance
* Medium: https://ape-swap.medium.com
* Twitter: https://twitter.com/ape_swap
* Discord: https://discord.com/invite/apeswap
* Telegram: https://t.me/ape_swap
* Announcements: https://t.me/ape_swap_news
* GitHub: https://github.com/ApeSwapFinance
Expand All @@ -27,11 +26,12 @@ pragma solidity 0.8.6;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/AccessControlEnumerable.sol";
import "../libs/IMasterApe.sol";
import "./libs/IMasterApeV2.sol";

/// @title Banana Vault
/// @title Banana Vault V2
/// @author ApeSwapFinance
/// @notice Banana vault without fees. Usage only for ApeSwap maximizer vaults
/// @dev This contract is used to interface with the MasterApeV2 contract
contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
using SafeERC20 for IERC20;

Expand All @@ -46,34 +46,29 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
bytes32 public constant DEPOSIT_ROLE = keccak256("DEPOSIT");

IERC20 public immutable bananaToken;
IMasterApe public immutable masterApe;
IMasterApeV2 public immutable masterApeV2;

mapping(address => UserInfo) public userInfo;

uint256 public totalShares;

event Deposit(
address indexed sender,
uint256 amount,
uint256 shares,
uint256 lastDepositedTime
);
event Deposit(address indexed sender, uint256 amount, uint256 shares, uint256 lastDepositedTime);
event Withdraw(address indexed sender, uint256 amount, uint256 shares);
event Earn(address indexed sender);

/**
* @notice Constructor
* @param _bananaToken: Banana token contract
* @param _masterApe: Master Ape contract
* @param _masterApeV2: Master Ape V2 contract
* @param _admin: address of the owner
*/
constructor(
IERC20 _bananaToken,
address _masterApe,
address _masterApeV2,
address _admin
) {
bananaToken = _bananaToken;
masterApe = IMasterApe(_masterApe);
masterApeV2 = IMasterApeV2(_masterApeV2);

// Setup access control
_setupRole(DEFAULT_ADMIN_ROLE, _admin);
Expand All @@ -88,13 +83,9 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
* @notice Deposits funds into the Banana Vault
* @param _amount: number of tokens to deposit (in BANANA)
*/
function deposit(uint256 _amount)
external
nonReentrant
onlyRole(DEPOSIT_ROLE)
{
if(_amount == 0){
// Depositing zero is a way for external contracts to know that an _earn was performed
function deposit(uint256 _amount) external nonReentrant onlyRole(DEPOSIT_ROLE) {
if (_amount == 0) {
// Depositing zero is a way for external contracts to know that an _earn was performed
_earn();
return;
}
Expand All @@ -107,7 +98,7 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
} else {
currentShares = _amount;
}
require(currentShares > 0, "BananaVault:: Adding 0 shares");
require(currentShares > 0, "BananaVault: Adding 0 shares");

UserInfo storage user = userInfo[msg.sender];
user.shares += currentShares;
Expand All @@ -134,7 +125,7 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
* @notice Reinvests BANANA tokens into MasterApe
*/
function earn() external {
masterApe.leaveStaking(0);
masterApeV2.deposit(0, 0);

_earn();

Expand All @@ -145,12 +136,8 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
* @notice Calculates the total pending rewards that can be restaked
* @return Returns total pending Banana rewards
*/
function calculateTotalPendingBananaRewards()
external
view
returns (uint256)
{
uint256 amount = masterApe.pendingCake(0, address(this));
function calculateTotalPendingBananaRewards() external view returns (uint256) {
uint256 amount = masterApeV2.pendingBanana(0, address(this));
return amount + available();
}

Expand Down Expand Up @@ -178,7 +165,7 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
uint256 bal = available();
if (bal < bananaTokensToWithdraw) {
uint256 balWithdraw = bananaTokensToWithdraw - bal;
masterApe.leaveStaking(balWithdraw);
masterApeV2.withdraw(0, balWithdraw);
// Check if the withdraw deposited enough tokens into this contract
uint256 balAfter = available();
if (balAfter < bananaTokensToWithdraw) {
Expand Down Expand Up @@ -210,7 +197,7 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
* @dev It includes tokens held by the contract and held in MasterApe
*/
function underlyingTokenBalance() public view returns (uint256) {
(uint256 amount, ) = masterApe.userInfo(0, address(this));
(uint256 amount, ) = masterApeV2.userInfo(0, address(this));

return bananaToken.balanceOf(address(this)) + amount;
}
Expand All @@ -222,14 +209,11 @@ contract BananaVault is AccessControlEnumerable, ReentrancyGuard {
uint256 balance = available();

if (balance > 0) {
if (
bananaToken.allowance(address(this), address(masterApe)) <
balance
) {
bananaToken.safeApprove(address(masterApe), type(uint256).max);
if (bananaToken.allowance(address(this), address(masterApeV2)) < balance) {
bananaToken.safeApprove(address(masterApeV2), type(uint256).max);
}

masterApe.enterStaking(balance);
masterApeV2.deposit(0, balance);
}
}
}
Loading