Skip to content

Commit

Permalink
add AutoPoolStrategy (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
midnight-commit authored Aug 30, 2023
1 parent 7412957 commit 4f729ac
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 0 deletions.
91 changes: 91 additions & 0 deletions contracts/strategies/crosschain/traderjoe/AutoPoolStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import "../../BaseStrategy.sol";

import "./interfaces/IAPTFarm.sol";
import "./interfaces/IAutomatedPoolToken.sol";

contract AutoPoolStrategy is BaseStrategy {
IAPTFarm public stakingContract;
uint256 public immutable PID;
address public immutable pairTokenIn;

address private immutable JOE;
address private immutable tokenX;
address private immutable tokenY;

constructor(
address _stakingContract,
address _pairTokenIn,
BaseStrategySettings memory _settings,
StrategySettings memory _strategySettings
) BaseStrategy(_settings, _strategySettings) {
stakingContract = IAPTFarm(_stakingContract);
PID = stakingContract.vaultFarmId(address(depositToken));
JOE = stakingContract.joe();
tokenX = IAutomatedPoolToken(address(depositToken)).getTokenX();
tokenY = IAutomatedPoolToken(address(depositToken)).getTokenY();
require(_pairTokenIn == tokenX || _pairTokenIn == tokenY, "AutoPoolStrategy::Invalid configuration");
pairTokenIn = _pairTokenIn;
}

function _depositToStakingContract(uint256 _amount, uint256) internal override {
depositToken.approve(address(stakingContract), _amount);
stakingContract.deposit(PID, _amount);
}

function _withdrawFromStakingContract(uint256 _amount) internal override returns (uint256 withdrawAmount) {
stakingContract.withdraw(PID, _amount);
return _amount;
}

function _emergencyWithdraw() internal override {
stakingContract.withdraw(PID, totalDeposits());
depositToken.approve(address(stakingContract), 0);
}

function _pendingRewards() internal view override returns (Reward[] memory) {
(uint256 pendingJoe, address bonusTokenAddress,, uint256 pendingBonusToken) =
stakingContract.pendingTokens(PID, address(this));
Reward[] memory pendingRewards = new Reward[](supportedRewards.length);
for (uint256 i = 0; i < pendingRewards.length; i++) {
address supportedReward = supportedRewards[i];
uint256 amount;
if (supportedReward == JOE) {
amount = pendingJoe;
} else if (supportedReward == bonusTokenAddress) {
amount = pendingBonusToken;
}
pendingRewards[i] = Reward({reward: supportedReward, amount: amount});
}
return pendingRewards;
}

function _getRewards() internal override {
uint256[] memory pids = new uint[](1);
pids[0] = PID;
stakingContract.harvestRewards(pids);
}

function _convertRewardTokenToDepositToken(uint256 _fromAmount) internal override returns (uint256 toAmount) {
if (pairTokenIn != address(rewardToken)) {
FormattedOffer memory offer = simpleRouter.query(_fromAmount, address(rewardToken), pairTokenIn);
_fromAmount = _swap(offer);
}
uint256 amountX;
uint256 amountY;
if (pairTokenIn == tokenX) {
amountX = _fromAmount;
} else {
amountY = _fromAmount;
}
IERC20(pairTokenIn).approve(address(depositToken), _fromAmount);
(toAmount,,) = IAutomatedPoolToken(address(depositToken)).deposit(amountX, amountY);
}

function totalDeposits() public view override returns (uint256) {
IAPTFarm.UserInfo memory userInfo = stakingContract.userInfo(PID, address(this));
return userInfo.amount;
}
}
70 changes: 70 additions & 0 deletions contracts/strategies/crosschain/traderjoe/interfaces/IAPTFarm.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IAPTFarm {
/**
* @notice Info of each APTFarm user.
* `amount` LP token amount the user has provided.
* `rewardDebt` The amount of JOE entitled to the user.
* `unpaidRewards` The amount of JOE that could not be transferred to the user.
*/
struct UserInfo {
uint256 amount;
uint256 rewardDebt;
uint256 unpaidRewards;
}

/**
* @notice Info of each APTFarm farm.
* `apToken` Address of the LP token.
* `accJoePerShare` Accumulated JOE per share.
* `lastRewardTimestamp` Last timestamp that JOE distribution occurs.
* `joePerSec` JOE tokens distributed per second.
* `rewarder` Address of the rewarder contract that handles the distribution of bonus tokens.
*/
struct FarmInfo {
address apToken;
uint256 accJoePerShare;
uint256 lastRewardTimestamp;
uint256 joePerSec;
address rewarder;
}

function joe() external view returns (address joe);

function hasFarm(address apToken) external view returns (bool hasFarm);

function vaultFarmId(address apToken) external view returns (uint256 vaultFarmId);

function apTokenBalances(address apToken) external view returns (uint256 apTokenBalance);

function farmLength() external view returns (uint256 farmLength);

function farmInfo(uint256 pid) external view returns (FarmInfo memory farmInfo);

function userInfo(uint256 pid, address user) external view returns (UserInfo memory userInfo);

function add(uint256 joePerSec, address apToken, address rewarder) external;

function set(uint256 pid, uint256 joePerSec, address rewarder, bool overwrite) external;

function pendingTokens(uint256 pid, address user)
external
view
returns (
uint256 pendingJoe,
address bonusTokenAddress,
string memory bonusTokenSymbol,
uint256 pendingBonusToken
);

function deposit(uint256 pid, uint256 amount) external;

function withdraw(uint256 pid, uint256 amount) external;

function harvestRewards(uint256[] calldata pids) external;

function emergencyWithdraw(uint256 pid) external;

function skim(address token, address to) external;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IAutomatedPoolToken {
function getTokenX() external view returns (address);
function getTokenY() external view returns (address);
function deposit(uint256 amountX, uint256 amountY)
external
returns (uint256 shares, uint256 effectiveX, uint256 effectiveY);
}

0 comments on commit 4f729ac

Please sign in to comment.