Skip to content

Commit f328b01

Browse files
authored
Merge pull request #246 from fei-protocol/feat/v2/interfaces
V2 Interfaces
2 parents 928727c + 499ed6c commit f328b01

24 files changed

+2658
-1626
lines changed

contract-addresses/mainnetAddresses.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ const MainnetAddresses = {
301301
uniswapPCVController: { artifactName: 'unknown', address: '0x0760dfe09bd6d04d0df9a60c51f01ecedceb5132' },
302302
uniswapPCVDeposit: { artifactName: 'UniswapPCVDeposit', address: '0x15958381E9E6dc98bD49655e36f524D2203a28bD' },
303303
uniswapRouter: { artifactName: 'unknown', address: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D' },
304-
weth: { artifactName: 'IWETH', address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' },
304+
weth: { artifactName: 'IWETH', address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' },
305305
wethERC20: { artifactName: 'IERC20', address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' }
306306
};
307307

contracts/oracle/collateralization/CollateralizationOracle.sol

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ contract CollateralizationOracle is ICollateralizationOracle, CoreRef {
6363
_addDeposits(_deposits);
6464

6565
// Shared admin with other oracles
66-
_setContractAdminRole(keccak256("ORACLE_ADMIN_ROLE"));
66+
_setContractAdminRole(keccak256("GUARDIAN_ROLE")); // initialize with Guardian before transitioning to ORACLE_ADMIN via DAO
67+
// _setContractAdminRole(keccak256("ORACLE_ADMIN_ROLE"));
6768
}
6869

6970
// ----------- Convenience getters -----------
@@ -75,12 +76,7 @@ contract CollateralizationOracle is ICollateralizationOracle, CoreRef {
7576

7677
/// @notice returns an array of the addresses of tokens held in the pcv.
7778
function getTokensInPcv() external view returns(address[] memory) {
78-
uint256 _length = tokensInPcv.length();
79-
address[] memory tokens = new address[](_length);
80-
for (uint256 i = 0; i < _length; i++) {
81-
tokens[i] = tokensInPcv.at(i);
82-
}
83-
return tokens;
79+
return tokensInPcv.values();
8480
}
8581

8682
/// @notice returns token at index i of the array of PCV tokens
@@ -90,12 +86,7 @@ contract CollateralizationOracle is ICollateralizationOracle, CoreRef {
9086

9187
/// @notice returns an array of the deposits holding a given token.
9288
function getDepositsForToken(address _token) external view returns(address[] memory) {
93-
uint256 _length = tokenToDeposits[_token].length();
94-
address[] memory deposits = new address[](_length);
95-
for (uint256 i = 0; i < _length; i++) {
96-
deposits[i] = tokenToDeposits[_token].at(i);
97-
}
98-
return deposits;
89+
return tokenToDeposits[_token].values();
9990
}
10091

10192
/// @notice returns the address of deposit at index i of token _token

contracts/oracle/collateralization/CollateralizationOracleWrapper.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ contract CollateralizationOracleWrapper is Timed, ICollateralizationOracleWrappe
6767
deviationThresholdBasisPoints = _deviationThresholdBasisPoints;
6868

6969
// Shared admin with other oracles
70-
_setContractAdminRole(keccak256("ORACLE_ADMIN_ROLE"));
70+
_setContractAdminRole(keccak256("GUARDIAN_ROLE")); // initialize with Guardian before transitioning to ORACLE_ADMIN via DAO
71+
// _setContractAdminRole(keccak256("ORACLE_ADMIN_ROLE"));
7172
}
7273

7374
// ----------- Setter methods ----------------------------------------------
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.4;
3+
4+
import "./IPCVDeposit.sol";
5+
import "../external/Decimal.sol";
6+
7+
/**
8+
@title a PCV Deposit aggregation interface
9+
@author Fei Protocol
10+
11+
This contract is a single interface for allocating a specific token to multiple PCV Deposits.
12+
The aggregator handles new incoming funds and outgoing funds by selecting deposits which are over or under-funded to save for gas and efficiency
13+
*/
14+
interface IPCVDepositAggregator is IPCVDeposit {
15+
16+
// ----------- State changing api -----------
17+
/// @notice rebalance funds of the underlying deposits to the optimal target percents
18+
function rebalance() external;
19+
20+
// ----------- Governor only state changing api -----------
21+
/// @notice adds a new PCV Deposit to the set of deposits
22+
/// @param weight a relative (i.e. not normalized) weight of this PCV deposit
23+
function addPCVDeposit(IPCVDeposit newPCVDeposit, uint256 weight) external;
24+
25+
/// @notice replaces this contract with a new PCV Deposit Aggregator on the rewardsAssetManager
26+
function setNewAggregator(IPCVDepositAggregator newAggregator) external;
27+
28+
// ----------- Governor or Guardian only state changing api -----------
29+
/// @notice remove a PCV deposit from the set of deposits
30+
function removePCVDeposit(IPCVDeposit pcvDeposit) external;
31+
32+
// ----------- Read-only api -----------
33+
/// @notice the upstream rewardsAssetManager funding this contract
34+
function rewardsAssetManager() external returns(address);
35+
36+
/// @notice the set of PCV deposits and non-normalized weights this contract allocates to
37+
function pcvDeposits() external view returns(IPCVDeposit[] memory deposits, uint256[] memory weights);
38+
39+
/// @notice current percent of PCV held by the input `pcvDeposit` relative to the total managed by aggregator.
40+
/// @param depositAmount a hypothetical deposit amount, to be included in the calculation
41+
function percentHeld(IPCVDeposit pcvDeposit, uint256 depositAmount) external view returns(Decimal.D256 memory);
42+
43+
/// @notice the normalized target percent of PCV held by `pcvDeposit` relative to aggregator total
44+
function targetPercentHeld(IPCVDeposit pcvDeposit) external view returns(Decimal.D256 memory);
45+
46+
/// @notice the raw amount of PCV off of the target percent held by `pcvDeposit`
47+
function amountFromTarget(IPCVDeposit pcvDeposit) external view returns(int256);
48+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
3+
pragma solidity ^0.8.0;
4+
5+
import "../IPCVDepositAggregator.sol";
6+
7+
/**
8+
@title IRewardsAssetManager
9+
@author Fei Protocol
10+
11+
interface intended to extend the balancer RewardsAssetManager
12+
https://github.com/balancer-labs/balancer-v2-monorepo/blob/389b52f1fc9e468de854810ce9dc3251d2d5b212/pkg/asset-manager-utils/contracts/RewardsAssetManager.sol
13+
14+
This contract will essentially pass-through funds to an IPCVDepositAggregator denominated in the same underlying asset
15+
*/
16+
interface IRewardsAssetManager {
17+
// ----------- Governor only state changing api -----------
18+
function setNewAggregator(address newAggregator) external;
19+
20+
// ----------- Read-only api -----------
21+
function pcvDepositAggregator() external returns(address);
22+
}

contracts/pcv/balancer/IWeightedPool.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ interface IWeightedPool is IBasePool {
2525
uint256[] memory endWeights
2626
) external;
2727

28+
function withdrawCollectedManagementFees(address recipient) external;
29+
2830
enum JoinKind { INIT, EXACT_TOKENS_IN_FOR_BPT_OUT, TOKEN_IN_FOR_EXACT_BPT_OUT }
2931
enum ExitKind { EXACT_BPT_IN_FOR_ONE_TOKEN_OUT, EXACT_BPT_IN_FOR_TOKENS_OUT, BPT_IN_FOR_EXACT_TOKENS_OUT }
3032
}

contracts/pcv/balancer/manager/IWeightedBalancerPoolManager.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ interface IWeightedBalancerPoolManager is IBaseBalancerPoolManager {
1414
uint256 endTime,
1515
uint256[] memory endWeights
1616
) external;
17+
18+
function withdrawCollectedManagementFees(IWeightedPool pool, address recipient) external;
1719
}

contracts/pcv/balancer/manager/WeightedBalancerPoolManager.sol

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ abstract contract WeightedBalancerPoolManager is IWeightedBalancerPoolManager, B
3232
) internal {
3333
pool.updateWeightsGradually(startTime, endTime, endWeights);
3434
}
35+
36+
function withdrawCollectedManagementFees(IWeightedPool pool, address recipient) public override onlyGovernorOrAdmin {
37+
pool.withdrawCollectedManagementFees(recipient);
38+
}
3539
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.0;
3+
4+
/**
5+
@title Fei Risk Curve Interface
6+
@author Fei Protocol
7+
8+
Risk Curves define a set of balancer weights for a given level of *leverage* in the PCV, which is computable from the collateralization ratio.
9+
10+
The goal is to have higher weights on stable assets at high leverage (low collateralization) to derisk, and add more volatile assets at high collateralization.
11+
12+
The Risk Curve will also take into account the magnitute of the change in weights to determine an amount of time to transition
13+
*/
14+
interface IRiskCurve {
15+
struct CurveParams {
16+
address[] assets;
17+
uint256[] baseWeights;
18+
int256[] slopes;
19+
}
20+
21+
// ----------- public state changing API -----------
22+
/// @notice kick off a new weight change using the current leverage and weight change time
23+
function changeWeights() external;
24+
25+
// ----------- Governor or admin only state changing API -----------
26+
/// @notice change the risk curve parameters
27+
function changeCurve(CurveParams memory curveParams) external;
28+
29+
// ----------- Read-only API -----------
30+
/// @notice determine whether or not to kick off a new weight change
31+
function isWeightChangeEligible() external view returns(bool);
32+
33+
/// @notice return the risk curve parameters
34+
function getCurveParams() external view returns(CurveParams memory);
35+
36+
/// @notice return the current leverage in the protocol, defined as PCV / protocol equity
37+
function getCurrentLeverage() external view returns(uint256);
38+
39+
/// @notice return the balancer weight of an asset at a given leverage
40+
function getAssetWeight(address asset, uint256 leverage) external view returns(uint256);
41+
42+
/// @notice return the set of assets and their corresponding weights at a given leverage
43+
function getWeights(uint256 leverage) external view returns(address[] memory, uint256[] memory);
44+
45+
/// @notice return the target weight for an asset at current leverage
46+
function getCurrentTargetAssetWeight(address asset) external view returns(uint256);
47+
48+
/// @notice return the set of assets and their corresponding weights at a current leverage
49+
function getCurrentTargetWeights() external view returns(address[] memory, uint256[] memory);
50+
51+
/// @notice get the number of seconds to transition weights given the old and new weights
52+
function getWeightChangeTime(uint256[] memory oldWeights, uint256[] memory newWeights) external view returns(uint256);
53+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
pragma solidity ^0.8.4;
2+
3+
import "../IPCVDepositBalances.sol";
4+
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5+
6+
/**
7+
@notice a lightweight contract to wrap ERC20 holding PCV contracts
8+
@author Fei Protocol
9+
When upgrading the PCVDeposit interface, there are many old contracts which do not support it.
10+
The main use case for the new interface is to add read methods for the Collateralization Oracle.
11+
Most PCVDeposits resistant balance method is simply returning the balance as a pass-through
12+
If the PCVDeposit holds FEI it may be considered as protocol FEI
13+
14+
This wrapper can be used in the CR oracle which reduces the number of contract upgrades and reduces the complexity and risk of the upgrade
15+
*/
16+
contract ERC20PCVDepositWrapper is IPCVDepositBalances {
17+
18+
/// @notice the referenced token deposit
19+
address public tokenDeposit;
20+
21+
/// @notice the balance reported in token
22+
IERC20 public token;
23+
24+
/// @notice a flag for whether to report the balance as protocol owned FEI
25+
bool public isProtocolFeiDeposit;
26+
27+
constructor(address _tokenDeposit, IERC20 _token, bool _isProtocolFeiDeposit) {
28+
tokenDeposit = _tokenDeposit;
29+
token = _token;
30+
isProtocolFeiDeposit = _isProtocolFeiDeposit;
31+
}
32+
33+
/// @notice returns total balance of PCV in the Deposit
34+
function balance() public view override returns (uint256) {
35+
return token.balanceOf(tokenDeposit);
36+
}
37+
38+
/// @notice returns the resistant balance and FEI in the deposit
39+
function resistantBalanceAndFei() public view override returns (uint256, uint256) {
40+
uint256 resistantBalance = balance();
41+
uint256 reistantFei = isProtocolFeiDeposit ? resistantBalance : 0;
42+
return (resistantBalance, reistantFei);
43+
}
44+
45+
/// @notice display the related token of the balance reported
46+
function balanceReportedIn() public view override returns (address) {
47+
return address(token);
48+
}
49+
}

0 commit comments

Comments
 (0)