Skip to content
Draft

SHELL #184

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
23 changes: 23 additions & 0 deletions contracts/interfaces/joe.sol
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,26 @@ interface IJoeFactory {
external
returns (address pair);
}

interface IVeJoeStaking {
/// @notice Deposits JOE to start staking for veJOE. Note that any pending veJOE
/// will also be claimed in the process.
/// @param _amount The amount of JOE to deposit
function deposit(uint256 _amount) external;

/// @notice Claim any pending veJOE
function claim() external;

/// @notice Info for each user
/// `balance`: Amount of JOE currently staked by user
/// `rewardDebt`: The reward debt of the user
/// `lastClaimTimestamp`: The timestamp of user's last claim or withdraw
/// `speedUpEndTimestamp`: The timestamp when user stops receiving speed up benefits, or
/// zero if user is not currently receiving speed up benefits
function userInfo(address) external view returns (
uint256 balance,
uint256 rewardDebt,
uint256 lastClaimTimestamp,
uint256 speedUpEndTimestamp
);
}
105 changes: 105 additions & 0 deletions contracts/strategies/traderJoe/veJoe/strategy-vejoe.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.7;

import "../../../interfaces/joe.sol";
import "../../../lib/erc20.sol";
import "../../../lib/safe-math.sol";
import "../../../lib/ownable.sol";

/// @notice The staking contract for TraderJoe's veJoe booster for earning boosted JOE yields for select farms
contract StakingVeJoe is Ownable {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint256;

address public veJoeStaking = 0x25D85E17dD9e544F6E9F8D44F99602dbF5a97341;
address public constant joe = 0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd;

bool public enableDeposit = true;
address public voterProxy;

modifier onlyJoeVoterProxy() {
require(msg.sender == voterProxy, "JoeVoter::onlyJoeVoterProxy");
_;
}

constructor (
address _owner
)
public
{}

receive() external payable {}

/**
* @notice Update proxy address
* @dev Restricted to owner
* @param _voterProxy new address
*/
function setVoterProxy(address _voterProxy) external onlyOwner {
voterProxy = _voterProxy;
}

/**
* @notice Allows account holder to enable/disable deposits
* @param value bool
*/
function updateEnableDeposit(bool value) external onlyOwner{
require(enableDeposit != value);
enableDeposit = value;
}

/**
* @notice veJOE balance
* @return uint256 balance
*/
function balanceOfVeJoe() external view returns (uint256) {
(uint256 balance, , , ) = IVeJoeStaking(veJoeStaking).userInfo(address(this));
return balance;
}

/**
* @notice External deposit function for JOE
* @param _amount to deposit
*/
function deposit(uint256 _amount) external {
require(enableDeposit == true, "Deposits for veJoe is disabled!");
bool success = IERC20(joe).transferFrom(msg.sender, address(this), _amount);
require(success, "JoeVoter::transfer failed");
_deposit(_amount);
}

/**
* @notice Deposit function for JOE
* @dev Restricted to proxy
* @param _amount to deposit
*/
function depositFromProxy(uint256 _amount) external onlyJoeVoterProxy {
require(enableDeposit == true, "Deposits for veJoe is disabled!");
_deposit(_amount);
}

/**
* @notice Approves and deposits joe and mints veJoe 1:1
* @param _amount to deposit
*/
function _deposit(uint256 _amount) internal {
uint256 _joe = IERC20(joe).balanceOf(address(this));
if (_joe > 0) {
IERC20(joe).safeApprove(veJoeStaking, 0);
IERC20(joe).safeApprove(veJoeStaking, _amount);

IVeJoeStaking(veJoeStaking).deposit(_amount);
}
}

/**
* @notice Claims veJOE and automatically applies a Boost APR,
* which is the additional yield earned on top of the JOE APR and POOL APR
* Also updates veJoe balance
*/
function claimVeJoe() external {
IVeJoeStaking(veJoeStaking).claim();
}

}