Skip to content
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
15 changes: 15 additions & 0 deletions contracts/Registry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ contract Registry is IRegistry, ModifiersControllerExt {
odefiVaultBooster = _odefiVaultBooster;
}

/**
* @inheritdoc IRegistry
*/
function setStrategyRegistry(address _strategyRegistry) external override onlyOperator {
require(IContractRegistry(_strategyRegistry).registryContract() == address(this), "!registryContract");
strategyRegistry = _strategyRegistry;
}

/**
* @inheritdoc IRegistry
*/
Expand Down Expand Up @@ -526,6 +534,13 @@ contract Registry is IRegistry, ModifiersControllerExt {
return liquidityPoolToAdapter[_pool];
}

/**
* @inheritdoc IRegistry
*/
function getStrategyRegistry() public view override returns (address) {
return strategyRegistry;
}

/**
* @inheritdoc IRegistry
*/
Expand Down
4 changes: 2 additions & 2 deletions contracts/RegistryStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ contract RegistryStorage is RegistryAdminStorage {
address public strategyProvider;

/**
* @notice investStrategyRegistry contract address
* @notice strategyRegistry contract address
*/
address public investStrategyRegistry;
address public strategyRegistry;

/**
* @notice riskManager contract address
Expand Down
11 changes: 11 additions & 0 deletions contracts/RiskManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Modifiers } from "./Modifiers.sol";

// interfaces
import { IStrategyProvider } from "./interfaces/opty/IStrategyProvider.sol";
import { IStrategyRegistry } from "./interfaces/opty/IStrategyRegistry.sol";
import { IRiskManager } from "./interfaces/opty/IRiskManager.sol";
import { Constants } from "./utils/Constants.sol";

Expand Down Expand Up @@ -102,4 +103,14 @@ contract RiskManager is IRiskManager, Modifiers {
}
return false;
}

function isValidStrategy(bytes32 _strategyHash, uint256 _riskProfileCode) external override {
require(
!_isInValidStrategy(
IStrategyRegistry(registryContract.getStrategyRegistry()).getStrategySteps(_strategyHash),
registryContract.getRiskProfile(_riskProfileCode)
),
"Strategy invalid"
);
}
}
321 changes: 321 additions & 0 deletions contracts/StrategyRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;

// libraries
import { DataTypes } from "./libraries/types/DataTypes.sol";

// helper contracts
import { Modifiers } from "./Modifiers.sol";
import { StrategyRegistryStorage } from "./StrategyRegistryStorage.sol";

// interfaces
import { IStrategyRegistry } from "./interfaces/opty/IStrategyRegistry.sol";

/**
* @title StrategyRegistry Contract
* @author Opty.fi
* @dev Contract to persist strategy metadata and there plans
*/
contract StrategyRegistry is IStrategyRegistry, Modifiers, StrategyRegistryStorage {
/* solhint-disable no-empty-blocks */
constructor(address _registry) public Modifiers(_registry) {}

/**
* @notice adds new strategy
* @dev this function can be only called by operator
* @param _strategyHash keccak256 hash of the strategy steps
* @param _steps strategy steps containing pool, outputToken, isSwap
*/
function addStrategy(bytes32 _strategyHash, DataTypes.StrategyStep[] memory _steps) external onlyOperator {
_addStrategySteps(_strategyHash, _steps);
}

/**
* @notice adds new strategy plan
* @dev this function can be only called by operator
* @param _vault address of the vault
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlan core plan of the strategy execution
*/
function addStrategyPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlan memory _strategyPlan
) external onlyOperator {
_addStrategyPlan(_vault, _strategyHash, _strategyPlan);
}

/**
* @notice set multiple strategies
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _strategyHashes list of keccak256 hash of the strategy steps
* @param _steps strategy steps containing pool, outputToken, isSwap
*/
function addStrategies(bytes32[] memory _strategyHashes, DataTypes.StrategyStep[][] memory _steps)
external
onlyOperator
{
uint256 _strategyHashLen = _strategyHashes.length;
uint256 _stepsLen = _steps.length;
require(_strategyHashLen == _stepsLen, "StrategyRegistry::length mismatch");
for (uint256 _i; _i < _strategyHashLen; _i++) {
_addStrategySteps(_strategyHashes[_i], _steps[_i]);
}
}

/**
* @notice set multiple strategy plans
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vaults list of vault addresses
* @param _strategyHashes list of keccak256 hash of the strategy steps
* @param _strategyPlans list of strategy plans for execution
*/
function addStrategyPlans(
address[] memory _vaults,
bytes32[] memory _strategyHashes,
DataTypes.StrategyPlan[] memory _strategyPlans
) external onlyOperator {
uint256 _vaultLen = _vaults.length;
uint256 _strategyHashLen = _strategyHashes.length;
require(
_vaultLen == _strategyHashLen && _strategyHashLen == _strategyPlans.length,
"StrategyRegistry::length mismatch"
);
for (uint256 _i; _i < _strategyHashLen; _i++) {
_addStrategyPlan(_vaults[_i], _strategyHashes[_i], _strategyPlans[_i]);
}
}

/**
* @notice set ora value UT plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setOraValueUTPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].oraValueUTPlan = _strategyPlanInput;
}

/**
* @notice set ora value LP plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setOraValueLPPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].oraValueLPPlan = _strategyPlanInput;
}

/**
* @notice set last step balance LP plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setLastStepBalanceLPPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].lastStepBalanceLPPlan = _strategyPlanInput;
}

/**
* @notice set deposit some to strategy plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setDepositSomeToStrategyPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].depositSomeToStrategyPlan = _strategyPlanInput;
}

/**
* @notice set withdraw some from strategy plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setWithdrawSomeFromStrategyPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].withdrawSomeFromStrategyPlan = _strategyPlanInput;
}

/**
* @notice set claim rewards plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setClaimRewardsPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].claimRewardsPlan = _strategyPlanInput;
}

/**
* @notice set harvest rewards plan
* @dev all the arguments corresponding to each other in the sequence they are passed.
* this function can be only called by operator
* @param _vault vault addresses
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlanInput strategy plan for execution
*/
function setHarvestRewardsPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlanInput memory _strategyPlanInput
) external onlyOperator {
strategyPlans[_vault][_strategyHash].harvestRewardsPlan = _strategyPlanInput;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getStrategySteps(bytes32 _strategyHash) external view override returns (DataTypes.StrategyStep[] memory) {
return steps[_strategyHash];
}

/**
* @inheritdoc IStrategyRegistry
*/
function getOraValueUTPlan(address _vault, bytes32 _strategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_strategyHash].oraValueUTPlan;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getOraValueLPPlan(address _vault, bytes32 _strategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_strategyHash].oraValueLPPlan;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getLastStepBalanceLPPlan(address _vault, bytes32 _stategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_stategyHash].lastStepBalanceLPPlan;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getDepositSomeToStrategyPlan(address _vault, bytes32 _strategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_strategyHash].depositSomeToStrategyPlan;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getWithdrawSomeFromStrategyPlan(address _vault, bytes32 _strategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_strategyHash].withdrawSomeFromStrategyPlan;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getClaimRewardsPlan(address _vault, bytes32 _strategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_strategyHash].claimRewardsPlan;
}

/**
* @inheritdoc IStrategyRegistry
*/
function getHarvestRewardsPlan(address _vault, bytes32 _strategyHash)
external
view
override
returns (DataTypes.StrategyPlanInput memory)
{
return strategyPlans[_vault][_strategyHash].harvestRewardsPlan;
}

/**
* @dev private function to add new strategy
* @param _strategyHash keccak256 hash of the strategy steps
* @param _steps strategy steps containing pool, outputToken, isSwap
*/
function _addStrategySteps(bytes32 _strategyHash, DataTypes.StrategyStep[] memory _steps) private {
delete steps[_strategyHash];
uint256 _stepLength = _steps.length;
for (uint256 _i; _i < _stepLength; _i++) {
steps[_strategyHash].push(_steps[_i]);
}
}

/**
* @dev private function to store core plan for strategy execution
* @param _strategyHash keccak256 hash of the strategy steps
* @param _strategyPlan core plan of the strategy execution
*/
function _addStrategyPlan(
address _vault,
bytes32 _strategyHash,
DataTypes.StrategyPlan memory _strategyPlan
) private {
strategyPlans[_vault][_strategyHash] = _strategyPlan;
}
}
13 changes: 13 additions & 0 deletions contracts/StrategyRegistryStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.12;

import { DataTypes } from "./libraries/types/DataTypes.sol";

contract StrategyRegistryStorage {
/** @dev strategy => strategy steps metadata */
mapping(bytes32 => DataTypes.StrategyStep[]) internal steps;

/** @dev vault to strategy to strategy plan */
mapping(address => mapping(bytes32 => DataTypes.StrategyPlan)) internal strategyPlans;
}
Loading