Strategy Contract
Strategy Contracts are the core of FlowDex's yield generation, enabling autocompounding of rewards from various staking protocols. They handle three key steps: (1) staking deposited tokens, (2) harvesting rewards, and (3) reinvesting rewards to maximize yield.
Each Strategy Contract interacts with a Vault Contract to manage user deposits, ensuring risks are isolated from user funds.
Dependencies
StratFeeManager Contract: Manages fee distribution.
GasOptimizer Contract: Optimizes gas usage for transactions.
Interfaces
Router Interface: Facilitates token swaps (e.g., IUniswapRouterETH.sol).
Liquidity Pool Interface: Interacts with underlying liquidity pools (e.g., IUniswapV2Pair.sol).
Chef Interface: Manages staking farms and rewards (e.g., IMiniChefV2.sol).
View Functions
1. balanceOf()
Returns the total amount of the underlying token (e.g., ETH) stored in the strategy.
function balanceOf() public view returns (uint256) {
return balanceOfWant() + balanceOfPool();
}
2. balanceOfWant()
Returns the amount of the underlying token held directly by the strategy.
function balanceOfWant() public view returns (uint256) {
return IERC20(want).balanceOf(address(this));
}
3. balanceOfPool()
Returns the amount of the underlying token staked in the external protocol.
function balanceOfPool() public view returns (uint256) {
(uint256 _amount, ) = IMiniChefV2(chef).userInfo(poolId, address(this));
return _amount;
}
4. rewardsAvailable()
Returns the amount of pending rewards available for harvest.
function rewardsAvailable() public view returns (uint256) {
return IMiniChefV2(chef).pendingSushi(poolId, address(this));
}
Write Functions
1. deposit()
Deposits the underlying token into the external staking protocol.
function deposit() public whenNotPaused {
uint256 wantBal = IERC20(want).balanceOf(address(this));
if (wantBal > 0) {
IMiniChefV2(chef).deposit(poolId, wantBal, address(this));
emit Deposit(balanceOf());
}
}
2. withdraw(uint256 _amount)
Withdraws the underlying token from the external protocol and transfers it back to the Vault.
function withdraw(uint256 _amount) external {
require(msg.sender == vault, "!vault");
uint256 wantBal = IERC20(want).balanceOf(address(this));
if (wantBal < _amount) {
IMiniChefV2(chef).withdraw(poolId, _amount.sub(wantBal), address(this));
}
IERC20(want).safeTransfer(vault, wantBal);
emit Withdraw(balanceOf());
}
3. harvest()
Harvests rewards, charges fees, and reinvests the remaining rewards.
function harvest() external virtual gasThrottle {
IMiniChefV2(chef).harvest(poolId, address(this));
uint256 outputBal = IERC20(output).balanceOf(address(this));
if (outputBal > 0) {
chargeFees(tx.origin);
addLiquidity();
deposit();
emit StratHarvest(msg.sender, balanceOfWant(), balanceOf());
}
}
4. panic()
Withdraws all funds from the external protocol in case of emergencies.
function panic() public onlyManager {
pause();
IMiniChefV2(chef).emergencyWithdraw(poolId, address(this));
}
Additional Functions
setHarvestOnDeposit(bool _harvestOnDeposit)
: Toggles harvesting on deposit.beforeDeposit()
: Ensures rewards are harvested before new deposits.retireStrat()
: Withdraws all funds and transfers them back to the Vault.
Security
ReentrancyGuard: Prevents reentrancy attacks.
Pausable: Allows pausing of critical functions during emergencies.
Fee Management: Ensures fair distribution of fees.
Last updated