Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds TrueFi adapter #21

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
18 changes: 18 additions & 0 deletions adapters/truefi/ITrueFarm.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.6.10;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface ITrueFarm {
// writes
function stakingToken() external view returns (IERC20);
function trustToken() external view returns (IERC20);
function trueDistributor() external view returns (ITrueDistributor);
function name() external view returns (string memory);
function totalStaked() external view returns (uint256);
function stake(uint256 amount) external;
function unstake(uint256 amount) external;
function claim() external;
function exit(uint256 amount) external;
function staked(uint256 address) external returns (uint265);
}
97 changes: 97 additions & 0 deletions adapters/truefi/TrueFiAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.6.12;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../../interfaces/IUniswapV2Pair.sol";
import "../../interfaces/IUniswapV2Factory.sol";
import "../../interfaces/IUniswapV2Router02.sol";
import "../../libraries/UniswapV2Library.sol";
import "../../IVampireAdapter.sol";
import "../../IDrainController.sol";
import "./ITrueFarm.sol";

contract TruefiAdapter is IVampireAdapter {
IDrainController constant drainController = IDrainController(0x2e813f2e524dB699d279E631B0F2117856eb902C);
ITrueFarm constant trueFarm = ITrueFarm(0xED45Cf4895C110f464cE857eBE5f270949eC2ff4);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only represents the UNI LP farm. We should aim to support all 3 farms on TrueFi.

IUniswapV2Router02 constant router = IUniswapV2Router02(0x1d5C6F1607A171Ad52EFB270121331b3039dD83e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the wrong address being used. This is the LuaSwap router not Uniswap.

IERC20 constant tru = IERC20(0x4C19596f5aAfF459fA38B0f7eD92F11AE6543784);
IERC20 constant weth = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
IUniswapV2Pair constant truWethPair = IUniswapV2Pair(0xeC6a6b7dB761A5c9910bA8fcaB98116d384b1B85);

constructor() public {}

// Victim info
function rewardToken() external view override returns (IERC20) {
return tru;
}

function poolCount() external view override returns (uint256) {
return trueFarm.totalStaked();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should return the number of pools, not the amount staked. Looking at TrueFi website (https://app.truefi.io/farm). There should be 3 pools we can support.

}

function sellableRewardAmount() external view override returns (uint256) {
return uint256(-1);
}

// Victim actions, requires impersonation via delegatecall
function sellRewardForWeth(address, uint256 rewardAmount, address to) external override returns(uint256) {
require(drainController.priceIsUnderRejectionTreshold(), "Possible price manipulation, drain rejected");
address[] memory path = new address[](2);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is any reason to use router here. Probably cheaper to swap using the UniswapV2Pair interface. You can see examples in other adapters.

path[0] = address(tru);
path[1] = address(weth);
uint[] memory amounts = router.getAmountsOut(rewardAmount, path);
tru.approve(address(router), uint256(-1));
amounts = router.swapExactTokensForTokens(rewardAmount, amounts[amounts.length - 1], path, to, block.timestamp );
return amounts[amounts.length - 1];
}

// Pool info
function lockableToken(uint256 poolId) external view override returns (IERC20) {
return trueFarm.stakingToken();
}

function lockedAmount(address user, uint256 poolId) external view override returns (uint256) {
return trueFarm.staked(user);
}

// Pool actions, requires impersonation via delegatecall
function deposit(address _adapter, uint256 poolId, uint256 amount) external override {
IVampireAdapter adapter = IVampireAdapter(_adapter);
adapter.lockableToken(poolId).approve(address(trueFarm), uint256(-1));
trueFarm.deposit(amount);
}

function withdraw(address, uint256 poolId, uint256 amount) external override {
trueFarm.unstake(amount);
}

function claimReward(address, uint256 poolId) external override {
trueFarm.claim();
}

function emergencyWithdraw(address, uint256 poolId) external override {
require(false, "not implemented");
}

// Service methods
function poolAddress(uint256) external view override returns (address) {
return address(trueFarm);
}

function rewardToWethPool() external view override returns (address) {
return address(truWethPair);
}

function lockedValue(address, uint256) external override view returns (uint256) {
require(false, "not implemented");
}

function totalLockedValue(uint256) external override view returns (uint256) {
require(false, "not implemented");
}

function normalizedAPY(uint256) external override view returns (uint256) {
require(false, "not implemented");
}
}