dsa-connectors/contracts/avalanche/connectors/pangolin/staking/helpers.sol
2022-03-22 20:25:14 +05:30

162 lines
5.5 KiB
Solidity

//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma abicoder v2;
import { TokenInterface } from "../../../common/interfaces.sol";
import { DSMath } from "../../../common/math.sol";
import { Basic } from "../../../common/basic.sol";
import { IERC20, IMiniChefV2, IStakingRewards } from "./interface.sol";
abstract contract Helpers is DSMath, Basic {
/**
* @dev Pangolin MiniChefV2
*/
IMiniChefV2 internal constant minichefv2 = IMiniChefV2(0x1f806f7C8dED893fd3caE279191ad7Aa3798E928);
/**
* @dev Pangolin Token
*/
IERC20 internal constant PNG = IERC20(0x60781C2586D68229fde47564546784ab3fACA982);
// LP Staking, use minichefv2 to staking lp tokens and earn png
function _depositLPStake(
uint pid,
uint amount
) internal returns (address lpTokenAddr) {
require(pid < minichefv2.poolLength(), "Invalid pid!");
IERC20 lptoken = minichefv2.lpToken(pid);
require(amount > 0, "Invalid amount, amount cannot be 0");
require(lptoken.balanceOf(address(this)) > 0, "Invalid LP token balance");
require(lptoken.balanceOf(address(this)) >= amount, "Invalid amount, amount greater than balance of LP token");
approve(
lptoken,
address(minichefv2),
amount
);
minichefv2.deposit(pid, amount, address(this));
lpTokenAddr = address(lptoken);
}
function _withdraw_LP_Stake(
uint pid,
uint amount
) internal returns (address lpTokenAddr) {
require(pid < minichefv2.poolLength(), "Invalid pid!");
IMiniChefV2.UserInfo memory userinfo = minichefv2.userInfo(pid, address(this));
require(userinfo.amount >= amount, "Invalid amount, amount greater than balance of staking");
require(amount > 0, "Invalid amount, amount cannot be 0");
minichefv2.withdraw(pid, amount, address(this));
IERC20 lptoken = minichefv2.lpToken(pid);
lpTokenAddr = address(lptoken);
}
function _withdraw_and_getRewards_LP_Stake(
uint pid,
uint amount
) internal returns (uint256 rewardAmount, address lpTokenAddr) {
require(pid < minichefv2.poolLength(), "Invalid pid!");
IMiniChefV2.UserInfo memory userinfo = minichefv2.userInfo(pid, address(this));
require(userinfo.amount >= amount, "Invalid amount, amount greater than balance of staking");
require(amount > 0, "Invalid amount, amount cannot be 0");
rewardAmount = minichefv2.pendingReward(pid, address(this));
minichefv2.withdrawAndHarvest(pid, amount, address(this));
IERC20 lptoken = minichefv2.lpToken(pid);
lpTokenAddr = address(lptoken);
}
function _getLPStakeReward(
uint pid
) internal returns (uint256 rewardAmount, address lpTokenAddr) {
require(pid < minichefv2.poolLength(), "Invalid pid!");
rewardAmount = minichefv2.pendingReward(pid, address(this));
require(rewardAmount > 0, "No rewards to claim");
minichefv2.harvest(pid, address(this));
IERC20 lptoken = minichefv2.lpToken(pid);
lpTokenAddr = address(lptoken);
}
function _emergencyWithdraw_LP_Stake(
uint pid
) internal returns (uint256 lpAmount, address lpTokenAddr) {
require(pid < minichefv2.poolLength(), "Invalid pid!");
IMiniChefV2.UserInfo memory userinfo = minichefv2.userInfo(pid, address(this));
lpAmount = userinfo.amount;
minichefv2.emergencyWithdraw(pid, address(this));
IERC20 lptoken = minichefv2.lpToken(pid);
lpTokenAddr = address(lptoken);
}
// PNG Staking (Stake PNG, earn another token)
function _depositPNGStake(
address stakingContract_addr,
uint amount
) internal {
IStakingRewards stakingContract = IStakingRewards(stakingContract_addr);
require(amount > 0, "Invalid amount, amount cannot be 0");
require(PNG.balanceOf(address(this)) > 0, "Invalid PNG balance");
require(PNG.balanceOf(address(this)) >= amount, "Invalid amount, amount greater than balance of PNG");
approve(PNG, stakingContract_addr, amount);
stakingContract.stake(amount);
}
function _withdrawPNGStake(
address stakingContract_addr,
uint amount
) internal {
IStakingRewards stakingContract = IStakingRewards(stakingContract_addr);
require(stakingContract.balanceOf(address(this)) >= amount, "Invalid amount, amount greater than balance of staking");
require(amount > 0, "Invalid amount, amount cannot be 0");
stakingContract.withdraw(amount);
}
function _exitPNGStake(
address stakingContract_addr
) internal returns (uint256 exitAmount, uint256 rewardAmount, address rewardToken){
IStakingRewards stakingContract = IStakingRewards(stakingContract_addr);
exitAmount = stakingContract.balanceOf(address(this));
rewardAmount = stakingContract.rewards(address(this));
require(exitAmount > 0, "No balance to exit");
stakingContract.exit();
}
function _claimPNGStakeReward(
address stakingContract_addr
) internal returns (uint256 rewardAmount, address rewardToken) {
IStakingRewards stakingContract = IStakingRewards(stakingContract_addr);
rewardAmount = stakingContract.rewards(address(this));
rewardToken = stakingContract.rewardsToken();
require(rewardAmount > 0, "No rewards to claim");
stakingContract.getReward();
}
}